docs: stop justifying the asyncUtilTimeout pin by pointing at #2335

Both web test-setup comments explained the 1000ms pin by saying the
tests that let a Testing Library wait expire "are the real defect and
are #2335; revisit when they are gone." #2335 found there are no such
tests, and its interleaved three-arm re-run showed a raise to 5000 is a
no-op on the passing path. The comments now record that finding and
keep the pin on the measured ground: raising buys nothing, so the value
stays until a measurement says otherwise.

Comment-only; the pin and the runtime assertion are unchanged.

Closes #2347

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PsmUAZ6aLUAFqenjJKSSRp
Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-09-13 11:55:42 -04:00
commit 4e19598d6b
2 changed files with 26 additions and 14 deletions

View file

@ -22,11 +22,14 @@ import { getConfig } from "@testing-library/react";
*
* A different unrelated set failed each time and every one passed in about a
* second in isolation, which is the shape of CPU starvation rather than of a
* slow assertion. The mechanism: `asyncUtilTimeout` is not only a ceiling — any
* wait that is *meant* to expire spends the whole budget on the happy path, so
* a 5x raise is a 5x cost on exactly those tests, which saturates the worker
* pool and starves tests that were never slow. The tests that assert absence
* that way are the real defect and are #2335; revisit this when they are gone.
* slow assertion. The mechanism proposed at the time — a wait that is *meant*
* to expire spends the whole budget on the happy path, so a 5x raise is a 5x
* cost on those tests — was checked on #2335 and does not hold here: no web
* test lets a Testing Library wait expire on its passing path, and the same
* three-arm protocol re-run interleaved on a leased machine showed 0 failures
* in every arm and 0 tests at or above 5000ms with the raise in place. Raising
* the budget buys nothing, so the pin stays at the default until a measurement
* says otherwise. `setup.ts` carries the full record.
*
* ⚠️ This asserts the EFFECTIVE value at runtime rather than checking that
* `setup.ts` contains a `configure()` call. An earlier revision of #2334 did

View file

@ -21,17 +21,26 @@ import { cleanup, configure } from "@testing-library/react";
//
// The failures were a different, unrelated set each time and every one passed
// in about a second in isolation, which is the shape of CPU starvation rather
// than of a slow assertion. The mechanism is that `asyncUtilTimeout` is not
// only a ceiling: any wait that is *meant* to expire — a test asserting
// something never appears, and anything that lets a poll run out — spends the
// whole budget on the happy path, so a 5x raise is a 5x cost on those tests,
// which saturates the worker pool and starves tests that were never slow.
// than of a slow assertion. The mechanism proposed at the time was that
// `asyncUtilTimeout` is not only a ceiling: a wait that is *meant* to expire —
// a test asserting something never appears, a poll allowed to run out — spends
// the whole budget on the happy path, so a 5x raise would be a 5x cost on
// those tests, saturating the worker pool.
//
// #2335 went looking for those tests and found none. Zero hits for every
// expiring-wait shape against Testing Library across the unit, `core/`,
// integration and story files; no test at or above 2000ms in a full unit run;
// and the same three-arm protocol re-run interleaved on a leased machine
// (1000 / 5000 / reverted, three rounds) gave 0 failures in every arm and
// 0 tests at or above 5000ms with the raise in place. Nothing on the passing
// path spends this budget, so raising it buys nothing — and the #2323 reds
// read as ambient load the arms did not share (an inference from that data,
// not a re-measurement of the original run).
//
// So the general rule this repo now follows — a budget must be a value someone
// chose — is satisfied by choosing it, not by raising it. Raising it is what
// #2323's own "do not raise" list would have said had the measurement been
// taken first. The tests that assert absence by letting a wait expire are the
// real defect and are tracked on #2335; when they are gone, revisit this.
// chose — is satisfied by choosing it, not by raising it. The pin stays at the
// default until a measurement says otherwise; `asyncUtilTimeout.test.ts`
// asserts the effective value, so moving it is deliberate by construction.
configure({ asyncUtilTimeout: 1000 });
// Node 22+ exposes an experimental `localStorage` placeholder that overrides