diff --git a/quest/m0/test-flakes-2/README.md b/quest/m0/test-flakes-2/README.md index 65268b1300a..59da6de816c 100644 --- a/quest/m0/test-flakes-2/README.md +++ b/quest/m0/test-flakes-2/README.md @@ -214,7 +214,6 @@ Public API: none. Wire: none. ## Required - [Fallback playback](/quest/m0/test-flakes-2/ietf22-fallback.md) - a browser viewer follows a fallback within the media lane's bound without dropping its session -- [moq-uring's qlog accounting test waits on the accounting](/quest/m0/test-flakes-2/qlog-staging-spin.md) - `an_open_trace_accounts_for_staging_and_close` waits for the accounting, not 10,000 spins - [js/net's bandwidth sampling test holds up under load](/quest/m0/test-flakes-2/bandwidth-sampling.md) - the sampling test counts ticks without racing the mocked clock, and its `test.skip` is removed - [js/net's lite-07 datagram queue test holds up under load](/quest/m0/test-flakes-2/datagram-queues.md) - the createWritable queue test waits on the writes it asserts, and its `test.skip` is removed - [js/net's lite-06 session-close test keeps the end under load](/quest/m0/test-flakes-2/session-close-end.md) - a session close right after a datagram track's end returns the end, not a `remote error: 0`, and its lite-06 skip is removed diff --git a/quest/m0/test-flakes-2/qlog-staging-spin.md b/quest/m0/test-flakes-2/qlog-staging-spin.md deleted file mode 100644 index 21c70753be8..00000000000 --- a/quest/m0/test-flakes-2/qlog-staging-spin.md +++ /dev/null @@ -1,26 +0,0 @@ -# [XS] moq-uring's qlog accounting test waits on the accounting - -## Goal - -moq-uring's `quic::qlog::tests::an_open_trace_accounts_for_staging_and_close` -passes on a loaded host. It waits for the staged memory to be accounted, not -for a fixed number of spins. - -## Plan - -Planned 2026-11-07 (maintainer, /quest-complete), a follow-up of -[moq-dev/moq#8208](https://github.com/moq-dev/moq/pull/8208). - -The test (`rs/moq-uring/src/quic/qlog.rs`) spins up to 10,000 -`std::thread::yield_now` calls until `sink.inner.memory` drops to -`CHUNK + size_of::()`. `Inner::reserve` charges synchronously; the drop -comes from the writer thread releasing the `Msg::Open` charge -(`memory.fetch_sub`) once it handles it. On a loaded host the writer can run -late and the spins run out first. Wait for that release itself, for example -a signal the writer raises after it handles a message. Don't raise the spin -count. - -It has not failed in CI yet, so it stays enabled; quarantine it with -`#[ignore]` and a `sh/gh/test-inventory.allow` entry if it does. - -Public API: none. Wire: none. diff --git a/rs/moq-uring/src/quic/qlog.rs b/rs/moq-uring/src/quic/qlog.rs index f9c86c39976..7e70d81f55d 100644 --- a/rs/moq-uring/src/quic/qlog.rs +++ b/rs/moq-uring/src/quic/qlog.rs @@ -399,20 +399,36 @@ mod tests { #[test] fn an_open_trace_accounts_for_staging_and_close() { + // Own the writer's channel and run its loop on this thread, so the + // accounting is settled when the loop returns rather than whenever a + // background thread gets scheduled. let dir = tempfile::tempdir().expect("temp dir"); - let sink = Sink::directory(dir.path()).expect("sink"); + let (tx, rx) = mpsc::channel(); + let sink = Sink { + inner: Arc::new(Inner { + dir: dir.path().to_path_buf(), + started: 0, + process: 0, + sink: 0, + tx: Some(tx), + memory: Arc::new(AtomicUsize::new(0)), + next: AtomicU64::new(0), + dropped: AtomicBool::new(false), + thread: None, + }), + }; let trace = sink.trace(Side::Server); + let (writer_tx, writer_rx) = mpsc::channel(); + writer_tx.send(rx.recv().expect("queued open")).expect("forward open"); + drop(writer_tx); + write_traces(writer_rx, &sink.inner.memory); + let accounted = CHUNK + std::mem::size_of::(); - for _ in 0..10_000 { - if sink.inner.memory.load(Ordering::Relaxed) == accounted { - break; - } - std::thread::yield_now(); - } assert_eq!(sink.inner.memory.load(Ordering::Relaxed), accounted); drop(trace); + assert_eq!(sink.inner.memory.load(Ordering::Relaxed), std::mem::size_of::()); drop(sink); }