From 76d4e7d2c92478e50a6424a17768a4ef9d68730a Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Sat, 23 May 2020 09:53:59 +1200 Subject: [PATCH] Capture interop test client output --- .../InteropTests/Helpers/ClientProcess.cs | 37 ++++++++++++++++--- src/Grpc/test/InteropTests/InteropTests.cs | 19 +++++++--- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src/Grpc/test/InteropTests/Helpers/ClientProcess.cs b/src/Grpc/test/InteropTests/Helpers/ClientProcess.cs index 689b81e572d2..9d3e982661a7 100644 --- a/src/Grpc/test/InteropTests/Helpers/ClientProcess.cs +++ b/src/Grpc/test/InteropTests/Helpers/ClientProcess.cs @@ -3,6 +3,7 @@ using System; using System.Diagnostics; +using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Internal; @@ -15,9 +16,13 @@ public class ClientProcess : IDisposable private readonly Process _process; private readonly ProcessEx _processEx; private readonly TaskCompletionSource _startTcs; + private readonly StringBuilder _output; + private readonly object _outputLock = new object(); public ClientProcess(ITestOutputHelper output, string path, string serverPort, string testCase) { + _output = new StringBuilder(); + _process = new Process(); _process.StartInfo = new ProcessStartInfo { @@ -28,6 +33,7 @@ public ClientProcess(ITestOutputHelper output, string path, string serverPort, s }; _process.EnableRaisingEvents = true; _process.OutputDataReceived += Process_OutputDataReceived; + _process.ErrorDataReceived += Process_ErrorDataReceived; _process.Start(); _processEx = new ProcessEx(output, _process, timeout: Timeout.InfiniteTimeSpan); @@ -35,14 +41,18 @@ public ClientProcess(ITestOutputHelper output, string path, string serverPort, s _startTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); } - public Task WaitForReady() + public Task WaitForReadyAsync() => _startTcs.Task; + public Task WaitForExitAsync() => _processEx.Exited; + public int ExitCode => _process.ExitCode; + + public string GetOutput() { - return _startTcs.Task; + lock (_outputLock) + { + return _output.ToString(); + } } - public int ExitCode => _process.ExitCode; - public Task Exited => _processEx.Exited; - private void Process_OutputDataReceived(object sender, DataReceivedEventArgs e) { var data = e.Data; @@ -52,6 +62,23 @@ private void Process_OutputDataReceived(object sender, DataReceivedEventArgs e) { _startTcs.TrySetResult(null); } + + lock (_outputLock) + { + _output.AppendLine(data); + } + } + } + + private void Process_ErrorDataReceived(object sender, DataReceivedEventArgs e) + { + var data = e.Data; + if (data != null) + { + lock (_outputLock) + { + _output.AppendLine(data); + } } } diff --git a/src/Grpc/test/InteropTests/InteropTests.cs b/src/Grpc/test/InteropTests/InteropTests.cs index 2a9a1f66d771..1ece566503c0 100644 --- a/src/Grpc/test/InteropTests/InteropTests.cs +++ b/src/Grpc/test/InteropTests/InteropTests.cs @@ -2,9 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Collections.Generic; using System.IO; -using System.Linq; using System.Threading.Tasks; using InteropTests.Helpers; using Microsoft.AspNetCore.Testing; @@ -36,11 +34,22 @@ public async Task InteropTestCase(string name) using (var clientProcess = new ClientProcess(_output, _clientPath, serverProcess.ServerPort, name)) { - await clientProcess.WaitForReady().TimeoutAfter(DefaultTimeout); + try + { + await clientProcess.WaitForReadyAsync().TimeoutAfter(DefaultTimeout); - await clientProcess.Exited.TimeoutAfter(DefaultTimeout); + await clientProcess.WaitForExitAsync().TimeoutAfter(DefaultTimeout); - Assert.Equal(0, clientProcess.ExitCode); + Assert.Equal(0, clientProcess.ExitCode); + } + catch (Exception ex) + { + var clientOutput = clientProcess.GetOutput(); + var errorMessage = $@"Error while running client process. Process output: +====================================== +{clientOutput}"; + throw new InvalidOperationException(errorMessage, ex); + } } } }