From 914f313740c8156f55f0f07ed33246bf1fb1ad61 Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Fri, 29 May 2026 17:11:05 -0700 Subject: [PATCH] test(unit-fast): isolate fake-timer files (#88160) --- scripts/lib/ci-node-test-plan.mjs | 5 ++- scripts/test-projects.test-support.mjs | 15 ++++++- src/scripts/test-projects.test.ts | 15 +++++-- test/AGENTS.md | 3 ++ test/CLAUDE.md | 1 + test/scripts/ci-node-test-plan.test.ts | 5 ++- test/scripts/test-projects.test.ts | 14 +++++++ test/vitest-projects-config.test.ts | 9 +++++ test/vitest-unit-fast-config.test.ts | 28 ++++++++++++- test/vitest/vitest.config.ts | 1 + .../vitest.full-core-unit-fast.config.ts | 5 ++- test/vitest/vitest.shared.config.ts | 1 + test/vitest/vitest.test-shards.mjs | 5 ++- .../vitest.unit-fast-fake-timers.config.ts | 32 +++++++++++++++ test/vitest/vitest.unit-fast-paths.mjs | 39 +++++++++++++++++++ test/vitest/vitest.unit-fast.config.ts | 5 ++- 16 files changed, 171 insertions(+), 12 deletions(-) create mode 100644 test/AGENTS.md create mode 120000 test/CLAUDE.md create mode 100644 test/vitest/vitest.unit-fast-fake-timers.config.ts diff --git a/scripts/lib/ci-node-test-plan.mjs b/scripts/lib/ci-node-test-plan.mjs index d71d0e6e6a18..610fce5b4d0a 100644 --- a/scripts/lib/ci-node-test-plan.mjs +++ b/scripts/lib/ci-node-test-plan.mjs @@ -250,7 +250,10 @@ const SPLIT_NODE_SHARDS = new Map([ [ { shardName: "core-unit-fast", - configs: ["test/vitest/vitest.unit-fast.config.ts"], + configs: [ + "test/vitest/vitest.unit-fast.config.ts", + "test/vitest/vitest.unit-fast-fake-timers.config.ts", + ], requiresDist: false, }, ], diff --git a/scripts/test-projects.test-support.mjs b/scripts/test-projects.test-support.mjs index 9d48e13cdf17..3e8321aaf60a 100644 --- a/scripts/test-projects.test-support.mjs +++ b/scripts/test-projects.test-support.mjs @@ -37,7 +37,10 @@ import { } from "../test/vitest/vitest.plugin-sdk-paths.mjs"; import { fullSuiteVitestShards } from "../test/vitest/vitest.test-shards.mjs"; import { isUnitUiTestTarget } from "../test/vitest/vitest.ui-paths.mjs"; -import { resolveUnitFastTestIncludePattern } from "../test/vitest/vitest.unit-fast-paths.mjs"; +import { + resolveUnitFastTestIncludePattern, + resolveUnitFastTimerTestIncludePattern, +} from "../test/vitest/vitest.unit-fast-paths.mjs"; import { isBoundaryTestFile, isBundledPluginDependentUnitTestFile, @@ -127,6 +130,7 @@ const PLUGIN_SDK_LIGHT_VITEST_CONFIG = "test/vitest/vitest.plugin-sdk-light.conf const PLUGIN_SDK_VITEST_CONFIG = "test/vitest/vitest.plugin-sdk.config.ts"; const PLUGINS_VITEST_CONFIG = "test/vitest/vitest.plugins.config.ts"; const UNIT_FAST_VITEST_CONFIG = "test/vitest/vitest.unit-fast.config.ts"; +const UNIT_FAST_FAKE_TIMERS_VITEST_CONFIG = "test/vitest/vitest.unit-fast-fake-timers.config.ts"; const UNIT_SECURITY_VITEST_CONFIG = "test/vitest/vitest.unit-security.config.ts"; const UNIT_SRC_VITEST_CONFIG = "test/vitest/vitest.unit-src.config.ts"; const UNIT_SUPPORT_VITEST_CONFIG = "test/vitest/vitest.unit-support.config.ts"; @@ -320,6 +324,7 @@ const VITEST_CONFIG_BY_KIND = { pluginSdkLight: PLUGIN_SDK_LIGHT_VITEST_CONFIG, process: PROCESS_VITEST_CONFIG, unitFast: UNIT_FAST_VITEST_CONFIG, + unitFastFakeTimers: UNIT_FAST_FAKE_TIMERS_VITEST_CONFIG, unitSecurity: UNIT_SECURITY_VITEST_CONFIG, unitSrc: UNIT_SRC_VITEST_CONFIG, unitSupport: UNIT_SUPPORT_VITEST_CONFIG, @@ -1505,6 +1510,9 @@ function classifyTarget(arg, cwd) { if (relative.startsWith("src/plugins/contracts/")) { return "contractsPlugin"; } + if (resolveUnitFastTimerTestIncludePattern(relative)) { + return "unitFastFakeTimers"; + } if (resolveUnitFastTestIncludePattern(relative)) { return "unitFast"; } @@ -1684,6 +1692,10 @@ function resolveLightLaneIncludePatterns(kind, targetArg, cwd) { const includePattern = resolveUnitFastTestIncludePattern(relative); return includePattern ? [includePattern] : null; } + if (kind === "unitFastFakeTimers") { + const includePattern = resolveUnitFastTimerTestIncludePattern(relative); + return includePattern ? [includePattern] : null; + } if (kind === "pluginSdkLight") { const includePattern = resolvePluginSdkLightIncludePattern(relative); return includePattern ? [includePattern] : null; @@ -1804,6 +1816,7 @@ export function buildVitestRunPlans( const nonTargetArgs = activeForwardedArgs.filter((arg) => !activeTargetArgs.includes(arg)); const orderedKinds = [ "unitFast", + "unitFastFakeTimers", "default", "boundary", "toolingIsolated", diff --git a/src/scripts/test-projects.test.ts b/src/scripts/test-projects.test.ts index 3524a80e16fc..b2417b4cf969 100644 --- a/src/scripts/test-projects.test.ts +++ b/src/scripts/test-projects.test.ts @@ -113,9 +113,7 @@ const resolveExpectedVitestCliEntry = () => { return path.join(path.dirname(vitestPackageJson), "vitest.mjs"); }; const resolveExpectedVitestNodeArgs = (env: NodeJS.ProcessEnv) => - ["1", "true", "yes", "on"].includes( - env.OPENCLAW_VITEST_ENABLE_MAGLEV?.trim().toLowerCase() ?? "", - ) + ["1", "true", "yes", "on"].includes(env.OPENCLAW_VITEST_ENABLE_MAGLEV?.trim().toLowerCase() ?? "") ? [] : ["--no-maglev"]; const VITEST_NODE_PREFIX = [ @@ -287,6 +285,17 @@ describe("test-projects args", () => { ]); }); + it("routes fake-timer unit-fast targets to the serial fake-timer config", () => { + expect(buildVitestRunPlans(["src/acp/control-plane/manager.test.ts"])).toEqual([ + { + config: "test/vitest/vitest.unit-fast-fake-timers.config.ts", + forwardedArgs: [], + includePatterns: ["src/acp/control-plane/manager.test.ts"], + watchMode: false, + }, + ]); + }); + it("routes process targets to the process config", () => { expect(buildVitestRunPlans(["src/process/exec.test.ts"])).toEqual([ { diff --git a/test/AGENTS.md b/test/AGENTS.md new file mode 100644 index 000000000000..e656201c915a --- /dev/null +++ b/test/AGENTS.md @@ -0,0 +1,3 @@ +# Test Rules + +- Fake-timer tests in `unit-fast` belong in `vitest.unit-fast-fake-timers`: `unit-fast` is `isolate: false` and parallel, so fake timers share worker globals and can hang unrelated real-timer tests. diff --git a/test/CLAUDE.md b/test/CLAUDE.md new file mode 120000 index 000000000000..47dc3e3d863c --- /dev/null +++ b/test/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/test/scripts/ci-node-test-plan.test.ts b/test/scripts/ci-node-test-plan.test.ts index 8bf930e951de..be8fc9093f1f 100644 --- a/test/scripts/ci-node-test-plan.test.ts +++ b/test/scripts/ci-node-test-plan.test.ts @@ -117,7 +117,10 @@ describe("scripts/lib/ci-node-test-plan.mjs", () => { expect(coreUnitShards).toEqual([ { - configs: ["test/vitest/vitest.unit-fast.config.ts"], + configs: [ + "test/vitest/vitest.unit-fast.config.ts", + "test/vitest/vitest.unit-fast-fake-timers.config.ts", + ], requiresDist: false, shardName: "core-unit-fast", }, diff --git a/test/scripts/test-projects.test.ts b/test/scripts/test-projects.test.ts index c434c19d159e..e6269e9b4ad7 100644 --- a/test/scripts/test-projects.test.ts +++ b/test/scripts/test-projects.test.ts @@ -959,6 +959,19 @@ describe("scripts/test-projects changed-target routing", () => { ]); }); + it("routes fake-timer unit-fast tests to the serial fake-timer lane", () => { + const plans = buildVitestRunPlans(["src/acp/control-plane/manager.test.ts"], process.cwd()); + + expect(plans).toEqual([ + { + config: "test/vitest/vitest.unit-fast-fake-timers.config.ts", + forwardedArgs: [], + includePatterns: ["src/acp/control-plane/manager.test.ts"], + watchMode: false, + }, + ]); + }); + it("routes changed commands source allowlist files to sibling light tests", () => { const plans = buildVitestRunPlans(["--changed", "origin/main"], process.cwd(), () => [ "src/commands/status-overview-values.ts", @@ -1444,6 +1457,7 @@ describe("scripts/test-projects full-suite sharding", () => { } expect(leafShardPlans.map((plan) => plan.config)).toEqual([ "test/vitest/vitest.unit-fast.config.ts", + "test/vitest/vitest.unit-fast-fake-timers.config.ts", "test/vitest/vitest.unit-src.config.ts", "test/vitest/vitest.unit-security.config.ts", "test/vitest/vitest.unit-ui.config.ts", diff --git a/test/vitest-projects-config.test.ts b/test/vitest-projects-config.test.ts index c55776352cd3..a6b8e07d954d 100644 --- a/test/vitest-projects-config.test.ts +++ b/test/vitest-projects-config.test.ts @@ -28,6 +28,7 @@ import { import { fullSuiteVitestShards } from "./vitest/vitest.test-shards.mjs"; import { unitUiIncludePatterns } from "./vitest/vitest.ui-paths.mjs"; import { createUiVitestConfig } from "./vitest/vitest.ui.config.ts"; +import { createUnitFastFakeTimersVitestConfig } from "./vitest/vitest.unit-fast-fake-timers.config.ts"; import { createUnitFastVitestConfig } from "./vitest/vitest.unit-fast.config.ts"; import unitUiConfig from "./vitest/vitest.unit-ui.config.ts"; import { createUnitVitestConfig } from "./vitest/vitest.unit.config.ts"; @@ -225,6 +226,14 @@ describe("projects vitest config", () => { expect(config.test.runner).toBeUndefined(); }); + it("keeps fake-timer unit-fast files serial with the non-isolated runner", () => { + const config = createUnitFastFakeTimersVitestConfig(); + expect(config.test.isolate).toBe(false); + expect(normalizeConfigPath(config.test.runner)).toBe("test/non-isolated-runner.ts"); + expect(config.test.fileParallelism).toBe(false); + expect(config.test.maxWorkers).toBe(1); + }); + it("keeps the bundled lane on thread workers with the non-isolated runner", () => { const testConfig = requireTestConfig(bundledConfig); expect(testConfig.pool).toBe("threads"); diff --git a/test/vitest-unit-fast-config.test.ts b/test/vitest-unit-fast-config.test.ts index c806156511f5..a27bed028514 100644 --- a/test/vitest-unit-fast-config.test.ts +++ b/test/vitest-unit-fast-config.test.ts @@ -2,6 +2,7 @@ import { beforeAll, describe, expect, it } from "vitest"; import { spawnNodeEvalSync } from "../src/test-utils/node-process.js"; import { createCommandsLightVitestConfig } from "./vitest/vitest.commands-light.config.ts"; import { createPluginSdkLightVitestConfig } from "./vitest/vitest.plugin-sdk-light.config.ts"; +import { createUnitFastFakeTimersVitestConfig } from "./vitest/vitest.unit-fast-fake-timers.config.ts"; import { classifyUnitFastTestFileContent, collectBroadUnitFastTestCandidates, @@ -9,8 +10,11 @@ import { collectUnitFastTestFileAnalysis, forcedUnitFastTestFiles, getUnitFastTestFiles, + getUnitFastTimerTestFiles, isUnitFastTestFile, + isUnitFastTimerTestFile, resolveUnitFastTestIncludePattern, + resolveUnitFastTimerTestIncludePattern, } from "./vitest/vitest.unit-fast-paths.mjs"; import { createUnitFastVitestConfig } from "./vitest/vitest.unit-fast.config.ts"; @@ -53,6 +57,7 @@ describe("unit-fast vitest lane", () => { let configProbeResult: ReturnType; let unitFastConfig: ReturnType; let unitFastTestFiles: ReturnType; + let unitFastTimerTestFiles: ReturnType; let unitFastAnalysis: ReturnType; let broadCandidates: ReturnType; let broadAnalysis: ReturnType; @@ -77,6 +82,7 @@ describe("unit-fast vitest lane", () => { }); unitFastConfig = createUnitFastVitestConfig({}); unitFastTestFiles = getUnitFastTestFiles(); + unitFastTimerTestFiles = getUnitFastTimerTestFiles(); unitFastAnalysis = collectUnitFastTestFileAnalysis(); currentCandidates = collectUnitFastTestCandidates(); broadCandidates = collectBroadUnitFastTestCandidates(); @@ -106,7 +112,6 @@ describe("unit-fast vitest lane", () => { expect(testConfig.include).toContain("src/acp/control-plane/runtime-cache.test.ts"); expect(testConfig.include).toContain("src/acp/runtime/registry.test.ts"); expect(testConfig.include).toContain("src/commands/status-overview-values.test.ts"); - expect(testConfig.include).toContain("src/entry.respawn.test.ts"); expect(testConfig.include).toContain("src/entry.version-fast-path.test.ts"); expect(testConfig.include).toContain("src/flows/doctor-startup-channel-maintenance.test.ts"); expect(testConfig.include).toContain("src/crestodian/rescue-policy.test.ts"); @@ -127,7 +132,6 @@ describe("unit-fast vitest lane", () => { expect(testConfig.include).toContain("src/security/audit-gateway-tools-http.test.ts"); expect(testConfig.include).toContain("src/security/audit-plugin-readonly-scope.test.ts"); expect(testConfig.include).toContain("src/security/audit-loopback-logging.test.ts"); - expect(testConfig.include).toContain("src/security/audit-sandbox-browser.test.ts"); expect(testConfig.include).toContain("src/ui-app-settings.agents-files-refresh.test.ts"); expect(testConfig.include).toContain("src/video-generation/provider-registry.test.ts"); expect(testConfig.include).toContain("src/plugin-sdk/provider-entry.test.ts"); @@ -187,6 +191,26 @@ describe("unit-fast vitest lane", () => { expect(unroutedForcedFiles).toStrictEqual([]); }); + it("routes fake-timer unit-fast tests through the serial fake-timer lane", () => { + const fakeTimerFiles = unitFastAnalysis + .filter((entry) => entry.unitFast && entry.reasons.includes("fake-timers")) + .map((entry) => entry.file); + expect(unitFastTimerTestFiles.length).toBeGreaterThan(0); + expect(unitFastTimerTestFiles).toEqual(fakeTimerFiles); + for (const file of unitFastTimerTestFiles) { + expect(isUnitFastTimerTestFile(file)).toBe(true); + expect(resolveUnitFastTestIncludePattern(file)).toBeNull(); + expect(resolveUnitFastTimerTestIncludePattern(file)).toBe(file); + } + + const fastConfig = requireTestConfig(unitFastConfig); + const timerConfig = requireTestConfig(createUnitFastFakeTimersVitestConfig({})); + expect(fastConfig.include).not.toEqual(expect.arrayContaining(unitFastTimerTestFiles)); + expect(timerConfig.include).toEqual(unitFastTimerTestFiles); + expect(timerConfig.fileParallelism).toBe(false); + expect(timerConfig.maxWorkers).toBe(1); + }); + it("keeps broad audit candidates separate from automatically routed unit-fast tests", () => { expect(currentCandidates.length).toBeGreaterThanOrEqual(unitFastTestFiles.length); expect(broadCandidates.length).toBeGreaterThan(currentCandidates.length); diff --git a/test/vitest/vitest.config.ts b/test/vitest/vitest.config.ts index 8a434fee98f9..823aeff3f37d 100644 --- a/test/vitest/vitest.config.ts +++ b/test/vitest/vitest.config.ts @@ -39,6 +39,7 @@ export const rootVitestProjects = [ "test/vitest/vitest.daemon.config.ts", "test/vitest/vitest.media.config.ts", "test/vitest/vitest.unit-fast.config.ts", + "test/vitest/vitest.unit-fast-fake-timers.config.ts", "test/vitest/vitest.plugin-sdk-light.config.ts", "test/vitest/vitest.plugin-sdk.config.ts", "test/vitest/vitest.plugins.config.ts", diff --git a/test/vitest/vitest.full-core-unit-fast.config.ts b/test/vitest/vitest.full-core-unit-fast.config.ts index 74c74d9fe6ec..5a93ed430ec3 100644 --- a/test/vitest/vitest.full-core-unit-fast.config.ts +++ b/test/vitest/vitest.full-core-unit-fast.config.ts @@ -6,6 +6,9 @@ export default defineConfig({ test: { ...sharedVitestConfig.test, runner: undefined, - projects: ["test/vitest/vitest.unit-fast.config.ts"], + projects: [ + "test/vitest/vitest.unit-fast.config.ts", + "test/vitest/vitest.unit-fast-fake-timers.config.ts", + ], }, }); diff --git a/test/vitest/vitest.shared.config.ts b/test/vitest/vitest.shared.config.ts index 38acfec0aa92..a0b9ce5db059 100644 --- a/test/vitest/vitest.shared.config.ts +++ b/test/vitest/vitest.shared.config.ts @@ -341,6 +341,7 @@ export const sharedVitestConfig = { "test/vitest/vitest.media-understanding.config.ts", "test/vitest/vitest.performance-config.ts", "test/vitest/vitest.unit-fast.config.ts", + "test/vitest/vitest.unit-fast-fake-timers.config.ts", "test/vitest/vitest.unit-fast-paths.mjs", "test/vitest/vitest.scoped-config.ts", "test/vitest/vitest.shared-core.config.ts", diff --git a/test/vitest/vitest.test-shards.mjs b/test/vitest/vitest.test-shards.mjs index 63cdd6915dde..6002853183ed 100644 --- a/test/vitest/vitest.test-shards.mjs +++ b/test/vitest/vitest.test-shards.mjs @@ -10,7 +10,10 @@ export const fullSuiteVitestShards = [ { config: "test/vitest/vitest.full-core-unit-fast.config.ts", name: "core-unit-fast", - projects: ["test/vitest/vitest.unit-fast.config.ts"], + projects: [ + "test/vitest/vitest.unit-fast.config.ts", + "test/vitest/vitest.unit-fast-fake-timers.config.ts", + ], }, { config: "test/vitest/vitest.full-core-unit-src.config.ts", diff --git a/test/vitest/vitest.unit-fast-fake-timers.config.ts b/test/vitest/vitest.unit-fast-fake-timers.config.ts new file mode 100644 index 000000000000..0525b5e4ac73 --- /dev/null +++ b/test/vitest/vitest.unit-fast-fake-timers.config.ts @@ -0,0 +1,32 @@ +import { defineConfig } from "vitest/config"; +import { loadPatternListFromEnv, narrowIncludePatternsForCli } from "./vitest.pattern-file.ts"; +import { nonIsolatedRunnerPath, sharedVitestConfig } from "./vitest.shared.config.ts"; +import { getUnitFastTimerTestFiles } from "./vitest.unit-fast-paths.mjs"; + +export function createUnitFastFakeTimersVitestConfig( + env: Record = process.env, + options: { argv?: string[] } = {}, +) { + const sharedTest = sharedVitestConfig.test ?? {}; + const includeFromEnv = loadPatternListFromEnv("OPENCLAW_VITEST_INCLUDE_FILE", env); + const unitFastTimerTestFiles = getUnitFastTimerTestFiles(); + const cliInclude = narrowIncludePatternsForCli(unitFastTimerTestFiles, options.argv); + + return defineConfig({ + ...sharedVitestConfig, + test: { + ...sharedTest, + name: "unit-fast-fake-timers", + isolate: false, + runner: nonIsolatedRunnerPath, + setupFiles: [], + include: includeFromEnv ?? cliInclude ?? unitFastTimerTestFiles, + exclude: sharedTest.exclude ?? [], + maxWorkers: 1, + fileParallelism: false, + passWithNoTests: true, + }, + }); +} + +export default createUnitFastFakeTimersVitestConfig(); diff --git a/test/vitest/vitest.unit-fast-paths.mjs b/test/vitest/vitest.unit-fast-paths.mjs index 8998be8aa0a9..ee4145b8d6ac 100644 --- a/test/vitest/vitest.unit-fast-paths.mjs +++ b/test/vitest/vitest.unit-fast-paths.mjs @@ -425,6 +425,8 @@ export function collectUnitFastTestFileAnalysis(cwd = process.cwd(), options = { let cachedUnitFastTestFiles = null; let cachedUnitFastTestFileSet = null; +let cachedUnitFastTimerTestFiles = null; +let cachedUnitFastTimerTestFileSet = null; const cachedSingleUnitFastTestFileResults = new Map(); export function getUnitFastTestFiles() { @@ -437,6 +439,16 @@ export function getUnitFastTestFiles() { return cachedUnitFastTestFiles; } +export function getUnitFastTimerTestFiles() { + if (cachedUnitFastTimerTestFiles !== null) { + return cachedUnitFastTimerTestFiles; + } + cachedUnitFastTimerTestFiles = collectUnitFastTestFileAnalysis() + .filter((entry) => entry.unitFast && entry.reasons.includes("fake-timers")) + .map((entry) => entry.file); + return cachedUnitFastTimerTestFiles; +} + function getUnitFastTestFileSet() { if (cachedUnitFastTestFileSet !== null) { return cachedUnitFastTestFileSet; @@ -445,6 +457,14 @@ function getUnitFastTestFileSet() { return cachedUnitFastTestFileSet; } +function getUnitFastTimerTestFileSet() { + if (cachedUnitFastTimerTestFileSet !== null) { + return cachedUnitFastTimerTestFileSet; + } + cachedUnitFastTimerTestFileSet = new Set(getUnitFastTimerTestFiles()); + return cachedUnitFastTimerTestFileSet; +} + function isUnitFastTestFileOnDemand(file, cwd = process.cwd()) { const normalized = normalizeRepoPath(file); const cacheKey = `${normalizeRepoPath(cwd)}\0${normalized}`; @@ -476,12 +496,22 @@ export function isUnitFastTestFile(file) { return getUnitFastTestFileSet().has(normalizeRepoPath(file)); } +export function isUnitFastTimerTestFile(file) { + return getUnitFastTimerTestFileSet().has(normalizeRepoPath(file)); +} + export function resolveUnitFastTestIncludePattern(file) { const normalized = normalizeRepoPath(file); + if (isUnitFastTimerTestFile(normalized)) { + return null; + } if (isUnitFastTestFileOnDemand(normalized)) { return normalized; } const siblingTestFile = normalized.replace(/\.ts$/u, ".test.ts"); + if (isUnitFastTimerTestFile(siblingTestFile)) { + return null; + } if (isUnitFastTestFileOnDemand(siblingTestFile)) { return siblingTestFile; } @@ -491,3 +521,12 @@ export function resolveUnitFastTestIncludePattern(file) { } return null; } + +export function resolveUnitFastTimerTestIncludePattern(file) { + const normalized = normalizeRepoPath(file); + if (isUnitFastTimerTestFile(normalized)) { + return normalized; + } + const siblingTestFile = normalized.replace(/\.ts$/u, ".test.ts"); + return isUnitFastTimerTestFile(siblingTestFile) ? siblingTestFile : null; +} diff --git a/test/vitest/vitest.unit-fast.config.ts b/test/vitest/vitest.unit-fast.config.ts index 03bb126c56f9..41a133af45d7 100644 --- a/test/vitest/vitest.unit-fast.config.ts +++ b/test/vitest/vitest.unit-fast.config.ts @@ -1,7 +1,7 @@ import { defineConfig } from "vitest/config"; import { loadPatternListFromEnv, narrowIncludePatternsForCli } from "./vitest.pattern-file.ts"; import { sharedVitestConfig } from "./vitest.shared.config.ts"; -import { getUnitFastTestFiles } from "./vitest.unit-fast-paths.mjs"; +import { getUnitFastTestFiles, getUnitFastTimerTestFiles } from "./vitest.unit-fast-paths.mjs"; export function createUnitFastVitestConfig( env: Record = process.env, @@ -9,7 +9,8 @@ export function createUnitFastVitestConfig( ) { const sharedTest = sharedVitestConfig.test ?? {}; const includeFromEnv = loadPatternListFromEnv("OPENCLAW_VITEST_INCLUDE_FILE", env); - const unitFastTestFiles = getUnitFastTestFiles(); + const timerTestFiles = new Set(getUnitFastTimerTestFiles()); + const unitFastTestFiles = getUnitFastTestFiles().filter((file) => !timerTestFiles.has(file)); const cliInclude = narrowIncludePatternsForCli(unitFastTestFiles, options.argv); return defineConfig({