diff --git a/js/publish/src/audio/encoder.test.ts b/js/publish/src/audio/encoder.test.ts index 1152a76b5b..156817e7ee 100644 --- a/js/publish/src/audio/encoder.test.ts +++ b/js/publish/src/audio/encoder.test.ts @@ -1,4 +1,5 @@ import { describe, expect, mock, spyOn, test } from "bun:test"; +import { u53 } from "@moq/hang/catalog"; import * as Moq from "@moq/net"; import { Time } from "@moq/net"; import { Signal } from "@moq/signals"; @@ -320,24 +321,34 @@ test("passes an explicit Opus DTX request to the encoder", async () => { // it, which the catalog advertises as `delay`. test("a rendition trailing the broadcast's earliest advertises delay", async () => { using _webcodecs = installFakeWebCodecs(); - const baseline = new Baseline(); - using env = await setup(baseline); - const { encoder, feed } = env; + // A process that has just started reports performance.now() under 100ms, so a capture "100ms ago" + // is negative and the frame encoder rejects it. A fixed origin keeps every stamp nonnegative. + const clock = spyOn(performance, "now").mockReturnValue(200); + try { + const baseline = new Baseline(); + using env = await setup(baseline); + const { encoder, feed } = env; - expect(encoder.out.catalog.peek()?.delay).toBeUndefined(); + expect(encoder.out.catalog.peek()?.delay).toBeUndefined(); - // A sibling that flushes each frame the instant it is captured. - baseline.observe(0, performance.now() * 1000); + // A sibling that flushes each frame the instant it is captured. + baseline.observe(0, performance.now() * 1000); - // Captured 100ms ago, so this rendition flushes at least that late. - const start = performance.now() * 1000 - 100_000; - for (let index = 0; index < 4; index++) { - await feed.push({ timestamp: Time.Micro(start + index * 20_000), channels: [new Float32Array(960)] }); - } - await feed.drain(); + // Captured 100ms ago, so this rendition flushes at least that late. + const start = performance.now() * 1000 - 100_000; + for (let index = 0; index < 4; index++) { + await feed.push({ timestamp: Time.Micro(start + index * 20_000), channels: [new Float32Array(960)] }); + } + await feed.drain(); - expect(env.written.length).toBe(2); - expect(encoder.out.catalog.peek()?.delay).toBeGreaterThanOrEqual(100); + expect(env.written).toEqual([ + [100_000, 1], + [120_000, 1], + ]); + expect(encoder.out.catalog.peek()?.delay).toBe(u53(100)); + } finally { + clock.mockRestore(); + } }); // Regression: codec settings that can't resolve left the encoder unsettled, so `` never diff --git a/quest/m1/test-flakes-2/README.md b/quest/m1/test-flakes-2/README.md index 345570e472..123198fe9e 100644 --- a/quest/m1/test-flakes-2/README.md +++ b/quest/m1/test-flakes-2/README.md @@ -37,7 +37,6 @@ Public API: none. Wire: none. - [Shaper virtual time](/quest/m1/test-flakes-2/shaper-virtual-time.md) - `moq-shaper` tests judge seeded decisions on paused time, not on wall-clock delivery under load - [Scoped WARN capture](/quest/m1/test-flakes-2/warn-capture.md) - the drop-unfinished tests count only their own WARNs - [moq-mux debounce clock](/quest/m1/test-flakes-2/mux-debounce-clock.md) - the TS export debounce test advances on the paused clock -- [js/publish audio clock](/quest/m1/test-flakes-2/publish-audio-clock.md) - the audio encoder delay test runs on mock time - [WebSocket paused TLS dial](/quest/m1/test-flakes-2/websocket-paused-tls.md) - the fixed-address WebSocket tests stop pausing the clock over a real dial - [Rejoin after idle](/quest/m1/test-flakes-2/rejoin-idle-race.md) - an IETF rejoin never gets the stale warm cache first, because the copy goes idle before the cancel diff --git a/quest/m1/test-flakes-2/publish-audio-clock.md b/quest/m1/test-flakes-2/publish-audio-clock.md deleted file mode 100644 index ccc4becaad..0000000000 --- a/quest/m1/test-flakes-2/publish-audio-clock.md +++ /dev/null @@ -1,11 +0,0 @@ -# [XS] js/publish audio delay test on mock time - -## Goal - -The js/publish audio encoder test "a rendition trailing the broadcast's -earliest advertises delay" passes when its file runs alone. - -## Plan - -It reads the real clock, so timestamps go negative early in the process and -it fails when run alone (#4414). Run it on mock time.