Example #1
0
        public async Task AsyncUnaryCall_SubdirectoryHandlerConfigured_RequestUriChanged()
        {
            // Arrange
            HttpRequestMessage?httpRequestMessage = null;

            var handler = TestHttpMessageHandler.Create(async r =>
            {
                httpRequestMessage = r;

                var reply = new HelloReply
                {
                    Message = "Hello world"
                };

                var streamContent = await ClientTestHelpers.CreateResponseContent(reply).DefaultTimeout();
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });

            var httpClient = new HttpClient(new SubdirectoryHandler(handler, "/TestSubdirectory"));

            httpClient.BaseAddress = new Uri("https://localhost");

            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

            // Act
            var rs = await invoker.AsyncUnaryCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions(), new HelloRequest());

            // Assert
            Assert.AreEqual("Hello world", rs.Message);

            Assert.IsNotNull(httpRequestMessage);
            Assert.AreEqual(new Version(2, 0), httpRequestMessage !.Version);
            Assert.AreEqual(HttpMethod.Post, httpRequestMessage.Method);
            Assert.AreEqual(new Uri("https://localhost/TestSubdirectory/ServiceName/MethodName"), httpRequestMessage.RequestUri);
        }
        public async Task MoveNext_StreamThrowsIOException_ThrowErrorUnavailable()
        {
            // Arrange
            var handler = TestHttpMessageHandler.Create(request =>
            {
                var stream  = new TestStream();
                var content = new StreamContent(stream);
                return(Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.OK, content)));
            });

            var testSink          = new TestSink(e => e.LogLevel >= LogLevel.Error);
            var testLoggerFactory = new TestLoggerFactory(testSink, enabled: true);

            var channel = CreateChannel(handler, "http://localhost", loggerFactory: testLoggerFactory);
            var call    = CreateGrpcCall(channel);

            call.StartServerStreaming(new HelloRequest());

            // Act
            var ex = await ExceptionAssert.ThrowsAsync <RpcException>(() => call.ClientStreamReader !.MoveNext(CancellationToken.None)).DefaultTimeout();

            // Assert
            Assert.AreEqual(StatusCode.Unavailable, ex.StatusCode);
            Assert.AreEqual("Error reading next message. IOException: Test", ex.Status.Detail);
        }
Example #3
0
        public async Task ResolverReturnsNoAddresses_DeadlineWhileWaitForReady_Error()
        {
            // Arrange
            var testMessageHandler = TestHttpMessageHandler.Create(async request =>
            {
                var reply = new HelloReply {
                    Message = "Hello world"
                };
                var streamContent = await ClientTestHelpers.CreateResponseContent(reply).DefaultTimeout();
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });

            var services = new ServiceCollection();
            var resolver = new TestResolver();

            services.AddSingleton <ResolverFactory>(new TestResolverFactory(resolver));
            services.AddSingleton <ISubchannelTransportFactory>(new TestSubchannelTransportFactory());

            var invoker = HttpClientCallInvokerFactory.Create(testMessageHandler, "test:///localhost", configure: o =>
            {
                o.Credentials     = ChannelCredentials.Insecure;
                o.ServiceProvider = services.BuildServiceProvider();
            });

            // Act
            var callOptions = new CallOptions(deadline: DateTime.UtcNow.AddSeconds(0.2)).WithWaitForReady();
            var call        = invoker.AsyncUnaryCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, callOptions, new HelloRequest());

            var ex = await ExceptionAssert.ThrowsAsync <RpcException>(() => call.ResponseAsync).DefaultTimeout();

            Assert.AreEqual(StatusCode.DeadlineExceeded, ex.StatusCode);
            Assert.AreEqual(string.Empty, ex.Status.Detail);
        }
        public void GlobalSetup()
        {
            _content =
                "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed at ligula nec orci placerat mollis. " +
                "Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut aliquet non nunc id lobortis. " +
                "In tincidunt ac sapien sit amet consequat. Interdum et malesuada fames ac ante ipsum primis in faucibus. " +
                "Duis vel tristique ipsum, eget hendrerit justo. Donec accumsan, purus quis cursus auctor, sapien nisi " +
                "lacinia ligula, ut vehicula lorem augue vel est. Vestibulum finibus ornare vulputate.";

            var requestMessage = GetMessageData(new HelloReply {
                Message = _content
            });

            var handler = TestHttpMessageHandler.Create(async r =>
            {
                await r.Content.CopyToAsync(Stream.Null);

                var content = new ByteArrayContent(requestMessage);
                content.Headers.ContentType = new MediaTypeHeaderValue("application/grpc");

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, content, grpcEncoding: ResponseCompressionAlgorithm));
            });

            var channel = GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions
            {
                HttpHandler          = handler,
                CompressionProviders = CompressionProviders
            });

            _client = new Greeter.GreeterClient(channel);
        }
        public async Task AsyncUnaryCall_Success_RequestContentSent()
        {
            // Arrange
            HttpContent?content = null;

            var handler = TestHttpMessageHandler.Create(async request =>
            {
                content = request.Content;

                HelloReply reply = new HelloReply
                {
                    Message = "Hello world"
                };

                var streamContent = await ClientTestHelpers.CreateResponseContent(reply).DefaultTimeout();

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });
            var invoker = HttpClientCallInvokerFactory.Create(handler, "http://localhost");

            // Act
            var rs = await invoker.AsyncUnaryCall <HelloRequest, HelloReply>(
                ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions(), new HelloRequest { Name = "World" }).ResponseAsync.DefaultTimeout();

            // Assert
            Assert.AreEqual("Hello world", rs.Message);

            Assert.IsNotNull(content);

            var requestContent = await content !.ReadAsStreamAsync().DefaultTimeout();
            var requestMessage = await StreamSerializationHelper.ReadMessageAsync(
                requestContent,
                ClientTestHelpers.ServiceMethod.RequestMarshaller.ContextualDeserializer,
                GrpcProtocolConstants.IdentityGrpcEncoding,
                maximumMessageSize : null,
                GrpcProtocolConstants.DefaultCompressionProviders,
                singleMessage : true,
                CancellationToken.None).DefaultTimeout();

            Assert.AreEqual("World", requestMessage !.Name);
        }
Example #6
0
        public async Task AsyncUnaryCall_NoTrailers_WinHttpHandler_ThrowsError()
        {
            // Arrange
            var httpMessageHandler = TestHttpMessageHandler.Create(async request =>
            {
                var streamContent = await ClientTestHelpers.CreateResponseContent(new HelloReply()).DefaultTimeout();
                var response = ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent);
                response.RequestMessage.Properties.Remove("__ResponseTrailers");
                response.Headers.Add("custom", "ABC");
                return response;
            });
            var invoker = HttpClientCallInvokerFactory.Create(new WinHttpHandler(httpMessageHandler), "https://localhost");

            // Act
            var call = invoker.AsyncUnaryCall<HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions(), new HelloRequest());
            var ex = await ExceptionAssert.ThrowsAsync<RpcException>(() => call.ResponseAsync).DefaultTimeout();

            // Assert
            Assert.AreEqual(StatusCode.Cancelled, ex.StatusCode);
            Assert.AreEqual("No grpc-status found on response. Using gRPC with WinHttp has Windows and package version requirements. See https://aka.ms/aspnet/grpc/netstandard for details.", ex.Status.Detail);
            Assert.AreEqual(0, ex.Trailers.Count);
        }
Example #7
0
        public void GlobalSetup()
        {
            var ms = new MemoryStream();

            MessageHelpers.WriteMessage(ms, new HelloReply());
            var requestMessage = ms.ToArray();

            var handler = TestHttpMessageHandler.Create(r =>
            {
                var content = new ByteArrayContent(requestMessage);
                content.Headers.ContentType = new MediaTypeHeaderValue("application/grpc");

                return(Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.OK, content)));
            });

            var httpClient = new HttpClient(handler);

            var channel = GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions
            {
                HttpClient = httpClient
            });

            _client = new Greeter.GreeterClient(channel);
        }
        public async Task CreateClient_ServerCallContextAndUserCancellationToken_PropogatedDeadlineAndCancellation(Canceller canceller)
        {
            // Arrange
            var baseAddress = new Uri("http://localhost");
            var deadline    = DateTime.UtcNow.AddDays(1);
            var contextCts  = new CancellationTokenSource();
            var userCts     = new CancellationTokenSource();
            var tcs         = new TaskCompletionSource <object?>(TaskCreationOptions.RunContinuationsAsynchronously);

            CallOptions options = default;

            var handler = TestHttpMessageHandler.Create(async(r, token) =>
            {
                token.Register(() => tcs.SetCanceled());

                await tcs.Task;

                var streamContent = await ClientTestHelpers.CreateResponseContent(new HelloReply()).DefaultTimeout();
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });

            var services = new ServiceCollection();

            services.AddOptions();
            services.AddSingleton(CreateHttpContextAccessorWithServerCallContext(deadline, contextCts.Token));
            services
            .AddGrpcClient <Greeter.GreeterClient>(o =>
            {
                o.Address = baseAddress;
            })
            .EnableCallContextPropagation()
            .AddInterceptor(() => new CallbackInterceptor(o => options = o))
            .ConfigurePrimaryHttpMessageHandler(() => handler);

            var serviceProvider = services.BuildServiceProvider(validateScopes: true);

            var clientFactory = CreateGrpcClientFactory(serviceProvider);
            var client        = clientFactory.CreateClient <Greeter.GreeterClient>(nameof(Greeter.GreeterClient));

            // Act
            using var call = client.SayHelloAsync(new HelloRequest(), cancellationToken: userCts.Token);
            var responseTask = call.ResponseAsync;

            // Assert
            Assert.AreEqual(deadline, options.Deadline);

            // CancellationToken passed to call is a linked cancellation token.
            // It's created from the context and user tokens.
            Assert.AreNotEqual(contextCts.Token, options.CancellationToken);
            Assert.AreNotEqual(userCts.Token, options.CancellationToken);
            Assert.AreNotEqual(CancellationToken.None, options.CancellationToken);

            Assert.IsFalse(responseTask.IsCompleted);

            // Either CTS should cancel call.
            switch (canceller)
            {
            case Canceller.Context:
                contextCts.Cancel();
                break;

            case Canceller.User:
                userCts.Cancel();
                break;
            }

            var ex = await ExceptionAssert.ThrowsAsync <RpcException>(() => responseTask).DefaultTimeout();

            Assert.AreEqual(StatusCode.Cancelled, ex.StatusCode);
            ex = await ExceptionAssert.ThrowsAsync <RpcException>(() => call.ResponseHeadersAsync).DefaultTimeout();

            Assert.AreEqual(StatusCode.Cancelled, ex.StatusCode);

            Assert.AreEqual(StatusCode.Cancelled, call.GetStatus().StatusCode);
            Assert.Throws <InvalidOperationException>(() => call.GetTrailers());
        }