Dedup test-realm lifecycle hooks + contention-proof hook timeout - #7
Merged
Merged
Conversation
The non-live suite intermittently failed on cache-miss runs (comms-xwqm): under a full-parallel `bun run check` the starved event loop stretched real-in-process-realm setup/teardown past bun's default 5s HOOK timeout — independent of the per-test body timeout the gap-replay test already raised — so the failure landed on whichever test the slow hook wrapped, explaining the moving test name. Extract one shared `registerRealmHooks(start, assign)` + `REALM_HOOK_TIMEOUT_MS` (packages/testing/realm-hooks.ts). The byte-identical realm beforeEach/afterEach boilerplate in adapter.test.ts and bot-dm-guard.test.ts, the same-shaped fixture hooks in http.test.ts, and the contract suite's factory/dispose hooks all route through it. The `assign` callback hands the instance back to each file's own `let` binding, so the ~170 `realm.`/`fixture.` call sites stay untouched. contract.ts (async factory / Effect dispose) just imports the timeout constant. This is headroom, not a full cure: the two infinite-long-poll teardown tests (gap-replay comms-4au, scope-close-interrupt spj3.8) can still exceed even 30s under aggressive contention. That residual is a fiber/scope lifecycle problem (server.stop(true) is not the blocker — an isolated probe resolves it in 0.2ms with a handler stuck forever), tracked for the Effect-Scope-based realm rework in comms-4lz5 / comms-30hq.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The non-live test suite intermittently failed on cache-miss / pre-commit runs. Reproduced under concurrent-suite contention (a proxy for the full-parallel
bun run checkload): the failures were always"a beforeEach/afterEach hook timed out", never a test-body timeout.Root cause: bun's lifecycle hooks keep their own 5s timeout, independent of a test's per-test timeout. Real in-process-realm setup/teardown runs in a few ms in isolation, but under a starved event loop it stretches past 5s — and the hook, not the body, times out, landing the failure on whichever test the hook happened to wrap (which is why the failing test name moved run-to-run, and why the earlier per-test-body 30s bump didn't help).
How
Extract one shared
registerRealmHooks(start, assign)+REALM_HOOK_TIMEOUT_MSinpackages/testing/realm-hooks.ts:beforeEach/afterEachboilerplate inadapter.test.tsandbot-dm-guard.test.tswas byte-identical;http.test.tsis the same shape with a fixture; the contract suite is a third (async factory / Effect dispose) variant. All now route through the shared helper / constant.assigncallback hands the fresh instance back to each file's ownletbinding, so the ~170realm./fixture.call sites are untouched — no getter churn.So this both removes the duplication and gives the hooks the headroom the per-test bodies already had.
Known residual (deferred)
This is headroom, not a full cure. The two infinite-long-poll teardown tests (gap-replay
comms-4au, scope-close-interruptspj3.8) can still exceed even 30s under aggressive contention. That residual is a fiber/scope lifecycle problem —server.stop(true)is provably not the blocker (an isolated probe resolves it in 0.2ms with a handler stuck forever and the client aborted). It's tracked for the Effect-Scope-based realm rework (comms-4lz5/comms-30hq), where running the whole test inside one scope with guaranteed finalizers removes the leftover-fiber-starves-teardown mode structurally.