fix: ensure process output pipe is drained by caller
Some checks failed
default / dotnet-default-workflow (pull_request) Successful in 2m27s
default / dotnet-default-workflow (push) Has been cancelled

This commit is contained in:
Louis Seubert 2026-08-25 19:43:01 +02:00
commit 25ad2b55b5
3 changed files with 155 additions and 50 deletions

View file

@ -0,0 +1,59 @@
// Copyright (c) The Geekeey Authors
// SPDX-License-Identifier: EUPL-1.2
namespace Geekeey.Process.Tests;
internal sealed class NullPipeConcurrencyTests
{
// A process writing enough output to fill its pipe can receive SIGPIPE if the read end is closed too early.
// Run many chatty processes at once to make premature pipe closure observable and to exercise pipe lifetime
// while processes are being started and completed concurrently.
// Test both the default targets and explicitly configured null targets, since both must keep consuming
// process output until the process exits.
[Test]
public async Task Chatty_commands_can_run_concurrently_with_default_null_output_pipes()
{
var commands = new List<Command>();
for (var i = 0; i < 64; i++)
{
commands.Add(new Command(Testing.Fixture.Program.FilePath)
.WithArguments(["generate", "clob", "--length", "100000", "--lines", "2"]));
}
var results = await Task.WhenAll(commands.Select(async command => await command.ExecuteAsync()));
using (Assert.Multiple())
{
foreach (var result in results)
{
await Assert.That(result.ExitCode).IsZero();
}
}
}
[Test]
public async Task Chatty_commands_can_run_concurrently_with_explicit_null_output_pipes()
{
var commands = new List<Command>();
for (var i = 0; i < 64; i++)
{
commands.Add(new Command(Testing.Fixture.Program.FilePath)
.WithArguments(["generate", "clob", "--length", "100000", "--lines", "2"])
.WithStandardOutputPipe(PipeTarget.Null)
.WithStandardErrorPipe(PipeTarget.Null));
}
var results = await Task.WhenAll(commands.Select(async command => await command.ExecuteAsync()));
using (Assert.Multiple())
{
foreach (var result in results)
{
await Assert.That(result.ExitCode).IsZero();
}
}
}
}