Skip to content

Commit a816a7f

Browse files
committed
Ensure test process is cleaned up
1 parent 16650da commit a816a7f

File tree

1 file changed

+31
-9
lines changed

1 file changed

+31
-9
lines changed

test/WebJobs.Script.Tests/Workers/Rpc/RpcWorkerProcessTests.cs

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -272,10 +272,11 @@ public async Task WorkerProcess_WaitForExit_NotStarted_Throws()
272272
public async Task WorkerProcess_WaitForExit_Success_TaskCompletes()
273273
{
274274
// arrange
275-
using Process process = GetProcess(exitCode: 0);
276-
_hostProcessMonitorMock.Setup(m => m.RegisterChildProcess(process));
277-
_hostProcessMonitorMock.Setup(m => m.UnregisterChildProcess(process));
278-
_workerProcessFactory.Setup(m => m.CreateWorkerProcess(It.IsNotNull<WorkerContext>())).Returns(process);
275+
await using ProcessWrapper wrapper = new(exitCode: 0);
276+
_hostProcessMonitorMock.Setup(m => m.RegisterChildProcess(wrapper.Process));
277+
_hostProcessMonitorMock.Setup(m => m.UnregisterChildProcess(wrapper.Process));
278+
_workerProcessFactory.Setup(m => m.CreateWorkerProcess(It.IsNotNull<WorkerContext>()))
279+
.Returns(wrapper.Process);
279280
using var rpcWorkerProcess = GetRpcWorkerConfigProcess(
280281
TestHelpers.GetTestWorkerConfigsWithExecutableWorkingDirectory().ElementAt(0));
281282

@@ -290,10 +291,11 @@ public async Task WorkerProcess_WaitForExit_Success_TaskCompletes()
290291
public async Task WorkerProcess_WaitForExit_Error_Rethrows()
291292
{
292293
// arrange
293-
using Process process = GetProcess(exitCode: -1);
294-
_hostProcessMonitorMock.Setup(m => m.RegisterChildProcess(process));
295-
_hostProcessMonitorMock.Setup(m => m.UnregisterChildProcess(process));
296-
_workerProcessFactory.Setup(m => m.CreateWorkerProcess(It.IsNotNull<WorkerContext>())).Returns(process);
294+
await using ProcessWrapper wrapper = new(exitCode: -1);
295+
_hostProcessMonitorMock.Setup(m => m.RegisterChildProcess(wrapper.Process));
296+
_hostProcessMonitorMock.Setup(m => m.UnregisterChildProcess(wrapper.Process));
297+
_workerProcessFactory.Setup(m => m.CreateWorkerProcess(It.IsNotNull<WorkerContext>()))
298+
.Returns(wrapper.Process);
297299
using var rpcWorkerProcess = GetRpcWorkerConfigProcess(
298300
TestHelpers.GetTestWorkerConfigsWithExecutableWorkingDirectory().ElementAt(0));
299301

@@ -310,13 +312,33 @@ private static Process GetProcess(int exitCode)
310312
{
311313
StartInfo = new()
312314
{
313-
WindowStyle = ProcessWindowStyle.Hidden,
314315
FileName = OperatingSystem.IsWindows() ? "cmd" : "bash",
315316
Arguments = OperatingSystem.IsWindows() ? $"/C exit {exitCode}" : $"-c \"exit {exitCode}\"",
316317
RedirectStandardError = true,
317318
RedirectStandardOutput = true,
319+
CreateNoWindow = true,
320+
ErrorDialog = false,
321+
UseShellExecute = false
318322
}
319323
};
320324
}
325+
326+
private class ProcessWrapper(int exitCode) : IAsyncDisposable
327+
{
328+
public Process Process { get; } = GetProcess(exitCode);
329+
330+
public async ValueTask DisposeAsync()
331+
{
332+
if (!Process.HasExited)
333+
{
334+
// We need to kill the entire process tree to ensure
335+
// CI tests don't hang due to child processes lingering around.
336+
Process.Kill(entireProcessTree: true);
337+
await Process.WaitForExitAsync();
338+
}
339+
340+
Process.Dispose();
341+
}
342+
}
321343
}
322344
}

0 commit comments

Comments
 (0)