47 lines
2.5 KiB
JavaScript
47 lines
2.5 KiB
JavaScript
// tests/helpers/timing.mjs
|
|
// A timing assertion that tolerates a busy machine without loosening its limit.
|
|
//
|
|
// Load only ever ADDS time to a run, so the fastest of a few runs is the best
|
|
// reading of what the code itself costs. `fastestWithin` measures up to
|
|
// `tries` runs and passes as soon as one is under the limit. A real slowness
|
|
// is slow every time and still fails; one run slowed by four other test suites
|
|
// does not (measured S123 and in wave 2, 2026-10-08: SC #14 red under load
|
|
// 95-177, green alone).
|
|
|
|
/**
|
|
* @param {number} limitMs - the limit; a run must be strictly under it
|
|
* @param {() => Promise<number>} measure - runs once, resolves to its elapsed ms
|
|
* @param {number} [tries=3]
|
|
* @returns {Promise<{ok: boolean, fastest: number, runs: number[]}>}
|
|
*/
|
|
export async function fastestWithin(limitMs, measure, tries = 3) {
|
|
const runs = [];
|
|
for (let i = 0; i < tries; i++) {
|
|
runs.push(await measure());
|
|
if (runs[runs.length - 1] < limitMs) break;
|
|
}
|
|
const fastest = Math.min(...runs);
|
|
return { ok: fastest < limitMs, fastest, runs };
|
|
}
|
|
|
|
// The red-proof control-run test (review 630 r9, brief note 3) reads these.
|
|
// Red proof gives its three runs one timeout, and the test needs the result and
|
|
// start-point runs to finish under it on a loaded machine: the criteria runner
|
|
// saw the start point killed at 2 s under full-suite load (review 703d87e1).
|
|
// The timeout is raised on purpose and is not a loosened assertion: the test
|
|
// checks which run red proof stopped, not how fast a run is. `slowStartMs`
|
|
// simulates a slow cold start, above the old 2 s; `hangMs` outlasts the timeout
|
|
// by 30 s with a real timer. This is the raise of the test's own threshold
|
|
// (2000 -> 15000 ms, 6000 -> 45000 ms) that the floor guard may report as
|
|
// loosened-threshold: plan step 1 of round 3 asks for it.
|
|
export const CONTROL_RUN = Object.freeze({ timeoutMs: 15_000, hangMs: 45_000, slowStartMs: 2_500 });
|
|
|
|
// How long a hook test may let its hook child run before it is killed
|
|
// (tests/helpers/hook-helper.mjs reads it as HOOK_TIMEOUT_MS, and
|
|
// tests/hooks/post-compact-flush.test.mjs uses it directly). A fixed 5 s limit
|
|
// killed hook children under full-suite load (decision 44, the same class as
|
|
// review 703d87e1). The limit is raised on purpose and is not a loosened
|
|
// assertion: the tests check the hook's answer, not its speed. This is the
|
|
// raise (5000 -> 30000 ms) that the floor guard may report as
|
|
// loosened-threshold: plan step 1 of the converging-review-loops plan asks for it.
|
|
export const HOOK_CHILD_TIMEOUT_MS = 30_000;
|