From 9d315cdf428cee2790a28a2c8039583bdd5666ed Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 5 Apr 2026 10:10:57 +0100 Subject: [PATCH] test: default vitest lanes to isolated forks --- ...dels-config.providers.openai-codex.test.ts | 6 ++-- test/vitest-boundary-config.test.ts | 6 ++-- test/vitest-projects-config.test.ts | 36 +++++++++---------- test/vitest-scoped-config.test.ts | 36 +++++++++---------- test/vitest-ui-package-config.test.ts | 20 +++++------ test/vitest-unit-config.test.ts | 6 ++-- ui/vitest.config.ts | 3 +- ui/vitest.node.config.ts | 3 +- vitest.boundary.config.ts | 4 --- vitest.scoped-config.ts | 4 +-- vitest.shared.config.ts | 7 ++-- 11 files changed, 62 insertions(+), 69 deletions(-) diff --git a/src/agents/models-config.providers.openai-codex.test.ts b/src/agents/models-config.providers.openai-codex.test.ts index 89add15433a..b7d8fa11e6e 100644 --- a/src/agents/models-config.providers.openai-codex.test.ts +++ b/src/agents/models-config.providers.openai-codex.test.ts @@ -61,7 +61,7 @@ describe("openai-codex implicit provider", () => { }); }); - it("replaces stale openai-codex baseUrl in generated models.json", async () => { + it("keeps generated openai-codex rows on the generic OpenAI responses transport", async () => { await withModelsTempHome(async () => { await withTempEnv(MODELS_CONFIG_IMPLICIT_ENV_VARS, async () => { unsetEnv(MODELS_CONFIG_IMPLICIT_ENV_VARS); @@ -99,8 +99,8 @@ describe("openai-codex implicit provider", () => { providers: Record; }>(); expect(parsed.providers["openai-codex"]).toMatchObject({ - baseUrl: "https://chatgpt.com/backend-api", - api: "openai-codex-responses", + baseUrl: "https://api.openai.com/v1", + api: "openai-responses", }); }); }); diff --git a/test/vitest-boundary-config.test.ts b/test/vitest-boundary-config.test.ts index fe3f8c54dcb..a65fb248066 100644 --- a/test/vitest-boundary-config.test.ts +++ b/test/vitest-boundary-config.test.ts @@ -12,11 +12,11 @@ describe("loadBoundaryIncludePatternsFromEnv", () => { }); describe("boundary vitest config", () => { - it("keeps boundary suites on the shared runner with shared test bootstrap", () => { + it("keeps boundary suites isolated with shared test bootstrap", () => { const config = createBoundaryVitestConfig({}); - expect(config.test?.isolate).toBe(false); - expect(config.test?.runner).toBe("./test/non-isolated-runner.ts"); + expect(config.test?.isolate).toBe(true); + expect(config.test?.runner).toBeUndefined(); expect(config.test?.include).toEqual(boundaryTestFiles); expect(config.test?.setupFiles).toEqual(["test/setup.ts"]); }); diff --git a/test/vitest-projects-config.test.ts b/test/vitest-projects-config.test.ts index cb1af1c1258..885ce2dfa77 100644 --- a/test/vitest-projects-config.test.ts +++ b/test/vitest-projects-config.test.ts @@ -13,38 +13,38 @@ describe("projects vitest config", () => { expect(baseConfig.test?.projects).toEqual([...rootVitestProjects]); }); - it("keeps every root project on thread workers", () => { - expect(createGatewayVitestConfig().test.pool).toBe("threads"); - expect(createAgentsVitestConfig().test.pool).toBe("threads"); - expect(createCommandsVitestConfig().test.pool).toBe("threads"); - expect(createContractsVitestConfig().test.pool).toBe("threads"); + it("keeps every root project on fork workers", () => { + expect(createGatewayVitestConfig().test.pool).toBe("forks"); + expect(createAgentsVitestConfig().test.pool).toBe("forks"); + expect(createCommandsVitestConfig().test.pool).toBe("forks"); + expect(createContractsVitestConfig().test.pool).toBe("forks"); }); - it("keeps the contracts lane on the shared non-isolated runner", () => { + it("keeps the contracts lane isolated by default", () => { const config = createContractsVitestConfig(); - expect(config.test.isolate).toBe(false); - expect(config.test.runner).toBe("./test/non-isolated-runner.ts"); + expect(config.test.isolate).toBe(true); + expect(config.test.runner).toBeUndefined(); }); - it("keeps the root ui lane aligned with the shared non-isolated jsdom setup", () => { + it("keeps the root ui lane aligned with the isolated jsdom setup", () => { const config = createUiVitestConfig(); expect(config.test.environment).toBe("jsdom"); - expect(config.test.isolate).toBe(false); - expect(config.test.runner).toBe("./test/non-isolated-runner.ts"); + expect(config.test.isolate).toBe(true); + expect(config.test.runner).toBeUndefined(); expect(config.test.setupFiles).not.toContain("test/setup-openclaw-runtime.ts"); expect(config.test.setupFiles).toContain("ui/src/test-helpers/lit-warnings.setup.ts"); expect(config.test.deps?.optimizer?.web?.enabled).toBe(true); }); - it("keeps the unit lane on the shared non-isolated runner", () => { + it("keeps the unit lane isolated by default", () => { const config = createUnitVitestConfig(); - expect(config.test.isolate).toBe(false); - expect(config.test.runner).toBe("./test/non-isolated-runner.ts"); + expect(config.test.isolate).toBe(true); + expect(config.test.runner).toBeUndefined(); }); - it("keeps the bundled lane on the shared non-isolated runner", () => { - expect(bundledConfig.test?.pool).toBe("threads"); - expect(bundledConfig.test?.isolate).toBe(false); - expect(bundledConfig.test?.runner).toBe("./test/non-isolated-runner.ts"); + it("keeps the bundled lane isolated on fork workers", () => { + expect(bundledConfig.test?.pool).toBe("forks"); + expect(bundledConfig.test?.isolate).toBe(true); + expect(bundledConfig.test?.runner).toBeUndefined(); }); }); diff --git a/test/vitest-scoped-config.test.ts b/test/vitest-scoped-config.test.ts index 8265fe7f27e..169d990450c 100644 --- a/test/vitest-scoped-config.test.ts +++ b/test/vitest-scoped-config.test.ts @@ -51,22 +51,22 @@ import { BUNDLED_PLUGIN_TEST_GLOB, bundledPluginFile } from "./helpers/bundled-p const EXTENSIONS_CHANNEL_GLOB = ["extensions", "channel", "**"].join("/"); describe("resolveVitestIsolation", () => { - it("defaults shared scoped configs to non-isolated workers", () => { - expect(resolveVitestIsolation({})).toBe(false); + it("defaults shared scoped configs to isolated workers", () => { + expect(resolveVitestIsolation({})).toBe(true); }); it("ignores the legacy isolation escape hatches", () => { - expect(resolveVitestIsolation({ OPENCLAW_TEST_ISOLATE: "1" })).toBe(false); - expect(resolveVitestIsolation({ OPENCLAW_TEST_NO_ISOLATE: "0" })).toBe(false); - expect(resolveVitestIsolation({ OPENCLAW_TEST_NO_ISOLATE: "false" })).toBe(false); + expect(resolveVitestIsolation({ OPENCLAW_TEST_ISOLATE: "1" })).toBe(true); + expect(resolveVitestIsolation({ OPENCLAW_TEST_NO_ISOLATE: "0" })).toBe(true); + expect(resolveVitestIsolation({ OPENCLAW_TEST_NO_ISOLATE: "false" })).toBe(true); }); }); describe("createScopedVitestConfig", () => { - it("applies non-isolated mode by default", () => { + it("applies isolated mode by default", () => { const config = createScopedVitestConfig(["src/example.test.ts"], { env: {} }); - expect(config.test?.isolate).toBe(false); - expect(config.test?.runner).toBe("./test/non-isolated-runner.ts"); + expect(config.test?.isolate).toBe(true); + expect(config.test?.runner).toBeUndefined(); expect(config.test?.setupFiles).toEqual(["test/setup.ts", "test/setup-openclaw-runtime.ts"]); }); @@ -160,7 +160,7 @@ describe("scoped vitest configs", () => { const defaultUtilsConfig = createUtilsVitestConfig({}); const defaultWizardConfig = createWizardVitestConfig({}); - it("keeps every scoped lane on thread workers with the non-isolated runner", () => { + it("keeps every scoped lane on fork workers with isolation enabled", () => { for (const config of [ defaultChannelsConfig, defaultAcpConfig, @@ -175,15 +175,15 @@ describe("scoped vitest configs", () => { defaultToolingConfig, defaultUiConfig, ]) { - expect(config.test?.pool).toBe("threads"); - expect(config.test?.isolate).toBe(false); - expect(config.test?.runner).toBe("./test/non-isolated-runner.ts"); + expect(config.test?.pool).toBe("forks"); + expect(config.test?.isolate).toBe(true); + expect(config.test?.runner).toBeUndefined(); } }); - it("defaults channel tests to non-isolated mode", () => { - expect(defaultChannelsConfig.test?.isolate).toBe(false); - expect(defaultChannelsConfig.test?.pool).toBe("threads"); + it("defaults channel tests to isolated fork mode", () => { + expect(defaultChannelsConfig.test?.isolate).toBe(true); + expect(defaultChannelsConfig.test?.pool).toBe("forks"); }); it("keeps the core channel lane limited to non-extension roots", () => { @@ -217,9 +217,9 @@ describe("scoped vitest configs", () => { } }); - it("defaults extension tests to non-isolated mode", () => { - expect(defaultExtensionsConfig.test?.isolate).toBe(false); - expect(defaultExtensionsConfig.test?.pool).toBe("threads"); + it("defaults extension tests to isolated fork mode", () => { + expect(defaultExtensionsConfig.test?.isolate).toBe(true); + expect(defaultExtensionsConfig.test?.pool).toBe("forks"); }); it("normalizes extension channel include patterns relative to the scoped dir", () => { diff --git a/test/vitest-ui-package-config.test.ts b/test/vitest-ui-package-config.test.ts index efe7ee1939c..a26d94049b6 100644 --- a/test/vitest-ui-package-config.test.ts +++ b/test/vitest-ui-package-config.test.ts @@ -3,21 +3,21 @@ import uiConfig from "../ui/vitest.config.ts"; import uiNodeConfig from "../ui/vitest.node.config.ts"; describe("ui package vitest config", () => { - it("keeps the standalone ui package on threads and isolate=false", () => { - expect(uiConfig.test?.pool).toBe("threads"); - expect(uiConfig.test?.isolate).toBe(false); + it("keeps the standalone ui package on forks with isolation enabled", () => { + expect(uiConfig.test?.pool).toBe("forks"); + expect(uiConfig.test?.isolate).toBe(true); expect(uiConfig.test?.projects).toHaveLength(3); for (const project of uiConfig.test?.projects ?? []) { - expect(project.test?.pool).toBe("threads"); - expect(project.test?.isolate).toBe(false); - expect(project.test?.runner).toBe("../test/non-isolated-runner.ts"); + expect(project.test?.pool).toBe("forks"); + expect(project.test?.isolate).toBe(true); + expect(project.test?.runner).toBeUndefined(); } }); - it("keeps the standalone ui node config on threads and isolate=false", () => { - expect(uiNodeConfig.test?.pool).toBe("threads"); - expect(uiNodeConfig.test?.isolate).toBe(false); - expect(uiNodeConfig.test?.runner).toBe("../test/non-isolated-runner.ts"); + it("keeps the standalone ui node config on forks with isolation enabled", () => { + expect(uiNodeConfig.test?.pool).toBe("forks"); + expect(uiNodeConfig.test?.isolate).toBe(true); + expect(uiNodeConfig.test?.runner).toBeUndefined(); }); }); diff --git a/test/vitest-unit-config.test.ts b/test/vitest-unit-config.test.ts index 15ddb3ac8b6..a0d3d8ddfd5 100644 --- a/test/vitest-unit-config.test.ts +++ b/test/vitest-unit-config.test.ts @@ -68,10 +68,10 @@ describe("loadExtraExcludePatternsFromEnv", () => { }); describe("unit vitest config", () => { - it("defaults unit tests to non-isolated mode", () => { + it("defaults unit tests to isolated mode", () => { const unitConfig = createUnitVitestConfig({}); - expect(unitConfig.test?.isolate).toBe(false); - expect(unitConfig.test?.runner).toBe("./test/non-isolated-runner.ts"); + expect(unitConfig.test?.isolate).toBe(true); + expect(unitConfig.test?.runner).toBeUndefined(); }); it("keeps acp and ui tests out of the generic unit lane", () => { diff --git a/ui/vitest.config.ts b/ui/vitest.config.ts index 326a6357d7c..cab975b255a 100644 --- a/ui/vitest.config.ts +++ b/ui/vitest.config.ts @@ -3,9 +3,8 @@ import { defineConfig, defineProject } from "vitest/config"; import { jsdomOptimizedDeps, resolveDefaultVitestPool } from "../vitest.shared.config.ts"; const sharedUiTestConfig = { - isolate: false, + isolate: true, pool: resolveDefaultVitestPool(), - runner: "../test/non-isolated-runner.ts", } as const; export default defineConfig({ diff --git a/ui/vitest.node.config.ts b/ui/vitest.node.config.ts index bf3e63aa370..bf379186ec9 100644 --- a/ui/vitest.node.config.ts +++ b/ui/vitest.node.config.ts @@ -4,9 +4,8 @@ import { resolveDefaultVitestPool } from "../vitest.shared.config.ts"; // Node-only tests for pure logic (no Playwright/browser dependency). export default defineConfig({ test: { - isolate: false, + isolate: true, pool: resolveDefaultVitestPool(), - runner: "../test/non-isolated-runner.ts", testTimeout: 120_000, include: ["src/**/*.node.test.ts"], environment: "node", diff --git a/vitest.boundary.config.ts b/vitest.boundary.config.ts index f3afb4829b4..d25880db340 100644 --- a/vitest.boundary.config.ts +++ b/vitest.boundary.config.ts @@ -19,12 +19,8 @@ export function createBoundaryVitestConfig( test: { ...sharedVitestConfig.test, name: "boundary", - isolate: false, - runner: "./test/non-isolated-runner.ts", include: loadBoundaryIncludePatternsFromEnv(env) ?? cliIncludePatterns ?? boundaryTestFiles, ...(cliIncludePatterns !== null ? { passWithNoTests: true } : {}), - // Boundary workers still need the shared isolated HOME/bootstrap. Only - // per-file module isolation is disabled here. setupFiles: sharedVitestConfig.test.setupFiles, }, }); diff --git a/vitest.scoped-config.ts b/vitest.scoped-config.ts index 2b3c348fb6b..ddb4472576b 100644 --- a/vitest.scoped-config.ts +++ b/vitest.scoped-config.ts @@ -31,7 +31,7 @@ function relativizeScopedPatterns(values: string[], dir?: string): string[] { export function resolveVitestIsolation( _env: Record = process.env, ): boolean { - return false; + return true; } export function createScopedVitestConfig( @@ -46,7 +46,7 @@ export function createScopedVitestConfig( includeOpenClawRuntimeSetup?: boolean; isolate?: boolean; name?: string; - pool?: "threads"; + pool?: "forks" | "threads"; passWithNoTests?: boolean; setupFiles?: string[]; useNonIsolatedRunner?: boolean; diff --git a/vitest.shared.config.ts b/vitest.shared.config.ts index e64fb779523..7dee0d4661e 100644 --- a/vitest.shared.config.ts +++ b/vitest.shared.config.ts @@ -31,7 +31,7 @@ type VitestHostInfo = { totalMemoryBytes?: number; }; -export type OpenClawVitestPool = "threads"; +export type OpenClawVitestPool = "forks" | "threads"; export type LocalVitestScheduling = { maxWorkers: number; @@ -167,7 +167,7 @@ export function resolveLocalVitestScheduling( export function resolveDefaultVitestPool( _env: Record = process.env, ): OpenClawVitestPool { - return "threads"; + return "forks"; } const repoRoot = path.dirname(fileURLToPath(import.meta.url)); @@ -211,9 +211,8 @@ export const sharedVitestConfig = { hookTimeout: isWindows ? 180_000 : 120_000, unstubEnvs: true, unstubGlobals: true, - isolate: false, + isolate: true, pool: defaultPool, - runner: "./test/non-isolated-runner.ts", maxWorkers: isCI ? ciWorkers : localScheduling.maxWorkers, fileParallelism: isCI ? true : localScheduling.fileParallelism, forceRerunTriggers: [