private async Task <(int sent, int received)> EchoData(int total, byte[] data, StreamService.StreamServiceClient client)
        {
            var sent     = 0;
            var received = 0;
            var call     = client.EchoAllData();

            var readTask = Task.Run(async() =>
            {
                await foreach (var message in call.ResponseStream.ReadAllAsync())
                {
                    received += message.Data.Length;

                    Logger.LogInformation($"Received {sent} bytes");
                }
            });

            while (sent < total)
            {
                var writeCount = Math.Min(total - sent, data.Length);

                await call.RequestStream.WriteAsync(new DataMessage
                {
                    Data = ByteString.CopyFrom(data, 0, writeCount)
                }).DefaultTimeout();

                sent += writeCount;

                Logger.LogInformation($"Sent {sent} bytes");
            }

            await call.RequestStream.CompleteAsync().DefaultTimeout();

            await readTask;

            return(sent, received);
        }
示例#2
0
        private async Task CancelInParallel(int tasks, bool waitForHeaders, int interations)
        {
            SetExpectedErrorsFilter(writeContext =>
            {
                if (writeContext.LoggerName == TestConstants.ServerCallHandlerTestName)
                {
                    // Kestrel cancellation error message
                    if (writeContext.Exception is IOException &&
                        writeContext.Exception.Message == "The client reset the request stream.")
                    {
                        return(true);
                    }

                    // Cancellation when service is receiving message
                    if (writeContext.Exception is InvalidOperationException &&
                        writeContext.Exception.Message == "Cannot write message after request is complete.")
                    {
                        return(true);
                    }

                    // Cancellation before service writes message
                    if (writeContext.Exception is TaskCanceledException &&
                        writeContext.Exception.Message == "A task was canceled.")
                    {
                        return(true);
                    }
                }

                if (writeContext.LoggerName == "Grpc.Net.Client.Internal.GrpcCall")
                {
                    // Cancellation when call hasn't returned headers
                    if (writeContext.EventId.Name == "ErrorStartingCall" &&
                        writeContext.Exception is TaskCanceledException)
                    {
                        return(true);
                    }

                    if (writeContext.EventId.Name == "GrpcStatusError")
                    {
                        if (writeContext.Message == "Call failed with gRPC error status. Status code: 'Cancelled', Message: 'Call canceled by the client.'." ||
                            writeContext.Message == "Call failed with gRPC error status. Status code: 'Cancelled', Message: 'Error starting gRPC call.'.")
                        {
                            return(true);
                        }
                    }
                }

                return(false);
            });

            // Arrange
            var data = new byte[1024 * 64];

            var client = new StreamService.StreamServiceClient(Channel);

            await TestHelpers.RunParallel(tasks, async() =>
            {
                for (int i = 0; i < interations; i++)
                {
                    var cts     = new CancellationTokenSource();
                    var headers = new Metadata();
                    if (waitForHeaders)
                    {
                        headers.Add("flush-headers", bool.TrueString);
                    }
                    var call = client.EchoAllData(cancellationToken: cts.Token, headers: headers);

                    if (waitForHeaders)
                    {
                        await call.ResponseHeadersAsync.DefaultTimeout();
                    }

                    await call.RequestStream.WriteAsync(new DataMessage
                    {
                        Data = ByteString.CopyFrom(data)
                    }).DefaultTimeout();

                    cts.Cancel();
                }
            });
        }
示例#3
0
        private async Task CancelInParallel(int tasks, bool waitForHeaders, int interations)
        {
            SetExpectedErrorsFilter(writeContext =>
            {
                if (writeContext.LoggerName == TestConstants.ServerCallHandlerTestName)
                {
                    // Kestrel cancellation error message
                    if (writeContext.Exception is IOException &&
                        writeContext.Exception.Message == "The client reset the request stream.")
                    {
                        return(true);
                    }

                    // Cancellation when service is receiving message
                    if (writeContext.Exception is InvalidOperationException &&
                        writeContext.Exception.Message == "Can't read messages after the request is complete.")
                    {
                        return(true);
                    }

                    // Cancellation when service is writing message
                    if (writeContext.Exception is InvalidOperationException &&
                        writeContext.Exception.Message == "Can't write the message because the request is complete.")
                    {
                        return(true);
                    }

                    // Cancellation before service writes message
                    if (writeContext.Exception is TaskCanceledException &&
                        writeContext.Exception.Message == "A task was canceled.")
                    {
                        return(true);
                    }
                }

                if (writeContext.LoggerName == "Grpc.Net.Client.Internal.GrpcCall")
                {
                    // Cancellation when call hasn't returned headers
                    if (writeContext.EventId.Name == "ErrorStartingCall" &&
                        writeContext.Exception is TaskCanceledException)
                    {
                        return(true);
                    }
                }

                return(false);
            });

            // Arrange
            var data = new byte[1024 * 64];

            var client = new StreamService.StreamServiceClient(Channel);

            await TestHelpers.RunParallel(tasks, async taskIndex =>
            {
                try
                {
                    for (var i = 0; i < interations; i++)
                    {
                        Logger.LogInformation($"Staring {taskIndex}-{i}");

                        var cts     = new CancellationTokenSource();
                        var headers = new Metadata();
                        if (waitForHeaders)
                        {
                            headers.Add("flush-headers", bool.TrueString);
                        }
                        using var call = client.EchoAllData(cancellationToken: cts.Token, headers: headers);

                        if (waitForHeaders)
                        {
                            await call.ResponseHeadersAsync.DefaultTimeout();
                        }

                        await call.RequestStream.WriteAsync(new DataMessage
                        {
                            Data = ByteString.CopyFrom(data)
                        }).DefaultTimeout();

                        cts.Cancel();
                    }
                }
                catch (Exception ex)
                {
                    Logger.LogError(ex, "Cancellation error");
                    throw;
                }
            });

            // Wait a short amount of time so that any server cancellation error
            // finishes being thrown before the next test starts.
            await Task.Delay(50);
        }