diff --git a/packages/drivers/driver-sql/src/sql-driver-11389-date-tz-skew.test.ts b/packages/drivers/driver-sql/src/sql-driver-11389-date-tz-skew.test.ts index 866c6e25c4..f32ddf98a6 100644 --- a/packages/drivers/driver-sql/src/sql-driver-11389-date-tz-skew.test.ts +++ b/packages/drivers/driver-sql/src/sql-driver-11389-date-tz-skew.test.ts @@ -436,6 +436,17 @@ declareDialectCell(PG_CELL, 'date wire form (#11389)', (cell) => { driver = undefined; }); + // ── Why the it() below carries an explicit 60_000 budget (#13902) ── + // It constructs a FRESH `new SqlDriver(...)` against this cell's live + // server inside its own body — so the live connect cycle, and the + // schema-sync DDL and catalog read-back that all but the cheapest of these + // drive through it, are paid PER TEST rather than once in a beforeAll. + // With no third argument vitest applies its own 5000ms default — a number + // nobody chose for that work, and one that reddens unrelated PRs when the + // runner is merely a bit slow (#13688 measured exactly this shape: a timeout, + // no MySQL error in the logs, on a diff that touched no driver). Sized like + // this package's siblings — 60_000 is 7 of its 9 explicit budgets — and NOT + // an assertion that these tests are normally anywhere near that slow. it('hands back strings for `date` and `date[]`, and keeps `timestamptz` an instant', async () => { driver = new SqlDriver(cell.config()); await underProcessZone('Asia/Shanghai', async () => { @@ -456,6 +467,6 @@ declareDialectCell(PG_CELL, 'date wire form (#11389)', (cell) => { expect(row.ts instanceof Date).toBe(true); expect((row.ts as Date).toISOString()).toBe(`${DAY}T00:00:00.000Z`); }); - }); + }, 60_000); }); }); diff --git a/packages/drivers/driver-sql/src/sql-driver-11565-row-byte-budget.test.ts b/packages/drivers/driver-sql/src/sql-driver-11565-row-byte-budget.test.ts index c8122d8113..b1534d3534 100644 --- a/packages/drivers/driver-sql/src/sql-driver-11565-row-byte-budget.test.ts +++ b/packages/drivers/driver-sql/src/sql-driver-11565-row-byte-budget.test.ts @@ -198,12 +198,23 @@ declareDialectCell(MYSQL_CELL, 'row byte budget (#11565)', (cell) => { * the cell asserts the multiplier rather than assuming it, the same way the * matrix asserts its zone skew instead of hoping for it. */ + // ── Why the 6 it() blocks below carry an explicit 60_000 budget (#13902) ── + // Each constructs a FRESH `new SqlDriver(...)` against this cell's live + // server inside their own body — so the live connect cycle, and the + // schema-sync DDL and catalog read-back that all but the cheapest of these + // drive through it, are paid PER TEST rather than once in a beforeAll. + // With no third argument vitest applies its own 5000ms default — a number + // nobody chose for that work, and one that reddens unrelated PRs when the + // runner is merely a bit slow (#13688 measured exactly this shape: a timeout, + // no MySQL error in the logs, on a diff that touched no driver). Sized like + // this package's siblings — 60_000 is 7 of its 9 explicit budgets — and NOT + // an assertion that these tests are normally anywhere near that slow. it('runs on a 4-byte charset — the boundaries below are utf8mb4 numbers', async () => { driver = new SqlDriver(cell.config()); const seen = await (driver as any).schemaBytesPerChar(); expect(seen).not.toBeNull(); expect(seen.bytesPerChar).toBe(4); - }); + }, 60_000); /** * Both sides of the boundary, in one test, because only the pair means @@ -245,7 +256,7 @@ declareDialectCell(MYSQL_CELL, 'row byte budget (#11565)', (cell) => { // ⛔ And nothing was left behind: the object is not registered half-built. const exists = await (driver as any).knex.schema.hasTable('os11565_over'); expect(exists).toBe(false); - }); + }, 60_000); /** The card's second measured row, moved by the driver's own `id` column. */ it('creates 63 fields at maxLength 255 and refuses 64', async () => { @@ -259,7 +270,7 @@ declareDialectCell(MYSQL_CELL, 'row byte budget (#11565)', (cell) => { await expect(driver.initObjects([wideObject('os11565_over255', 64, 255)])).rejects.toThrow( /cannot create table "os11565_over255".*Its 64 varchar column\(s\) take 65408 bytes/s, ); - }); + }, 60_000); /** * The path that is more likely than CREATE in a living app: a field added @@ -275,7 +286,7 @@ declareDialectCell(MYSQL_CELL, 'row byte budget (#11565)', (cell) => { await expect(driver.initObjects([wideObject('os11565_grow', 16, 1024)])).rejects.toThrow( /cannot add column\(s\) "f16" to "os11565_grow".*Its 16 varchar column\(s\)/s, ); - }); + }, 60_000); /** * The SECOND limit, which the card's threshold table does not reach and a @@ -296,7 +307,7 @@ declareDialectCell(MYSQL_CELL, 'row byte budget (#11565)', (cell) => { expect(message).toMatch(/InnoDB's per-PAGE limit of 8126 bytes/); expect(message).not.toMatch(/65535-byte budget for one ROW/); expect(message).toMatch(/"f1" varchar\(63\) = 253 bytes/); - }); + }, 60_000); /** * The shape a diagnostic reading only DECLARED bounds would have nothing to @@ -315,6 +326,6 @@ declareDialectCell(MYSQL_CELL, 'row byte budget (#11565)', (cell) => { const message = String(failure.message); expect(message).toMatch(/"f1" varchar\(255\) = 1022 bytes/); expect(message).toMatch(/a field declaring NO `maxLength` still takes varchar\(255\)/i); - }); + }, 60_000); }); }); diff --git a/packages/drivers/driver-sql/src/sql-driver-11627-hash-shadow-key.test.ts b/packages/drivers/driver-sql/src/sql-driver-11627-hash-shadow-key.test.ts index 6410300805..d0f8b29446 100644 --- a/packages/drivers/driver-sql/src/sql-driver-11627-hash-shadow-key.test.ts +++ b/packages/drivers/driver-sql/src/sql-driver-11627-hash-shadow-key.test.ts @@ -132,6 +132,17 @@ declareDialectCell(MYSQL_CELL, 'hash-shadow key (#11627)', (cell) => { * The accept transition: schema creation MySQL REFUSED before this change * now succeeds, and the constraint is carried on a full-width digest. */ + // ── Why the 9 it() blocks below carry an explicit 60_000 budget (#13902) ── + // Each constructs a FRESH `new SqlDriver(...)` against this cell's live + // server inside their own body — so the live connect cycle, and the + // schema-sync DDL and catalog read-back that all but the cheapest of these + // drive through it, are paid PER TEST rather than once in a beforeAll. + // With no third argument vitest applies its own 5000ms default — a number + // nobody chose for that work, and one that reddens unrelated PRs when the + // runner is merely a bit slow (#13688 measured exactly this shape: a timeout, + // no MySQL error in the logs, on a diff that touched no driver). Sized like + // this package's siblings — 60_000 is 7 of its 9 explicit budgets — and NOT + // an assertion that these tests are normally anywhere near that slow. it('creates a UNIQUE index over a 1024-char column, on a varbinary(32) shadow', async () => { driver = new SqlDriver(cell.config()); await driver.initObjects([uniqueOn('os11627_wide', 1024)]); @@ -156,7 +167,7 @@ declareDialectCell(MYSQL_CELL, 'hash-shadow key (#11627)', (cell) => { // ⛔ The control that separates this from the REJECTED route: a prefix // index reports a SUB_PART. The shadow index keys a whole column. expect(carried[0].SUB_PART).toBeNull(); - }); + }, 60_000); /** * The boundary, both sides, read from the catalog: 768 characters is the @@ -176,7 +187,7 @@ declareDialectCell(MYSQL_CELL, 'hash-shadow key (#11627)', (cell) => { const over = await catalog('os11627_over'); expect(String(over.cols.find((c: any) => c.COLUMN_NAME === 'v').DATA_TYPE)).toBe('text'); expect(over.cols.filter((c: any) => isHashShadowColumn(c.COLUMN_NAME)).length).toBe(1); - }); + }, 60_000); /** * ⛔ The assertion a PREFIX index fails. Two distinct values sharing their @@ -198,7 +209,7 @@ declareDialectCell(MYSQL_CELL, 'hash-shadow key (#11627)', (cell) => { // …and the constraint is real: the same value twice is refused. await expect(knex('os11627_sem').insert({ id: 'dup', v: `${shared}AAA` })).rejects.toThrow(); - }); + }, 60_000); /** * NULL must stay DISTINCT, exactly as under a direct UNIQUE index. @@ -213,7 +224,7 @@ declareDialectCell(MYSQL_CELL, 'hash-shadow key (#11627)', (cell) => { const knex = (driver as any).knex; await knex('os11627_null').insert([{ id: 'n1', v: null }, { id: 'n2', v: null }, { id: 'n3', v: null }]); expect((await knex('os11627_null').whereNull('v')).length).toBe(3); - }); + }, 60_000); /** * A COMPOSITE unique hashes the tuple, and a tuple containing NULL must @@ -239,7 +250,7 @@ declareDialectCell(MYSQL_CELL, 'hash-shadow key (#11627)', (cell) => { await knex('os11627_comp').insert([{ id: 's1', a: 'xy', b: '' }, { id: 's2', a: 'x', b: 'y2' }]); // …and the composite constraint still bites. await expect(knex('os11627_comp').insert({ id: 'dup', a: 'x', b: 'y' })).rejects.toThrow(); - }); + }, 60_000); /** * The digest stored is the one this repo can independently recompute — the @@ -257,7 +268,7 @@ declareDialectCell(MYSQL_CELL, 'hash-shadow key (#11627)', (cell) => { const stored: Buffer = row[shadowCol]; expect(stored.length).toBe(32); expect(stored.toString('hex')).toBe(createHash('sha256').update(value).digest('hex')); - }); + }, 60_000); /** * The clause-② half: once uniqueness is enforced over a DIGEST, MySQL's @@ -277,7 +288,7 @@ declareDialectCell(MYSQL_CELL, 'hash-shadow key (#11627)', (cell) => { await expect(driver.create('os11627_dup', { v: 'T'.repeat(900) })).rejects.toThrow( /duplicate value for the UNIQUE constraint 'uniq_os11627_dup_v'.*\(v\)/s, ); - }); + }, 60_000); /** * ⛔ NON-UNIQUE indexes are deliberately NOT shadowed. An index over a @@ -296,7 +307,7 @@ declareDialectCell(MYSQL_CELL, 'hash-shadow key (#11627)', (cell) => { await expect(driver.initObjects([nonUnique])).rejects.toThrow( /hash-shadow|cannot create index|BLOB\/TEXT/i, ); - }); + }, 60_000); }); }); @@ -327,6 +338,6 @@ declareDialectCell(PG_CELL, 'hash-shadow key (#11627)', (cell) => { ); const defs = (idx.rows ?? []).map((r: any) => String(r.indexdef)).join('\n'); expect(defs).toMatch(/UNIQUE INDEX .*uniq_os11627_pg_v.*\(v\)/i); - }); + }, 60_000); }); }); diff --git a/packages/drivers/driver-sql/src/sql-driver-11794-richtext-text-family.test.ts b/packages/drivers/driver-sql/src/sql-driver-11794-richtext-text-family.test.ts index da2ac357b1..6d90f4040e 100644 --- a/packages/drivers/driver-sql/src/sql-driver-11794-richtext-text-family.test.ts +++ b/packages/drivers/driver-sql/src/sql-driver-11794-richtext-text-family.test.ts @@ -236,6 +236,17 @@ for (const liveCell of [PG_CELL, MYSQL_CELL]) { await driver?.disconnect().catch(() => {}); }); + // ── Why the 3 it() blocks below carry an explicit 60_000 budget (#13902) ── + // Each constructs a FRESH `new SqlDriver(...)` against this cell's live + // server inside their own body — so the live connect cycle, and the + // schema-sync DDL and catalog read-back that all but the cheapest of these + // drive through it, are paid PER TEST rather than once in a beforeAll. + // With no third argument vitest applies its own 5000ms default — a number + // nobody chose for that work, and one that reddens unrelated PRs when the + // runner is merely a bit slow (#13688 measured exactly this shape: a timeout, + // no MySQL error in the logs, on a diff that touched no driver). Sized like + // this package's siblings — 60_000 is 7 of its 9 explicit budgets — and NOT + // an assertion that these tests are normally anywhere near that slow. it('accepts a >255-char richtext body, and the column really is TEXT (information_schema)', async () => { driver = new SqlDriver(cell.config()); await driver.execute(`drop table if exists ${T}`).catch(() => {}); @@ -280,7 +291,7 @@ for (const liveCell of [PG_CELL, MYSQL_CELL]) { expect(refusal).toBeInstanceOf(Error); const said = `${String((refusal as { code?: string })?.code ?? '')} ${String((refusal as Error).message)}`; expect(said).toMatch(/ER_DATA_TOO_LONG|22001|too long/i); - }); + }, 60_000); it('closes the formerly-open half (#11875): an oversized data-URI signature/qrcode is accepted and round-trips', async () => { // The #11794 version of this case asserted the COST of leaving @@ -299,7 +310,7 @@ for (const liveCell of [PG_CELL, MYSQL_CELL]) { const [row] = await driver.find(T, { where: { id: 's1' } }, OPTS); expect(row.body_sig).toBe(DATA_URI); expect(row.body_qr).toBe(DATA_URI); - }); + }, 60_000); it('keeps #11374 keyed-and-bounded semantics live for the new members (#11875)', async () => { // A KEYED bounded signature/qrcode column is varchar(maxLength) — the @@ -348,7 +359,7 @@ for (const liveCell of [PG_CELL, MYSQL_CELL]) { const said = `${String((refusal as { code?: string })?.code ?? '')} ${String((refusal as Error).message)}`; expect(said).toMatch(/ER_DATA_TOO_LONG|22001|too long/i); await driver.execute(`drop table if exists ${KT}`).catch(() => {}); - }); + }, 60_000); }); }); } diff --git a/packages/drivers/driver-sql/src/sql-driver-12998-shadow-null-safe-key.test.ts b/packages/drivers/driver-sql/src/sql-driver-12998-shadow-null-safe-key.test.ts index 575ab9d1c6..6bbd6183e0 100644 --- a/packages/drivers/driver-sql/src/sql-driver-12998-shadow-null-safe-key.test.ts +++ b/packages/drivers/driver-sql/src/sql-driver-12998-shadow-null-safe-key.test.ts @@ -86,6 +86,17 @@ declareDialectCell(MYSQL_CELL, 'hash-shadow NULL-safe key (#12998)', (cell) => { * equivalence pin: the shadow enforces the SAME key the direct * `COALESCE(organization_id, '__global__')` index would have. */ + // ── Why the 4 it() blocks below carry an explicit 60_000 budget (#13902) ── + // Each constructs a FRESH `new SqlDriver(...)` against this cell's live + // server inside their own body — so the live connect cycle, and the + // schema-sync DDL and catalog read-back that all but the cheapest of these + // drive through it, are paid PER TEST rather than once in a beforeAll. + // With no third argument vitest applies its own 5000ms default — a number + // nobody chose for that work, and one that reddens unrelated PRs when the + // runner is merely a bit slow (#13688 measured exactly this shape: a timeout, + // no MySQL error in the logs, on a diff that touched no driver). Sized like + // this package's siblings — 60_000 is 7 of its 9 explicit budgets — and NOT + // an assertion that these tests are normally anywhere near that slow. it('collides two NULL-organization rows under an org-scoped shadow unique', async () => { driver = new SqlDriver(cell.config()); await driver.initObjects([orgUniqueOn('os12998_org')]); @@ -124,7 +135,7 @@ declareDialectCell(MYSQL_CELL, 'hash-shadow NULL-safe key (#12998)', (cell) => { await expect( knex('os12998_org').insert({ id: 'f', v: V2, organization_id: null }), ).rejects.toThrow(/duplicate/i); - }); + }, 60_000); /** * ⛔ The control, colocated: a PLAIN composite's expression must NOT gain a @@ -151,7 +162,7 @@ declareDialectCell(MYSQL_CELL, 'hash-shadow NULL-safe key (#12998)', (cell) => { { id: 'n2', a: 'x'.repeat(900), b: null }, ]); expect((await knex('os12998_plain').whereNull('b')).length).toBe(2); - }); + }, 60_000); /** * Turning the constraint ON is data-dependent (ADR-0120 D4's exact shape): @@ -196,7 +207,7 @@ declareDialectCell(MYSQL_CELL, 'hash-shadow NULL-safe key (#12998)', (cell) => { const { cols, idx } = await catalog('os12998_dirty'); expect(idx.some((i: any) => i.INDEX_NAME === 'uniq_os12998_dirty_org_v')).toBe(false); expect(cols.filter((c: any) => isHashShadowColumn(c.COLUMN_NAME))).toEqual([]); - }); + }, 60_000); /** * The write-path half of ruling #11627 clause-②, now for the NULL-safe @@ -220,6 +231,6 @@ declareDialectCell(MYSQL_CELL, 'hash-shadow NULL-safe key (#12998)', (cell) => { expect(msg).toMatch(/duplicate value for the UNIQUE constraint 'uniq_os12998_msg_org_v'/); expect(msg).toContain("COALESCE(organization_id, '__global__')"); expect(msg).not.toContain('HASH COLLISION'); - }); + }, 60_000); }); }); diff --git a/packages/drivers/driver-sql/src/sql-driver-13015-shadow-carried-index-drift.test.ts b/packages/drivers/driver-sql/src/sql-driver-13015-shadow-carried-index-drift.test.ts index 3c994f79d5..5f2a26ef14 100644 --- a/packages/drivers/driver-sql/src/sql-driver-13015-shadow-carried-index-drift.test.ts +++ b/packages/drivers/driver-sql/src/sql-driver-13015-shadow-carried-index-drift.test.ts @@ -266,6 +266,17 @@ declareDialectCell(MYSQL_CELL, 'shadow-carried index drift (#13015)', (cell) => ); }; + // ── Why the 4 it() blocks below carry an explicit 60_000 budget (#13902) ── + // Each constructs a FRESH `new SqlDriver(...)` against this cell's live + // server inside their own body — so the live connect cycle, and the + // schema-sync DDL and catalog read-back that all but the cheapest of these + // drive through it, are paid PER TEST rather than once in a beforeAll. + // With no third argument vitest applies its own 5000ms default — a number + // nobody chose for that work, and one that reddens unrelated PRs when the + // runner is merely a bit slow (#13688 measured exactly this shape: a timeout, + // no MySQL error in the logs, on a diff that touched no driver). Sized like + // this package's siblings — 60_000 is 7 of its 9 explicit budgets — and NOT + // an assertion that these tests are normally anywhere near that slow. it('a freshly synced shadow-carried unique reports no destructive index drift', async () => { driver = new SqlDriver(cell.config()); const obj = orgUniqueOn('os13015_fresh'); @@ -281,7 +292,7 @@ declareDialectCell(MYSQL_CELL, 'shadow-carried index drift (#13015)', (cell) => // And the shadow COLUMN is still protected from the orphan-column pass — // the half of the vocabulary that was already taught. expect(drift.filter((d) => d.kind === 'unmapped_column')).toEqual([]); - }); + }, 60_000); /** * The remedy pin. Even on a second boot — the runtime ledger empty again, @@ -312,7 +323,7 @@ declareDialectCell(MYSQL_CELL, 'shadow-carried index drift (#13015)', (cell) => await expect( knex('os13015_apply').insert({ id: 'b', v: V, organization_id: null }), ).rejects.toThrow(/duplicate/i); - }); + }, 60_000); /** * The surviving generated column, isolated: drop the index by name (exactly @@ -335,7 +346,7 @@ declareDialectCell(MYSQL_CELL, 'shadow-carried index drift (#13015)', (cell) => await driver.initObjects([obj]); expect(await carriedUniquePresent('os13015_survive', indexName)).toBe(true); - }); + }, 60_000); /** * The direction a blind skip would have lost: a shadow hashing the RAW @@ -376,6 +387,6 @@ declareDialectCell(MYSQL_CELL, 'shadow-carried index drift (#13015)', (cell) => const after = await catalog('os13015_stale'); const fixed = after.cols.find((c: any) => c.COLUMN_NAME === shadow); expect(String(fixed.GENERATION_EXPRESSION).toLowerCase()).toContain('coalesce'); - }); + }, 60_000); }); }); diff --git a/packages/drivers/driver-sql/src/sql-driver-keyed-text-mysql.test.ts b/packages/drivers/driver-sql/src/sql-driver-keyed-text-mysql.test.ts index c6fc4b2083..bd13110b48 100644 --- a/packages/drivers/driver-sql/src/sql-driver-keyed-text-mysql.test.ts +++ b/packages/drivers/driver-sql/src/sql-driver-keyed-text-mysql.test.ts @@ -175,6 +175,17 @@ declareDialectCell(MYSQL_CELL, 'keyed text columns (#11374)', (cell) => { await driver?.disconnect().catch(() => {}); }); + // ── Why the 5 it() blocks below carry an explicit 60_000 budget (#13902) ── + // Each constructs a FRESH `new SqlDriver(...)` against this cell's live + // server inside their own body — so the live connect cycle, and the + // schema-sync DDL and catalog read-back that all but the cheapest of these + // drive through it, are paid PER TEST rather than once in a beforeAll. + // With no third argument vitest applies its own 5000ms default — a number + // nobody chose for that work, and one that reddens unrelated PRs when the + // runner is merely a bit slow (#13688 measured exactly this shape: a timeout, + // no MySQL error in the logs, on a diff that touched no driver). Sized like + // this package's siblings — 60_000 is 7 of its 9 explicit budgets — and NOT + // an assertion that these tests are normally anywhere near that slow. it('creates the declared indexes — the whole defect, in one assertion', async () => { driver = new SqlDriver(cell.config()); await driver.execute(`drop table if exists ${BOUNDED_TABLE}`).catch(() => {}); @@ -204,7 +215,7 @@ declareDialectCell(MYSQL_CELL, 'keyed text columns (#11374)', (cell) => { [BOUNDED_TABLE, 'uniq_os11374_bounded_slug'], )) as any[]; expect(subPart ?? null).toBeNull(); - }); + }, 60_000); it('refuses a NON-UNIQUE unkeyable column by name instead of weakening it', async () => { driver = new SqlDriver(cell.config()); @@ -223,7 +234,7 @@ declareDialectCell(MYSQL_CELL, 'keyed text columns (#11374)', (cell) => { // relax this — a hash shadow is offered only to a UNIQUE index, because // a digest serves no lookup an ordinary index exists to accelerate. expect(await indexNames(driver, UNBOUNDED_NONUNIQUE_TABLE)).toEqual([]); - }); + }, 60_000); it('gives a NON-UNIQUE bound past the key ceiling the same named refusal', async () => { driver = new SqlDriver(cell.config()); @@ -232,7 +243,7 @@ declareDialectCell(MYSQL_CELL, 'keyed text columns (#11374)', (cell) => { /cannot create index 'idx_os11374_too_wide_nonuniq_token'.*wider than 768 characters/s, ); expect(await indexNames(driver, TOO_WIDE_NONUNIQUE_TABLE)).toEqual([]); - }); + }, 60_000); /** * The UNIQUE half of the same two shapes, after #11627: expressible, and @@ -268,7 +279,7 @@ declareDialectCell(MYSQL_CELL, 'keyed text columns (#11374)', (cell) => { expect(Number(rows[0].NON_UNIQUE)).toBe(0); expect(String(rows[0].COLUMN_NAME)).toContain('__hash'); } - }); + }, 60_000); /** * The measurement that DISQUALIFIED the prefix-index route, kept executable @@ -317,7 +328,7 @@ declareDialectCell(MYSQL_CELL, 'keyed text columns (#11374)', (cell) => { `select count(*) as N from os11374_prefix`, )) as any[]; expect(Number(n)).toBe(1); - }); + }, 60_000); }); }); diff --git a/packages/drivers/driver-sql/src/sql-driver-string-maxlength-varchar.test.ts b/packages/drivers/driver-sql/src/sql-driver-string-maxlength-varchar.test.ts index 346754a464..646b0050a5 100644 --- a/packages/drivers/driver-sql/src/sql-driver-string-maxlength-varchar.test.ts +++ b/packages/drivers/driver-sql/src/sql-driver-string-maxlength-varchar.test.ts @@ -163,6 +163,17 @@ for (const cell of [MYSQL_CELL, PG_CELL]) { await driver?.disconnect().catch(() => {}); }); + // ── Why the 3 it() blocks below carry an explicit 60_000 budget (#13902) ── + // Each constructs a FRESH `new SqlDriver(...)` against this cell's live + // server inside their own body — so the live connect cycle, and the + // schema-sync DDL and catalog read-back that all but the cheapest of these + // drive through it, are paid PER TEST rather than once in a beforeAll. + // With no third argument vitest applies its own 5000ms default — a number + // nobody chose for that work, and one that reddens unrelated PRs when the + // runner is merely a bit slow (#13688 measured exactly this shape: a timeout, + // no MySQL error in the logs, on a diff that touched no driver). Sized like + // this package's siblings — 60_000 is 7 of its 9 explicit budgets — and NOT + // an assertion that these tests are normally anywhere near that slow. it('accepts a write the declaration allows — the whole defect, in one assertion', async () => { driver = new SqlDriver(c.config()); for (const t of [T, PARENT]) await driver.execute(`drop table if exists ${t}`).catch(() => {}); @@ -185,7 +196,7 @@ for (const cell of [MYSQL_CELL, PG_CELL]) { ); const rows: any[] = Array.isArray(res) && Array.isArray(res[0]) ? res[0] : (res?.rows ?? res); expect(Number(rows[0]?.n ?? rows[0]?.N)).toBe(300); - }); + }, 60_000); it('reports no varchar drift against a table it just created', async () => { driver = new SqlDriver(c.config()); @@ -225,7 +236,7 @@ for (const cell of [MYSQL_CELL, PG_CELL]) { // same predicate, which is the whole point of the fix. expect(varcharDrift.map((d) => d.column)).not.toContain('bogus_url'); expect(varcharDrift.map((d) => d.column)).not.toContain('fractional_url'); - }); + }, 60_000); it('still refuses a value past the DECLARED bound — the bound binds, it did not merely move', async () => { driver = new SqlDriver(c.config()); @@ -238,7 +249,7 @@ for (const cell of [MYSQL_CELL, PG_CELL]) { await expect( driver.create(T, { id: 'r2', narrow_phone: 'p'.repeat(300) }), ).rejects.toThrow(/too long|ER_DATA_TOO_LONG|22001/i); - }); + }, 60_000); }); }); }