示例#1
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 log = testSink.Writes.Single(w => w.EventId.Name == "StartingCall");

            Assert.AreEqual("Starting gRPC call. Method type: 'Unary', URI: 'https://localhost/ServiceName/MethodName'.", log.State.ToString());
            AssertScope(log);

            log = testSink.Writes.Single(w => w.EventId.Name == "SendingMessage");
            Assert.AreEqual("Sending message.", log.State.ToString());
            AssertScope(log);

            log = testSink.Writes.Single(w => w.EventId.Name == "ReadingMessage");
            Assert.AreEqual("Reading message.", log.State.ToString());
            AssertScope(log);

            log = testSink.Writes.Single(w => w.EventId.Name == "FinishedCall");
            Assert.AreEqual("Finished gRPC call.", log.State.ToString());
            AssertScope(log);
示例#2
0
        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 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 ex = await ExceptionAssert.ThrowsAsync <RpcException>(() => call.RequestStream.WriteAsync(new HelloRequest())).DefaultTimeout();

            Assert.AreEqual(StatusCode.DeadlineExceeded, ex.Status.StatusCode);
        }
        public async Task AsyncClientStreamingCall_InvalidContentType_ResponseHeadersPopulated()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(request =>
            {
                var response = ResponseUtils.CreateResponse(HttpStatusCode.OK);
                response.Headers.Add("custom", "ABC");
                response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/plain");
                return(Task.FromResult(response));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

            // Assert
            Assert.AreEqual("ABC", responseHeaders.GetValue("custom"));
        }
        public async Task AsyncServerStreamingCall_Success_ResponseHeadersPopulated()
        {
            // 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");
                return(response);
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

            // Assert
            Assert.AreEqual("ABC", responseHeaders.GetValue("custom"));
        }
示例#5
0
        public void AsyncUnaryCall_CompressedResponseWithUnknownEncoding_ErrorThrown()
        {
            // Arrange
            HttpRequestMessage?httpRequestMessage = null;
            HelloRequest?      helloRequest       = null;

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

                var requestStream = await request.Content.ReadAsStreamAsync();

                helloRequest = await StreamExtensions.ReadSingleMessageAsync(
                    requestStream,
                    NullLogger.Instance,
                    ClientTestHelpers.ServiceMethod.RequestMarshaller.Deserializer,
                    "gzip",
                    CancellationToken.None);

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

                var compressionProvider = new GzipCompressionProvider(System.IO.Compression.CompressionLevel.Fastest);
                var streamContent       = await ClientTestHelpers.CreateResponseContent(reply, compressionProvider).DefaultTimeout();

                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent, grpcEncoding: "not-supported"));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

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

            Assert.AreEqual(StatusCode.Unimplemented, ex.StatusCode);
            Assert.AreEqual("Unsupported grpc-encoding value 'not-supported'. Supported encodings: gzip", ex.Status.Detail);
        }
        private static async Task StatusReturnedCore(StatusInterceptor interceptor, StatusCode statusCode)
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                if (statusCode == StatusCode.OK)
                {
                    var streamContent = await ClientTestHelpers.CreateResponseContent(new HelloReply {
                        Message = "PASS"
                    }).DefaultTimeout();
                    return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
                }
                else
                {
                    return(ResponseUtils.CreateHeadersOnlyResponse(HttpStatusCode.OK, statusCode));
                }
            });

            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

            // Act
            var callInvoker = invoker.Intercept(interceptor);

            var call = callInvoker.AsyncUnaryCall(ClientTestHelpers.ServiceMethod, Host, new CallOptions(), new HelloRequest());

            // Assert
            if (statusCode == StatusCode.OK)
            {
                var result = await call.ResponseAsync.DefaultTimeout();

                Assert.AreEqual("PASS", result.Message);
            }
            else
            {
                var ex = await ExceptionAssert.ThrowsAsync <RpcException>(() => call.ResponseAsync).DefaultTimeout();

                Assert.AreEqual(statusCode, ex.StatusCode);
            }

            var interceptorStatusCode = await interceptor.GetStatusCodeAsync().DefaultTimeout();

            Assert.AreEqual(statusCode, interceptorStatusCode);
        }
示例#7
0
        public async Task AsyncUnaryCall_UnknownCompressMetadataSentWithRequest_ThrowsError()
        {
            // Arrange
            HttpRequestMessage?httpRequestMessage = null;
            HelloRequest?      helloRequest       = null;

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

                var requestStream = await request.Content.ReadAsStreamAsync();

                helloRequest = await StreamExtensions.ReadSingleMessageAsync(
                    requestStream,
                    NullLogger.Instance,
                    ClientTestHelpers.ServiceMethod.RequestMarshaller.ContextualDeserializer,
                    "gzip",
                    maximumMessageSize: null,
                    CancellationToken.None);

                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 compressionMetadata = CreateClientCompressionMetadata("not-supported");
            var call = invoker.AsyncUnaryCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions(headers: compressionMetadata), new HelloRequest
            {
                Name = "Hello"
            });

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

            Assert.AreEqual("Could not find compression provider for 'not-supported'.", ex.Message);
        }
示例#8
0
        public async Task AsyncUnaryCall_MessageSmallerThanSendMaxMessageSize_Success()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(HandleRequest);
            var invoker    = HttpClientCallInvokerFactory.Create(httpClient);

            invoker.SendMaxMessageSize = 100;

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

            // Assert
            var response = await call.ResponseAsync.DefaultTimeout();

            Assert.AreEqual("Hello World", response.Message);
        }
        public async Task AsyncServerStreamingCall_DeadlineStatusResponse_ThrowOperationCanceledOnCancellation_ResponseThrowsDeadlineExceededStatus()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(request =>
            {
                return Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.OK, new StringContent(string.Empty), StatusCode.DeadlineExceeded));
            });
            var testSystemClock = new TestSystemClock(DateTime.UtcNow);
            var invoker = HttpClientCallInvokerFactory.Create(httpClient, systemClock: testSystemClock, configure: o => o.ThrowOperationCanceledOnCancellation = true, disableClientDeadline: true);

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

            // Assert
            var moveNextTask = call.ResponseStream.MoveNext(CancellationToken.None);

            await ExceptionAssert.ThrowsAsync<OperationCanceledException>(() => moveNextTask).DefaultTimeout();
            Assert.AreEqual(StatusCode.DeadlineExceeded, call.GetStatus().StatusCode);
        }
示例#10
0
        public void AsyncUnaryCall_UnfinishedCall_ThrowsError()
        {
            // Arrange
            var tcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);

            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                await tcs.Task.DefaultTimeout();
                throw new Exception("Test shouldn't reach here.");
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

            // Assert
            Assert.AreEqual("Can't get the call trailers because the call has not completed successfully.", ex.Message);
        }
        public async Task AsyncServerStreamingCall_NoContent_NoMessagesReturned()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(request =>
            {
                return(Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.OK, new ByteArrayContent(Array.Empty <byte>()))));
            });
            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.IsFalse(await responseStream.MoveNext(CancellationToken.None).DefaultTimeout());
            Assert.IsNull(responseStream.Current);
        }
示例#12
0
        public async Task AsyncUnaryCall_CompressedResponse_ResponseMessageDecompressed()
        {
            // Arrange
            HttpRequestMessage?httpRequestMessage = null;
            HelloRequest?      helloRequest       = null;

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

                var requestStream = await request.Content.ReadAsStreamAsync();

                helloRequest = await StreamExtensions.ReadSingleMessageAsync(
                    requestStream,
                    NullLogger.Instance,
                    ClientTestHelpers.ServiceMethod.RequestMarshaller.Deserializer,
                    "gzip",
                    CancellationToken.None);

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

                var compressionProvider = new GzipCompressionProvider(System.IO.Compression.CompressionLevel.Fastest);
                var streamContent       = await ClientTestHelpers.CreateResponseContent(reply, compressionProvider).DefaultTimeout();

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

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

            // Assert
            var response = await call.ResponseAsync;

            Assert.IsNotNull(response);
            Assert.AreEqual("Hello world", response.Message);
        }
示例#13
0
        public void AsyncClientStreamingCall_UncompleteWriter_ThrowsError()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(request =>
            {
                var stream = new SyncPointMemoryStream();

                var response = ResponseUtils.CreateResponse(HttpStatusCode.OK, new StreamContent(stream), grpcStatusCode: null);
                return(Task.FromResult(response));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

            // Assert
            Assert.AreEqual("Can't get the call trailers because the call has not completed successfully.", ex.Message);
        }
示例#14
0
        public async Task AsyncUnaryCall_ErrorSendingRequest_ThrowsError()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(request =>
            {
                return(Task.FromException <HttpResponseMessage>(new Exception("An error!")));
            });
            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.Internal, ex.StatusCode);
            Assert.AreEqual("Error starting gRPC call. Exception: An error!", ex.Status.Detail);
            Assert.AreEqual("An error!", ex.Status.DebugException.Message);
            Assert.AreEqual(StatusCode.Internal, call.GetStatus().StatusCode);
        }
        public async Task ClientStreamWriter_WriteAfterResponseHasFinished_ErrorThrown()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(request =>
            {
                return(Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.OK)));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

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

            // Assert
            Assert.AreEqual("Can't write the message because the call is complete.", ex.Message);
            Assert.AreEqual(StatusCode.Internal, call.GetStatus().StatusCode);
            Assert.AreEqual("Failed to deserialize response message.", call.GetStatus().Detail);
        }
示例#16
0
        public void AsyncUnaryCall_ErrorCall_ThrowsError()
        {
            // Arrange
            var tcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);

            var httpClient = ClientTestHelpers.CreateTestClient(request =>
            {
                return(Task.FromException <HttpResponseMessage>(new Exception("An error!")));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

            // Assert
            Assert.AreEqual("Can't get the call trailers because an error occured when making the request.", ex.Message);
            Assert.AreEqual("An error!", ex.InnerException?.InnerException?.Message);
        }
示例#17
0
        public void AsyncServerStreamingCall_DeadlineDuringWrite_ResponseThrowsDeadlineExceededStatus()
        {
            // Arrange
            var httpClient = TestHelpers.CreateTestClient(request =>
            {
                var stream  = new SyncPointMemoryStream();
                var content = new StreamContent(stream);
                return(Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.OK, content)));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

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

            Assert.AreEqual(StatusCode.DeadlineExceeded, ex.Status.StatusCode);
        }
示例#18
0
        public async Task AsyncUnaryCall_ExceedDeadlineWithActiveCalls_Failure()
        {
            // Arrange
            var testSink = new TestSink();
            var services = new ServiceCollection();

            services.AddLogging(b =>
            {
                b.AddProvider(new TestLoggerProvider(testSink));
            });
            services.AddNUnitLogger();
            var provider = services.BuildServiceProvider();

            var tcs = new TaskCompletionSource <HttpResponseMessage>(TaskCreationOptions.RunContinuationsAsynchronously);

            var callCount  = 0;
            var httpClient = ClientTestHelpers.CreateTestClient(async(request, ct) =>
            {
                // Ensure SendAsync call doesn't hang upon cancellation by gRPC client.
                using var registration = ct.Register(() => tcs.TrySetCanceled());

                Interlocked.Increment(ref callCount);
                return(await tcs.Task);
            });
            var serviceConfig = ServiceConfigHelpers.CreateHedgingServiceConfig(hedgingDelay: TimeSpan.FromMilliseconds(200));
            var invoker       = HttpClientCallInvokerFactory.Create(httpClient, loggerFactory: provider.GetRequiredService <ILoggerFactory>(), serviceConfig: serviceConfig);

            // Act
            var call = invoker.AsyncUnaryCall <HelloRequest, HelloReply>(ClientTestHelpers.ServiceMethod, string.Empty, new CallOptions(deadline: DateTime.UtcNow.AddMilliseconds(100)), new HelloRequest {
                Name = "World"
            });

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

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

            var write = testSink.Writes.Single(w => w.EventId.Name == "CallCommited");

            Assert.AreEqual("Call commited. Reason: DeadlineExceeded", write.State.ToString());
        }
示例#19
0
        public async Task AsyncClientStreamingCall_InvalidContentType_ThrowsError()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(request =>
            {
                var response = ResponseUtils.CreateResponse(HttpStatusCode.OK);
                response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/plain");
                return(Task.FromResult(response));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

            // Assert
            Assert.AreEqual(StatusCode.Cancelled, ex.StatusCode);
            Assert.AreEqual("Bad gRPC response. Invalid content-type value: text/plain", ex.Status.Detail);
        }
示例#20
0
        public async Task UnaryCall_Http1Response_ThrowError()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(async request =>
            {
                var streamContent = await ClientTestHelpers.CreateResponseContent(new HelloReply()).DefaultTimeout();
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent, version: new Version(1, 1)));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

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

            Assert.AreEqual(StatusCode.Internal, ex.StatusCode);
            Assert.AreEqual("Bad gRPC response. Response protocol downgraded to HTTP/1.1.", ex.Status.Detail);
        }
示例#21
0
        public async Task AsyncClientStreamingCall_CompleteWriter_ReturnsTrailers()
        {
            // Arrange
            var trailingHeadersWrittenTcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously);

            var httpClient = ClientTestHelpers.CreateTestClient(request =>
            {
                var content  = (PushStreamContent)request.Content;
                var stream   = new SyncPointMemoryStream();
                var response = ResponseUtils.CreateResponse(HttpStatusCode.OK, new StreamContent(stream));

                _ = Task.Run(async() =>
                {
                    // Add a response message after the client has completed
                    await content.PushComplete.DefaultTimeout();

                    var messageData = await ClientTestHelpers.GetResponseDataAsync(new HelloReply {
                        Message = "Hello world"
                    }).DefaultTimeout();
                    await stream.AddDataAndWait(messageData).DefaultTimeout();
                    await stream.AddDataAndWait(Array.Empty <byte>()).DefaultTimeout();

                    response.TrailingHeaders.Add("custom-header", "value");
                    trailingHeadersWrittenTcs.SetResult(true);
                });

                return(Task.FromResult(response));
            });

            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

            await Task.WhenAll(call.ResponseAsync, trailingHeadersWrittenTcs.Task).DefaultTimeout();

            var trailers = call.GetTrailers();

            // Assert
            Assert.AreEqual("value", trailers.Single(t => t.Key == "custom-header").Value);
        }
        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());
        }
示例#23
0
        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(o => stringBuilder.Append("array1")),
                new CallbackInterceptor(o => stringBuilder.Append("array2")),
                new CallbackInterceptor(o => 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());
        }
示例#24
0
        public void AsyncUnaryCall_SetNonUtcDeadline_ThrowError()
        {
            // Arrange
            HttpRequestMessage httpRequestMessage = null;

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

                var streamContent = await TestHelpers.CreateResponseContent(new HelloReply()).DefaultTimeout();
                return(ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

            // Act
            var ex = Assert.ThrowsAsync <InvalidOperationException>(async() => await invoker.AsyncUnaryCall <HelloRequest, HelloReply>(TestHelpers.ServiceMethod, null, new CallOptions(deadline: new DateTime(2000, DateTimeKind.Local)), new HelloRequest()));

            // Assert
            Assert.AreEqual("Deadline must have a kind DateTimeKind.Utc or be equal to DateTime.MaxValue or DateTime.MinValue.", ex.Message);
        }
示例#25
0
        public async Task ClientStreamWriter_WriteWithInvalidHttpStatus_ErrorThrown()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(request =>
            {
                var streamContent = new StreamContent(new SyncPointMemoryStream());
                return(Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.NotFound, streamContent)));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

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

            Assert.AreEqual("Can't write the message because the call is complete.", ex.Message);
        }
示例#26
0
        public void ClientStreamWriter_WriteWithInvalidHttpStatus_ErrorThrown()
        {
            // Arrange
            var httpClient = TestHelpers.CreateTestClient(request =>
            {
                var streamContent = new StreamContent(new SyncPointMemoryStream());
                return(Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.NotFound, streamContent)));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

            // Act
            var call = invoker.AsyncClientStreamingCall <HelloRequest, HelloReply>(TestHelpers.ServiceMethod, null, new CallOptions());

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

            Assert.AreEqual("Bad gRPC response. Expected HTTP status code 200. Got status code: 404", ex.Message);
        }
        public async Task AsyncClientStreamingCall_NotFoundStatus_ResponseHeadersPopulated()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(request =>
            {
                var response = ResponseUtils.CreateResponse(HttpStatusCode.NotFound);
                response.Headers.Add("custom", "ABC");
                return(Task.FromResult(response));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

            // Assert
            var header = responseHeaders.Single(h => h.Key == "custom");

            Assert.AreEqual("ABC", header.Value);
        }
示例#28
0
        public async Task ClientStreamWriter_CallThrowsException_WriteAsyncThrowsError()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(request =>
            {
                return(Task.FromException <HttpResponseMessage>(new InvalidOperationException("Error!")));
            });
            var invoker = HttpClientCallInvokerFactory.Create(httpClient);

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

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

            // Assert
            Assert.AreEqual("Error starting gRPC call. InvalidOperationException: Error!", writeException.Status.Detail);
            Assert.AreEqual("Error starting gRPC call. InvalidOperationException: Error!", resultException.Status.Detail);
            Assert.AreEqual(StatusCode.Internal, call.GetStatus().StatusCode);
        }
        public async Task AsyncDuplexStreamingCall_MessageSmallerThanReceiveMaxMessageSize_Success()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(HandleRequest);
            var invoker    = HttpClientCallInvokerFactory.Create(httpClient, configure: o => o.MaxReceiveMessageSize = 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().DefaultTimeout();

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

            Assert.AreEqual("Hello World", call.ResponseStream.Current.Message);
        }
示例#30
0
        public async Task AsyncClientStreamingCall_DeadlineStatusResponse_ResponseThrowsDeadlineExceededStatus()
        {
            // Arrange
            var httpClient = ClientTestHelpers.CreateTestClient(request =>
            {
                return Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.OK, new StringContent(string.Empty), StatusCode.DeadlineExceeded));
            });
            var testSystemClock = new TestSystemClock(DateTime.UtcNow);
            var invoker = HttpClientCallInvokerFactory.Create(httpClient, systemClock: testSystemClock, disableClientDeadline: 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;

            var ex = await ExceptionAssert.ThrowsAsync<RpcException>(() => responseTask).DefaultTimeout();
            Assert.AreEqual(StatusCode.DeadlineExceeded, ex.StatusCode);
            Assert.AreEqual(StatusCode.DeadlineExceeded, call.GetStatus().StatusCode);
        }