Пример #1
0
        public async Task WriteMessageAsync_GzipCompressed_WriteCompressedData()
        {
            // Arrange
            var compressionProviders = new List <ICompressionProvider>
            {
                new GzipCompressionProvider(System.IO.Compression.CompressionLevel.Fastest)
            };

            var httpContext = new DefaultHttpContext();

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

            var context = HttpContextServerCallContextHelper.CreateServerCallContext(
                httpContext,
                responseCompressionAlgorithm: "gzip",
                compressionProviders: compressionProviders);

            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
            var messageData = ms.ToArray();

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

            byte[] result = Decompress(compressionProviders.Single(), messageData);
            Assert.AreEqual(1, result.Length);
            Assert.AreEqual(0x10, result[0]);
        }
Пример #2
0
        public async Task Invoke_AwaitedSuccess_ReleaseCalled()
        {
            // Arrange
            var methodTcs        = new TaskCompletionSource <TestMessage>(TaskCreationOptions.RunContinuationsAsynchronously);
            var methodResult     = new TestMessage();
            var serviceActivator = new TestGrpcServiceActivator <TestService>();
            var invoker          = new UnaryServerMethodInvoker <TestService, TestMessage, TestMessage>(
                (service, reader, context) => methodTcs.Task,
                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);

            methodTcs.SetResult(methodResult);
            var awaitedResult = await task;

            // Assert
            Assert.AreEqual(methodResult, awaitedResult);
            Assert.True(serviceActivator.Released);
        }
Пример #3
0
        public async Task ReadSingleMessageAsync_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 = PipeReader.Create(ms);

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

            // Assert
            Assert.AreEqual("Received message exceeds the maximum configured message size.", ex.Status.Detail);
            Assert.AreEqual(StatusCode.ResourceExhausted, ex.StatusCode);
        }
Пример #4
0
        public async Task ReadSingleMessageAsync_AdditionalDataInSeparatePipeRead_ThrowError()
        {
            // Arrange
            var requestStream = new SyncPointMemoryStream();

            var pipeReader = PipeReader.Create(requestStream);

            // Act
            var readTask = pipeReader.ReadSingleMessageAsync(HttpContextServerCallContextHelper.CreateServerCallContext(), TestDataMarshaller.ContextualDeserializer).AsTask();

            // Assert
            Assert.IsFalse(readTask.IsCompleted, "Still waiting for data");

            await requestStream.AddDataAndWait(new byte[]
            {
                0x00,     // compression = 0
                0x00,
                0x00,
                0x00,
                0x01,     // length = 1
                0x10
            }).DefaultTimeout();

            Assert.IsFalse(readTask.IsCompleted, "Still waiting for data");

            await requestStream.AddDataAndWait(new byte[] { 0x00 }).DefaultTimeout();

            var ex = await ExceptionAssert.ThrowsAsync <RpcException>(() => readTask).DefaultTimeout();

            // Assert
            Assert.AreEqual("Additional data after the message received.", ex.Status.Detail);
            Assert.AreEqual(StatusCode.Internal, ex.StatusCode);
        }
Пример #5
0
        public async Task WriteMessageAsync_GzipCompressed_WriteCompressedData()
        {
            // Arrange
            var serviceOptions = new GrpcServiceOptions
            {
                ResponseCompressionAlgorithm = "gzip",
                CompressionProviders         =
                {
                    new GzipCompressionProvider(System.IO.Compression.CompressionLevel.Fastest)
                }
            };

            var httpContext = new DefaultHttpContext();

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

            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, Marshaller.ContextualSerializer, canFlush : true);

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

            Assert.AreEqual(1, messageData[0]);  // compression
            Assert.AreEqual(21, messageData[4]); // message length
        }
Пример #6
0
        public async Task WriteMessageAsync_UnderSendSize_WriteData()
        {
            // Arrange
            var context = HttpContextServerCallContextHelper.CreateServerCallContext(serviceOptions: new GrpcServiceOptions {
                SendMaxMessageSize = 1
            });
            var ms         = new MemoryStream();
            var pipeWriter = PipeWriter.Create(ms);

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

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

            CollectionAssert.AreEqual(
                new byte[]
            {
                0x00,     // compression = 0
                0x00,
                0x00,
                0x00,
                0x01,     // length = 1
                0x10
            },
                messageData);
        }
Пример #7
0
        public async Task WriteAsync_WriteInProgress_Error()
        {
            // Arrange
            var tcs = new TaskCompletionSource <object?>(TaskCreationOptions.RunContinuationsAsynchronously);

            var httpContext = new DefaultHttpContext();

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

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

            var ex = await ExceptionAssert.ThrowsAsync <InvalidOperationException>(() =>
            {
                return(writer.WriteAsync(new HelloReply
                {
                    Message = "Hello world 2"
                }));
            });

            // Assert
            Assert.AreEqual("Can't write the message because the previous write is in progress.", ex.Message);
        }
Пример #8
0
        public async Task ReadSingleMessageAsync_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 = PipeReader.Create(ms);

            // Act
            var messageData = await pipeReader.ReadSingleMessageAsync(context, Marshaller.ContextualDeserializer);

            // Assert
            Assert.AreEqual(1, messageData.Length);
            Assert.AreEqual(0x10, messageData[0]);
        }
        public async Task WriteStreamedMessageAsync_UnderSendSize_WriteData()
        {
            // Arrange
            var context    = HttpContextServerCallContextHelper.CreateServerCallContext(maxSendMessageSize: 1);
            var ms         = new MemoryStream();
            var pipeWriter = PipeWriter.Create(ms);

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

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

            CollectionAssert.AreEqual(
                new byte[]
            {
                0x00,     // compression = 0
                0x00,
                0x00,
                0x00,
                0x01,     // length = 1
                0x10
            },
                messageData);
        }
Пример #10
0
        public async Task Invoke_ThrowExceptionAwaitedRelease_ReleaseCalledAndErrorThrown()
        {
            // Arrange
            var releaseTcs       = new TaskCompletionSource <object?>(TaskCreationOptions.RunContinuationsAsynchronously);
            var serviceActivator = new TcsGrpcServiceActivator <TestService>(releaseTcs);
            var thrownException  = new Exception("Exception!");
            var invoker          = new UnaryServerMethodInvoker <TestService, TestMessage, TestMessage>(
                (service, reader, context) => throw thrownException,
                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);

            try
            {
                await task;
                Assert.Fail();
            }
            catch (Exception ex)
            {
                // Assert
                Assert.True(serviceActivator.Released);
                Assert.AreEqual(thrownException, ex);
            }
        }
        public async Task MoveNext_TokenCancelledDuringMoveNext_CancelTask()
        {
            // Arrange
            var ms = new SyncPointMemoryStream();

            var httpContext = new DefaultHttpContext();

            httpContext.Features.Set <IRequestBodyPipeFeature>(new TestRequestBodyPipeFeature(PipeReader.Create(ms)));
            var serverCallContext = HttpContextServerCallContextHelper.CreateServerCallContext(httpContext);
            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);
        }
Пример #12
0
        public async Task WriteMessageAsync_LongMessage_WriteData()
        {
            // Arrange
            var ms         = new MemoryStream();
            var pipeWriter = PipeWriter.Create(ms);
            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.");

            // Act
            await pipeWriter.WriteMessageAsync(new TestData(content), HttpContextServerCallContextHelper.CreateServerCallContext(), TestDataMarshaller.ContextualSerializer, canFlush : true);

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

            CollectionAssert.AreEqual(
                new byte[]
            {
                0x00,     // compression = 0
                0x00,
                0x00,
                0x01,
                0xC1,     // length = 449
            }.Concat(content).ToArray(),
                messageData);
        }
Пример #13
0
 private HttpContextServerCallContext CreateServerCallContext(HttpContext httpContext, ILogger?logger = null)
 {
     return(HttpContextServerCallContextHelper.CreateServerCallContext(
                httpContext: httpContext,
                logger: logger,
                initialize: false));
 }
Пример #14
0
        public void GetHttpContext_HttpContextServerCallContext_Success()
        {
            var httpContext = new DefaultHttpContext();

            var serverCallContext = HttpContextServerCallContextHelper.CreateServerCallContext(httpContext);

            Assert.AreEqual(httpContext, serverCallContext.GetHttpContext());
        }
Пример #15
0
        public async Task ReadStreamMessageAsync_MessageSplitAcrossReadsWithAdditionalData_ExamineMessageOnly()
        {
            // Arrange
            var emptyMessage = new byte[]
            {
                0x00,     // compression = 0
                0x00,
                0x00,
                0x00,
                0x00,     // length = 0
                0x00,     // compression = 0
            };
            var followingMessage = new byte[]
            {
                0x00,
                0x00,
                0x00,
                0x00,     // length = 0
                0x00,     // extra data
            };

            var requestStream = new SyncPointMemoryStream(runContinuationsAsynchronously: false);

            var pipeReader            = new TestPipeReader(PipeReader.Create(requestStream));
            var testServerCallContext = HttpContextServerCallContextHelper.CreateServerCallContext();

            // Act 1
            var messageData1Task = pipeReader.ReadStreamMessageAsync(testServerCallContext, TestDataMarshaller.ContextualDeserializer).AsTask();
            await requestStream.AddDataAndWait(emptyMessage).DefaultTimeout();

            // Assert 1
            Assert.AreEqual(0, (await messageData1Task.DefaultTimeout()) !.Span.Length);
            Assert.AreEqual(5, pipeReader.Consumed);
            Assert.AreEqual(5, pipeReader.Examined);

            // Act 2
            var messageData2Task = pipeReader.ReadStreamMessageAsync(testServerCallContext, TestDataMarshaller.ContextualDeserializer).AsTask();
            await requestStream.AddDataAndWait(followingMessage).DefaultTimeout();

            // Assert 2
            Assert.AreEqual(0, (await messageData2Task.DefaultTimeout()) !.Span.Length);
            Assert.AreEqual(10, pipeReader.Consumed);
            Assert.AreEqual(10, pipeReader.Examined);

            // Act 3
            var messageData3Task = pipeReader.ReadStreamMessageAsync(testServerCallContext, TestDataMarshaller.ContextualDeserializer).AsTask();
            await requestStream.AddDataAndWait(Array.Empty <byte>()).DefaultTimeout();

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

            Assert.AreEqual("Incomplete message.", ex.Status.Detail);
            Assert.AreEqual(10, pipeReader.Consumed);
            Assert.AreEqual(11, pipeReader.Examined); // Examined ahead to ask for more data
        }
Пример #16
0
        public async Task ReadSingleMessageAsync_MessageInMultiplePipeReads_ReadMessageData()
        {
            // Arrange
            var messageData = new byte[]
            {
                0x00,     // compression = 0
                0x00,
                0x00,
                0x00,
                0x01,     // length = 1
                0x10
            };

            // Run continuations without async so ReadSingleMessageAsync immediately consumes added data
            var requestStream = new SyncPointMemoryStream(runContinuationsAsynchronously: false);

            var pipeReader = new TestPipeReader(PipeReader.Create(requestStream));

            // Act
            var readTask = pipeReader.ReadSingleMessageAsync(HttpContextServerCallContextHelper.CreateServerCallContext(), TestDataMarshaller.ContextualDeserializer).AsTask();

            // Assert
            for (var i = 0; i < messageData.Length; i++)
            {
                var b      = messageData[i];
                var isLast = i == messageData.Length - 1;

                Assert.IsFalse(readTask.IsCompleted, "Still waiting for data");

                await requestStream.AddDataAndWait(new[] { b }).DefaultTimeout();

                if (!isLast)
                {
                    Assert.AreEqual(0, pipeReader.Consumed);
                    Assert.AreEqual(i + 1, pipeReader.Examined);
                }
                else
                {
                    Assert.AreEqual(messageData.Length, pipeReader.Consumed); // Consumed message
                    Assert.AreEqual(messageData.Length, pipeReader.Examined);
                }
            }

            await requestStream.AddDataAndWait(Array.Empty <byte>()).DefaultTimeout();

            var readMessageData = await readTask.DefaultTimeout();

            // Assert
            CollectionAssert.AreEqual(new byte[] { 0x10 }, readMessageData.Span.ToArray());
        }
Пример #17
0
        public async Task WriteMessageAsync_ExceedSendSize_ThrowError()
        {
            // Arrange
            var context    = HttpContextServerCallContextHelper.CreateServerCallContext(maxSendMessageSize: 1);
            var ms         = new MemoryStream();
            var pipeWriter = PipeWriter.Create(ms);

            // Act
            var ex = await ExceptionAssert.ThrowsAsync <RpcException>(() => pipeWriter.WriteMessageAsync(new TestData(new byte[] { 0x10, 0x10 }), context, TestDataMarshaller.ContextualSerializer, canFlush: true)).DefaultTimeout();

            // Assert
            Assert.AreEqual("Sending message exceeds the maximum configured message size.", ex.Status.Detail);
            Assert.AreEqual(StatusCode.ResourceExhausted, ex.StatusCode);
        }
        public void MoveNext_AlreadyCancelledToken_CancelReturnImmediately()
        {
            // Arrange
            var ms = new SyncPointMemoryStream();

            var httpContext       = new DefaultHttpContext();
            var serverCallContext = HttpContextServerCallContextHelper.CreateServerCallContext(httpContext);
            var reader            = new HttpContextStreamReader <HelloReply>(serverCallContext, MessageHelpers.ServiceMethod.ResponseMarshaller.ContextualDeserializer);

            // Act
            var nextTask = reader.MoveNext(new CancellationToken(true));

            // Assert
            Assert.IsTrue(nextTask.IsCompleted);
            Assert.IsTrue(nextTask.IsCanceled);
        }
Пример #19
0
        public void WriteMessageAsync_ExceedSendSize_ThrowError()
        {
            // Arrange
            var context = HttpContextServerCallContextHelper.CreateServerCallContext(serviceOptions: new GrpcServiceOptions {
                SendMaxMessageSize = 1
            });
            var ms         = new MemoryStream();
            var pipeWriter = new StreamPipeWriter(ms);

            // Act
            var ex = Assert.ThrowsAsync <RpcException>(() => pipeWriter.WriteMessageAsync(new byte[] { 0x10, 0x10 }, context, flush: true));

            // Assert
            Assert.AreEqual("Sending message exceeds the maximum configured message size.", ex.Status.Detail);
            Assert.AreEqual(StatusCode.ResourceExhausted, ex.StatusCode);
        }
Пример #20
0
        private static ServerCallHandlerBase <TestService, TestMessage, TestMessage> CreateHandler(MethodType methodType, ILoggerFactory?loggerFactory = null)
        {
            var method = new Method <TestMessage, TestMessage>(methodType, "test", "test", _marshaller, _marshaller);

            switch (methodType)
            {
            case MethodType.Unary:
                return(new UnaryServerCallHandler <TestService, TestMessage, TestMessage>(
                           method,
                           (service, reader, context) => Task.FromResult(new TestMessage()),
                           HttpContextServerCallContextHelper.CreateMethodContext(),
                           loggerFactory ?? NullLoggerFactory.Instance,
                           new TestGrpcServiceActivator <TestService>(),
                           TestServiceProvider.Instance));

            case MethodType.ClientStreaming:
                return(new ClientStreamingServerCallHandler <TestService, TestMessage, TestMessage>(
                           method,
                           (service, reader, context) => Task.FromResult(new TestMessage()),
                           HttpContextServerCallContextHelper.CreateMethodContext(),
                           loggerFactory ?? NullLoggerFactory.Instance,
                           new TestGrpcServiceActivator <TestService>(),
                           TestServiceProvider.Instance));

            case MethodType.ServerStreaming:
                return(new ServerStreamingServerCallHandler <TestService, TestMessage, TestMessage>(
                           method,
                           (service, request, writer, context) => Task.FromResult(new TestMessage()),
                           HttpContextServerCallContextHelper.CreateMethodContext(),
                           loggerFactory ?? NullLoggerFactory.Instance,
                           new TestGrpcServiceActivator <TestService>(),
                           TestServiceProvider.Instance));

            case MethodType.DuplexStreaming:
                return(new DuplexStreamingServerCallHandler <TestService, TestMessage, TestMessage>(
                           method,
                           (service, reader, writer, context) => Task.CompletedTask,
                           HttpContextServerCallContextHelper.CreateMethodContext(),
                           loggerFactory ?? NullLoggerFactory.Instance,
                           new TestGrpcServiceActivator <TestService>(),
                           TestServiceProvider.Instance));

            default:
                throw new ArgumentException();
            }
        }
Пример #21
0
        public async Task WriteMessageAsync_MultipleOneByteMessages_WriteData()
        {
            // Arrange
            var ms         = new MemoryStream();
            var pipeWriter = PipeWriter.Create(ms);
            var context    = HttpContextServerCallContextHelper.CreateServerCallContext();

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

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

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

            ms.Seek(0, SeekOrigin.Begin);

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

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

            CollectionAssert.AreEqual(
                new byte[]
            {
                0x00,     // compression = 0
                0x00,
                0x00,
                0x00,
                0x01,     // length = 1
                0x20
            },
                messageData);
        }
Пример #22
0
        public async Task WriteAsync_BufferHintWriteOptions_DoesNotFlush()
        {
            // 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);

            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.BodyWriter.FlushAsync();

            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);
        }
Пример #23
0
        public async Task WriteAsync_BufferHintWriteOptions_DoesNotFlush()
        {
            // 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());

            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);
        }
Пример #24
0
        public void Invoke_ThrowException_ReleaseCalledAndErrorThrown()
        {
            // Arrange
            var serviceActivator = new TestGrpcServiceActivator <TestService>();
            var ex      = new Exception("Exception!");
            var invoker = new UnaryServerMethodInvoker <TestService, TestMessage, TestMessage>(
                (service, reader, context) => throw ex,
                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
            Assert.True(serviceActivator.Released);
            Assert.True(task.IsFaulted);
            Assert.AreEqual(ex, task.Exception !.InnerException);
        }
Пример #25
0
        public async Task ReadMessageStreamAsync_HeaderIncomplete_ThrowError()
        {
            // Arrange
            var ms = new MemoryStream(new byte[]
            {
                0x00,     // compression = 0
                0x00,
                0x00
            });

            var pipeReader = PipeReader.Create(ms);

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

            // Assert
            Assert.AreEqual("Incomplete message.", ex.Status.Detail);
            Assert.AreEqual(StatusCode.Internal, ex.StatusCode);
        }
        public void MoveNext_AlreadyCancelledToken_CancelReturnImmediately()
        {
            // Arrange
            var ms = new SyncPointMemoryStream();

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

            // Act
            var nextTask = reader.MoveNext(new CancellationToken(true));

            // Assert
            Assert.IsTrue(nextTask.IsCompleted);
            Assert.IsTrue(nextTask.IsCanceled);
        }
Пример #27
0
        public async Task ReadSingleMessageAsync_EmptyMessage_ReturnNoData()
        {
            // Arrange
            var ms = new MemoryStream(new byte[]
            {
                0x00,     // compression = 0
                0x00,
                0x00,
                0x00,
                0x00     // length = 0
            });

            var pipeReader = new TestPipeReader(PipeReader.Create(ms));

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

            // Assert
            Assert.AreEqual(0, messageData.Span.Length);
            Assert.AreEqual(5, pipeReader.Consumed);
        }
        public async Task WriteAsync_DefaultWriteOptions_Flushes()
        {
            // Arrange
            var ms = new MemoryStream();

            var httpContext = new DefaultHttpContext();

            httpContext.Features.Set <IResponseBodyPipeFeature>(new TestResponseBodyPipeFeature(PipeWriter.Create(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 = 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);
        }
Пример #29
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]);
        }
Пример #30
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]);
        }