Skip to content

Commit d58947f

Browse files
authored
Capture gRPC interop test client output (#22163)
1 parent 6e91ff9 commit d58947f

File tree

2 files changed

+48
-12
lines changed

2 files changed

+48
-12
lines changed

src/Grpc/test/InteropTests/Helpers/ClientProcess.cs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Diagnostics;
6+
using System.Text;
67
using System.Threading;
78
using System.Threading.Tasks;
89
using Microsoft.AspNetCore.Internal;
@@ -15,9 +16,13 @@ public class ClientProcess : IDisposable
1516
private readonly Process _process;
1617
private readonly ProcessEx _processEx;
1718
private readonly TaskCompletionSource<object> _startTcs;
19+
private readonly StringBuilder _output;
20+
private readonly object _outputLock = new object();
1821

1922
public ClientProcess(ITestOutputHelper output, string path, string serverPort, string testCase)
2023
{
24+
_output = new StringBuilder();
25+
2126
_process = new Process();
2227
_process.StartInfo = new ProcessStartInfo
2328
{
@@ -28,21 +33,26 @@ public ClientProcess(ITestOutputHelper output, string path, string serverPort, s
2833
};
2934
_process.EnableRaisingEvents = true;
3035
_process.OutputDataReceived += Process_OutputDataReceived;
36+
_process.ErrorDataReceived += Process_ErrorDataReceived;
3137
_process.Start();
3238

3339
_processEx = new ProcessEx(output, _process, timeout: Timeout.InfiniteTimeSpan);
3440

3541
_startTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
3642
}
3743

38-
public Task WaitForReady()
44+
public Task WaitForReadyAsync() => _startTcs.Task;
45+
public Task WaitForExitAsync() => _processEx.Exited;
46+
public int ExitCode => _process.ExitCode;
47+
48+
public string GetOutput()
3949
{
40-
return _startTcs.Task;
50+
lock (_outputLock)
51+
{
52+
return _output.ToString();
53+
}
4154
}
4255

43-
public int ExitCode => _process.ExitCode;
44-
public Task Exited => _processEx.Exited;
45-
4656
private void Process_OutputDataReceived(object sender, DataReceivedEventArgs e)
4757
{
4858
var data = e.Data;
@@ -52,6 +62,23 @@ private void Process_OutputDataReceived(object sender, DataReceivedEventArgs e)
5262
{
5363
_startTcs.TrySetResult(null);
5464
}
65+
66+
lock (_outputLock)
67+
{
68+
_output.AppendLine(data);
69+
}
70+
}
71+
}
72+
73+
private void Process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
74+
{
75+
var data = e.Data;
76+
if (data != null)
77+
{
78+
lock (_outputLock)
79+
{
80+
_output.AppendLine(data);
81+
}
5582
}
5683
}
5784

src/Grpc/test/InteropTests/InteropTests.cs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
5-
using System.Collections.Generic;
65
using System.IO;
7-
using System.Linq;
86
using System.Threading.Tasks;
97
using InteropTests.Helpers;
108
using Microsoft.AspNetCore.Testing;
@@ -95,11 +93,22 @@ private async Task InteropTestCase(string name)
9593

9694
using (var clientProcess = new ClientProcess(_output, _clientPath, serverProcess.ServerPort, name))
9795
{
98-
await clientProcess.WaitForReady().TimeoutAfter(DefaultTimeout);
99-
100-
await clientProcess.Exited.TimeoutAfter(DefaultTimeout);
101-
102-
Assert.Equal(0, clientProcess.ExitCode);
96+
try
97+
{
98+
await clientProcess.WaitForReadyAsync().TimeoutAfter(DefaultTimeout);
99+
100+
await clientProcess.WaitForExitAsync().TimeoutAfter(DefaultTimeout);
101+
102+
Assert.Equal(0, clientProcess.ExitCode);
103+
}
104+
catch (Exception ex)
105+
{
106+
var clientOutput = clientProcess.GetOutput();
107+
var errorMessage = $@"Error while running client process. Process output:
108+
======================================
109+
{clientOutput}";
110+
throw new InvalidOperationException(errorMessage, ex);
111+
}
103112
}
104113
}
105114
}

0 commit comments

Comments
 (0)