You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Filed while implementing #14100 (unassigned: recording only). #14100 is scoped to exactly 4 it() and the 2 beforeAll hooks in sql-driver-backend-fault-envelope.test.ts, and that scoping is respected — nothing here was folded into its PR (#14212), following that card's own "separate card rather than a rider" precedent.
Two findings, one measured and one structural. The measured one comes first because it reframes the other.
1. A hook does NOT inherit the 5000ms default — it inherits hookTimeout, measured at 10000ms
Both #13902 and #14100 describe the defect class as work "on vitest's inherited 5000ms default". For it() sites that is exact. For hooks it is wrong, and the difference was measured in packages/drivers/driver-sql's real config (which sets neither testTimeout nor hookTimeout, so both are vitest's own defaults):
Leg
Shape
Result
A1
it(), 6000ms sleep, no budget
exit 1 — Test timed out in 5000ms (5.58s)
A2
it(), 6000ms sleep, 60_000
exit 0 (6.54s)
B1
beforeAll, 6000ms sleep, no budget
exit 0 — passed (6.46s)
B3
beforeAll, 11000ms sleep, no budget
exit 1 — Hook timed out in 10000ms (10.56s)
B4
beforeAll, 11000ms sleep, 60_000
exit 0 (11.52s)
A3
it(), 11000ms sleep, 60_000
exit 0 (11.50s) — control
Probes were run through the shared verify lock, exit codes captured by redirect before any pipe, on-disk landing proven by marker counts, and removed by trap with absence re-proven.
An unbudgeted hook has twice the headroom of an unbudgeted it(). A hook is therefore a less urgent instance of this class than an it(), not a more urgent one — worth knowing before anyone sizes the remaining work.
The third argument demonstrably does lift a hook's ceiling (B4), so budgeting hooks is effective, not decorative.
2. Seven unbudgeted hooks whose driver argument is unconditionally live
A per-site AST walk over all 159 test files in packages/drivers/driver-sql/src (193 driver-constructing sites total), classifying each site by reading its new SqlDriver(...) argument rather than by filename, finds these hooks with an unconditionally live cell argument and no explicit budget. None is named by #14100:
Three of these are beforeEach, so the cost is paid per test in the suite, not once — the heaviest shape in the population and the one #14100's framing does not cover at all.
Worth noting for whoever picks this up: the last row of the json-binding-without-ddl group sits in a file #14212 already edits (for its it() site). It was left alone deliberately rather than fixed in passing, because #14100's dispatch bounded the file surface to named sites and this card's lineage explicitly rules out silent package-wide creep.
Separately, a large population of beforeAll/beforeEach hooks inside declareDialectCell(...) callbacks take cell.config() and are therefore live for the pg and mysql cells but embedded for the sqlite cell. Those are not mechanical: budgeting them trades against keeping the sqlite path fast, which is a real judgement call rather than a missing argument. They are mentioned so the next sweep does not mistake them for the same easy shape, not proposed as work here.
The standing-gate ruling
The filing seat on #14100 ruled deliberately not to build a standing gate for this defect class, on the grounds that the repo already runs 197 gates and the class had exactly one measured instance (#13688) — and recorded that the ruling gets revisited if a third occurrence appears. That condition is now arguably met in population terms, though still with one measured timeout, not three. Recording the trigger; the decision is the maintainer's, not this card's.
Method note carried forward from #14100: use a per-site AST walk, not a file-level grep. #13902's original script pre-filtered out any file containing a budget line and thereby hid a true positive.
Filed while implementing #14100 (unassigned: recording only). #14100 is scoped to exactly 4
it()and the 2beforeAllhooks insql-driver-backend-fault-envelope.test.ts, and that scoping is respected — nothing here was folded into its PR (#14212), following that card's own "separate card rather than a rider" precedent.Two findings, one measured and one structural. The measured one comes first because it reframes the other.
1. A hook does NOT inherit the 5000ms default — it inherits
hookTimeout, measured at 10000msBoth #13902 and #14100 describe the defect class as work "on vitest's inherited 5000ms default". For
it()sites that is exact. For hooks it is wrong, and the difference was measured inpackages/drivers/driver-sql's real config (which sets neithertestTimeoutnorhookTimeout, so both are vitest's own defaults):it(), 6000ms sleep, no budgetTest timed out in 5000ms(5.58s)it(), 6000ms sleep,60_000beforeAll, 6000ms sleep, no budgetbeforeAll, 11000ms sleep, no budgetHook timed out in 10000ms(10.56s)beforeAll, 11000ms sleep,60_000it(), 11000ms sleep,60_000Probes were run through the shared verify lock, exit codes captured by redirect before any pipe, on-disk landing proven by marker counts, and removed by trap with absence re-proven.
Consequences, none of which change #14100's fix:
it(). A hook is therefore a less urgent instance of this class than anit(), not a more urgent one — worth knowing before anyone sizes the remaining work.2. Seven unbudgeted hooks whose driver argument is unconditionally live
A per-site AST walk over all 159 test files in
packages/drivers/driver-sql/src(193 driver-constructing sites total), classifying each site by reading itsnew SqlDriver(...)argument rather than by filename, finds these hooks with an unconditionally live cell argument and no explicit budget. None is named by #14100:sql-driver-datetime-mysql-storage.test.tsbeforeEach(x3, three suites)MYSQL_CELL.config()initObjects(...)sql-driver-datetime-postgres-timezone.test.tsbeforeAllPG_CELL.config()current_setting('TimeZone'), disconnectsql-driver-datetime-postgres-timezone.test.tsbeforeEachPG_CELL.config()initObjects(...)sql-driver-json-binding-without-ddl.test.tsbeforeAllPG_CELL.config()create table, register metadatasql-driver-time-live-dialects.test.tsbeforeEachMYSQL_CELL.config()create tableThree of these are
beforeEach, so the cost is paid per test in the suite, not once — the heaviest shape in the population and the one #14100's framing does not cover at all.Worth noting for whoever picks this up: the last row of the
json-binding-without-ddlgroup sits in a file #14212 already edits (for itsit()site). It was left alone deliberately rather than fixed in passing, because #14100's dispatch bounded the file surface to named sites and this card's lineage explicitly rules out silent package-wide creep.Separately, a large population of
beforeAll/beforeEachhooks insidedeclareDialectCell(...)callbacks takecell.config()and are therefore live for the pg and mysql cells but embedded for the sqlite cell. Those are not mechanical: budgeting them trades against keeping the sqlite path fast, which is a real judgement call rather than a missing argument. They are mentioned so the next sweep does not mistake them for the same easy shape, not proposed as work here.The standing-gate ruling
The filing seat on #14100 ruled deliberately not to build a standing gate for this defect class, on the grounds that the repo already runs 197 gates and the class had exactly one measured instance (#13688) — and recorded that the ruling gets revisited if a third occurrence appears. That condition is now arguably met in population terms, though still with one measured timeout, not three. Recording the trigger; the decision is the maintainer's, not this card's.
Method note carried forward from #14100: use a per-site AST walk, not a file-level grep. #13902's original script pre-filtered out any file containing a budget line and thereby hid a true positive.
Generated by Claude Code