diff --git a/src/tasks/task-registry.paths.test.ts b/src/tasks/task-registry.paths.test.ts new file mode 100644 index 00000000000..0aa97f3b0a7 --- /dev/null +++ b/src/tasks/task-registry.paths.test.ts @@ -0,0 +1,25 @@ +import os from "node:os"; +import path from "node:path"; +import { describe, expect, it } from "vitest"; +import { resolveTaskStateDir } from "./task-registry.paths.js"; + +describe("task registry paths", () => { + it("uses the Vitest worker id to shard test state dirs", () => { + expect( + resolveTaskStateDir({ + VITEST: "true", + VITEST_POOL_ID: "7", + } as NodeJS.ProcessEnv), + ).toBe(path.join(os.tmpdir(), "openclaw-test-state", `${process.pid}-7`)); + }); + + it("prefers explicit state dir overrides over Vitest sharding", () => { + expect( + resolveTaskStateDir({ + OPENCLAW_STATE_DIR: "/tmp/openclaw-custom-state", + VITEST: "true", + VITEST_POOL_ID: "7", + } as NodeJS.ProcessEnv), + ).toBe("/tmp/openclaw-custom-state"); + }); +}); diff --git a/src/tasks/task-registry.paths.ts b/src/tasks/task-registry.paths.ts index 35488f76b54..cb56130b89e 100644 --- a/src/tasks/task-registry.paths.ts +++ b/src/tasks/task-registry.paths.ts @@ -1,5 +1,6 @@ import os from "node:os"; import path from "node:path"; +import { isMainThread, threadId } from "node:worker_threads"; import { resolveStateDir } from "../config/paths.js"; export function resolveTaskStateDir(env: NodeJS.ProcessEnv = process.env): string { @@ -8,7 +9,14 @@ export function resolveTaskStateDir(env: NodeJS.ProcessEnv = process.env): strin return resolveStateDir(env); } if (env.VITEST || env.NODE_ENV === "test") { - return path.join(os.tmpdir(), "openclaw-test-state", String(process.pid)); + const workerIdRaw = env.VITEST_WORKER_ID ?? env.VITEST_POOL_ID ?? ""; + const workerId = Number.parseInt(workerIdRaw, 10); + const shardSuffix = Number.isFinite(workerId) + ? `${process.pid}-${workerId}` + : isMainThread + ? String(process.pid) + : `${process.pid}-${threadId}`; + return path.join(os.tmpdir(), "openclaw-test-state", shardSuffix); } return resolveStateDir(env); }