69 lines
2.7 KiB
C#
69 lines
2.7 KiB
C#
using System.Text.Json;
|
|
using NucleicBroker;
|
|
|
|
namespace NucleicBroker.Tests;
|
|
|
|
public sealed class OutboundWriterTests
|
|
{
|
|
[Fact]
|
|
public async Task PreservesEnqueueOrderAcrossKinds()
|
|
{
|
|
var captured = new StringWriter();
|
|
var writer = new OutboundWriter(captured);
|
|
writer.EnqueueJson("""{"a":1}""");
|
|
writer.EnqueueProcOutput(1, stderr: false, "one"u8);
|
|
writer.EnqueueProcOutput(1, stderr: false, "two"u8);
|
|
writer.EnqueueJson("""{"b":2}""");
|
|
await writer.CompleteAsync();
|
|
|
|
var lines = captured.ToString().Split('\n', StringSplitOptions.RemoveEmptyEntries);
|
|
Assert.Equal("""{"a":1}""", lines[0]);
|
|
Assert.Equal("""{"b":2}""", lines[^1]);
|
|
|
|
// The two same-stream chunks arrive between the json lines, concatenated in order —
|
|
// as ONE notification when the drain saw both queued, as two otherwise. Either way
|
|
// the decoded byte stream is identical.
|
|
var decoded = string.Concat(lines[1..^1].Select(l =>
|
|
{
|
|
var note = JsonDocument.Parse(l).RootElement;
|
|
Assert.Equal("proc.stdout", note.GetProperty("method").GetString());
|
|
return System.Text.Encoding.UTF8.GetString(
|
|
Convert.FromBase64String(note.GetProperty("params").GetProperty("b64").GetString()!));
|
|
}));
|
|
Assert.Equal("onetwo", decoded);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task FramesLinesWithBareLineFeed()
|
|
{
|
|
// The wire is LF-framed on every host (docs/WINDOWS_PORT.md §3.3). TextWriter.NewLine
|
|
// would otherwise be CRLF on Windows, hiding a stray \r inside every line hostd parses.
|
|
// Forcing CRLF on the sink reproduces the Windows default on any platform, so this
|
|
// pins the framing even when CI runs the suite on Linux.
|
|
var captured = new StringWriter { NewLine = "\r\n" };
|
|
var writer = new OutboundWriter(captured);
|
|
writer.EnqueueJson("""{"a":1}""");
|
|
writer.EnqueueProcOutput(1, stderr: false, "one"u8);
|
|
await writer.CompleteAsync();
|
|
|
|
var text = captured.ToString();
|
|
Assert.DoesNotContain('\r', text);
|
|
Assert.EndsWith("\n", text);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task StderrAndStdoutChunksNeverMerge()
|
|
{
|
|
var captured = new StringWriter();
|
|
var writer = new OutboundWriter(captured);
|
|
writer.EnqueueProcOutput(1, stderr: false, "out"u8);
|
|
writer.EnqueueProcOutput(1, stderr: true, "err"u8);
|
|
await writer.CompleteAsync();
|
|
|
|
var methods = captured.ToString().Split('\n', StringSplitOptions.RemoveEmptyEntries)
|
|
.Select(l => JsonDocument.Parse(l).RootElement.GetProperty("method").GetString())
|
|
.ToList();
|
|
Assert.Equal(["proc.stdout", "proc.stderr"], methods);
|
|
}
|
|
}
|