test(openai): GPT-Live peer-worker test fails under Bun when the far end sees the hang-up (#166465)

The blocked-Gateway tests close the GPT-Live peer first and terminate the
werift receiver Worker last. The surviving receiver keeps sending echo/RTCP
to the closed port; on Linux, Bun reports the ICMP refusal as a dgram
`recvmsg ECONNREFUSED` error that werift never handles, and the receiver
Worker's error event had no listener, so Vitest saw an unhandled error.

Observe receiver errors: any failure while media is under test fails the
test, and only the socket refusal after the intentional hang-up is expected.
This commit is contained in:
Peter Steinberger 2026-10-07 15:54:27 -07:00 • committed by GitHub
parent 9ef85029b0
commit b300e0edea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -197,6 +197,20 @@ describe("GPT-Live audio thread", () => {
weriftUrl: pathToFileURL(createRequire(import.meta.url).resolve("werift")).href,
},
});
// The receiver outlives each hang-up under test. On Linux, Bun reports the
// ICMP refusal of its next echo or RTCP send as a socket error that werift
// leaves uncaught, which fails the receiver thread. Only that is expected.
let hungUp = false;
const receiverErrors: { hungUp: boolean; error: unknown }[] = [];
receiver.on("error", (error) => receiverErrors.push({ hungUp, error }));
const expectReceiverHealthy = () =>
expect(
receiverErrors.filter(
({ hungUp: afterHangUp, error }) =>
!afterHangUp ||
!(error instanceof Error && "code" in error && error.code === "ECONNREFUSED"),
),
).toEqual([]);
const errors: Error[] = [];
let audibleSamples = 0;
let failAudioSink = false;
@ -264,6 +278,7 @@ describe("GPT-Live audio thread", () => {
"PCM messages reaching the playback worker during stall: " + mediaDuringStall,
);
expect(mediaDuringStall).toBeGreaterThanOrEqual(10);
hungUp = true;
peer.close();
expect(Atomics.load(new Int32Array(state), 0)).toBe(1);
const afterClose = Atomics.load(counts, 1);
@ -271,8 +286,11 @@ describe("GPT-Live audio thread", () => {
setTimeout(resolve, 80);
});
expect(Atomics.load(counts, 1)).toBe(afterClose);
expectReceiverHealthy();
return;
}
// The next PCM batch fails the sink, which hangs up the peer.
hungUp = true;
failAudioSink = true;
const failureDeadline = Date.now() + 2_000;
while (errors.length === 0 && Date.now() < failureDeadline) {
@ -282,6 +300,7 @@ describe("GPT-Live audio thread", () => {
}
expect(errors).toEqual([sinkError]);
await expect(peer.createOffer()).rejects.toThrow("closed");
expectReceiverHealthy();
} finally {
peer?.close();
await receiver.terminate();