2026-01-20 22:41:16 +01:00
|
|
|
// Copyright (c) The Geekeey Authors
|
|
|
|
|
// SPDX-License-Identifier: EUPL-1.2
|
|
|
|
|
|
|
|
|
|
using System.Text;
|
2026-08-25 22:15:40 +02:00
|
|
|
using System.IO.Pipelines;
|
2026-01-20 22:41:16 +01:00
|
|
|
|
|
|
|
|
using Geekeey.Process.Buffered;
|
|
|
|
|
|
|
|
|
|
namespace Geekeey.Process.Tests;
|
|
|
|
|
|
|
|
|
|
internal sealed class PipingTests
|
|
|
|
|
{
|
|
|
|
|
#region Stdin
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdin_from_an_async_anonymous_source()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var source = PipeSource.Create(async (destination, cancellationToken)
|
|
|
|
|
=> await destination.WriteAsync("Hello World!"u8.ToArray(), cancellationToken));
|
|
|
|
|
|
|
|
|
|
var cmd = source |
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments("echo-stdin");
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
var result = await cmd.ExecuteBufferedAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await Assert.That(result.StandardOutput.Trim()).IsEqualTo("Hello World!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdin_from_a_sync_anonymous_source()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var source = PipeSource.Create(destination
|
|
|
|
|
=> destination.Write("Hello World!"u8.ToArray()));
|
|
|
|
|
|
|
|
|
|
var cmd = source |
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments("echo-stdin");
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
var result = await cmd.ExecuteBufferedAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await Assert.That(result.StandardOutput.Trim()).IsEqualTo("Hello World!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdin_from_a_stream()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
using var source = new MemoryStream("Hello World!"u8.ToArray());
|
|
|
|
|
|
|
|
|
|
var cmd = source |
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments("echo-stdin");
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
var result = await cmd.ExecuteBufferedAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await Assert.That(result.StandardOutput.Trim()).IsEqualTo("Hello World!");
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-25 22:15:40 +02:00
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdin_from_a_pipe_reader()
|
|
|
|
|
{
|
|
|
|
|
var pipe = new Pipe();
|
|
|
|
|
await pipe.Writer.WriteAsync("Hello World!"u8.ToArray());
|
|
|
|
|
await pipe.Writer.CompleteAsync();
|
|
|
|
|
|
|
|
|
|
var cmd = PipeSource.FromPipeReader(pipe.Reader) |
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments("echo-stdin");
|
|
|
|
|
|
|
|
|
|
var result = await cmd.ExecuteBufferedAsync();
|
|
|
|
|
|
|
|
|
|
await Assert.That(result.StandardOutput.Trim()).IsEqualTo("Hello World!");
|
|
|
|
|
await pipe.Reader.CompleteAsync();
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-25 20:04:13 +02:00
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdin_from_a_stream_with_a_custom_buffer_size()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
using var source = new MemoryStream("Hello World!"u8.ToArray());
|
|
|
|
|
|
|
|
|
|
var cmd = PipeSource.FromStream(source, 1) |
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments("echo-stdin");
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
var result = await cmd.ExecuteBufferedAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await Assert.That(result.StandardOutput.Trim()).IsEqualTo("Hello World!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdin_from_a_file_with_a_custom_buffer_size()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
using var dir = TestTempDirectory.Create();
|
|
|
|
|
var filePath = Path.Combine(dir.Path, "input.txt");
|
|
|
|
|
await File.WriteAllTextAsync(filePath, "Hello World!");
|
|
|
|
|
|
|
|
|
|
var cmd = PipeSource.FromFile(filePath, 1) |
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments("echo-stdin");
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
var result = await cmd.ExecuteBufferedAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await Assert.That(result.StandardOutput.Trim()).IsEqualTo("Hello World!");
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-20 22:41:16 +01:00
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdin_from_memory()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var data = new ReadOnlyMemory<byte>("Hello World!"u8.ToArray());
|
|
|
|
|
|
|
|
|
|
var cmd = data |
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments("echo-stdin");
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
var result = await cmd.ExecuteBufferedAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await Assert.That(result.StandardOutput.Trim()).IsEqualTo("Hello World!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdin_from_a_byte_array()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var data = "Hello World!"u8.ToArray();
|
|
|
|
|
|
|
|
|
|
var cmd = data |
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments("echo-stdin");
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
var result = await cmd.ExecuteBufferedAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await Assert.That(result.StandardOutput.Trim()).IsEqualTo("Hello World!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdin_from_a_string()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var data = "Hello World!";
|
|
|
|
|
|
|
|
|
|
var cmd = data |
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments("echo-stdin");
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
var result = await cmd.ExecuteBufferedAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await Assert.That(result.StandardOutput.Trim()).IsEqualTo("Hello World!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdin_from_another_command()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var cmd =
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments(["generate", "blob", "--length", "100000"]) |
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments("length");
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
var result = await cmd.ExecuteBufferedAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await Assert.That(result.StandardOutput.Trim()).IsEqualTo("100000");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdin_from_a_chain_of_commands()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var cmd =
|
|
|
|
|
"Hello world" |
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments("echo-stdin") |
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments(["echo-stdin", "--length", "5"]) |
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments("length");
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
var result = await cmd.ExecuteBufferedAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await Assert.That(result.StandardOutput.Trim()).IsEqualTo("5");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Stdout
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdout_into_an_async_anonymous_target()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
using var stream = new MemoryStream();
|
|
|
|
|
|
|
|
|
|
var target = PipeTarget.Create(async (origin, cancellationToken) =>
|
|
|
|
|
// ReSharper disable once AccessToDisposedClosure
|
|
|
|
|
await origin.CopyToAsync(stream, cancellationToken)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
var cmd =
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments(["generate", "blob", "--length", "100000"]) |
|
|
|
|
|
target;
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await cmd.ExecuteAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await Assert.That(stream.Length).IsEqualTo(100_000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdout_into_a_sync_anonymous_target()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
using var stream = new MemoryStream();
|
|
|
|
|
|
|
|
|
|
var target = PipeTarget.Create(origin =>
|
|
|
|
|
// ReSharper disable once AccessToDisposedClosure
|
|
|
|
|
origin.CopyTo(stream)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
var cmd =
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments(["generate", "blob", "--length", "100000"]) |
|
|
|
|
|
target;
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await cmd.ExecuteAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await Assert.That(stream.Length).IsEqualTo(100_000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdout_into_a_stream()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
using var stream = new MemoryStream();
|
|
|
|
|
|
|
|
|
|
var cmd =
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments(["generate", "blob", "--length", "100000"]) |
|
|
|
|
|
stream;
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await cmd.ExecuteAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await Assert.That(stream.Length).IsEqualTo(100_000);
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-25 20:04:13 +02:00
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdout_into_a_stream_with_a_custom_buffer_size()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
using var stream = new MemoryStream();
|
|
|
|
|
var target = PipeTarget.ToStream(stream, 1);
|
|
|
|
|
|
|
|
|
|
var cmd = new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments(["generate", "blob", "--length", "100000"]) |
|
|
|
|
|
target;
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await cmd.ExecuteAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await Assert.That(stream.Length).IsEqualTo(100_000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdout_into_a_file_with_a_custom_buffer_size()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
using var dir = TestTempDirectory.Create();
|
|
|
|
|
var filePath = Path.Combine(dir.Path, "output.bin");
|
|
|
|
|
var target = PipeTarget.ToFile(filePath, 1);
|
|
|
|
|
|
|
|
|
|
var cmd = new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments(["generate", "blob", "--length", "100000"]) |
|
|
|
|
|
target;
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await cmd.ExecuteAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await Assert.That(new FileInfo(filePath).Length).IsEqualTo(100_000);
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-20 22:41:16 +01:00
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdout_into_a_string_builder()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var buffer = new StringBuilder();
|
|
|
|
|
|
|
|
|
|
var cmd =
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments(["echo", "Hello World!"]) |
|
|
|
|
|
buffer;
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await cmd.ExecuteAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await Assert.That(buffer.ToString().Trim()).IsEqualTo("Hello World!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdout_into_an_async_delegate()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var stdOutLinesCount = 0;
|
|
|
|
|
|
|
|
|
|
async Task HandleStdOutAsync(string line)
|
|
|
|
|
{
|
|
|
|
|
await Task.Yield();
|
|
|
|
|
stdOutLinesCount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var cmd =
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments(["generate", "clob", "--lines", "100"]) |
|
|
|
|
|
HandleStdOutAsync;
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await cmd.ExecuteAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await Assert.That(stdOutLinesCount).IsEqualTo(100);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdout_into_an_async_delegate_with_cancellation()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var stdOutLinesCount = 0;
|
|
|
|
|
|
|
|
|
|
async Task HandleStdOutAsync(string line, CancellationToken cancellationToken = default)
|
|
|
|
|
{
|
|
|
|
|
await Task.Delay(1, cancellationToken);
|
|
|
|
|
stdOutLinesCount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var cmd =
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments(["generate", "clob", "--lines", "100"]) |
|
|
|
|
|
HandleStdOutAsync;
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await cmd.ExecuteAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await Assert.That(stdOutLinesCount).IsEqualTo(100);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdout_into_a_sync_delegate()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var stdOutLinesCount = 0;
|
|
|
|
|
|
|
|
|
|
void HandleStdOut(string line)
|
|
|
|
|
{
|
|
|
|
|
stdOutLinesCount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var cmd =
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments(["generate", "clob", "--lines", "100"]) |
|
|
|
|
|
HandleStdOut;
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await cmd.ExecuteAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await Assert.That(stdOutLinesCount).IsEqualTo(100);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Stdout & Stderr
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdout_and_stderr_into_separate_stream()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
using var stdOut = new MemoryStream();
|
|
|
|
|
using var stdErr = new MemoryStream();
|
|
|
|
|
|
|
|
|
|
var cmd =
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments(["generate", "blob", "--target", "all", "--length", "100000"]) |
|
|
|
|
|
(stdOut, stdErr);
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await cmd.ExecuteAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
using (Assert.Multiple())
|
|
|
|
|
{
|
|
|
|
|
await Assert.That(stdOut.Length).IsEqualTo(100_000);
|
|
|
|
|
await Assert.That(stdErr.Length).IsEqualTo(100_000);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdout_and_stderr_into_string_builder()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var stdOutBuffer = new StringBuilder();
|
|
|
|
|
var stdErrBuffer = new StringBuilder();
|
|
|
|
|
|
|
|
|
|
var cmd =
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments(["echo", "Hello world!", "--target", "all"]) |
|
|
|
|
|
(stdOutBuffer, stdErrBuffer);
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await cmd.ExecuteAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
using (Assert.Multiple())
|
|
|
|
|
{
|
|
|
|
|
await Assert.That(stdOutBuffer.ToString().Trim()).IsEqualTo("Hello world!");
|
|
|
|
|
await Assert.That(stdErrBuffer.ToString().Trim()).IsEqualTo("Hello world!");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdout_and_stderr_into_separate_async_delegate()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var stdOutLinesCount = 0;
|
|
|
|
|
var stdErrLinesCount = 0;
|
|
|
|
|
|
|
|
|
|
async Task HandleStdOutAsync(string line)
|
|
|
|
|
{
|
|
|
|
|
await Task.Yield();
|
|
|
|
|
stdOutLinesCount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async Task HandleStdErrAsync(string line)
|
|
|
|
|
{
|
|
|
|
|
await Task.Yield();
|
|
|
|
|
stdErrLinesCount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var cmd =
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments(["generate", "clob", "--target", "all", "--lines", "100"]) |
|
|
|
|
|
(HandleStdOutAsync, HandleStdErrAsync);
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await cmd.ExecuteAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
using (Assert.Multiple())
|
|
|
|
|
{
|
|
|
|
|
await Assert.That(stdOutLinesCount).IsEqualTo(100);
|
|
|
|
|
await Assert.That(stdErrLinesCount).IsEqualTo(100);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task
|
|
|
|
|
I_can_execute_a_command_and_pipe_the_stdout_and_stderr_into_separate_async_delegate_with_cancellation()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var stdOutLinesCount = 0;
|
|
|
|
|
var stdErrLinesCount = 0;
|
|
|
|
|
|
|
|
|
|
async Task HandleStdOutAsync(string line, CancellationToken cancellationToken = default)
|
|
|
|
|
{
|
|
|
|
|
await Task.Delay(1, cancellationToken);
|
|
|
|
|
stdOutLinesCount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async Task HandleStdErrAsync(string line, CancellationToken cancellationToken = default)
|
|
|
|
|
{
|
|
|
|
|
await Task.Delay(1, cancellationToken);
|
|
|
|
|
stdErrLinesCount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var cmd =
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments(["generate", "clob", "--target", "all", "--lines", "100"]) |
|
|
|
|
|
(HandleStdOutAsync, HandleStdErrAsync);
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await cmd.ExecuteAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
using (Assert.Multiple())
|
|
|
|
|
{
|
|
|
|
|
await Assert.That(stdOutLinesCount).IsEqualTo(100);
|
|
|
|
|
await Assert.That(stdErrLinesCount).IsEqualTo(100);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdout_and_stderr_into_separate_sync_delegate()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var stdOutLinesCount = 0;
|
|
|
|
|
var stdErrLinesCount = 0;
|
|
|
|
|
|
|
|
|
|
void HandleStdOut(string line)
|
|
|
|
|
{
|
|
|
|
|
stdOutLinesCount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HandleStdErr(string line)
|
|
|
|
|
{
|
|
|
|
|
stdErrLinesCount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var cmd =
|
|
|
|
|
new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments(["generate", "clob", "--target", "all", "--lines", "100"]) |
|
|
|
|
|
(HandleStdOut, HandleStdErr);
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await cmd.ExecuteAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
using (Assert.Multiple())
|
|
|
|
|
{
|
|
|
|
|
await Assert.That(stdOutLinesCount).IsEqualTo(100);
|
|
|
|
|
await Assert.That(stdErrLinesCount).IsEqualTo(100);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdout_into_multiple_targets()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
using var stream1 = new MemoryStream();
|
|
|
|
|
using var stream2 = new MemoryStream();
|
|
|
|
|
using var stream3 = new MemoryStream();
|
|
|
|
|
|
|
|
|
|
var target = PipeTarget.Merge(
|
|
|
|
|
PipeTarget.ToStream(stream1),
|
|
|
|
|
PipeTarget.ToStream(stream2),
|
|
|
|
|
PipeTarget.ToStream(stream3)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
var cmd = new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments(["generate", "blob", "--length", "100000"]) |
|
|
|
|
|
target;
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await cmd.ExecuteAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
using (Assert.Multiple())
|
|
|
|
|
{
|
|
|
|
|
await Assert.That(stream1.Length).IsEqualTo(100_000);
|
|
|
|
|
await Assert.That(stream2.Length).IsEqualTo(100_000);
|
|
|
|
|
await Assert.That(stream3.Length).IsEqualTo(100_000);
|
|
|
|
|
await Assert.That(stream1.ToArray()).IsEquivalentTo(stream2.ToArray());
|
|
|
|
|
await Assert.That(stream2.ToArray()).IsEquivalentTo(stream3.ToArray());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-25 22:15:40 +02:00
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdout_to_a_pipe_writer()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var pipe = new Pipe();
|
|
|
|
|
var cmd = new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments(["generate", "blob", "--length", "100000"]) |
|
|
|
|
|
PipeTarget.ToPipeWriter(pipe.Writer);
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
using var output = new MemoryStream();
|
|
|
|
|
var executionTask = cmd.ExecuteAsync();
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
var result = await pipe.Reader.ReadAsync();
|
|
|
|
|
foreach (var segment in result.Buffer)
|
|
|
|
|
{
|
|
|
|
|
await output.WriteAsync(segment);
|
|
|
|
|
}
|
|
|
|
|
pipe.Reader.AdvanceTo(result.Buffer.End);
|
|
|
|
|
if (result.IsCompleted)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
await executionTask;
|
|
|
|
|
await pipe.Reader.CompleteAsync();
|
|
|
|
|
|
|
|
|
|
await Assert.That(output.Length).IsEqualTo(100_000);
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-20 22:41:16 +01:00
|
|
|
[Test]
|
|
|
|
|
public async Task I_can_execute_a_command_and_pipe_the_stdout_into_multiple_hierarchical_targets()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
using var stream1 = new MemoryStream();
|
|
|
|
|
using var stream2 = new MemoryStream();
|
|
|
|
|
using var stream3 = new MemoryStream();
|
|
|
|
|
using var stream4 = new MemoryStream();
|
|
|
|
|
|
|
|
|
|
var target = PipeTarget.Merge(
|
|
|
|
|
PipeTarget.ToStream(stream1),
|
|
|
|
|
PipeTarget.Merge(
|
|
|
|
|
PipeTarget.ToStream(stream2),
|
|
|
|
|
PipeTarget.Merge(
|
|
|
|
|
PipeTarget.ToStream(stream3),
|
|
|
|
|
PipeTarget.ToStream(stream4))));
|
|
|
|
|
|
|
|
|
|
var cmd = new Command(Testing.Fixture.Program.FilePath)
|
|
|
|
|
.WithArguments(["generate", "blob", "--length", "100000"]) |
|
|
|
|
|
target;
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await cmd.ExecuteAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
using (Assert.Multiple())
|
|
|
|
|
{
|
|
|
|
|
await Assert.That(stream1.Length).IsEqualTo(100_000);
|
|
|
|
|
await Assert.That(stream2.Length).IsEqualTo(100_000);
|
|
|
|
|
await Assert.That(stream3.Length).IsEqualTo(100_000);
|
|
|
|
|
await Assert.That(stream4.Length).IsEqualTo(100_000);
|
|
|
|
|
await Assert.That(stream1.ToArray()).IsEquivalentTo(stream2.ToArray());
|
|
|
|
|
await Assert.That(stream2.ToArray()).IsEquivalentTo(stream3.ToArray());
|
|
|
|
|
await Assert.That(stream3.ToArray()).IsEquivalentTo(stream4.ToArray());
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-05-16 12:25:38 +02:00
|
|
|
}
|