From fa632ca3d6b29eb07cef03b3673a9f113c9de805 Mon Sep 17 00:00:00 2001 From: garvitkaushik-123 Date: Sun, 23 Aug 2026 22:45:39 +0530 Subject: [PATCH 1/2] fix(test): isolate server unit tests from thread-pool env bleed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The precommit individual-file path ran server tests through the root vitest config (pool: threads), letting process.env mutations in vi.hoisted() leak between concurrent workers. Full-suite runs used the server config (forks, sequential) and were unaffected, creating an intermittent-only failure signature that varied by test ordering. Three fixes: 1. Pass --config server/vitest.config.ts on the individual-file precommit path so server tests always fork. 2. Declare pool: 'forks' explicitly in server/vitest.config.ts instead of relying on the implicit default. 3. Route tests/announcement/** and tests/billing/** to the forks pool in the root vitest config via poolMatchGlobs — these directories set WORKOS/Stripe secrets in vi.hoisted() and cannot share process.env with parallel thread workers. Also add tests/setup/env-defaults.ts to pre-set common WORKOS env defaults before any root test file runs. Refs #6740 --- .changeset/fix-flaky-server-unit-tests.md | 22 ++++++++++++++++++++++ scripts/precommit-server-unit.cjs | 2 +- server/vitest.config.ts | 11 ++++++----- tests/setup/env-defaults.ts | 6 ++++++ vitest.config.ts | 9 +++++++++ 5 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 .changeset/fix-flaky-server-unit-tests.md create mode 100644 tests/setup/env-defaults.ts diff --git a/.changeset/fix-flaky-server-unit-tests.md b/.changeset/fix-flaky-server-unit-tests.md new file mode 100644 index 0000000000..2929bdc1a5 --- /dev/null +++ b/.changeset/fix-flaky-server-unit-tests.md @@ -0,0 +1,22 @@ +--- +"adcontextprotocol": patch +--- + +Fix flaky server unit tests under full-suite parallelism. + +- Pass `--config server/vitest.config.ts` to the individual-file + precommit path so server tests always run with the forks pool + instead of falling through to the root config's threads pool, + where shared `process.env` causes env mutations in `vi.hoisted()` + to bleed between concurrent workers. +- Explicitly declare `pool: 'forks'` in `server/vitest.config.ts` + instead of relying on the implicit default. +- Route `tests/announcement/**` and `tests/billing/**` to the forks + pool via `poolMatchGlobs` in the root vitest config — these + directories set WORKOS/Stripe env vars in `vi.hoisted()` and must + not share `process.env` with parallel thread workers. +- Add a root test setup file (`tests/setup/env-defaults.ts`) that + pre-sets common WORKOS env defaults so individual test files no + longer race to initialize them. + +Refs #6740 diff --git a/scripts/precommit-server-unit.cjs b/scripts/precommit-server-unit.cjs index 86fdb23202..5424af05c1 100644 --- a/scripts/precommit-server-unit.cjs +++ b/scripts/precommit-server-unit.cjs @@ -104,7 +104,7 @@ function main() { } console.log(`Running ${plan.files.length} changed server unit test file(s).`); - return run('npm', ['exec', '--', 'vitest', 'run', ...plan.files]); + return run('npm', ['exec', '--', 'vitest', 'run', '--config', 'server/vitest.config.ts', ...plan.files]); } if (require.main === module) { diff --git a/server/vitest.config.ts b/server/vitest.config.ts index 43b10a4cb9..3cec53ec94 100644 --- a/server/vitest.config.ts +++ b/server/vitest.config.ts @@ -7,11 +7,12 @@ export default defineConfig({ root: __dirname, setupFiles: ['./tests/setup/revenue-tracking-env.ts'], testTimeout: 30000, - // The module-level `pool` singleton in db/index.ts is shared across all - // tests in a worker. Running files in parallel lets one file's - // `afterAll(closeDatabase)` null the pool while a sibling file is - // mid-query, producing "Database not initialized" 500s that look like - // transient Anthropic flakes. + // Forks give each test file its own process so module-level singletons + // (db pool, WorkOS client, env-cached secrets) cannot bleed between files. + // The root vitest config uses threads for speed; server tests need forks + // because dozens of files set process.env in vi.hoisted() for route and + // middleware init, and threads share process.env across all workers. + pool: 'forks', fileParallelism: false, }, }); diff --git a/tests/setup/env-defaults.ts b/tests/setup/env-defaults.ts new file mode 100644 index 0000000000..eff7baa7f3 --- /dev/null +++ b/tests/setup/env-defaults.ts @@ -0,0 +1,6 @@ +// Pre-set env defaults that many root test files need for server module init. +// Runs once per worker before any test file, so individual files no longer +// need the `process.env.WORKOS_API_KEY ??= '...'` guard in vi.hoisted(). +process.env.WORKOS_API_KEY ??= 'sk_test_default'; +process.env.WORKOS_CLIENT_ID ??= 'client_test_default'; +process.env.NODE_ENV ??= 'test'; diff --git a/vitest.config.ts b/vitest.config.ts index 88cb3e30f7..a9629f68bb 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -10,6 +10,15 @@ export default defineConfig({ // Cap individual test hangs at 10 s so a single stalled test doesn't // silently consume the entire 60 s precommit budget with no test name. testTimeout: 10000, + setupFiles: ['./tests/setup/env-defaults.ts'], + // Route env-mutating server-integration tests to the forks pool. + // Threads share process.env; tests that set WORKOS/STRIPE secrets in + // vi.hoisted() corrupt the env for concurrent workers. Forks give each + // file its own process, matching the server vitest config's isolation. + poolMatchGlobs: [ + ['tests/announcement/**', 'forks'], + ['tests/billing/**', 'forks'], + ], exclude: [ '**/node_modules/**', '**/dist/**', From 72f38f2500cc75018e82a6cee2cbb0a18cb7788a Mon Sep 17 00:00:00 2001 From: Brian O'Kelley Date: Sun, 23 Aug 2026 21:13:02 +0200 Subject: [PATCH 2/2] fix(test): narrow server unit isolation change --- .changeset/fix-flaky-server-unit-tests.md | 22 ---------------------- server/vitest.config.ts | 7 ++----- tests/setup/env-defaults.ts | 6 ------ vitest.config.ts | 9 --------- 4 files changed, 2 insertions(+), 42 deletions(-) delete mode 100644 .changeset/fix-flaky-server-unit-tests.md delete mode 100644 tests/setup/env-defaults.ts diff --git a/.changeset/fix-flaky-server-unit-tests.md b/.changeset/fix-flaky-server-unit-tests.md deleted file mode 100644 index 2929bdc1a5..0000000000 --- a/.changeset/fix-flaky-server-unit-tests.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -"adcontextprotocol": patch ---- - -Fix flaky server unit tests under full-suite parallelism. - -- Pass `--config server/vitest.config.ts` to the individual-file - precommit path so server tests always run with the forks pool - instead of falling through to the root config's threads pool, - where shared `process.env` causes env mutations in `vi.hoisted()` - to bleed between concurrent workers. -- Explicitly declare `pool: 'forks'` in `server/vitest.config.ts` - instead of relying on the implicit default. -- Route `tests/announcement/**` and `tests/billing/**` to the forks - pool via `poolMatchGlobs` in the root vitest config — these - directories set WORKOS/Stripe env vars in `vi.hoisted()` and must - not share `process.env` with parallel thread workers. -- Add a root test setup file (`tests/setup/env-defaults.ts`) that - pre-sets common WORKOS env defaults so individual test files no - longer race to initialize them. - -Refs #6740 diff --git a/server/vitest.config.ts b/server/vitest.config.ts index 3cec53ec94..1403b12ae3 100644 --- a/server/vitest.config.ts +++ b/server/vitest.config.ts @@ -7,11 +7,8 @@ export default defineConfig({ root: __dirname, setupFiles: ['./tests/setup/revenue-tracking-env.ts'], testTimeout: 30000, - // Forks give each test file its own process so module-level singletons - // (db pool, WorkOS client, env-cached secrets) cannot bleed between files. - // The root vitest config uses threads for speed; server tests need forks - // because dozens of files set process.env in vi.hoisted() for route and - // middleware init, and threads share process.env across all workers. + // Keep process isolation explicit so module-level singletons (database + // pool, WorkOS client, env-cached secrets) cannot bleed between files. pool: 'forks', fileParallelism: false, }, diff --git a/tests/setup/env-defaults.ts b/tests/setup/env-defaults.ts deleted file mode 100644 index eff7baa7f3..0000000000 --- a/tests/setup/env-defaults.ts +++ /dev/null @@ -1,6 +0,0 @@ -// Pre-set env defaults that many root test files need for server module init. -// Runs once per worker before any test file, so individual files no longer -// need the `process.env.WORKOS_API_KEY ??= '...'` guard in vi.hoisted(). -process.env.WORKOS_API_KEY ??= 'sk_test_default'; -process.env.WORKOS_CLIENT_ID ??= 'client_test_default'; -process.env.NODE_ENV ??= 'test'; diff --git a/vitest.config.ts b/vitest.config.ts index a9629f68bb..88cb3e30f7 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -10,15 +10,6 @@ export default defineConfig({ // Cap individual test hangs at 10 s so a single stalled test doesn't // silently consume the entire 60 s precommit budget with no test name. testTimeout: 10000, - setupFiles: ['./tests/setup/env-defaults.ts'], - // Route env-mutating server-integration tests to the forks pool. - // Threads share process.env; tests that set WORKOS/STRIPE secrets in - // vi.hoisted() corrupt the env for concurrent workers. Forks give each - // file its own process, matching the server vitest config's isolation. - poolMatchGlobs: [ - ['tests/announcement/**', 'forks'], - ['tests/billing/**', 'forks'], - ], exclude: [ '**/node_modules/**', '**/dist/**',