Example #1
0
        public async Task ReadSingleMessageAsync_OneByteMessage_ReturnData()
        {
            // Arrange
            var ms = new MemoryStream(new byte[]
            {
                0x00,     // compression = 0
                0x00,
                0x00,
                0x00,
                0x01,     // length = 1
                0x10
            });

            var pipeReader = PipeReader.Create(ms);

            // Act
            var messageData = await pipeReader.ReadSingleMessageAsync(HttpContextServerCallContextHelper.CreateServerCallContext(), TestDataMarshaller.ContextualDeserializer);

            // Assert
            Assert.AreEqual(1, messageData.Span.Length);
            Assert.AreEqual(0x10, messageData.Span[0]);
        }
Example #2
0
        public async Task WriteAsync_DefaultWriteOptions_Flushes()
        {
            // Arrange
            var ms = new MemoryStream();

            var httpContext = new DefaultHttpContext();

            httpContext.Features.Set <IHttpResponseBodyFeature>(new TestResponseBodyFeature(PipeWriter.Create(ms)));
            var serverCallContext = HttpContextServerCallContextHelper.CreateServerCallContext(httpContext);
            var writer            = new HttpContextStreamWriter <HelloReply>(serverCallContext, MessageHelpers.ServiceMethod.ResponseMarshaller.ContextualSerializer);

            // Act 1
            await writer.WriteAsync(new HelloReply
            {
                Message = "Hello world 1"
            });

            // Assert 1
            Assert.AreEqual(20, ms.Length);

            // Act 2
            await writer.WriteAsync(new HelloReply
            {
                Message = "Hello world 2"
            });

            // Assert 2
            Assert.AreEqual(40, ms.Length);

            ms.Seek(0, SeekOrigin.Begin);
            var pipeReader = PipeReader.Create(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);
        }
Example #3
0
        public async Task WriteAsync_DefaultWriteOptions_Flushes()
        {
            // Arrange
            var ms = new MemoryStream();

            var httpContext = new DefaultHttpContext();

            httpContext.Response.BodyPipe = new StreamPipeWriter(ms);
            var serverCallContext = HttpContextServerCallContextHelper.CreateServerCallContext(httpContext);
            var writer            = new HttpContextStreamWriter <HelloReply>(serverCallContext, (message) => message.ToByteArray());

            // Act 1
            await writer.WriteAsync(new HelloReply
            {
                Message = "Hello world 1"
            });

            // Assert 1
            Assert.AreEqual(20, ms.Length);

            // Act 2
            await writer.WriteAsync(new HelloReply
            {
                Message = "Hello world 2"
            });

            // Assert 2
            Assert.AreEqual(40, ms.Length);

            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);
        }
Example #4
0
        public async Task WriteMessageAsync_HasCustomCompressionLevel_WriteCompressedDataWithLevel()
        {
            // Arrange
            var mockCompressionProvider = new MockCompressionProvider();

            var httpContext = new DefaultHttpContext();

            httpContext.Request.Headers[GrpcProtocolConstants.MessageAcceptEncodingHeader] = "Mock";

            var context = HttpContextServerCallContextHelper.CreateServerCallContext(
                httpContext,
                responseCompressionAlgorithm: "Mock",
                responseCompressionLevel: System.IO.Compression.CompressionLevel.Optimal,
                compressionProviders: new List <ICompressionProvider>
            {
                mockCompressionProvider
            });

            context.Initialize();

            var ms         = new MemoryStream();
            var pipeWriter = PipeWriter.Create(ms);

            // Act
            await pipeWriter.WriteMessageAsync(new TestData(new byte[] { 0x10 }), context, TestDataMarshaller.ContextualSerializer, canFlush : true);

            // Assert
            Assert.AreEqual(System.IO.Compression.CompressionLevel.Optimal, mockCompressionProvider.ArgumentCompression);

            var messageData = ms.ToArray();

            Assert.AreEqual(1, messageData[0]);  // compression
            Assert.AreEqual(21, messageData[4]); // message length

            byte[] result = Decompress(mockCompressionProvider, messageData);
            Assert.AreEqual(1, result.Length);
            Assert.AreEqual(0x10, result[0]);
        }
Example #5
0
        public async Task MoveNext_TokenCancelledDuringMoveNext_CancelTask()
        {
            // Arrange
            var ms = new SyncPointMemoryStream();

            var testSink          = new TestSink();
            var testLoggerFactory = new TestLoggerFactory(testSink, enabled: true);

            var httpContext = new DefaultHttpContext();

            httpContext.Features.Set <IRequestBodyPipeFeature>(new TestRequestBodyPipeFeature(PipeReader.Create(ms)));
            var serverCallContext = HttpContextServerCallContextHelper.CreateServerCallContext(httpContext, logger: testLoggerFactory.CreateLogger("Test"));
            var reader            = new HttpContextStreamReader <HelloReply>(serverCallContext, MessageHelpers.ServiceMethod.ResponseMarshaller.ContextualDeserializer);

            var cts = new CancellationTokenSource();

            var nextTask = reader.MoveNext(cts.Token);

            Assert.IsFalse(nextTask.IsCompleted);
            Assert.IsFalse(nextTask.IsCanceled);

            cts.Cancel();

            try
            {
                await nextTask;
                Assert.Fail();
            }
            catch (TaskCanceledException)
            {
            }

            Assert.IsTrue(nextTask.IsCompleted);
            Assert.IsTrue(nextTask.IsCanceled);

            Assert.AreEqual(1, testSink.Writes.Count);
            Assert.AreEqual("ReadingMessage", testSink.Writes.First().EventId.Name);
        }
Example #6
0
        public async Task WriteMessageAsync_EmptyMessage_WriteMessageWithNoData()
        {
            // Arrange
            var ms         = new MemoryStream();
            var pipeWriter = PipeWriter.Create(ms);

            // Act
            await pipeWriter.WriteMessageAsync(new TestData(Array.Empty <byte>()), HttpContextServerCallContextHelper.CreateServerCallContext(), TestDataMarshaller.ContextualSerializer, canFlush : true);

            // Assert
            var messageData = ms.ToArray();

            CollectionAssert.AreEqual(
                new byte[]
            {
                0x00,     // compression = 0
                0x00,
                0x00,
                0x00,
                0x00,     // length = 0
            },
                messageData);
        }
Example #7
0
        public async Task ReadStreamMessageAsync_MessageDataIncomplete_ThrowError()
        {
            // Arrange
            var ms = new MemoryStream(new byte[]
            {
                0x00,     // compression = 0
                0x00,
                0x00,
                0x00,
                0x02,     // length = 2
                0x10
            });

            var pipeReader = PipeReader.Create(ms);

            // Act
            var ex = await ExceptionAssert.ThrowsAsync <RpcException>(
                () => pipeReader.ReadStreamMessageAsync(HttpContextServerCallContextHelper.CreateServerCallContext(), TestDataMarshaller.ContextualDeserializer).AsTask()).DefaultTimeout();

            // Assert
            Assert.AreEqual("Incomplete message.", ex.Status.Detail);
            Assert.AreEqual(StatusCode.Internal, ex.StatusCode);
        }
Example #8
0
        public async Task Invoke_SuccessAwaitedRelease_ReleaseCalled()
        {
            // Arrange
            var releaseTcs       = new TaskCompletionSource <object?>(TaskCreationOptions.RunContinuationsAsynchronously);
            var serviceActivator = new TcsGrpcServiceActivator <TestService>(releaseTcs);
            var invoker          = new UnaryServerMethodInvoker <TestService, TestMessage, TestMessage>(
                (service, reader, context) => Task.FromResult(new TestMessage()),
                new Method <TestMessage, TestMessage>(MethodType.Unary, "test", "test", _marshaller, _marshaller),
                HttpContextServerCallContextHelper.CreateMethodOptions(),
                serviceActivator);
            var httpContext = HttpContextHelpers.CreateContext();

            // Act
            var task = invoker.Invoke(httpContext, HttpContextServerCallContextHelper.CreateServerCallContext(), new TestMessage());

            Assert.False(task.IsCompleted);

            releaseTcs.SetResult(null);
            await task;

            // Assert
            Assert.True(serviceActivator.Released);
        }
        public async Task MoveNext_TokenCancelledDuringMoveNext_CancelTask()
        {
            // Arrange
            var ms = new SyncPointMemoryStream();

            var httpContext = new DefaultHttpContext();

            httpContext.Request.BodyReader = new StreamPipeReader(ms);
            var serverCallContext = HttpContextServerCallContextHelper.CreateServerCallContext(httpContext);
            var reader            = new HttpContextStreamReader <HelloReply>(serverCallContext, (data) =>
            {
                var message = new HelloReply();
                message.MergeFrom(data);
                return(message);
            });

            var cts = new CancellationTokenSource();

            var nextTask = reader.MoveNext(cts.Token);

            Assert.IsFalse(nextTask.IsCompleted);
            Assert.IsFalse(nextTask.IsCanceled);

            cts.Cancel();

            try
            {
                await nextTask;
                Assert.Fail();
            }
            catch (TaskCanceledException)
            {
            }

            Assert.IsTrue(nextTask.IsCompleted);
            Assert.IsTrue(nextTask.IsCanceled);
        }
Example #10
0
        public async Task ReadStreamMessageAsync_MultipleEmptyMessages_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 TestPipeReader(PipeReader.Create(ms));
            var testServerCallContext = HttpContextServerCallContextHelper.CreateServerCallContext();

            // Act 1
            var messageData1 = await pipeReader.ReadStreamMessageAsync(testServerCallContext, TestDataMarshaller.ContextualDeserializer);

            // Assert 1
            Assert.AreEqual(0, messageData1 !.Span.Length);
            Assert.AreEqual(emptyMessage.Length, pipeReader.Consumed);

            // Act 2
            var messageData2 = await pipeReader.ReadStreamMessageAsync(testServerCallContext, TestDataMarshaller.ContextualDeserializer);

            // Assert 2
            Assert.AreEqual(0, messageData2 !.Span.Length);
            Assert.AreEqual(emptyMessage.Length * 2, pipeReader.Consumed);

            // Act 3
            var messageData3 = await pipeReader.ReadStreamMessageAsync(testServerCallContext, TestDataMarshaller.ContextualDeserializer);

            // Assert 3
            Assert.IsNull(messageData3);
            Assert.AreEqual(emptyMessage.Length * 2, pipeReader.Consumed);
        }
        public async Task WriteMessageAsync_HasCustomCompressionLevel_WriteCompressedDataWithLevel()
        {
            // Arrange
            var mockCompressionProvider = new MockCompressionProvider();
            var serviceOptions          = new GrpcServiceOptions
            {
                ResponseCompressionAlgorithm = "Mock",
                ResponseCompressionLevel     = System.IO.Compression.CompressionLevel.Optimal,
                CompressionProviders         =
                {
                    mockCompressionProvider
                }
            };

            var httpContext = new DefaultHttpContext();

            httpContext.Request.Headers[GrpcProtocolConstants.MessageAcceptEncodingHeader] = "Mock";

            var context = HttpContextServerCallContextHelper.CreateServerCallContext(httpContext, serviceOptions);

            context.Initialize();

            var ms         = new MemoryStream();
            var pipeWriter = PipeWriter.Create(ms);

            // Act
            await pipeWriter.WriteMessageAsync(new byte[] { 0x10 }, context, flush : true);

            // Assert
            Assert.AreEqual(System.IO.Compression.CompressionLevel.Optimal, mockCompressionProvider.ArgumentCompression);

            var messageData = ms.ToArray();

            Assert.AreEqual(1, messageData[0]);  // compression
            Assert.AreEqual(21, messageData[4]); // message length
        }
Example #12
0
        public async Task ReadSingleMessageAsync_ExceedReceiveSize_ReturnData()
        {
            // Arrange
            var context = HttpContextServerCallContextHelper.CreateServerCallContext(maxReceiveMessageSize: 1);
            var ms      = new MemoryStream(new byte[]
            {
                0x00,     // compression = 0
                0x00,
                0x00,
                0x00,
                0x02,     // length = 1
                0x10,
                0x10
            });

            var pipeReader = PipeReader.Create(ms);

            // Act
            var ex = await ExceptionAssert.ThrowsAsync <RpcException>(() => pipeReader.ReadSingleMessageAsync(context, TestDataMarshaller.ContextualDeserializer).AsTask()).DefaultTimeout();

            // Assert
            Assert.AreEqual("Received message exceeds the maximum configured message size.", ex.Status.Detail);
            Assert.AreEqual(StatusCode.ResourceExhausted, ex.StatusCode);
        }
Example #13
0
        public async Task WriteMessageAsync_NoFlush_WriteNoData()
        {
            // Arrange
            var ms         = new MemoryStream();
            var pipeWriter = PipeWriter.Create(ms);

            // Act
            await pipeWriter.WriteMessageAsync(new TestData(Encoding.UTF8.GetBytes("Hello world")), HttpContextServerCallContextHelper.CreateServerCallContext(), TestDataMarshaller.ContextualSerializer, canFlush : false);

            // Assert
            var messageData = ms.ToArray();

            Assert.AreEqual(0, messageData.Length);
        }
        public async Task WriteStreamedMessageAsync_OneByteMessage_WriteData()
        {
            // Arrange
            var ms         = new MemoryStream();
            var pipeWriter = PipeWriter.Create(ms);

            // Act
            await pipeWriter.WriteStreamedMessageAsync(new TestData(new byte[] { 0x10 }), HttpContextServerCallContextHelper.CreateServerCallContext(), TestDataMarshaller.ContextualSerializer);

            // Assert
            var messageData = ms.ToArray();

            CollectionAssert.AreEqual(
                new byte[]
            {
                0x00,     // compression = 0
                0x00,
                0x00,
                0x00,
                0x01,     // length = 1
                0x10
            },
                messageData);
        }