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);
        }
Exemple #2
0
        public async Task BidirectionalStreaming(string scheme)
        {
            var hostBuilder = new HostBuilder()
                              .ConfigureWebHost(webHostBuilder =>
            {
                ConfigureKestrel(webHostBuilder, scheme);
                webHostBuilder.ConfigureServices(AddTestLogging)
                .Configure(app => app.Run(async context =>
                {
                    var reader = context.Request.BodyReader;
                    // Read Hello World and echo it back to the client, twice
                    for (var i = 0; i < 2; i++)
                    {
                        var readResult = await reader.ReadAsync().DefaultTimeout();
                        while (!readResult.IsCompleted && readResult.Buffer.Length < "Hello World".Length)
                        {
                            reader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End);
                            readResult = await reader.ReadAsync().DefaultTimeout();
                        }

                        var sequence = readResult.Buffer.Slice(0, "Hello World".Length);
                        Assert.True(sequence.IsSingleSegment);
                        await context.Response.BodyWriter.WriteAsync(sequence.First).DefaultTimeout();
                        reader.AdvanceTo(sequence.End);
                    }

                    var finalResult = await reader.ReadAsync().DefaultTimeout();
                    Assert.True(finalResult.IsCompleted && finalResult.Buffer.Length == 0);
                }));
            });

            using var host = await hostBuilder.StartAsync().DefaultTimeout();

            var url = host.MakeUrl(scheme);

            using var client = CreateClient();
            client.DefaultRequestHeaders.ExpectContinue = true;

            var streamingContent = new StreamingContent();
            var request          = CreateRequestMessage(HttpMethod.Post, url, streamingContent);
            var responseTask     = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout();
            // The server won't send headers until it gets the first message
            await streamingContent.SendAsync("Hello World").DefaultTimeout();

            var response = await responseTask;

            Assert.Equal(HttpVersion.Version20, response.Version);
            var stream = await response.Content.ReadAsStreamAsync().DefaultTimeout();

            await ReadStreamHelloWorld(stream);

            await streamingContent.SendAsync("Hello World").DefaultTimeout();

            streamingContent.Complete();

            await ReadStreamHelloWorld(stream);

            Assert.Equal(0, await stream.ReadAsync(new byte[10], 0, 10).DefaultTimeout());
            await host.StopAsync().DefaultTimeout();
        }
        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 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();
        }
Exemple #5
0
        public async Task ReverseEcho(string scheme)
        {
            var clientEcho  = new TaskCompletionSource <string>(TaskCreationOptions.RunContinuationsAsynchronously);
            var hostBuilder = new HostBuilder()
                              .ConfigureWebHost(webHostBuilder =>
            {
                ConfigureKestrel(webHostBuilder, scheme);
                webHostBuilder.ConfigureServices(AddTestLogging)
                .Configure(app => app.Run(async context =>
                {
                    // Prime it?
                    // var readTask = context.Request.BodyReader.ReadAsync();
                    context.Response.ContentType = "text/plain";
                    await context.Response.WriteAsync("Hello World");
                    await context.Response.CompleteAsync().DefaultTimeout();

                    try
                    {
                        // var readResult = await readTask;
                        // context.Request.BodyReader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End);
                        using var streamReader = new StreamReader(context.Request.Body);
                        var read = await streamReader.ReadToEndAsync().DefaultTimeout();
                        clientEcho.SetResult(read);
                    }
                    catch (Exception ex)
                    {
                        clientEcho.SetException(ex);
                    }
                }));
            });

            using var host = await hostBuilder.StartAsync().DefaultTimeout();

            var url = host.MakeUrl(scheme);

            using var client = CreateClient();
            // client.DefaultRequestHeaders.ExpectContinue = true;

            var streamingContent = new StreamingContent();
            var request          = CreateRequestMessage(HttpMethod.Post, url, streamingContent);

            using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout();

            Assert.Equal(HttpVersion.Version20, response.Version);

            // Read Hello World and echo it back to the server.

            /* https://github.com/dotnet/corefx/issues/39404
             * var read = await response.Content.ReadAsStringAsync().DefaultTimeout();
             * Assert.Equal("Hello World", read);
             */
            var stream = await response.Content.ReadAsStreamAsync().DefaultTimeout();

            await ReadStreamHelloWorld(stream).DefaultTimeout();

            Assert.Equal(0, await stream.ReadAsync(new byte[10], 0, 10).DefaultTimeout());
            stream.Dispose(); // https://github.com/dotnet/corefx/issues/39404 can be worked around by commenting out this Dispose

            await streamingContent.SendAsync("Hello World").DefaultTimeout();

            streamingContent.Complete();

            Assert.Equal("Hello World", await clientEcho.Task.DefaultTimeout());
            await host.StopAsync().DefaultTimeout();
        }
Exemple #6
0
        public async Task BidirectionalStreamingMoreClientData(string scheme)
        {
            var lastPacket  = new TaskCompletionSource <string>(TaskCreationOptions.RunContinuationsAsynchronously);
            var hostBuilder = new HostBuilder()
                              .ConfigureWebHost(webHostBuilder =>
            {
                ConfigureKestrel(webHostBuilder, scheme);
                webHostBuilder.ConfigureServices(AddTestLogging)
                .Configure(app => app.Run(async context =>
                {
                    var reader = context.Request.BodyReader;

                    var readResult = await reader.ReadAsync().DefaultTimeout();
                    while (!readResult.IsCompleted && readResult.Buffer.Length < "Hello World".Length)
                    {
                        reader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End);
                        readResult = await reader.ReadAsync().DefaultTimeout();
                    }

                    var sequence = readResult.Buffer.Slice(0, "Hello World".Length);
                    Assert.True(sequence.IsSingleSegment);
                    await context.Response.BodyWriter.WriteAsync(sequence.First).DefaultTimeout();
                    reader.AdvanceTo(sequence.End);
                    await context.Response.CompleteAsync().DefaultTimeout();

                    try
                    {
                        // The client sends one more packet after the server completes
                        readResult = await reader.ReadAsync().DefaultTimeout();
                        while (!readResult.IsCompleted && readResult.Buffer.Length < "Hello World".Length)
                        {
                            reader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End);
                            readResult = await reader.ReadAsync().DefaultTimeout();
                        }

                        Assert.True(readResult.Buffer.IsSingleSegment);
                        var result = Encoding.UTF8.GetString(readResult.Buffer.FirstSpan);
                        reader.AdvanceTo(readResult.Buffer.End);

                        var finalResult = await reader.ReadAsync().DefaultTimeout();
                        Assert.True(finalResult.IsCompleted && finalResult.Buffer.Length == 0);
                        lastPacket.SetResult(result);
                    }
                    catch (Exception ex)
                    {
                        lastPacket.SetException(ex);
                    }
                }));
            });

            using var host = await hostBuilder.StartAsync().DefaultTimeout();

            var url = host.MakeUrl(scheme);

            using var client = CreateClient();
            client.DefaultRequestHeaders.ExpectContinue = true;

            var streamingContent = new StreamingContent();
            var request          = CreateRequestMessage(HttpMethod.Post, url, streamingContent);
            var responseTask     = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout();
            // The server doesn't respond until we send the first set of data
            await streamingContent.SendAsync("Hello World").DefaultTimeout();

            var response = await responseTask;

            Assert.Equal(HttpVersion.Version20, response.Version);
            var stream = await response.Content.ReadAsStreamAsync();

            await ReadStreamHelloWorld(stream);

            Assert.Equal(0, await stream.ReadAsync(new byte[10], 0, 10).DefaultTimeout());
            stream.Dispose(); // https://github.com/dotnet/corefx/issues/39404 can be worked around by commenting out this Dispose

            // Send one more message after the server has finished.
            await streamingContent.SendAsync("Hello World").DefaultTimeout();

            streamingContent.Complete();

            var lastData = await lastPacket.Task.DefaultTimeout();

            Assert.Equal("Hello World", lastData);

            await host.StopAsync().DefaultTimeout();
        }