Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand All @@ -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);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 () => {
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -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)]);
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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.
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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);
});
});

Expand Down Expand Up @@ -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);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -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(() => {});
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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);
});
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -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')]);
Expand Down Expand Up @@ -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
Expand All @@ -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):
Expand Down Expand Up @@ -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
Expand All @@ -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);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -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,
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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);
});
});
Loading
Loading