Skip to content

Commit 5996972

Browse files
authored
Check for process exit as well as pipe message in test runners (#5490)
#5473 surfaced an issue of test resiliency. Per test we wait for a process to start and send a notification. If the process exits quickly, we'll wait for 5 min per test trying to see the message. This considers process exits as an error path eagerly.
1 parent 84b028b commit 5996972

File tree

3 files changed

+26
-5
lines changed

3 files changed

+26
-5
lines changed

src/SOS/SOS.UnitTests/SOSRunner.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,9 +378,10 @@ public static async Task<string> CreateDump(TestInformation information)
378378
if (pipeServer != null)
379379
{
380380
dotnetDumpOutputHelper.WriteLine("Waiting for connection on pipe {0}", pipeName);
381-
CancellationTokenSource source = new(TimeSpan.FromMinutes(5));
381+
using CancellationTokenSource source = new(TimeSpan.FromMinutes(5));
382382

383383
// Wait for debuggee to connect/write to pipe or if the process exits on some other failure/abnormally
384+
// TODO: This is a resiliency issue - we'll try to collect the dump even if the debuggee fails to connect.
384385
await Task.WhenAny(pipeServer.WaitForConnectionAsync(source.Token), processRunner.WaitForExit());
385386
}
386387

src/tests/CommonTestRunner/TestRunner.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,16 @@ public async Task WaitForTracee()
245245
WriteLine("WaitForTracee");
246246
try
247247
{
248-
CancellationTokenSource source = new(TimeSpan.FromMinutes(2));
249-
await _pipeServer.WaitForConnectionAsync(source.Token).ConfigureAwait(false);
248+
using CancellationTokenSource source = new(TimeSpan.FromMinutes(2));
249+
Task processDeath = _runner.WaitForExit();
250+
Task traceeReady = _pipeServer.WaitForConnectionAsync(source.Token);
251+
Task doneTask = await Task.WhenAny(processDeath, traceeReady).WaitAsync(source.Token).ConfigureAwait(false);
252+
253+
source.Cancel();
254+
if (doneTask == processDeath)
255+
{
256+
Trace.TraceWarning($"WaitForTracee: process {Pid} exited without sending the event");
257+
}
250258
WriteLine("WaitForTracee: DONE");
251259
}
252260
catch (Exception ex) when (ex is TaskCanceledException or OperationCanceledException)

src/tests/DbgShim.UnitTests/DebuggeeInfo.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,21 @@ public async Task<bool> WaitForDebuggee()
7171
}
7272
try
7373
{
74-
CancellationTokenSource source = new(TimeSpan.FromMinutes(5));
74+
using CancellationTokenSource source = new(TimeSpan.FromMinutes(5));
7575
Trace.TraceInformation($"DebuggeeInfo.WaitForDebuggee: waiting {ProcessId}");
76-
await _pipeServer.WaitForConnectionAsync(source.Token);
76+
77+
Task processDeath = _process.WaitForExitAsync(source.Token);
78+
Task debuggeeReady = _pipeServer.WaitForConnectionAsync(source.Token);
79+
Task doneTask = await Task.WhenAny(processDeath, debuggeeReady).WaitAsync(source.Token);
80+
81+
source.Cancel();
82+
83+
if (doneTask == processDeath)
84+
{
85+
Trace.TraceWarning($"DebuggeeInfo.WaitForDebuggee: process {ProcessId} exited");
86+
return false;
87+
}
88+
7789
Trace.TraceInformation($"DebuggeeInfo.WaitForDebuggee: after wait {ProcessId}");
7890
}
7991
catch (Exception ex) when (ex is TaskCanceledException or OperationCanceledException)

0 commit comments

Comments
 (0)