From 2d838857d55021e14718dee8bd813fbb0f64c4ed Mon Sep 17 00:00:00 2001 From: Toan Hoang Minh Date: Fri, 31 Jul 2026 15:15:11 +0700 Subject: [PATCH] fix: serialize test file execution to avoid cross-file DB races Each test file gets its own throwaway Postgres database by mutating process.env.DATABASE_URL in tests/setup.ts's beforeAll. That per-file DB switch is not safe under Vitest's default parallel file execution: timing between two files' beforeAll/query calls can interleave enough that both end up issuing real queries against the same throwaway DB. This was invisible before because no two test files shared tables with a real FK between them. It became visible once Request gained a real FK to Employee: tests/employees.test.ts and tests/requests.test.ts started intermittently deleting/reading each other's rows (FK violations on deleteMany, wrong row counts), reproducible on every run. Setting fileParallelism: false makes each file run to completion before the next starts, so the per-file throwaway DB is genuinely private. Confirmed: 31/31 tests pass reliably under plain npm test (previously reproducibly 4 failing). --- vitest.config.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/vitest.config.ts b/vitest.config.ts index ad09a1b..c30412e 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -10,5 +10,18 @@ export default defineConfig({ test: { environment: "node", setupFiles: ["./tests/setup.ts"], + // Each test file spins up its own throwaway Postgres database by + // mutating process.env.DATABASE_URL in tests/setup.ts's beforeAll (see + // that file). That per-file DB switch is not safe under Vitest's default + // parallel file execution: two files' beforeAll/query timing can + // interleave such that both end up issuing real queries against the + // same throwaway DB (confirmed empirically once Request gained a real + // FK to Employee — tests/employees.test.ts and tests/requests.test.ts + // started intermittently deleting/reading each other's rows, causing + // spurious FK-violation and row-count failures that disappear when run + // sequentially). Disabling file parallelism trades a bit of wall-clock + // test time for correctness — each file's throwaway DB is now genuinely + // private for the duration of that file's run. + fileParallelism: false, }, });