From b64fbcd5b20530e691f9f04b9c04ad689201801e Mon Sep 17 00:00:00 2001 From: Priya Raman Date: Thu, 27 Aug 2026 04:55:23 +0000 Subject: [PATCH] test(server): fix the pre-bind race in the byte-ledger ceiling test The test opened a duplex channel with data scripted to arrive right after the open reply. Under load, the host could process that data notification before the open reply's own continuation bound the route. The ceiling rejection then raced the bind, and the open call itself failed with DUPLEX_CHANNEL_OPEN_FAILED instead of the intended post-bind rejection. Open the channel with no scripted data, then write one byte after the open call resolves. The write is strictly post-bind, so the rejection is always a genuine post-bind event. Also name the reservation that rejects. The host makes two reservations for the write. The raw payload byte fits the ceiling. The serialized host-to-worker frame does not. The test name and the comments now describe that path. Co-authored-by: Paperclip --- ...-worker-manager-duplex-byte-ledger.test.ts | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/server/src/__tests__/plugin-worker-manager-duplex-byte-ledger.test.ts b/server/src/__tests__/plugin-worker-manager-duplex-byte-ledger.test.ts index 97f3783d84..12db030a4c 100644 --- a/server/src/__tests__/plugin-worker-manager-duplex-byte-ledger.test.ts +++ b/server/src/__tests__/plugin-worker-manager-duplex-byte-ledger.test.ts @@ -161,18 +161,24 @@ describe("plugin worker manager duplex aggregate byte ledger", () => { expect(telemetry.underflows).toBe(0); }); - it("fails closed and retains nothing when a buffered reservation would pass the ceiling", async () => { + it("fails closed and retains nothing when a write reservation would pass the ceiling", async () => { const telemetry = countingTelemetry(); - // A four-byte ceiling. One five-byte chunk cannot fit. + // A four-byte ceiling. A serialized host-to-worker write frame cannot fit. const ledger = new DuplexAggregateByteLedger({ ceilingBytes: 4, telemetry }); const handle = makeDuplexHandle({ duplexAggregateByteLedger: ledger }); try { await handle.start(); - await handle.openDuplexChannel( - // No listener attaches, so "hello" tries to buffer. Its five raw bytes pass - // the four-byte ceiling, so the reservation rejects and the route ends. - duplexOpenInput({ data: [{ chunk: "hello" }] }), - ); + // Open with no scripted data, so the fixture sends only the open reply. + // The route is bound and live by the time this line resolves. + const session = await handle.openDuplexChannel(duplexOpenInput({})); + // The write happens strictly after the bind, so the rejection is a genuine + // post-bind event, never a frame that races the open reply. The host makes + // two reservations for this write. The one raw payload byte fits the + // ceiling, so the pending-write reservation succeeds. The host then meters + // the serialized frame just before the stdin write. That frame is much + // larger than four bytes, so the transport reservation rejects, the host + // writes nothing, and the route ends fail-closed. + session.write(new TextEncoder().encode("a")); await vi.waitFor(() => { expect(telemetry.rejections).toBeGreaterThanOrEqual(1); expect(ledger.bytesInUse).toBe(0);