From 92f2566d2c49d4bf548405b3d9a71be87480cc6c Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Wed, 23 Sep 2026 15:21:03 +0200 Subject: [PATCH] Fix the golden-bytes lane to match by sequence, not assume frame 1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Found by a real failure on the Linux verification container: latest-only coalesces on both the provider's outbox and the managed connector's own receive-side inbox, so a single ReceiveAsync() call is not guaranteed to land on the first frame broadcast — on a slower host it landed on sequence 3. The C# test now also prints CULTMESH_GOLDEN_SEQUENCE, and the harness looks up the TypeScript peer's logged encoding of that same sequence instead of hardcoding sent === 1. Co-Authored-By: Claude Sonnet 5 --- .../test/interop/cultnet-interop.test.ts | 21 ++++++++++++------- .../CultMeshQuicRealtimeTransportTests.cs | 7 +++++++ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/packages/cultnet-ts/test/interop/cultnet-interop.test.ts b/packages/cultnet-ts/test/interop/cultnet-interop.test.ts index c72deaff..940fcaf4 100644 --- a/packages/cultnet-ts/test/interop/cultnet-interop.test.ts +++ b/packages/cultnet-ts/test/interop/cultnet-interop.test.ts @@ -548,13 +548,18 @@ test("CultMesh QUIC realtime: TypeScript provider and C# managed connector, with assert.match(stdout, /Passed:\s*1/, `expected exactly one passed test.\n${stdout}`); assert.doesNotMatch(stdout, /Skipped:\s*1/, `the env var should have made the test run, not skip.\n${stdout}`); - const goldenMatch = /CULTMESH_GOLDEN_HEX=([0-9A-Fa-f]+)/.exec(stdout); - assert.ok(goldenMatch, `expected the C# test to print its golden hex line.\n${stdout}`); - const csharpHex = goldenMatch![1].toLowerCase(); + const goldenHexMatch = /CULTMESH_GOLDEN_HEX=([0-9A-Fa-f]+)/.exec(stdout); + const goldenSequenceMatch = /CULTMESH_GOLDEN_SEQUENCE=(\d+)/.exec(stdout); + assert.ok(goldenHexMatch, `expected the C# test to print its golden hex line.\n${stdout}`); + assert.ok(goldenSequenceMatch, `expected the C# test to print which sequence it received.\n${stdout}`); + const csharpHex = goldenHexMatch![1].toLowerCase(); + const csharpSequence = Number(goldenSequenceMatch![1]); - // The typescript peer logs the hex of its own encoding of frame 1 (the - // first, and here the only, frame the managed connector's single - // ReceiveAsync call can have gotten) to stderr as it sends it. + // Which frame the managed connector's single ReceiveAsync() call actually + // got is not pinned to frame 1: latest-only coalesces on both the + // provider's outbox and the connector's own receive-side inbox, so a slow + // start can land on a later sequence. Match the typescript peer's logged + // encoding of that same sequence rather than assuming the first one sent. const tsSentLine = server.stderr .join("") .split("\n") @@ -567,8 +572,8 @@ test("CultMesh QUIC realtime: TypeScript provider and C# managed connector, with return undefined; } }) - .find((entry) => entry?.event === "quic-realtime-serve" && entry.sent === 1); - assert.ok(tsSentLine?.hex, "expected the typescript peer to log frame 1's hex encoding"); + .find((entry) => entry?.event === "quic-realtime-serve" && entry.sent === csharpSequence); + assert.ok(tsSentLine?.hex, `expected the typescript peer to log frame ${csharpSequence}'s hex encoding`); assert.equal(csharpHex, tsSentLine!.hex, "TypeScript and C# must encode the same frame identically"); }); diff --git a/tests/GameCult.Mesh.Quic.Tests/CultMeshQuicRealtimeTransportTests.cs b/tests/GameCult.Mesh.Quic.Tests/CultMeshQuicRealtimeTransportTests.cs index 1ff6fd20..a10c9671 100644 --- a/tests/GameCult.Mesh.Quic.Tests/CultMeshQuicRealtimeTransportTests.cs +++ b/tests/GameCult.Mesh.Quic.Tests/CultMeshQuicRealtimeTransportTests.cs @@ -193,7 +193,14 @@ public sealed class CultMeshQuicRealtimeTransportTests frame.BodyId.Should().NotBeNullOrWhiteSpace(); frame.Payload.Should().NotBeEmpty(); + // Which frame this actually is is not pinned to the provider's + // first broadcast: latest-only coalesces on both the provider's + // outbox and this connector's own receive-side inbox, so a + // single ReceiveAsync() can land on whichever sequence was + // latest by the time it was called. The harness matches by + // sequence rather than assuming the first frame sent. var hex = Convert.ToHexString(CultMeshRealtimeWireProtocol.EncodeFrame(frame)); + TestContext.Out.WriteLine($"CULTMESH_GOLDEN_SEQUENCE={frame.Sequence}"); TestContext.Out.WriteLine($"CULTMESH_GOLDEN_HEX={hex}"); } finally