From 1f23066f4713caff7f8633c3b56ecf24c4bf3aa5 Mon Sep 17 00:00:00 2001 From: davidmonterocrespo24 Date: Tue, 19 May 2026 18:09:34 +0200 Subject: [PATCH] fix(tests): migrate forks config to vitest-4 top-level + restore NODE_OPTIONS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two issues in PR #200 became obvious from the next CI run: 1. **`poolOptions.forks.execArgv` had no effect.** Vitest 4 removed `test.poolOptions` entirely — every key under it moved to top-level `test.*`. The runner emits this banner on every run: DEPRECATED `test.poolOptions` was removed in Vitest 4. All previous poolOptions are now top-level options. So `test.poolOptions.forks.execArgv: ['--max-old-space-size=8192']` was silently ignored. Move it to `test.forks.execArgv` (and `test.forks.singleFork`). 2. **NODE_OPTIONS got dropped when the shard step was rewritten.** PR #199 added `env: NODE_OPTIONS: --max-old-space-size=8192` to the `npm test` step; PR #200 replaced the step with `npx vitest run --shard X/2` but did not carry the env-var across. Combined with #1, the workers reverted to Node's 4 GB default and shard 2 (58 files) still OOMs at exactly 4128 MB heap. Restore NODE_OPTIONS on the workflow step as belt-and-braces — it gets honored by the parent vitest process, and the migrated config covers the forked children. With 8 GB heap × 2 shards × 58 files each, the cumulative state from ngspice WASM + singletons fits comfortably and the suite should exit cleanly. --- .github/workflows/frontend-tests.yml | 15 ++++++++++----- frontend/vitest.config.ts | 27 +++++++++++++-------------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/.github/workflows/frontend-tests.yml b/.github/workflows/frontend-tests.yml index ff481c6d..c3fb5c09 100644 --- a/.github/workflows/frontend-tests.yml +++ b/.github/workflows/frontend-tests.yml @@ -77,11 +77,16 @@ jobs: - name: Run tests (shard ${{ matrix.shard }}/2) run: cd frontend && npx vitest run --shard ${{ matrix.shard }}/2 - # Heap is also raised inside the vitest config via - # poolOptions.forks.execArgv — forks pool ignores - # NODE_OPTIONS. With sharding each runner only carries - # ~60 test files' worth of leaked WASM/singleton state - # so the heap stays well under the ceiling. + env: + # Belt-and-braces heap raise. The same flag is also set in + # vitest.config.ts under `forks.execArgv`, but that path was + # under the now-removed `poolOptions.forks` until the latest + # commit, and we want the workflow not to depend on the + # exact vitest config shape to keep CI green during the + # vitest 4 migration. NODE_OPTIONS gets picked up by the + # parent vitest process; the forks themselves rely on the + # config. + NODE_OPTIONS: --max-old-space-size=8192 # Production build smoke — catches Vite/Rollup-only failures that # vitest doesn't see (chunk wiring, dynamic imports, manualChunks diff --git a/frontend/vitest.config.ts b/frontend/vitest.config.ts index e9f217de..f148e41a 100644 --- a/frontend/vitest.config.ts +++ b/frontend/vitest.config.ts @@ -23,20 +23,19 @@ export default defineConfig({ include: ['src/__tests__/**/*.test.ts'], testTimeout: 30_000, hookTimeout: 30_000, - poolOptions: { - forks: { - singleFork: false, - // Vitest 4's forks pool spawns workers with its own execArgv - // and does NOT inherit NODE_OPTIONS from the parent shell, so - // raising `--max-old-space-size` via the GHA env-var has no - // effect on the actual worker process. The full suite leaks - // ngspice WASM modules + singleton state across 117 files and - // hits Node's 4 GB default at the end of the run ("Worker - // exited unexpectedly / Ineffective mark-compacts near heap - // limit"). Bump to 8 GB at the pool level so it actually - // takes effect. - execArgv: ['--max-old-space-size=8192'], - }, + // Vitest 4 removed `test.poolOptions` — config moved to top-level + // `forks` / `threads` / etc. See the deprecation banner the runner + // emits: "DEPRECATED test.poolOptions was removed in Vitest 4. All + // previous poolOptions are now top-level options." + // + // Each forked worker also needs its heap cap raised because the + // suite leaks state across the 117 test files (ngspice WASM ~30 MB + // per init, MixedModeScheduler singleton, zustand stores). Even + // sharded (60 files / shard) the leak overflows Node's 4 GB + // default; 8 GB plus sharding fits the runner's 16 GB budget. + forks: { + singleFork: false, + execArgv: ['--max-old-space-size=8192'], }, coverage: { provider: 'v8',