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)); }
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); }
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]); }
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); }
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()); }
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); }
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()); }
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); }
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); }