public async Task AsyncUnaryCall_Success_HttpRequestMessagePopulated()
        {
            // Arrange
            HttpRequestMessage?httpRequestMessage = null;

            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                httpRequestMessage = request;

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

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

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });
            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/ServiceName/MethodName"), httpRequestMessage.RequestUri);
            Assert.AreEqual(new MediaTypeHeaderValue("application/grpc"), httpRequestMessage.Content.Headers.ContentType);
            Assert.AreEqual(GrpcProtocolConstants.TEHeader, httpRequestMessage.Headers.TE.Single());
            Assert.AreEqual("identity,gzip", httpRequestMessage.Headers.GetValues(GrpcProtocolConstants.MessageAcceptEncodingHeader).Single());

            var userAgent = httpRequestMessage.Headers.UserAgent.Single();

            Assert.AreEqual(GrpcProtocolConstants.UserAgentHeader, userAgent);
            Assert.AreEqual("grpc-dotnet", userAgent.Product.Name);
            Assert.IsTrue(!string.IsNullOrEmpty(userAgent.Product.Version));
        }
Exemple #2
0
        public async Task AsyncUnaryCall_Success_RequestContentSent()
        {
            // Arrange
            HttpContent?content = null;

            var httpClient = ClientTestHelpers.CreateTestClient(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(httpClient);

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

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

            Assert.IsNotNull(content);

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

            Assert.AreEqual("World", requestMessage !.Name);
        }
        public async Task ClientStreamWriter_WriteWhileComplete_ErrorThrown()
        {
            // Arrange
            var streamContent = new SyncPointMemoryStream();
            var httpClient    = ClientTestHelpers.CreateTestClient(request =>
            {
                return(Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.OK, new StreamContent(streamContent))));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

            // Act
            var call = invoker.AsyncClientStreamingCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions());
            await call.RequestStream.CompleteAsync().DefaultTimeout();

            var resultTask = call.ResponseAsync;

            // Assert
            var writeException1 = await ExceptionAssert.ThrowsAsync <InvalidOperationException>(() => call.RequestStream.WriteAsync(new HelloRequest {
                Name = "1"
            })).DefaultTimeout();

            Assert.AreEqual("Request stream has already been completed.", writeException1.Message);

            await streamContent.AddDataAndWait(await ClientTestHelpers.GetResponseDataAsync(new HelloReply
            {
                Message = "Hello world 1"
            }).DefaultTimeout()).DefaultTimeout();

            await streamContent.AddDataAndWait(new byte[0]);

            var result = await resultTask.DefaultTimeout();

            Assert.AreEqual("Hello world 1", result.Message);

            var writeException2 = await ExceptionAssert.ThrowsAsync <InvalidOperationException>(() => call.RequestStream.WriteAsync(new HelloRequest {
                Name = "2"
            })).DefaultTimeout();

            Assert.AreEqual("Request stream has already been completed.", writeException2.Message);
        }
Exemple #4
0
        public async Task AsyncUnaryCall_Success_LogToFactory()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                // Trigger request stream serialization
                await request.Content.ReadAsStreamAsync().DefaultTimeout();

                var streamContent = await ClientTestHelpers.CreateResponseContent(new HelloReply
                {
                    Message = "Hello world"
                }).DefaultTimeout();

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });

            var testSink      = new TestSink();
            var loggerFactory = new TestLoggerFactory(testSink, true);

            var invoker = HttpClientCallInvokerFactory.Create(httpClient, loggerFactory);

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

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

            var logs = testSink.Writes.Where(w => w.LogLevel >= Microsoft.Extensions.Logging.LogLevel.Debug).ToList();

            Assert.AreEqual("Starting gRPC call. Method type: 'Unary', URI: '/ServiceName/MethodName'.", logs[0].State.ToString());
            AssertScope(logs[0]);

            Assert.AreEqual("Sending message.", logs[1].State.ToString());
            AssertScope(logs[1]);

            Assert.AreEqual("Reading message.", logs[2].State.ToString());
            AssertScope(logs[2]);

            Assert.AreEqual("Finished gRPC call.", logs[3].State.ToString());
            AssertScope(logs[3]);
        public async Task AsyncUnaryCall_Success_ResponseHeadersPopulated()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                HelloReply reply = new HelloReply
                {
                    Message = "Hello world"
                };

                var streamContent = await ClientTestHelpers.CreateResponseContent(reply).DefaultTimeout();
                var response      = ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent);
                response.Headers.Server.Add(new ProductInfoHeaderValue("TestName", "1.0"));
                response.Headers.Add("custom", "ABC");
                response.Headers.Add("binary-bin", Convert.ToBase64String(Encoding.UTF8.GetBytes("Hello world")));
                return(response);
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

            var responseHeaders2 = await call.ResponseHeadersAsync.DefaultTimeout();

            // Assert
            Assert.AreSame(responseHeaders1, responseHeaders2);

            var header = responseHeaders1.Single(h => h.Key == "server");

            Assert.AreEqual("TestName/1.0", header.Value);

            header = responseHeaders1.Single(h => h.Key == "custom");
            Assert.AreEqual("ABC", header.Value);

            header = responseHeaders1.Single(h => h.Key == "binary-bin");
            Assert.AreEqual(true, header.IsBinary);
            CollectionAssert.AreEqual(Encoding.UTF8.GetBytes("Hello world"), header.ValueBytes);
        }
        public async Task AsyncUnaryCall_HeadersReturned_ReturnsTrailers()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                var streamContent = await ClientTestHelpers.CreateResponseContent(new HelloReply()).DefaultTimeout();
                var response      = ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent);
                response.Headers.Add("custom", "ABC");
                response.TrailingHeaders.Add("custom-header", "value");
                return(response);
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

            var trailers = call.GetTrailers();

            // Assert
            Assert.AreEqual("value", trailers.Single(t => t.Key == "custom-header").Value);
        }
        public async Task AsyncUnaryCall_BadTrailersType_ThrowsError()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                var streamContent = await ClientTestHelpers.CreateResponseContent(new HelloReply()).DefaultTimeout();
                var response = ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent);
                response.RequestMessage.Properties["__ResponseTrailers"] = new object();
                response.Headers.Add("custom", "ABC");
                return response;
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

            // 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.", ex.Status.Detail);
            Assert.AreEqual(0, ex.Trailers.Count);
        }
        public async Task ReadAllAsync_CancelCallViaWithCancellation_ForEachExitedOnCancellation()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                var streamContent = await ClientTestHelpers.CreateResponsesContent(
                    new HelloReply
                {
                    Message = "Hello world 1"
                },
                    new HelloReply
                {
                    Message = "Hello world 2"
                }).DefaultTimeout();

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);
            var cts     = new CancellationTokenSource();

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

            var messages = new List <string>();
            var ex       = await ExceptionAssert.ThrowsAsync <RpcException>(async() =>
            {
                await foreach (var item in call.ResponseStream.ReadAllAsync().DefaultTimeout().WithCancellation(cts.Token))
                {
                    messages.Add(item.Message);

                    cts.Cancel();
                }
            }).DefaultTimeout();

            // Assert
            Assert.AreEqual(StatusCode.Cancelled, ex.StatusCode);
            Assert.AreEqual(1, messages.Count);
            Assert.AreEqual("Hello world 1", messages[0]);
        }
Exemple #9
0
        public async Task AsyncClientStreamingCall_DeadlineLargerThanMaxTimerDueTime_DeadlineExceeded()
        {
            // Arrange
            var testSink          = new TestSink();
            var testLoggerFactory = new TestLoggerFactory(testSink, true);

            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                var content = (PushStreamContent <HelloRequest, HelloReply>)request.Content;
                await content.PushComplete.DefaultTimeout();

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
            });
            var testSystemClock = new TestSystemClock(DateTime.UtcNow);
            var invoker         = HttpClientCallInvokerFactory.Create(httpClient, systemClock: testSystemClock, maxTimerPeriod: 20, loggerFactory: testLoggerFactory);
            var timeout         = TimeSpan.FromSeconds(0.2);
            var deadline        = testSystemClock.UtcNow.Add(timeout);

            // Act
            var call = invoker.AsyncClientStreamingCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions(deadline: deadline));

            // Assert
            var responseTask = call.ResponseAsync;

            await Task.Delay(timeout);

            // Update time so deadline exceeds correctly
            testSystemClock.UtcNow = deadline;

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

            Assert.AreEqual(StatusCode.DeadlineExceeded, ex.StatusCode);
            Assert.AreEqual(StatusCode.DeadlineExceeded, call.GetStatus().StatusCode);

            var write = testSink.Writes.First(w => w.EventId.Name == "DeadlineTimerRescheduled");

            Assert.AreEqual(LogLevel.Trace, write.LogLevel);
            Assert.AreEqual("Deadline timer triggered but 00:00:00.2000000 remaining before deadline exceeded. Deadline timer rescheduled.", write.Message);
        }
        public async Task CompositeCallCredentialsWithHttps_MetadataOnRequest()
        {
            // Arrange
            HttpRequestHeaders?requestHeaders = null;
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                requestHeaders = request.Headers;

                var reply = new HelloReply {
                    Message = "Hello world"
                };
                var streamContent = await ClientTestHelpers.CreateResponseContent(reply).DefaultTimeout();
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

            var first = CallCredentials.FromInterceptor(new AsyncAuthInterceptor((context, metadata) => {
                metadata.Add("first_authorization", "FIRST_SECRET_TOKEN");
                return(Task.CompletedTask);
            }));
            var second = CallCredentials.FromInterceptor(new AsyncAuthInterceptor((context, metadata) => {
                metadata.Add("second_authorization", "SECOND_SECRET_TOKEN");
                return(Task.CompletedTask);
            }));
            var third = CallCredentials.FromInterceptor(new AsyncAuthInterceptor((context, metadata) => {
                metadata.Add("third_authorization", "THIRD_SECRET_TOKEN");
                return(Task.CompletedTask);
            }));

            // Act
            var callCredentials = CallCredentials.Compose(first, second, third);
            var call            = invoker.AsyncUnaryCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions(credentials: callCredentials), new HelloRequest());
            await call.ResponseAsync.DefaultTimeout();

            // Assert
            Assert.AreEqual("FIRST_SECRET_TOKEN", requestHeaders !.GetValues("first_authorization").Single());
            Assert.AreEqual("SECOND_SECRET_TOKEN", requestHeaders !.GetValues("second_authorization").Single());
            Assert.AreEqual("THIRD_SECRET_TOKEN", requestHeaders !.GetValues("third_authorization").Single());
        }
        public async Task AsyncUnaryCall_InvalidStatus_ThrowError()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                var streamContent = await ClientTestHelpers.CreateResponseContent(new HelloReply()).DefaultTimeout();
                var response      = ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent, grpcStatusCode: null);
                response.TrailingHeaders.Add(GrpcProtocolConstants.StatusTrailer, "value");
                return(response);
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

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

            Assert.AreEqual("Unexpected grpc-status value: value", ex.Status.Detail);
            Assert.AreEqual(StatusCode.Cancelled, ex.StatusCode);
            Assert.AreEqual(StatusCode.Cancelled, call.GetStatus().StatusCode);
        }
        public async Task MoveNextAsync_CancelCall_EnumeratorThrows()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                var streamContent = await ClientTestHelpers.CreateResponsesContent(
                    new HelloReply
                {
                    Message = "Hello world 1"
                },
                    new HelloReply
                {
                    Message = "Hello world 2"
                }).DefaultTimeout();

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);
            var cts     = new CancellationTokenSource();

            // Act
            var call = invoker.AsyncServerStreamingCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions(cancellationToken: cts.Token), new HelloRequest());

            var enumerator = call.ResponseStream.ReadAllAsync().GetAsyncEnumerator();

            // Assert
            Assert.IsNull(enumerator.Current);

            Assert.IsTrue(await enumerator.MoveNextAsync().AsTask().DefaultTimeout());
            Assert.IsNotNull(enumerator.Current);
            Assert.AreEqual("Hello world 1", enumerator.Current.Message);

            cts.Cancel();

            var ex = await ExceptionAssert.ThrowsAsync <RpcException>(() => enumerator.MoveNextAsync().AsTask()).DefaultTimeout();

            Assert.AreEqual(StatusCode.Cancelled, ex.StatusCode);
            Assert.AreEqual(StatusCode.Cancelled, call.GetStatus().StatusCode);
        }
Exemple #13
0
        public async Task AsyncDuplexStreamingCall_MessageSmallerThanReceiveMaxMessageSize_Success()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(HandleRequest);
            var invoker    = HttpClientCallInvokerFactory.Create(httpClient);

            invoker.ReceiveMaxMessageSize = 100;

            // Act
            var call = invoker.AsyncDuplexStreamingCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions());
            await call.RequestStream.WriteAsync(new HelloRequest
            {
                Name = "World"
            });

            await call.RequestStream.CompleteAsync();

            // Assert
            await call.ResponseStream.MoveNext(CancellationToken.None).DefaultTimeout();

            Assert.AreEqual("Hello World", call.ResponseStream.Current.Message);
        }
        public void Intercept_InterceptorOrder_ExecutedInReversedOrder()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                var streamContent = await ClientTestHelpers.CreateResponseContent(new HelloReply {
                    Message = "PASS"
                }).DefaultTimeout();
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });

            var stringBuilder = new StringBuilder();
            var invoker       = HttpClientCallInvokerFactory.Create(httpClient);

            // Act
            var callInvoker = invoker.Intercept(metadata =>
            {
                stringBuilder.Append("interceptor1");
                return(metadata);
            }).Intercept(new CallbackInterceptor(() => stringBuilder.Append("array1")),
                         new CallbackInterceptor(() => stringBuilder.Append("array2")),
                         new CallbackInterceptor(() => stringBuilder.Append("array3")))
                              .Intercept(metadata =>
            {
                stringBuilder.Append("interceptor2");
                return(metadata);
            }).Intercept(metadata =>
            {
                stringBuilder.Append("interceptor3");
                return(metadata);
            });

            var result = callInvoker.BlockingUnaryCall(ClientTestHelpers.ServiceMethod, Host, new CallOptions(), new HelloRequest());

            // Assert
            Assert.AreEqual("PASS", result.Message);
            Assert.AreEqual("interceptor3interceptor2array1array2array3interceptor1", stringBuilder.ToString());
        }
Exemple #15
0
        public async Task AsyncDuplexStreamingCall_MessageLargerThanReceiveMaxMessageSize_ThrowsError()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(HandleRequest);
            var invoker    = HttpClientCallInvokerFactory.Create(httpClient);

            invoker.ReceiveMaxMessageSize = 1;

            // Act
            var call = invoker.AsyncDuplexStreamingCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions());
            await call.RequestStream.WriteAsync(new HelloRequest
            {
                Name = "World"
            });

            await call.RequestStream.CompleteAsync();

            // Assert
            var ex = await ExceptionAssert.ThrowsAsync <RpcException>(() => call.ResponseStream.MoveNext(CancellationToken.None));

            Assert.AreEqual(StatusCode.ResourceExhausted, ex.StatusCode);
            Assert.AreEqual("Received message exceeds the maximum configured message size.", ex.Status.Detail);
        }
        public async Task AsyncUnaryCall_SetSecondDeadline_RequestMessageContainsDeadlineHeader()
        {
            // Arrange
            HttpRequestMessage?httpRequestMessage = null;

            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                httpRequestMessage = request;

                var streamContent = await ClientTestHelpers.CreateResponseContent(new HelloReply()).DefaultTimeout();
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });
            var invoker = HttpClientCallInvokerFactory.Create(
                httpClient,
                systemClock: new TestSystemClock(new DateTime(2019, 11, 29, 1, 1, 1, DateTimeKind.Utc)));

            // Act
            await invoker.AsyncUnaryCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions(deadline : invoker.Channel.Clock.UtcNow.AddSeconds(1)), new HelloRequest());

            // Assert
            Assert.IsNotNull(httpRequestMessage);
            Assert.AreEqual("1S", httpRequestMessage !.Headers.GetValues(GrpcProtocolConstants.TimeoutHeader).Single());
        }
        public async Task AsyncClientStreamingCall_DeadlineDuringSend_ThrowOperationCanceledOnCancellation_ResponseThrowsDeadlineExceededStatus()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                var content = (PushStreamContent)request.Content;
                await content.PushComplete.DefaultTimeout();

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
            });
            var testSystemClock = new TestSystemClock(DateTime.UtcNow);
            var invoker         = HttpClientCallInvokerFactory.Create(httpClient, systemClock: testSystemClock, configure: o => o.ThrowOperationCanceledOnCancellation = true);

            // Act
            var call = invoker.AsyncClientStreamingCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions(deadline: testSystemClock.UtcNow.AddSeconds(0.5)));

            // Assert
            var responseTask = call.ResponseAsync;

            await ExceptionAssert.ThrowsAsync <OperationCanceledException>(() => responseTask).DefaultTimeout();

            Assert.AreEqual(StatusCode.DeadlineExceeded, call.GetStatus().StatusCode);
        }
        public async Task AsyncClientStreamingCall_DeadlineDuringWrite_ResponseThrowsDeadlineExceededStatus()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(request =>
            {
                var stream = new SyncPointMemoryStream();
                var content = new StreamContent(stream);
                return Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.OK, content, grpcStatusCode: null));
            });
            var systemClock = new TestSystemClock(DateTime.UtcNow);
            var invoker = HttpClientCallInvokerFactory.Create(httpClient, systemClock: systemClock);
            var deadline = systemClock.UtcNow.AddMilliseconds(0.1);

            // Act
            var call = invoker.AsyncClientStreamingCall<HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions(deadline: deadline));

            systemClock.UtcNow = deadline;

            // Assert
            var ex = await ExceptionAssert.ThrowsAsync<RpcException>(() => call.RequestStream.WriteAsync(new HelloRequest())).DefaultTimeout();
            Assert.AreEqual(StatusCode.DeadlineExceeded, ex.StatusCode);
            Assert.AreEqual(StatusCode.DeadlineExceeded, call.GetStatus().StatusCode);
        }
        public async Task AsyncUnaryCall_Non200HttpStatusCode_MappedToGrpcStatusCode(HttpStatusCode httpStatusCode, StatusCode statusCode)
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(request =>
            {
                var response = ResponseUtils.CreateResponse(httpStatusCode);
                return(Task.FromResult(response));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

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

            Assert.AreEqual(statusCode, ex.StatusCode);

            var status = call.GetStatus();

            Assert.AreEqual(statusCode, status.StatusCode);
            Assert.AreEqual("Bad gRPC response. HTTP status code: " + (int)httpStatusCode, status.Detail);
        }
        public async Task AsyncClientStreamingCall_DeadlineBeforeWrite_ResponseThrowsDeadlineExceededStatus()
        {
            // Arrange
            var tcs        = new TaskCompletionSource <object?>(TaskCreationOptions.RunContinuationsAsynchronously);
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                await tcs.Task.DefaultTimeout();
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
            });
            var systemClock = new TestSystemClock(DateTime.UtcNow);
            var invoker     = HttpClientCallInvokerFactory.Create(httpClient, systemClock: systemClock);

            // Act
            var call = invoker.AsyncClientStreamingCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions(deadline: systemClock.UtcNow.AddMilliseconds(10)));

            await Task.Delay(200); // Ensure the deadline has passed

            // Assert
            var ex = await ExceptionAssert.ThrowsAsync <RpcException>(() => call.RequestStream.WriteAsync(new HelloRequest())).DefaultTimeout();

            Assert.AreEqual(StatusCode.DeadlineExceeded, ex.StatusCode);
            Assert.AreEqual(StatusCode.DeadlineExceeded, call.GetStatus().StatusCode);
        }
Exemple #21
0
        public async Task Intercept_WrapClientStream_ClientStreamWrapperExecuted()
        {
            // Arrange
            var serviceMethod = new Method <string, string>(MethodType.Unary, "ServiceName", "Unary", Marshallers.StringMarshaller, Marshallers.StringMarshaller);

            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                var requestContent = await request.Content.ReadAsStreamAsync();
                await requestContent.CopyToAsync(new MemoryStream());

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

            var stringBuilder = new StringBuilder();
            var invoker       = HttpClientCallInvokerFactory.Create(httpClient);

            // Act
            var callInvoker = invoker.Intercept(new ClientStreamingCountingInterceptor());

            var call = callInvoker.AsyncClientStreamingCall(serviceMethod, Host, new CallOptions());
            await call.RequestStream.WriteAsync("A");

            await call.RequestStream.WriteAsync("B");

            await call.RequestStream.WriteAsync("C");

            await call.RequestStream.CompleteAsync();

            // Assert
            Assert.AreEqual("3", await call.ResponseAsync);

            Assert.AreEqual(StatusCode.OK, call.GetStatus().StatusCode);
            Assert.IsNotNull(call.GetTrailers());
        }
        public async Task MoveNextAsync_MultipleMessages_MessagesReceived()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                var streamContent = await ClientTestHelpers.CreateResponsesContent(
                    new HelloReply
                {
                    Message = "Hello world 1"
                },
                    new HelloReply
                {
                    Message = "Hello world 2"
                }).DefaultTimeout();

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

            var enumerator = call.ResponseStream.ReadAllAsync().GetAsyncEnumerator();

            // Assert
            Assert.IsNull(enumerator.Current);

            Assert.IsTrue(await enumerator.MoveNextAsync().AsTask().DefaultTimeout());
            Assert.IsNotNull(enumerator.Current);
            Assert.AreEqual("Hello world 1", enumerator.Current.Message);

            Assert.IsTrue(await enumerator.MoveNextAsync().AsTask().DefaultTimeout());
            Assert.IsNotNull(enumerator.Current);
            Assert.AreEqual("Hello world 2", enumerator.Current.Message);

            Assert.IsFalse(await enumerator.MoveNextAsync().AsTask().DefaultTimeout());
        }
        public async Task AsyncServerStreamingCall_MessagesReturnedTogether_MessagesReceived()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                var streamContent = await ClientTestHelpers.CreateResponsesContent(
                    new HelloReply
                {
                    Message = "Hello world 1"
                },
                    new HelloReply
                {
                    Message = "Hello world 2"
                }).DefaultTimeout();

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

            var responseStream = call.ResponseStream;

            // Assert
            Assert.IsNull(responseStream.Current);

            Assert.IsTrue(await responseStream.MoveNext(CancellationToken.None).DefaultTimeout());
            Assert.IsNotNull(responseStream.Current);
            Assert.AreEqual("Hello world 1", responseStream.Current.Message);

            Assert.IsTrue(await responseStream.MoveNext(CancellationToken.None).DefaultTimeout());
            Assert.IsNotNull(responseStream.Current);
            Assert.AreEqual("Hello world 2", responseStream.Current.Message);

            Assert.IsFalse(await responseStream.MoveNext(CancellationToken.None).DefaultTimeout());
        }
        public async Task CallCredentialsWithHttp_NoMetadataOnRequest()
        {
            // Arrange
            bool?hasAuthorizationValue = null;
            var  httpClient            = ClientTestHelpers.CreateTestClient(async request =>
            {
                hasAuthorizationValue = request.Headers.TryGetValues("authorization", out _);

                var reply = new HelloReply {
                    Message = "Hello world"
                };
                var streamContent = await ClientTestHelpers.CreateResponseContent(reply).DefaultTimeout();
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            }, new Uri("http://localhost"));

            var testSink      = new TestSink();
            var loggerFactory = new TestLoggerFactory(testSink, true);

            var invoker = HttpClientCallInvokerFactory.Create(httpClient, loggerFactory);

            // Act
            var callCredentials = CallCredentials.FromInterceptor((context, metadata) =>
            {
                metadata.Add("authorization", "SECRET_TOKEN");
                return(Task.CompletedTask);
            });
            var call = invoker.AsyncUnaryCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions(credentials: callCredentials), new HelloRequest());
            await call.ResponseAsync.DefaultTimeout();

            // Assert
            Assert.AreEqual(false, hasAuthorizationValue);

            var log = testSink.Writes.Single(w => w.EventId.Name == "CallCredentialsNotUsed");

            Assert.AreEqual("The configured CallCredentials were not used because the call does not use TLS.", log.State.ToString());
        }
Exemple #25
0
        public async Task AsyncClientStreamingCall_DeadlineDuringSend_ResponseThrowsDeadlineExceededStatus()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                var content = (PushStreamContent)request.Content;
                await content.PushComplete.DefaultTimeout();

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

            // Assert
            var responseTask = call.ResponseAsync;

            Assert.IsFalse(responseTask.IsCompleted, "Response not returned until client stream is complete.");

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

            Assert.AreEqual(StatusCode.DeadlineExceeded, ex.Status.StatusCode);
        }
Exemple #26
0
        public async Task AsyncServerStreamingCall_MessagesReturnedTogether_MessagesReceived()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(request =>
            {
                HelloReply reply = new HelloReply
                {
                    Message = "Hello world"
                };

                return(Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.OK, new ByteArrayContent(Array.Empty <byte>()))));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

            var responseStream = call.ResponseStream;

            // Assert
            Assert.IsNull(responseStream.Current);
            Assert.IsFalse(await responseStream.MoveNext(CancellationToken.None).DefaultTimeout());
            Assert.IsNull(responseStream.Current);
        }
        public async Task AsyncUnaryCall_ErrorParsingTrailers_ThrowsError()
        {
            // Arrange
            var testSink      = new TestSink();
            var loggerFactory = new TestLoggerFactory(testSink, true);

            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                var streamContent = await ClientTestHelpers.CreateResponseContent(new HelloReply()).DefaultTimeout();
                var response      = ResponseUtils.CreateResponse(
                    HttpStatusCode.OK,
                    streamContent,
                    grpcStatusCode: StatusCode.Aborted,
                    customTrailers: new Dictionary <string, string>
                {
                    ["blah-bin"] = "!"
                });
                response.Headers.Add("custom", "ABC");
                return(response);
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient, loggerFactory);

            // 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.Aborted, ex.StatusCode);
            Assert.AreEqual(null, ex.Status.Detail);
            Assert.AreEqual(0, ex.Trailers.Count);

            var log = testSink.Writes.Single(w => w.EventId.Name == "ErrorParsingTrailers");

            Assert.AreEqual("Error parsing trailers.", log.State.ToString());
            Assert.AreEqual("Invalid Base-64 header value.", log.Exception.Message);
        }
        public async Task AsyncDuplexStreamingCall_MessagesStreamed_MessagesReceived()
        {
            // Arrange
            var streamContent = new SyncPointMemoryStream();

            PushStreamContent?content = null;

            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                content = (PushStreamContent)request.Content;
                await content.PushComplete.DefaultTimeout();

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, new StreamContent(streamContent)));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

            var requestStream  = call.RequestStream;
            var responseStream = call.ResponseStream;

            // Assert
            await call.RequestStream.WriteAsync(new HelloRequest { Name = "1" }).DefaultTimeout();

            await call.RequestStream.WriteAsync(new HelloRequest { Name = "2" }).DefaultTimeout();

            await call.RequestStream.CompleteAsync().DefaultTimeout();

            Assert.IsNotNull(content);
            var requestContent = await content !.ReadAsStreamAsync().DefaultTimeout();
            var requestMessage = await requestContent.ReadStreamedMessageAsync(NullLogger.Instance, ClientTestHelpers.ServiceMethod.RequestMarshaller.Deserializer, CancellationToken.None).DefaultTimeout();

            Assert.AreEqual("1", requestMessage.Name);
            requestMessage = await requestContent.ReadStreamedMessageAsync(NullLogger.Instance, ClientTestHelpers.ServiceMethod.RequestMarshaller.Deserializer, CancellationToken.None).DefaultTimeout();

            Assert.AreEqual("2", requestMessage.Name);

            Assert.IsNull(responseStream.Current);

            var moveNextTask1 = responseStream.MoveNext(CancellationToken.None);

            Assert.IsFalse(moveNextTask1.IsCompleted);

            await streamContent.AddDataAndWait(await ClientTestHelpers.GetResponseDataAsync(new HelloReply
            {
                Message = "Hello world 1"
            }).DefaultTimeout()).DefaultTimeout();

            Assert.IsTrue(await moveNextTask1.DefaultTimeout());
            Assert.IsNotNull(responseStream.Current);
            Assert.AreEqual("Hello world 1", responseStream.Current.Message);

            var moveNextTask2 = responseStream.MoveNext(CancellationToken.None);

            Assert.IsFalse(moveNextTask2.IsCompleted);

            await streamContent.AddDataAndWait(await ClientTestHelpers.GetResponseDataAsync(new HelloReply
            {
                Message = "Hello world 2"
            }).DefaultTimeout()).DefaultTimeout();

            Assert.IsTrue(await moveNextTask2.DefaultTimeout());
            Assert.IsNotNull(responseStream.Current);
            Assert.AreEqual("Hello world 2", responseStream.Current.Message);

            var moveNextTask3 = responseStream.MoveNext(CancellationToken.None);

            Assert.IsFalse(moveNextTask3.IsCompleted);

            await streamContent.AddDataAndWait(Array.Empty <byte>()).DefaultTimeout();

            Assert.IsFalse(await moveNextTask3.DefaultTimeout());

            var moveNextTask4 = responseStream.MoveNext(CancellationToken.None);

            Assert.IsTrue(moveNextTask4.IsCompleted);
            Assert.IsFalse(await moveNextTask3.DefaultTimeout());
        }
        public async Task AsyncClientStreamingCall_Success_RequestContentSent()
        {
            // Arrange
            PushStreamContent <HelloRequest, HelloReply>?content = null;

            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                content = (PushStreamContent <HelloRequest, HelloReply>)request.Content;
                await content.PushComplete.DefaultTimeout();

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

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

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

            // Assert
            Assert.IsNotNull(call);
            Assert.IsNotNull(content);

            var responseTask = call.ResponseAsync;

            Assert.IsFalse(responseTask.IsCompleted, "Response not returned until client stream is complete.");

            var streamTask = content !.ReadAsStreamAsync();

            await call.RequestStream.WriteAsync(new HelloRequest { Name = "1" }).DefaultTimeout();

            await call.RequestStream.WriteAsync(new HelloRequest { Name = "2" }).DefaultTimeout();

            await call.RequestStream.CompleteAsync().DefaultTimeout();

            var requestContent = await streamTask.DefaultTimeout();

            var requestMessage = await requestContent.ReadMessageAsync(
                NullLogger.Instance,
                ClientTestHelpers.ServiceMethod.RequestMarshaller.ContextualDeserializer,
                GrpcProtocolConstants.IdentityGrpcEncoding,
                maximumMessageSize : null,
                GrpcProtocolConstants.DefaultCompressionProviders,
                singleMessage : false,
                CancellationToken.None).AsTask().DefaultTimeout();

            Assert.AreEqual("1", requestMessage !.Name);
            requestMessage = await requestContent.ReadMessageAsync(
                NullLogger.Instance,
                ClientTestHelpers.ServiceMethod.RequestMarshaller.ContextualDeserializer,
                GrpcProtocolConstants.IdentityGrpcEncoding,
                maximumMessageSize : null,
                GrpcProtocolConstants.DefaultCompressionProviders,
                singleMessage : false,
                CancellationToken.None).AsTask().DefaultTimeout();

            Assert.AreEqual("2", requestMessage !.Name);

            var responseMessage = await responseTask.DefaultTimeout();

            Assert.AreEqual("Hello world", responseMessage.Message);
        }
        public async Task AsyncUnaryCall_CompressMetadataSentWithRequest_RequestMessageCompressed(bool compressionDisabledOnOptions)
        {
            // Arrange
            HttpRequestMessage?httpRequestMessage = null;
            HelloRequest?      helloRequest       = null;
            bool?isRequestNotCompressed           = null;

            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                httpRequestMessage = request;

                var requestData        = await request.Content.ReadAsByteArrayAsync();
                isRequestNotCompressed = requestData[0] == 0;

                helloRequest = await StreamExtensions.ReadSingleMessageAsync(
                    new MemoryStream(requestData),
                    NullLogger.Instance,
                    ClientTestHelpers.ServiceMethod.RequestMarshaller.ContextualDeserializer,
                    "gzip",
                    maximumMessageSize: null,
                    GrpcProtocolConstants.DefaultCompressionProviders,
                    CancellationToken.None);

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

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

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });

            var compressionProviders = GrpcProtocolConstants.DefaultCompressionProviders.Values.ToList();

            compressionProviders.Add(new TestCompressionProvider());

            var invoker = HttpClientCallInvokerFactory.Create(httpClient, configure: o => o.CompressionProviders = compressionProviders);

            var compressionMetadata = CreateClientCompressionMetadata("gzip");
            var callOptions         = new CallOptions(headers: compressionMetadata);

            if (compressionDisabledOnOptions)
            {
                callOptions = callOptions.WithWriteOptions(new WriteOptions(WriteFlags.NoCompress));
            }

            // Act
            var call = invoker.AsyncUnaryCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, callOptions, new HelloRequest
            {
                Name = "Hello"
            });

            // Assert
            var response = await call.ResponseAsync;

            Assert.IsNotNull(response);
            Assert.AreEqual("Hello world", response.Message);

            Debug.Assert(httpRequestMessage != null);
            Assert.AreEqual("identity,gzip,deflate,test", httpRequestMessage.Headers.GetValues(GrpcProtocolConstants.MessageAcceptEncodingHeader).Single());
            Assert.AreEqual("gzip", httpRequestMessage.Headers.GetValues(GrpcProtocolConstants.MessageEncodingHeader).Single());
            Assert.AreEqual(false, httpRequestMessage.Headers.Contains(GrpcProtocolConstants.CompressionRequestAlgorithmHeader));

            Debug.Assert(helloRequest != null);
            Assert.AreEqual("Hello", helloRequest.Name);

            Assert.AreEqual(compressionDisabledOnOptions, isRequestNotCompressed);
        }