using System.IO.Pipes; namespace ZB.MOM.WW.MxGateway.Tests.TestSupport; /// /// Creates the gateway-side that in-process worker fakes connect /// to, with an explicit OS buffer so a test that deliberately stops draining the pipe cannot block /// its own writer forever. /// /// /// The NamedPipeServerStream(string, PipeDirection, int, PipeTransmissionMode, PipeOptions) /// overload passes inBufferSize: 0 and outBufferSize: 0 to CreateNamedPipe. On /// Windows that reserves no buffer at all: a write completes only once the peer reads it — /// measured on a Windows 10 host, the very first 63-byte write to a non-reading peer never completed, /// against 65 520 bytes absorbed by the same pipe declared with 64 KiB buffers. On macOS and Linux /// .NET backs named pipes with Unix domain sockets, whose socket buffer absorbs several kilobytes /// regardless, so the zero-buffer declaration is invisible there. /// /// That asymmetry wedged the whole Windows test host: WorkerClientTests pushes events past the /// worker client's staging bound to prove the client faults, and after the fault the client's read /// loop stops by design. On Windows the next test-side write then blocked forever with no timeout, so /// the test never returned, xUnit never raised ITestAssemblyFinished, and testhost never /// exited even though every other test had already passed. /// /// /// Buffering the test pipe scopes those tests to the behavior they are actually asserting — the /// gateway's own staging/queue backpressure — instead of the OS pipe's flow control. The gateway's /// production pipe in SessionWorkerClientFactory keeps the unbuffered declaration on purpose: /// there both ends run continuous read loops and every write is bounded by the worker client's stop /// token, so a stalled peer cancels rather than blocks. /// /// internal static class TestNamedPipe { /// /// The buffer reserved for each direction. Comfortably larger than any frame volume a test /// pushes at a stopped reader, and the size Windows itself uses for a typical named pipe. /// internal const int BufferBytes = 64 * 1024; /// Creates the gateway-side server pipe for . /// The pipe name the fake worker connects to. /// An asynchronous, byte-mode server pipe with explicit buffers. internal static NamedPipeServerStream CreateServer(string pipeName) { return new NamedPipeServerStream( pipeName, PipeDirection.InOut, maxNumberOfServerInstances: 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, inBufferSize: BufferBytes, outBufferSize: BufferBytes); } }