diff --git a/server/test/status-log-prune-hardening.test.js b/server/test/status-log-prune-hardening.test.js index 53a1f0d..01cc449 100644 --- a/server/test/status-log-prune-hardening.test.js +++ b/server/test/status-log-prune-hardening.test.js @@ -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 () => { diff --git a/server/test/storm-harness.test.js b/server/test/storm-harness.test.js index ce9855c..2a6a407 100644 --- a/server/test/storm-harness.test.js +++ b/server/test/storm-harness.test.js @@ -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`);