public async Task InterceptorsExecutedInRegistrationOrder_AndGlobalInterceptorExecutesFirst_ServerStreaming() { // Arrange var url = Fixture.DynamicGrpc.AddServerStreamingMethod <InterceptorOrderTests, Empty, Empty>((request, responseStream, context) => { var items = context.GetHttpContext().Items; Assert.AreEqual(3, items[OrderedInterceptor.OrderHeaderKey]); return(Task.CompletedTask); }); var ms = new MemoryStream(); MessageHelpers.WriteMessage(ms, new Empty()); // Act var response = await Fixture.Client.PostAsync( url, new GrpcStreamContent(ms)).DefaultTimeout(); var responseStream = await response.Content.ReadAsStreamAsync().DefaultTimeout(); var pipeReader = new StreamPipeReader(responseStream); // Assert await MessageHelpers.AssertReadStreamMessageAsync <Empty>(pipeReader); response.AssertTrailerStatus(); }
protected StreamPipeTest() { Pool = new TestMemoryPool(); Stream = new MemoryStream(); Writer = new StreamPipeWriter(Stream, MinimumSegmentSize, Pool); Reader = new StreamPipeReader(Stream, new StreamPipeReaderOptions(MinimumSegmentSize, minimumReadThreshold: 256, Pool)); }
public async Task ReadMessageStreamAsync_MultipleEmptyMessage_ReturnNoDataMessageThenComplete() { // Arrange var emptyMessage = new byte[] { 0x00, // compression = 0 0x00, 0x00, 0x00, 0x00 // length = 0 }; var ms = new MemoryStream(emptyMessage.Concat(emptyMessage).ToArray()); var pipeReader = new StreamPipeReader(ms); // Act 1 var messageData1 = await pipeReader.ReadStreamMessageAsync(TestServerCallContext); // Assert 1 Assert.AreEqual(0, messageData1 !.Length); // Act 2 var messageData2 = await pipeReader.ReadStreamMessageAsync(TestServerCallContext); // Assert 2 Assert.AreEqual(0, messageData2 !.Length); // Act 3 var messageData3 = await pipeReader.ReadStreamMessageAsync(TestServerCallContext); // Assert 3 Assert.IsNull(messageData3); }
public async Task ReadMessageStreamAsync_LongMessage_ReturnData() { // Arrange var content = Encoding.UTF8.GetBytes("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam varius nibh a blandit mollis. " + "In hac habitasse platea dictumst. Proin non quam nec neque convallis commodo. Orci varius natoque penatibus et magnis dis " + "parturient montes, nascetur ridiculus mus. Mauris commodo est vehicula, semper arcu eu, ornare urna. Mauris malesuada nisl " + "nisl, vitae tincidunt purus vestibulum sit amet. Interdum et malesuada fames ac ante ipsum primis in faucibus."); var ms = new MemoryStream(new byte[] { 0x00, // compression = 0 0x00, 0x00, 0x01, 0xC1 // length = 449 }.Concat(content).ToArray()); var pipeReader = new StreamPipeReader(ms); // Act var messageData = await pipeReader.ReadStreamMessageAsync(TestServerCallContext); // Assert Assert.AreEqual(449, messageData !.Length); CollectionAssert.AreEqual(content, messageData); }
public async Task ReadMessageAsync_UnderReceiveSize_ReturnData() { // Arrange var context = HttpContextServerCallContextHelper.CreateServerCallContext(serviceOptions: new GrpcServiceOptions { SendMaxMessageSize = 1 }); var ms = new MemoryStream(new byte[] { 0x00, // compression = 0 0x00, 0x00, 0x00, 0x01, // length = 1 0x10 }); var pipeReader = new StreamPipeReader(ms); // Act var messageData = await pipeReader.ReadSingleMessageAsync(context); // Assert Assert.AreEqual(1, messageData.Length); Assert.AreEqual(0x10, messageData[0]); }
public void ReadMessageAsync_ExceedReceiveSize_ReturnData() { // Arrange var context = HttpContextServerCallContextHelper.CreateServerCallContext(serviceOptions: new GrpcServiceOptions { ReceiveMaxMessageSize = 1 }); var ms = new MemoryStream(new byte[] { 0x00, // compression = 0 0x00, 0x00, 0x00, 0x02, // length = 1 0x10, 0x10 }); var pipeReader = new StreamPipeReader(ms); // Act var ex = Assert.ThrowsAsync <RpcException>(() => pipeReader.ReadSingleMessageAsync(context).AsTask()); // Assert Assert.AreEqual("Received message exceeds the maximum configured message size.", ex.Status.Detail); Assert.AreEqual(StatusCode.ResourceExhausted, ex.StatusCode); }
public static async Task <T> AssertReadMessageAsync <T>(Stream stream, string compressionEncoding = null, List <ICompressionProvider> compressionProviders = null) where T : IMessage, new() { compressionProviders = compressionProviders ?? new List <ICompressionProvider> { new GzipCompressionProvider(CompressionLevel.Fastest) }; var pipeReader = new StreamPipeReader(stream); var httpContext = new DefaultHttpContext(); httpContext.Request.Headers[GrpcProtocolConstants.MessageEncodingHeader] = compressionEncoding; var serverCallContext = HttpContextServerCallContextHelper.CreateServerCallContext( httpContext: httpContext, serviceOptions: new GrpcServiceOptions { ResponseCompressionAlgorithm = compressionEncoding, CompressionProviders = compressionProviders }); var messageData = await pipeReader.ReadSingleMessageAsync(serverCallContext); var message = new T(); message.MergeFrom(messageData); return(message); }
public async Task ReadCanBeCancelledViaProvidedCancellationToken() { var pipeReader = new StreamPipeReader(new HangingStream()); var cts = new CancellationTokenSource(1); await Task.Delay(1); await Assert.ThrowsAsync <TaskCanceledException>(async() => await pipeReader.ReadAsync(cts.Token)); }
private void CreateReader(int minimumSegmentSize = 16, int minimumReadThreshold = 4, MemoryPool <byte> memoryPool = null) { Reader = new StreamPipeReader(MemoryStream, new StreamPipeReaderOptions( minimumSegmentSize, minimumReadThreshold, memoryPool ?? new TestMemoryPool())); }
public static async Task <T> AssertReadMessageStreamAsync <T>(Stream stream) where T : IMessage, new() { var pipeReader = new StreamPipeReader(stream); var messageData = await pipeReader.ReadStreamMessageAsync(); if (messageData == null) { return(default);
public async Task WriteUntilDeadline_SuccessResponsesStreamed_CoreAsync(ServerStreamingServerMethod <HelloRequest, HelloReply> method) { // Arrange var url = Fixture.DynamicGrpc.AddServerStreamingMethod <DeadlineTests, HelloRequest, HelloReply>(method); var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage); var httpRequest = new HttpRequestMessage(HttpMethod.Post, url); 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 = new StreamPipeReader(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); Assert.AreEqual(StatusCode.DeadlineExceeded.ToTrailerString(), Fixture.TrailersContainer.Trailers[GrpcProtocolConstants.StatusTrailer].Single()); Assert.AreEqual("Deadline Exceeded", Fixture.TrailersContainer.Trailers[GrpcProtocolConstants.MessageTrailer].Single()); }
public async Task WriteUntilDeadline_SuccessResponsesStreamed(string requestUri) { // Arrange var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage); var httpRequest = new HttpRequestMessage(HttpMethod.Post, requestUri); httpRequest.Headers.Add(GrpcProtocolConstants.TimeoutHeader, "200m"); httpRequest.Content = new StreamContent(requestStream); // Act var response = await Fixture.Client.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout(); // Assert Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); Assert.AreEqual("identity", response.Headers.GetValues("grpc-encoding").Single()); Assert.AreEqual("application/grpc", response.Content.Headers.ContentType.MediaType); var responseStream = await response.Content.ReadAsStreamAsync().DefaultTimeout(); var pipeReader = new StreamPipeReader(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); Assert.AreEqual(StatusCode.DeadlineExceeded.ToTrailerString(), Fixture.TrailersContainer.Trailers[GrpcProtocolConstants.StatusTrailer].Single()); Assert.AreEqual("Deadline Exceeded", Fixture.TrailersContainer.Trailers[GrpcProtocolConstants.MessageTrailer].Single()); }
public async Task ReadAsyncAfterReceivingCompletedReadResultDoesNotThrow() { Stream = new ThrowAfterZeroByteReadStream(); Reader = new StreamPipeReader(Stream); var readResult = await Reader.ReadAsync(); readResult = await Reader.ReadAsync(); Assert.True(readResult.Buffer.IsEmpty); Assert.True(readResult.IsCompleted); }
public async Task CheckBasicReadPipeApi() { var pipe = new Pipe(); var readStream = new ReadOnlyPipeStream(pipe.Reader); var pipeReader = new StreamPipeReader(readStream); await pipe.Writer.WriteAsync(new byte[10]); var res = await pipeReader.ReadAsync(); Assert.Equal(new byte[10], res.Buffer.ToArray()); }
public static async Task <T> AssertReadMessageAsync <T>(Stream stream) where T : IMessage, new() { var pipeReader = new StreamPipeReader(stream); var messageData = await pipeReader.ReadSingleMessageAsync(TestServerCallContext); var message = new T(); message.MergeFrom(messageData); return(message); }
public async Task AdvancePastMinReadSizeReadAsyncReturnsMoreData() { Reader = new StreamPipeReader(MemoryStream, 16, new TestMemoryPool()); Write(new byte[32]); var result = await Reader.ReadAsync(); Assert.Equal(16, result.Buffer.Length); Reader.AdvanceTo(result.Buffer.GetPosition(12), result.Buffer.End); result = await Reader.ReadAsync(); Assert.Equal(20, result.Buffer.Length); }
public async Task ReadWithAdvanceSmallSegments() { Reader = new StreamPipeReader(MemoryStream, 16, new TestMemoryPool()); Write(new byte[128]); var readResult = await Reader.ReadAsync(); Reader.AdvanceTo(readResult.Buffer.End); readResult = await Reader.ReadAsync(); Assert.Equal(16, readResult.Buffer.Length); Assert.True(readResult.Buffer.IsSingleSegment); }
public async Task CheckBasicReadStreamApi() { var stream = new MemoryStream(); await stream.WriteAsync(new byte[10]); stream.Position = 0; var pipeReader = new StreamPipeReader(stream); var readOnlyStream = new ReadOnlyPipeStream(pipeReader); var resSize = await readOnlyStream.ReadAsync(new byte[10]); Assert.Equal(10, resSize); }
public async Task WriteResponseHeadersAsyncCore_FlushesHeadersToClient() { // Arrange var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage); var httpRequest = new HttpRequestMessage(HttpMethod.Post, "Greet.Greeter/SayHellosSendHeadersFirst"); httpRequest.Content = new StreamContent(requestStream); // Act var response = await Fixture.Client.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout(); // Assert Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); Assert.AreEqual("identity", response.Headers.GetValues("grpc-encoding").Single()); Assert.AreEqual("application/grpc", response.Content.Headers.ContentType.MediaType); var responseStream = await response.Content.ReadAsStreamAsync().DefaultTimeout(); var pipeReader = new StreamPipeReader(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 ReadWithAdvanceDifferentSegmentSize() { Reader = new StreamPipeReader(MemoryStream, 4095, new TestMemoryPool()); Write(new byte[10000]); var readResult = await Reader.ReadAsync(); Reader.AdvanceTo(readResult.Buffer.End); readResult = await Reader.ReadAsync(); Assert.Equal(4095, readResult.Buffer.Length); Assert.True(readResult.Buffer.IsSingleSegment); }
public async Task ConsumePartialBufferWorks() { Reader = new StreamPipeReader(MemoryStream, 16, new TestMemoryPool()); Write(Encoding.ASCII.GetBytes(new string('a', 8))); var readResult = await Reader.ReadAsync(); Reader.AdvanceTo(readResult.Buffer.GetPosition(4), readResult.Buffer.End); MemoryStream.Position = 0; readResult = await Reader.ReadAsync(); var resultString = Encoding.ASCII.GetString(readResult.Buffer.ToArray()); Assert.Equal(new string('a', 12), resultString); Reader.AdvanceTo(readResult.Buffer.End); }
public async Task Buffering_SuccessResponsesStreamed() { // Arrange var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage); var httpRequest = new HttpRequestMessage(HttpMethod.Post, "Greet.Greeter/SayHellosBufferHint"); httpRequest.Content = new StreamContent(requestStream); // Act var responseTask = Fixture.Client.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout(); // Assert Assert.IsFalse(responseTask.IsCompleted, "Server should wait for first message from client"); var response = await responseTask; Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); Assert.AreEqual("identity", response.Headers.GetValues("grpc-encoding").Single()); Assert.AreEqual("application/grpc", response.Content.Headers.ContentType.MediaType); var responseStream = await response.Content.ReadAsStreamAsync().DefaultTimeout(); var pipeReader = new StreamPipeReader(new PipeReaderFixStream(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()); Assert.AreEqual(StatusCode.OK.ToTrailerString(), Fixture.TrailersContainer.Trailers[GrpcProtocolConstants.StatusTrailer].Single()); }
public async Task CheckNestedPipeApi() { var pipe = new Pipe(); var reader = pipe.Reader; for (var i = 0; i < 3; i++) { var readStream = new ReadOnlyPipeStream(reader); reader = new StreamPipeReader(readStream); } await pipe.Writer.WriteAsync(new byte[10]); var res = await reader.ReadAsync(); Assert.Equal(new byte[10], res.Buffer.ToArray()); }
public async Task NoBuffering_SuccessResponsesStreamed() { // Arrange var requestMessage = new HelloRequest { Name = "World" }; var requestStream = new MemoryStream(); MessageHelpers.WriteMessage(requestStream, requestMessage); var httpRequest = new HttpRequestMessage(HttpMethod.Post, "Greet.Greeter/SayHellos"); 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 = new StreamPipeReader(responseStream); for (var i = 0; i < 3; i++) { var greetingTask = MessageHelpers.AssertReadStreamMessageAsync <HelloReply>(pipeReader); Assert.IsFalse(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 AsyncReadWorks() { MemoryStream = new AsyncStream(); Reader = new StreamPipeReader(MemoryStream, 16, new TestMemoryPool()); Write(Encoding.ASCII.GetBytes(new string('a', 10000))); for (var i = 0; i < 99; i++) { var readResult = await Reader.ReadAsync(); Reader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End); } var result = await Reader.ReadAsync(); Assert.Equal(1600, result.Buffer.Length); Reader.AdvanceTo(result.Buffer.End); }
public async Task ReadCanBeCanceledViaCancelPendingReadWhenReadIsAsync() { var pipeReader = new StreamPipeReader(new HangingStream()); var result = new ReadResult(); var tcs = new TaskCompletionSource <int>(TaskCreationOptions.RunContinuationsAsynchronously); var task = Task.Run(async() => { var readingTask = pipeReader.ReadAsync(); tcs.SetResult(0); result = await readingTask; }); await tcs.Task; pipeReader.CancelPendingRead(); await task; Assert.True(result.IsCanceled); }
public async Task CheckNestedStreamApi() { var stream = new MemoryStream(); await stream.WriteAsync(new byte[10]); stream.Position = 0; Stream readOnlyStream = stream; for (var i = 0; i < 3; i++) { var pipeReader = new StreamPipeReader(readOnlyStream); readOnlyStream = new ReadOnlyPipeStream(pipeReader); } var resSize = await readOnlyStream.ReadAsync(new byte[10]); Assert.Equal(10, resSize); }
public async Task WriteAsync_BufferHintWriteOptions_DoesNotFlush() { // Arrange var ms = new MemoryStream(); var httpContext = new DefaultHttpContext(); httpContext.Response.BodyPipe = new StreamPipeWriter(ms); var serverCallContext = new HttpContextServerCallContext(httpContext, NullLogger.Instance); var writer = new HttpContextStreamWriter <HelloReply>(serverCallContext, TestServiceOptions, (message) => message.ToByteArray()); serverCallContext.WriteOptions = new WriteOptions(WriteFlags.BufferHint); // Act 1 await writer.WriteAsync(new HelloReply { Message = "Hello world 1" }); // Assert 1 Assert.AreEqual(0, ms.Length); // Act 2 await writer.WriteAsync(new HelloReply { Message = "Hello world 2" }); // Assert 2 Assert.AreEqual(0, ms.Length); await httpContext.Response.BodyPipe.FlushAsync(); ms.Seek(0, SeekOrigin.Begin); var pipeReader = new StreamPipeReader(ms); var writtenMessage1 = await MessageHelpers.AssertReadStreamMessageAsync <HelloReply>(pipeReader); Assert.AreEqual("Hello world 1", writtenMessage1.Message); var writtenMessage2 = await MessageHelpers.AssertReadStreamMessageAsync <HelloReply>(pipeReader); Assert.AreEqual("Hello world 2", writtenMessage2.Message); }
public async Task AdvanceMultipleSegments() { Reader = new StreamPipeReader(MemoryStream, 16, new TestMemoryPool()); Write(new byte[128]); var result = await Reader.ReadAsync(); Assert.Equal(16, result.Buffer.Length); Reader.AdvanceTo(result.Buffer.Start, result.Buffer.End); var result2 = await Reader.ReadAsync(); Assert.Equal(32, result2.Buffer.Length); Reader.AdvanceTo(result.Buffer.End, result2.Buffer.End); var result3 = await Reader.ReadAsync(); Assert.Equal(32, result3.Buffer.Length); }
public void ReadMessageStreamAsync_HeaderIncomplete_ThrowError() { // Arrange var ms = new MemoryStream(new byte[] { 0x00, // compression = 0 0x00, 0x00 }); var pipeReader = new StreamPipeReader(ms); // Act var ex = Assert.ThrowsAsync <InvalidDataException>( () => pipeReader.ReadSingleMessageAsync().AsTask()); // Assert Assert.AreEqual("Incomplete message.", ex.Message); }