public async Task HostActivityTags_ReturnedInTrailers_Success() { // Arrange var requestMessage = new HelloRequest { Name = "World" }; var ms = new MemoryStream(); MessageHelpers.WriteMessage(ms, requestMessage); var httpRequest = GrpcHttpHelper.Create("Greet.Greeter/SayHello"); httpRequest.Content = new GrpcStreamContent(ms); httpRequest.Headers.Add("return-tags-trailers", "true"); // Act var response = await Fixture.Client.SendAsync(httpRequest).DefaultTimeout(); // Assert var responseMessage = await response.GetSuccessfulGrpcMessageAsync <HelloReply>().DefaultTimeout(); Assert.AreEqual("Hello World", responseMessage.Message); response.AssertTrailerStatus(); var trailers = response.TrailingHeaders; Assert.AreEqual("0", trailers.GetValues("grpc.status_code").Single()); Assert.AreEqual("/Greet.Greeter/SayHello", trailers.GetValues("grpc.method").Single()); }
public async Task SendCompressedMessage_ServiceHasNoCompressionConfigured_ResponseIdentityEncoding() { // Arrange var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage, "gzip"); var httpRequest = GrpcHttpHelper.Create("Greet.Greeter/SayHello"); httpRequest.Headers.Add(GrpcProtocolConstants.MessageEncodingHeader, "gzip"); httpRequest.Content = new GrpcStreamContent(requestStream); // Act var response = await Fixture.Client.SendAsync(httpRequest).DefaultTimeout(); // Assert Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); Assert.IsFalse(response.Headers.Contains(GrpcProtocolConstants.MessageEncodingHeader)); var responseMessage = MessageHelpers.AssertReadMessage <HelloReply>(await response.Content.ReadAsByteArrayAsync().DefaultTimeout()); Assert.AreEqual("Hello World", responseMessage.Message); response.AssertTrailerStatus(); }
public async Task SendCompressedMessageWithIdentity_ReturnInternalError() { // Arrange SetExpectedErrorsFilter(writeContext => { return(writeContext.LoggerName == "SERVER " + typeof(GreeterService).FullName && writeContext.EventId.Name == "RpcConnectionError" && writeContext.State.ToString() == "Error status code 'Internal' raised."); }); var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage, "gzip"); var httpRequest = GrpcHttpHelper.Create("Greet.Greeter/SayHello"); httpRequest.Headers.Add(GrpcProtocolConstants.MessageEncodingHeader, "identity"); httpRequest.Content = new GrpcStreamContent(requestStream); // Act var response = await Fixture.Client.SendAsync(httpRequest).DefaultTimeout(); // Assert Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); response.AssertTrailerStatus(StatusCode.Internal, "Request sent 'identity' grpc-encoding value with compressed message."); }
public async Task MultipleMessagesThenClose_SuccessResponse() { // Arrange var ms = new MemoryStream(); MessageHelpers.WriteMessage(ms, new CounterRequest { Count = 1 }); var httpRequest = GrpcHttpHelper.Create("Count.Counter/AccumulateCount"); httpRequest.Content = new PushStreamContent( async s => { await s.WriteAsync(ms.ToArray()).AsTask().DefaultTimeout(); await s.WriteAsync(ms.ToArray()).AsTask().DefaultTimeout(); await s.WriteAsync(Array.Empty <byte>()).AsTask().DefaultTimeout(); }); // Act var responseTask = Fixture.Client.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead); // Assert Assert.IsFalse(responseTask.IsCompleted, "Server should wait for client to finish streaming"); var response = await responseTask.DefaultTimeout(); var reply = await response.GetSuccessfulGrpcMessageAsync <CounterReply>().DefaultTimeout(); Assert.AreEqual(2, reply.Count); response.AssertTrailerStatus(); }
public async Task StreamedMessage_SuccessResponseAfterMessageReceived() { // Arrange var requestMessage = new HelloRequest { Name = "World" }; var ms = new MemoryStream(); MessageHelpers.WriteMessage(ms, requestMessage); var streamingContent = new StreamingContent(); var httpRequest = GrpcHttpHelper.Create("Greet.Greeter/SayHello"); httpRequest.Content = streamingContent; // Act var responseTask = Fixture.Client.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead); // Assert Assert.IsFalse(responseTask.IsCompleted, "Server should wait for client to finish streaming"); var requestStream = await streamingContent.GetRequestStreamAsync().DefaultTimeout(); await requestStream.WriteAsync(ms.ToArray()).AsTask().DefaultTimeout(); streamingContent.Complete(); var response = await responseTask.DefaultTimeout(); var responseMessage = await response.GetSuccessfulGrpcMessageAsync <HelloReply>().DefaultTimeout(); Assert.AreEqual("Hello World", responseMessage.Message); }
public async Task UnimplementedContentType_ReturnUnimplementedForAppGrpc(string contentType, string httpMethod, HttpStatusCode httpStatusCode, StatusCode?grpcStatusCode) { // Arrange var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage); var httpRequest = GrpcHttpHelper.Create("HasMapped/Extra"); httpRequest.Method = new HttpMethod(httpMethod); httpRequest.Content = new StreamContent(requestStream); httpRequest.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType); // Act var response = await Fixture.Client.SendAsync(httpRequest).DefaultTimeout(); // Assert Assert.AreEqual(httpStatusCode, response.StatusCode); if (grpcStatusCode != null) { Assert.AreEqual(grpcStatusCode.Value.ToTrailerString(), response.Headers.GetValues(GrpcProtocolConstants.StatusTrailer).Single()); } else { Assert.IsFalse(response.Headers.TryGetValues(GrpcProtocolConstants.StatusTrailer, out _)); Assert.IsFalse(response.TrailingHeaders.TryGetValues(GrpcProtocolConstants.StatusTrailer, out _)); } }
public async Task SendCompressedMessageAndReturnResultWithNoCompressFlag_ResponseNotCompressed() { // Arrange var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage, "gzip"); var httpRequest = GrpcHttpHelper.Create("Compression.CompressionService/WriteMessageWithoutCompression"); httpRequest.Headers.Add(GrpcProtocolConstants.MessageEncodingHeader, "gzip"); httpRequest.Headers.Add(GrpcProtocolConstants.MessageAcceptEncodingHeader, "gzip"); httpRequest.Content = new GrpcStreamContent(requestStream); // Act var response = await Fixture.Client.SendAsync(httpRequest).DefaultTimeout(); // Assert Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); // The overall encoding is gzip but the actual response does not use compression Assert.AreEqual("gzip", response.Headers.GetValues(GrpcProtocolConstants.MessageEncodingHeader).Single()); var responseMessage = MessageHelpers.AssertReadMessage <HelloReply>(await response.Content.ReadAsByteArrayAsync().DefaultTimeout()); Assert.AreEqual("Hello World", responseMessage.Message); response.AssertTrailerStatus(); }
public async Task CallAuthorizedServiceWithToken_Success() { // Arrange var tokenResponse = await Fixture.Client.GetAsync("generateJwtToken").DefaultTimeout(); var token = await tokenResponse.Content.ReadAsStringAsync().DefaultTimeout(); var requestMessage = new HelloRequest { Name = "World" }; var ms = new MemoryStream(); MessageHelpers.WriteMessage(ms, requestMessage); var httpRequest = GrpcHttpHelper.Create("Authorize.AuthorizedGreeter/SayHello"); httpRequest.Headers.Add("Authorization", $"Bearer {token}"); httpRequest.Content = new GrpcStreamContent(ms); // Act var response = await Fixture.Client.SendAsync(httpRequest).DefaultTimeout(); // Assert var responseMessage = await response.GetSuccessfulGrpcMessageAsync <HelloReply>().DefaultTimeout(); Assert.AreEqual("Hello World", responseMessage.Message); response.AssertTrailerStatus(); }
public async Task SendIdentityGrpcAcceptEncodingToServiceWithCompression_ResponseUncompressed() { // Arrange var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage); var httpRequest = GrpcHttpHelper.Create("Compression.CompressionService/SayHello"); httpRequest.Headers.Add(GrpcProtocolConstants.MessageEncodingHeader, "identity"); httpRequest.Headers.Add(GrpcProtocolConstants.MessageAcceptEncodingHeader, "identity"); httpRequest.Content = new GrpcStreamContent(requestStream); // Act var response = await Fixture.Client.SendAsync(httpRequest).DefaultTimeout(); // Assert Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); Assert.AreEqual("identity", response.Headers.GetValues(GrpcProtocolConstants.MessageEncodingHeader).Single()); var responseMessage = MessageHelpers.AssertReadMessage <HelloReply>(await response.Content.ReadAsByteArrayAsync().DefaultTimeout()); Assert.AreEqual("Hello World", responseMessage.Message); response.AssertTrailerStatus(); }
public async Task HttpContextExtensionMethod_ReturnContextInTrailer() { // Arrange var url = Fixture.DynamicGrpc.AddUnaryMethod <HelloRequest, HelloReply>((request, context) => { var httpContext = context.GetHttpContext(); context.ResponseTrailers.Add("Test-HttpContext-PathAndQueryString", httpContext.Request.Path + httpContext.Request.QueryString); return(Task.FromResult(new HelloReply { Message = "Hello " + request.Name })); }); var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage); var httpRequest = GrpcHttpHelper.Create($"{url}?query=extra"); httpRequest.Content = new GrpcStreamContent(requestStream); // Act var response = await Fixture.Client.SendAsync(httpRequest).DefaultTimeout(); // Assert response.AssertIsSuccessfulGrpcRequest(); response.AssertTrailerStatus(); Assert.AreEqual($"{url}?query=extra", response.TrailingHeaders.GetValues("Test-HttpContext-PathAndQueryString").Single()); }
public async Task CompleteThenIncompleteMessage_ErrorResponse() { // Arrange SetExpectedErrorsFilter(writeContext => { if (writeContext.LoggerName == "SERVER " + typeof(CounterService).FullName && writeContext.EventId.Name == "RpcConnectionError" && writeContext.State.ToString() == "Error status code 'Internal' raised." && GetRpcExceptionDetail(writeContext.Exception) == "Incomplete message.") { return(true); } if (writeContext.LoggerName == "SERVER " + typeof(CounterService).FullName && writeContext.EventId.Name == "ErrorReadingMessage" && writeContext.State.ToString() == "Error reading message." && GetRpcExceptionDetail(writeContext.Exception) == "Incomplete message.") { return(true); } return(false); }); var ms = new MemoryStream(); MessageHelpers.WriteMessage(ms, new CounterRequest { Count = 1 }); var httpRequest = GrpcHttpHelper.Create("Count.Counter/AccumulateCount"); httpRequest.Content = new PushStreamContent( async s => { // Complete message await s.WriteAsync(ms.ToArray()).AsTask().DefaultTimeout(); await s.FlushAsync().DefaultTimeout(); // Incomplete message and finish await s.WriteAsync(ms.ToArray().AsSpan().Slice(0, (int)ms.Length - 1).ToArray()).AsTask().DefaultTimeout(); await s.FlushAsync().DefaultTimeout(); }); // Act var responseTask = Fixture.Client.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead); // Assert Assert.IsFalse(responseTask.IsCompleted, "Server should wait for client to finish streaming"); var response = await responseTask.DefaultTimeout(); // Read to end of response so headers are available await response.Content.CopyToAsync(new MemoryStream()).DefaultTimeout(); response.AssertTrailerStatus(StatusCode.Internal, "Incomplete message."); }
private static HttpRequestMessage CreateRequestMessage(string path) { var httpRequestMessage = GrpcHttpHelper.Create(path, HttpMethod.Options); httpRequestMessage.Headers.Add("Origin", "http://localhost"); httpRequestMessage.Headers.Add("Access-Control-Request-Method", "POST"); return(httpRequestMessage); }
public async Task SendCompressedMessageWithUnsupportedEncoding_ReturnUnimplemented() { // Arrange var expectedError = #if NET6_0_OR_GREATER "Unsupported grpc-encoding value 'DOES_NOT_EXIST'. Supported encodings: identity, gzip, deflate"; #else "Unsupported grpc-encoding value 'DOES_NOT_EXIST'. Supported encodings: identity, gzip"; #endif SetExpectedErrorsFilter(writeContext => { if (writeContext.LoggerName == TestConstants.ServerCallHandlerTestName && writeContext.EventId.Name == "ErrorReadingMessage" && writeContext.State.ToString() == "Error reading message." && GetRpcExceptionDetail(writeContext.Exception) == expectedError) { return(true); } return(false); }); var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage( requestStream, requestMessage, "DOES_NOT_EXIST", new List <ICompressionProvider> { new DoesNotExistCompressionProvider() }); var httpRequest = GrpcHttpHelper.Create("Greet.Greeter/SayHello"); httpRequest.Headers.Add(GrpcProtocolConstants.MessageEncodingHeader, "DOES_NOT_EXIST"); httpRequest.Content = new GrpcStreamContent(requestStream); // Act var response = await Fixture.Client.SendAsync(httpRequest).DefaultTimeout(); // Assert Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); #if NET6_0_OR_GREATER Assert.AreEqual("identity,gzip,deflate", response.Headers.GetValues(GrpcProtocolConstants.MessageAcceptEncodingHeader).Single()); #else Assert.AreEqual("identity,gzip", response.Headers.GetValues(GrpcProtocolConstants.MessageAcceptEncodingHeader).Single()); #endif response.AssertTrailerStatus(StatusCode.Unimplemented, expectedError); AssertHasLogRpcConnectionError(StatusCode.Unimplemented, expectedError); }
public async Task AdditionalDataAfterStreamedMessage_ErrorResponse() { // Arrange SetExpectedErrorsFilter(writeContext => { if (writeContext.LoggerName == TestConstants.ServerCallHandlerTestName && writeContext.EventId.Name == "RpcConnectionError" && writeContext.State.ToString() == "Error status code 'Internal' raised.") { return(true); } if (writeContext.LoggerName == TestConstants.ServerCallHandlerTestName && writeContext.EventId.Name == "ErrorReadingMessage" && writeContext.State.ToString() == "Error reading message.") { return(true); } return(false); }); var requestMessage = new HelloRequest { Name = "World" }; var ms = new MemoryStream(); MessageHelpers.WriteMessage(ms, requestMessage); var streamingContent = new StreamingContent(); var httpRequest = GrpcHttpHelper.Create("Greet.Greeter/SayHello"); httpRequest.Content = streamingContent; // Act var responseTask = Fixture.Client.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead); // Assert Assert.IsFalse(responseTask.IsCompleted, "Server should wait for client to finish streaming"); var requestStream = await streamingContent.GetRequestStreamAsync().DefaultTimeout(); await requestStream.WriteAsync(ms.ToArray()).AsTask().DefaultTimeout(); await requestStream.WriteAsync(ms.ToArray()).AsTask().DefaultTimeout(); streamingContent.Complete(); var response = await responseTask.DefaultTimeout(); // Read to end of response so headers are available await response.Content.CopyToAsync(new MemoryStream()).DefaultTimeout(); response.AssertTrailerStatus(StatusCode.Internal, "Additional data after the message received."); }
public async Task UnaryMethodDeadlineExceeded(bool throwErrorOnCancellation) { async Task <HelloReply> WaitUntilDeadline(HelloRequest request, ServerCallContext context) { try { await Task.Delay(1000, context.CancellationToken); } catch (OperationCanceledException) when(!throwErrorOnCancellation) { // nom nom nom } return(new HelloReply()); } SetExpectedErrorsFilter(writeContext => { if (writeContext.LoggerName == TestConstants.ServerCallHandlerTestName) { // Deadline happened before write if (writeContext.EventId.Name == "ErrorExecutingServiceMethod" && writeContext.State.ToString() == "Error when executing service method 'WaitUntilDeadline-True'.") { return(true); } } return(false); }); var method = Fixture.DynamicGrpc.AddUnaryMethod <HelloRequest, HelloReply>(WaitUntilDeadline, $"{nameof(WaitUntilDeadline)}-{throwErrorOnCancellation}"); var grpcWebClient = CreateGrpcWebClient(); var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage); var httpRequest = GrpcHttpHelper.Create(method.FullName); httpRequest.Headers.Add(GrpcProtocolConstants.TimeoutHeader, "100m"); httpRequest.Content = new GrpcStreamContent(requestStream); // Act var response = await grpcWebClient.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout(); // Assert response.AssertIsSuccessfulGrpcRequest(); response.AssertTrailerStatus(StatusCode.DeadlineExceeded, "Deadline Exceeded"); }
public async Task WriteUntilDeadline_SuccessResponsesStreamed_CoreAsync(ServerStreamingServerMethod <HelloRequest, HelloReply> callHandler) { // Arrange var method = Fixture.DynamicGrpc.AddServerStreamingMethod <HelloRequest, HelloReply>(callHandler); var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage); var httpRequest = GrpcHttpHelper.Create(method.FullName); httpRequest.Headers.Add(GrpcProtocolConstants.TimeoutHeader, "200m"); httpRequest.Content = new GrpcStreamContent(requestStream); // Act var response = await Fixture.Client.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout(); // Assert response.AssertIsSuccessfulGrpcRequest(); var responseStream = await response.Content.ReadAsStreamAsync().DefaultTimeout(); var pipeReader = PipeReader.Create(responseStream); var messageCount = 0; var readTask = Task.Run(async() => { while (true) { var greeting = await MessageHelpers.AssertReadStreamMessageAsync <HelloReply>(pipeReader).DefaultTimeout(); if (greeting != null) { Assert.AreEqual($"How are you World? {messageCount}", greeting.Message); messageCount++; } else { break; } } }); await readTask.DefaultTimeout(); Assert.AreNotEqual(0, messageCount); response.AssertTrailerStatus(StatusCode.DeadlineExceeded, "Deadline Exceeded"); }
public async Task SendCompressedMessageWithUnsupportedEncoding_ReturnUnimplemented() { // Arrange SetExpectedErrorsFilter(writeContext => { if (writeContext.LoggerName == "SERVER " + typeof(GreeterService).FullName && writeContext.EventId.Name == "RpcConnectionError" && writeContext.State.ToString() == "Error status code 'Unimplemented' raised." && GetRpcExceptionDetail(writeContext.Exception) == "Unsupported grpc-encoding value 'DOES_NOT_EXIST'. Supported encodings: gzip") { return(true); } if (writeContext.LoggerName == "SERVER " + typeof(GreeterService).FullName && writeContext.EventId.Name == "ErrorReadingMessage" && writeContext.State.ToString() == "Error reading message." && GetRpcExceptionDetail(writeContext.Exception) == "Unsupported grpc-encoding value 'DOES_NOT_EXIST'. Supported encodings: gzip") { return(true); } return(false); }); var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage( requestStream, requestMessage, "DOES_NOT_EXIST", new List <ICompressionProvider> { new DoesNotExistCompressionProvider() }); var httpRequest = GrpcHttpHelper.Create("Greet.Greeter/SayHello"); httpRequest.Headers.Add(GrpcProtocolConstants.MessageEncodingHeader, "DOES_NOT_EXIST"); httpRequest.Content = new GrpcStreamContent(requestStream); // Act var response = await Fixture.Client.SendAsync(httpRequest).DefaultTimeout(); // Assert Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); Assert.AreEqual("gzip", response.Headers.GetValues(GrpcProtocolConstants.MessageAcceptEncodingHeader).Single()); response.AssertTrailerStatus(StatusCode.Unimplemented, "Unsupported grpc-encoding value 'DOES_NOT_EXIST'. Supported encodings: gzip"); }
public async Task SendCompressedMessage_UnaryEnabledInCallWithInvalidSetting_UncompressedMessageReturned() { async Task <HelloReply> UnaryEnableCompression(HelloRequest request, ServerCallContext context) { var headers = new Metadata { new Metadata.Entry("grpc-internal-encoding-request", "PURPLE_MONKEY_DISHWASHER") }; await context.WriteResponseHeadersAsync(headers); return(new HelloReply { Message = "Hello " + request.Name }); } // Arrange var method = Fixture.DynamicGrpc.AddUnaryMethod <HelloRequest, HelloReply>(UnaryEnableCompression); var ms = new MemoryStream(); MessageHelpers.WriteMessage(ms, new HelloRequest { Name = "World" }); var httpRequest = GrpcHttpHelper.Create(method.FullName); httpRequest.Content = new PushStreamContent( async s => { await s.WriteAsync(ms.ToArray()).AsTask().DefaultTimeout(); await s.FlushAsync().DefaultTimeout(); }); // Act var responseTask = Fixture.Client.SendAsync(httpRequest); // Assert var response = await responseTask.DefaultTimeout(); response.AssertIsSuccessfulGrpcRequest(); // Because the client didn't send this encoding in accept, the server has sent the message uncompressed. Assert.AreEqual("PURPLE_MONKEY_DISHWASHER", response.Headers.GetValues("grpc-encoding").Single()); var returnedMessageData = await response.Content.ReadAsByteArrayAsync().DefaultTimeout(); Assert.AreEqual(0, returnedMessageData[0]); var responseMessage = MessageHelpers.AssertReadMessage <HelloReply>(returnedMessageData); Assert.AreEqual("Hello World", responseMessage.Message); response.AssertTrailerStatus(); }
public async Task WriteResponseHeadersAsyncCore_FlushesHeadersToClient() { // Arrange var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage); var httpRequest = GrpcHttpHelper.Create("Greet.Greeter/SayHellosSendHeadersFirst"); httpRequest.Content = new GrpcStreamContent(requestStream); // Act var response = await Fixture.Client.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout(); // Assert response.AssertIsSuccessfulGrpcRequest(); var responseStream = await response.Content.ReadAsStreamAsync().DefaultTimeout(); var pipeReader = PipeReader.Create(responseStream); for (var i = 0; i < 3; i++) { var greetingTask = MessageHelpers.AssertReadStreamMessageAsync <HelloReply>(pipeReader); // The headers are already sent // All responses are streamed Assert.False(greetingTask.IsCompleted); var greeting = await greetingTask.DefaultTimeout(); Assert.AreEqual($"How are you World? {i}", greeting.Message); } var goodbyeTask = MessageHelpers.AssertReadStreamMessageAsync <HelloReply>(pipeReader); Assert.False(goodbyeTask.IsCompleted); Assert.AreEqual("Goodbye World!", (await goodbyeTask.DefaultTimeout()).Message); var finishedTask = MessageHelpers.AssertReadStreamMessageAsync <HelloReply>(pipeReader); Assert.IsNull(await finishedTask.DefaultTimeout()); }
public async Task SendCompressedMessageWithoutEncodingHeader_ServerErrorResponse() { // Arrange SetExpectedErrorsFilter(writeContext => { if (writeContext.LoggerName == TestConstants.ServerCallHandlerTestName && writeContext.EventId.Name == "RpcConnectionError" && writeContext.State.ToString() == "Error status code 'Internal' raised." && GetRpcExceptionDetail(writeContext.Exception) == "Request did not include grpc-encoding value with compressed message.") { return(true); } if (writeContext.LoggerName == TestConstants.ServerCallHandlerTestName && writeContext.EventId.Name == "ErrorReadingMessage" && writeContext.State.ToString() == "Error reading message." && GetRpcExceptionDetail(writeContext.Exception) == "Request did not include grpc-encoding value with compressed message.") { return(true); } return(false); }); var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage, "gzip"); var httpRequest = GrpcHttpHelper.Create("Greet.Greeter/SayHello"); httpRequest.Content = new GrpcStreamContent(requestStream); // Act var response = await Fixture.Client.SendAsync(httpRequest).DefaultTimeout(); // Assert Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); response.AssertTrailerStatus(StatusCode.Internal, "Request did not include grpc-encoding value with compressed message."); }
public async Task SendCompressedMessageWithIdentity_ReturnInternalError(string algorithmName) { // Arrange SetExpectedErrorsFilter(writeContext => { if (writeContext.LoggerName == TestConstants.ServerCallHandlerTestName && writeContext.EventId.Name == "ErrorReadingMessage" && writeContext.State.ToString() == "Error reading message.") { return(true); } return(false); }); var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage, algorithmName); var httpRequest = GrpcHttpHelper.Create("Greet.Greeter/SayHello"); httpRequest.Headers.Add(GrpcProtocolConstants.MessageEncodingHeader, "identity"); httpRequest.Content = new GrpcStreamContent(requestStream); // Act var response = await Fixture.Client.SendAsync(httpRequest).DefaultTimeout(); // Assert Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); response.AssertTrailerStatus(StatusCode.Internal, "Request sent 'identity' grpc-encoding value with compressed message."); AssertHasLogRpcConnectionError(StatusCode.Internal, "Request sent 'identity' grpc-encoding value with compressed message."); }
public async Task HttpContextAccessor_ReturnContextInTrailer() { // Arrange var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage); var httpRequest = GrpcHttpHelper.Create("Greet.Greeter/SayHelloWithHttpContextAccessor?query=extra"); httpRequest.Content = new GrpcStreamContent(requestStream); // Act var response = await Fixture.Client.SendAsync(httpRequest).DefaultTimeout(); // Assert response.AssertIsSuccessfulGrpcRequest(); response.AssertTrailerStatus(); Assert.AreEqual("/Greet.Greeter/SayHelloWithHttpContextAccessor?query=extra", response.TrailingHeaders.GetValues("Test-HttpContext-PathAndQueryString").Single()); }
public async Task CallAuthorizedServiceWithInvalidToken_ReturnUnauthorized() { // Arrange var requestMessage = new HelloRequest { Name = "World" }; var ms = new MemoryStream(); MessageHelpers.WriteMessage(ms, requestMessage); var httpRequest = GrpcHttpHelper.Create("Authorize.AuthorizedGreeter/SayHello"); httpRequest.Headers.Add("Authorization", $"Bearer SomeInvalidTokenHere"); httpRequest.Content = new GrpcStreamContent(ms); // Act var response = await Fixture.Client.SendAsync(httpRequest).DefaultTimeout(); // Assert Assert.AreEqual(HttpStatusCode.Unauthorized, response.StatusCode); }
public async Task SendUnsupportedEncodingHeaderWithUncompressedMessage_ReturnUncompressedMessage() { // Arrange var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage); var httpRequest = GrpcHttpHelper.Create("Greet.Greeter/SayHello"); httpRequest.Headers.Add(GrpcProtocolConstants.MessageEncodingHeader, "DOES_NOT_EXIST"); httpRequest.Content = new GrpcStreamContent(requestStream); // Act var response = await Fixture.Client.SendAsync(httpRequest).DefaultTimeout(); // Assert Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); response.AssertTrailerStatus(); }
public async Task HttpContextExtensionMethod_ReturnContextInTrailer() { // Arrange var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage); var httpRequest = GrpcHttpHelper.Create("Greet.ServiceDoesNotExist/Method"); httpRequest.Content = new GrpcStreamContent(requestStream); // Act var response = await Fixture.Client.SendAsync(httpRequest).DefaultTimeout(); // Assert response.AssertIsSuccessfulGrpcRequest(); response.AssertTrailerStatus(StatusCode.Unimplemented, "Service is unimplemented."); }
public async Task WriteUntilDeadline_SuccessResponsesStreamed_CoreAsync(ServerStreamingServerMethod <HelloRequest, HelloReply> callHandler) { // Arrange var method = Fixture.DynamicGrpc.AddServerStreamingMethod <HelloRequest, HelloReply>(callHandler); var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage); var httpRequest = GrpcHttpHelper.Create(method.FullName); httpRequest.Headers.Add(GrpcProtocolConstants.TimeoutHeader, "200m"); httpRequest.Content = new GrpcStreamContent(requestStream); try { // Act var response = await Fixture.Client.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout(); // Assert response.AssertIsSuccessfulGrpcRequest(); var responseStream = await response.Content.ReadAsStreamAsync().DefaultTimeout(); var pipeReader = PipeReader.Create(responseStream); var messageCount = 0; var readTask = Task.Run(async() => { while (true) { var greeting = await MessageHelpers.AssertReadStreamMessageAsync <HelloReply>(pipeReader).DefaultTimeout(); if (greeting != null) { Assert.AreEqual($"How are you World? {messageCount}", greeting.Message); messageCount++; } else { break; } } }); await readTask.DefaultTimeout(); Assert.AreNotEqual(0, messageCount); response.AssertTrailerStatus(StatusCode.DeadlineExceeded, "Deadline Exceeded"); } catch (Exception ex) when(Net.Client.Internal.GrpcProtocolHelpers.ResolveRpcExceptionStatusCode(ex) == StatusCode.Cancelled) { // Ignore exception from deadline abort } Assert.True(HasLog(LogLevel.Debug, "DeadlineExceeded", "Request with timeout of 00:00:00.2000000 has exceeded its deadline.")); await TestHelpers.AssertIsTrueRetryAsync( () => HasLog(LogLevel.Trace, "DeadlineStopped", "Request deadline stopped."), "Missing deadline stopped log.").DefaultTimeout(); }
public async Task SendCompressedMessage_ServerStreamingEnabledInCall_CompressedMessageReturned() { async Task ServerStreamingEnableCompression(HelloRequest request, IServerStreamWriter <HelloReply> responseStream, ServerCallContext context) { var headers = new Metadata { new Metadata.Entry("grpc-internal-encoding-request", "gzip") }; await context.WriteResponseHeadersAsync(headers); await responseStream.WriteAsync(new HelloReply { Message = "Hello 1" }); responseStream.WriteOptions = new WriteOptions(WriteFlags.NoCompress); await responseStream.WriteAsync(new HelloReply { Message = "Hello 2" }); } // Arrange var method = Fixture.DynamicGrpc.AddServerStreamingMethod <HelloRequest, HelloReply>(ServerStreamingEnableCompression); var ms = new MemoryStream(); MessageHelpers.WriteMessage(ms, new HelloRequest { Name = "World" }); var httpRequest = GrpcHttpHelper.Create(method.FullName); httpRequest.Content = new PushStreamContent( async s => { await s.WriteAsync(ms.ToArray()).AsTask().DefaultTimeout(); await s.FlushAsync().DefaultTimeout(); }); // Act var responseTask = Fixture.Client.SendAsync(httpRequest); // Assert var response = await responseTask.DefaultTimeout(); response.AssertIsSuccessfulGrpcRequest(); Assert.AreEqual("gzip", response.Headers.GetValues("grpc-encoding").Single()); var responseStream = await response.Content.ReadAsStreamAsync().DefaultTimeout(); var pipeReader = PipeReader.Create(responseStream); ReadResult readResult; readResult = await pipeReader.ReadAsync(); Assert.AreEqual(1, readResult.Buffer.FirstSpan[0]); // Message is compressed var greeting1 = await MessageHelpers.AssertReadStreamMessageAsync <HelloReply>(pipeReader, "gzip").DefaultTimeout(); Assert.AreEqual($"Hello 1", greeting1.Message); readResult = await pipeReader.ReadAsync(); Assert.AreEqual(0, readResult.Buffer.FirstSpan[0]); // Message is uncompressed var greeting2 = await MessageHelpers.AssertReadStreamMessageAsync <HelloReply>(pipeReader, "gzip").DefaultTimeout(); Assert.AreEqual($"Hello 2", greeting2.Message); var finishedTask = MessageHelpers.AssertReadStreamMessageAsync <HelloReply>(pipeReader); Assert.IsNull(await finishedTask.DefaultTimeout()); }
public async Task NoBuffering_SuccessResponsesStreamed() { using var httpEventSource = new HttpEventSourceListener(LoggerFactory); var methodWrapper = new MethodWrapper { Logger = Logger, SyncPoint = new SyncPoint(runContinuationsAsynchronously: true) }; async Task SayHellos(HelloRequest request, IServerStreamWriter <HelloReply> responseStream, ServerCallContext context) { // Explicitly send the response headers before any streamed content Metadata responseHeaders = new Metadata(); responseHeaders.Add("test-response-header", "value"); await context.WriteResponseHeadersAsync(responseHeaders); await methodWrapper.SayHellosAsync(request, responseStream); } // Arrange var method = Fixture.DynamicGrpc.AddServerStreamingMethod <HelloRequest, HelloReply>(SayHellos); var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage); var httpRequest = GrpcHttpHelper.Create(method.FullName); httpRequest.Content = new GrpcStreamContent(requestStream); // Act var response = await Fixture.Client.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout(); // Assert response.AssertIsSuccessfulGrpcRequest(); var responseStream = await response.Content.ReadAsStreamAsync().DefaultTimeout(); var pipeReader = PipeReader.Create(responseStream); for (var i = 0; i < 3; i++) { var greetingTask = MessageHelpers.AssertReadStreamMessageAsync <HelloReply>(pipeReader); Assert.IsFalse(greetingTask.IsCompleted); await methodWrapper.SyncPoint.WaitForSyncPoint().DefaultTimeout(); var currentSyncPoint = methodWrapper.SyncPoint; methodWrapper.SyncPoint = new SyncPoint(runContinuationsAsynchronously: true); currentSyncPoint.Continue(); var greeting = (await greetingTask.DefaultTimeout()) !; Assert.AreEqual($"How are you World? {i}", greeting.Message); } var goodbyeTask = MessageHelpers.AssertReadStreamMessageAsync <HelloReply>(pipeReader); Assert.False(goodbyeTask.IsCompleted); await methodWrapper.SyncPoint.WaitForSyncPoint().DefaultTimeout(); methodWrapper.SyncPoint.Continue(); Assert.AreEqual("Goodbye World!", (await goodbyeTask.DefaultTimeout()) !.Message); var finishedTask = MessageHelpers.AssertReadStreamMessageAsync <HelloReply>(pipeReader); Assert.IsNull(await finishedTask.DefaultTimeout()); }
public async Task MultipleMessagesFromOneClient_SuccessResponses() { // Arrange var ms = new MemoryStream(); MessageHelpers.WriteMessage(ms, new ChatMessage { Name = "John", Message = "Hello Jill" }); var streamingContent = new StreamingContent(); var httpRequest = GrpcHttpHelper.Create("Chat.Chatter/Chat"); httpRequest.Content = streamingContent; // Act var responseTask = Fixture.Client.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead); // Assert Assert.IsFalse(responseTask.IsCompleted, "Server should wait for first message from client"); var requestStream = await streamingContent.GetRequestStreamAsync().DefaultTimeout(); await requestStream.WriteAsync(ms.ToArray()).AsTask().DefaultTimeout(); await requestStream.FlushAsync().DefaultTimeout(); var response = await responseTask.DefaultTimeout(); response.AssertIsSuccessfulGrpcRequest(); var responseStream = await response.Content.ReadAsStreamAsync().DefaultTimeout(); var pipeReader = PipeReader.Create(responseStream); var message1Task = MessageHelpers.AssertReadStreamMessageAsync <ChatMessage>(pipeReader); var message1 = await message1Task.DefaultTimeout(); Assert.AreEqual("John", message1.Name); Assert.AreEqual("Hello Jill", message1.Message); var message2Task = MessageHelpers.AssertReadStreamMessageAsync <ChatMessage>(pipeReader); Assert.IsFalse(message2Task.IsCompleted, "Server is waiting for messages from client"); ms = new MemoryStream(); MessageHelpers.WriteMessage(ms, new ChatMessage { Name = "Jill", Message = "Hello John" }); await requestStream.WriteAsync(ms.ToArray()).AsTask().DefaultTimeout(); await requestStream.FlushAsync().DefaultTimeout(); var message2 = await message2Task.DefaultTimeout(); Assert.AreEqual("Jill", message2.Name); Assert.AreEqual("Hello John", message2.Message); var finishedTask = MessageHelpers.AssertReadStreamMessageAsync <ChatMessage>(pipeReader); Assert.IsFalse(finishedTask.IsCompleted, "Server is waiting for client to end streaming"); // Complete request stream streamingContent.Complete(); await finishedTask.DefaultTimeout(); response.AssertTrailerStatus(); }
public async Task Buffering_SuccessResponsesStreamed() { var methodWrapper = new MethodWrapper { Logger = Logger, SyncPoint = new SyncPoint(runContinuationsAsynchronously: true) }; Task SayHellosBufferHint(HelloRequest request, IServerStreamWriter <HelloReply> responseStream, ServerCallContext context) { context.WriteOptions = new WriteOptions(WriteFlags.BufferHint); return(methodWrapper.SayHellosAsync(request, responseStream)); } // Arrange var method = Fixture.DynamicGrpc.AddServerStreamingMethod <HelloRequest, HelloReply>(SayHellosBufferHint); var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage); var httpRequest = GrpcHttpHelper.Create(method.FullName); httpRequest.Content = new GrpcStreamContent(requestStream); // Act var responseTask = Fixture.Client.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout(); // Assert Assert.IsFalse(responseTask.IsCompleted, "Server should wait for first message from client"); await methodWrapper.SyncPoint.WaitForSyncPoint().DefaultTimeout(); methodWrapper.SyncPoint.Continue(); var response = await responseTask.DefaultTimeout(); response.AssertIsSuccessfulGrpcRequest(); var responseStream = await response.Content.ReadAsStreamAsync().DefaultTimeout(); var pipeReader = PipeReader.Create(responseStream); for (var i = 0; i < 3; i++) { var greeting = (await MessageHelpers.AssertReadStreamMessageAsync <HelloReply>(pipeReader).DefaultTimeout()) !; Assert.AreEqual($"How are you World? {i}", greeting.Message); } var goodbye = await MessageHelpers.AssertReadStreamMessageAsync <HelloReply>(pipeReader).DefaultTimeout(); Assert.AreEqual("Goodbye World!", goodbye !.Message); Assert.IsNull(await MessageHelpers.AssertReadStreamMessageAsync <HelloReply>(pipeReader).DefaultTimeout()); response.AssertTrailerStatus(); }