test: widen CI-fragile event-loop-gap timing bars (flaky prune/storm asserts)

CI flaked on the 300k-row prune non-blocking assert: a healthy chunked prune hit a 417ms max
event-loop gap on a shared runner, over the strict 250ms bar (the same test passed on the prior
commit; the release bump changed no logic). These probes exist to catch a MULTI-SECOND freeze (the
pre-fix whole-table sort froze 40-48s) — not to enforce a sub-300ms latency SLA — so a strict bar is
fragile under runner contention/GC. Widen both to <1500ms: still << "seconds" (catches any real
regression) but robust on CI. No production code changed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
ScreenTinker 2026-07-08 17:31:27 -05:00
parent dfd954d2ad
commit 09e11397b4
2 changed files with 10 additions and 5 deletions

View file

@ -55,8 +55,11 @@ test('non-blocking: 300k-row single-device backlog trims in many batches, loop s
assert.equal(count('flapper'), 300000, 'seeded 300k');
// Event-loop responsiveness probe: a 10ms ticker; the max gap between ticks is the
// worst synchronous block during the prune. A single unbatched DELETE would freeze
// it for seconds; chunked+yield keeps every gap small.
// worst synchronous block during the prune. A single unbatched DELETE of 300k rows would
// freeze it for SECONDS; chunked+yield keeps every gap well under a second. The bar is set to
// catch that multi-second freeze while tolerating shared-CI-runner noise (a strict sub-300ms
// bar flakes under runner contention/GC — the intent is "not a seconds-long freeze", not a
// fixed-latency SLA).
let maxGap = 0, last = Date.now();
const ticker = setInterval(() => { const n = Date.now(); maxGap = Math.max(maxGap, n - last); last = n; }, 10);
@ -65,7 +68,7 @@ test('non-blocking: 300k-row single-device backlog trims in many batches, loop s
assert.equal(count('flapper'), 500, 'trimmed to the cap');
assert.ok(deleted >= 299000, `deleted the backlog (${deleted})`);
assert.ok(maxGap < 250, `no long freeze — max event-loop gap ${maxGap}ms (would be seconds if unbatched)`);
assert.ok(maxGap < 1500, `no seconds-long freeze — max event-loop gap ${maxGap}ms (an unbatched 300k DELETE would be multiple seconds)`);
});
test('band-gate: interval run is a no-op when loaded; startup/normal runs', async () => {

View file

@ -64,8 +64,10 @@ test('storm: bloated-table sweep + flapper + OTA flood — loop stays responsive
clearInterval(ticker);
// 1) THE REAL INVARIANT — NO multi-second freeze. The old whole-table sort would
// freeze the ticker for tens of seconds here.
assert.ok(maxGap < 300, `loop never froze — max event-loop gap ${maxGap}ms (was 40-48s pre-fix)`);
// freeze the ticker for tens of seconds here (40-48s). The bar catches that while
// tolerating shared-CI-runner noise — the intent is "not seconds", not a sub-300ms SLA
// (a strict bar flakes under runner contention/GC, e.g. an observed 417ms on a healthy prune).
assert.ok(maxGap < 1500, `loop never froze — max event-loop gap ${maxGap}ms (was 40-48s pre-fix)`);
// #146 P3.9: the exact tick count is environment-timing-sensitive; assert only that
// the ticker sampled enough to have MEASURED a real gap (>=2), not a brittle count.
assert.ok(ticks >= 2, `ticker sampled the run (${ticks} ticks) — max-gap measurement is meaningful`);