From b62b4b0e30c5d55ef0bb279d0f87fa3a79b3be19 Mon Sep 17 00:00:00 2001 From: Phil Larson Date: Thu, 25 Jun 2026 11:16:16 -0700 Subject: [PATCH] fix(FN-798): scope engine vitest fork pool Fusion-Task-Id: FN-798 --- packages/engine/vitest.config.ts | 13 ++++++---- .../engine-vitest-gate-policy.test.mjs | 25 ++++++++++++++++--- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/packages/engine/vitest.config.ts b/packages/engine/vitest.config.ts index 6210d621af..c084507b47 100644 --- a/packages/engine/vitest.config.ts +++ b/packages/engine/vitest.config.ts @@ -19,11 +19,9 @@ export default defineConfig({ resolve(__dirname, "../core/src/__test-utils__/vitest-setup.ts"), ], globalSetup: [resolve(__dirname, "../core/src/__test-utils__/vitest-teardown.ts")], - // Node 24.15.0 on macOS aborts in libuv kqueue when Vitest's - // worker-thread pool closes unmanaged file descriptors during this gate. - // Fork workers preserve real failure semantics while avoiding the raw - // SIGABRT/warning flood; keep worker counts bounded below. - pool: "forks", + // Keep the broad engine lanes on worker threads; engine-core overrides this + // below because only the curated merge gate has hit the Node/macOS abort. + pool: "threads", maxWorkers, minWorkers: 1, fileParallelism: true, @@ -56,6 +54,11 @@ export default defineConfig({ extends: true, test: { name: "engine-core", + /* + FNXC:EngineTests 2026-06-25-11:11: + The curated engine-core merge gate hits a Node 24.15.0/macOS libuv kqueue SIGABRT when Vitest thread workers close unmanaged file descriptors. Scope fork workers to this gate so the broad default engine suite keeps its explicit worker-thread behavior. + */ + pool: "forks", // The curated merge-gate suite (see docs/testing.md "Merge gate"). // Membership is an explicit allow-list, NOT a glob: tests earn their // way in with evidence of value, and a flaky gate test is evicted by diff --git a/scripts/__tests__/engine-vitest-gate-policy.test.mjs b/scripts/__tests__/engine-vitest-gate-policy.test.mjs index 6e7e3a792d..9a544da03c 100644 --- a/scripts/__tests__/engine-vitest-gate-policy.test.mjs +++ b/scripts/__tests__/engine-vitest-gate-policy.test.mjs @@ -16,13 +16,32 @@ function readJson(relativePath) { return JSON.parse(read(relativePath)); } -test("engine-core gate keeps a Node 24/macOS-safe Vitest pool without hiding warnings", () => { +test("engine-core gate keeps a Node 24/macOS-safe Vitest pool without changing broad engine lanes", () => { const config = read("packages/engine/vitest.config.ts"); + const projectsIndex = config.indexOf("projects:"); + const rootTestConfig = projectsIndex === -1 ? config : config.slice(0, projectsIndex); + const engineCoreBlock = config.match(/name:\s*"engine-core"[\s\S]*?include:\s*\[/)?.[0] ?? ""; + const engineDefaultBlock = config.match(/name:\s*"engine-default"[\s\S]*?include:\s*\[/)?.[0] ?? ""; assert.match( - config, + engineCoreBlock, /pool:\s*"forks"/, - "engine Vitest must use fork workers; thread workers abort with Node 24/macOS libuv kqueue", + "engine-core must use fork workers; thread workers abort with Node 24/macOS libuv kqueue", + ); + assert.doesNotMatch( + rootTestConfig, + /pool:\s*"forks"/, + "fork workers must not be configured at root scope because that slows the broad engine-default lane", + ); + assert.match( + rootTestConfig, + /pool:\s*"threads"/, + "root engine config must explicitly keep broad lanes on threads because Vitest 4 defaults to forks", + ); + assert.doesNotMatch( + engineDefaultBlock, + /pool:\s*"forks"/, + "engine-default must keep inheriting Vitest's default thread pool for broad src/**/*.test.ts runs", ); assert.doesNotMatch( config,