Skip to content

Commit 013e121

Browse files
xialongleeclaude
andcommitted
test: migrate leaky raw mkdtemp calls to createSuiteTempRootTracker()
Gap finding: tempdir-8h9i0j1k, tempdir-9i0j1k2l Replace bare fs.mkdtemp/mkdtempSync calls in 4 test files with the shared createSuiteTempRootTracker() helper, adding proper cleanup where none existed. Background: the project has standardized on shared temp dir helpers since 88b87d8 (withTempDir) -> 13df67e (createSuiteTempRootTracker) -> 06431fd / #87298 (CI guard + docs guidance). This PR continues that migration for the highest-risk files. Files changed: - src/skills/lifecycle/install-fallback.test.ts: variable overwrite risk - src/auto-reply/reply/session-hooks-context.test.ts: helper leaks temp dirs - src/auto-reply/reply/abort.test.ts: createAbortConfig leaks root dir - src/auto-reply/inbound.test.ts: test cases without cleanup Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
1 parent d42b864 commit 013e121

4 files changed

Lines changed: 47 additions & 15 deletions

File tree

src/auto-reply/inbound.test.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
/** Tests inbound auto-reply handling across channel message contexts. */
2-
import fs from "node:fs/promises";
3-
import os from "node:os";
42
import path from "node:path";
5-
import { beforeEach, describe, expect, it, vi } from "vitest";
3+
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
64
import type { OpenClawConfig } from "../config/config.js";
75
import type { GroupKeyResolution } from "../config/sessions.js";
86
import { channelRouteDedupeKey } from "../plugin-sdk/channel-route.js";
97
import { resetPluginRuntimeStateForTest, setActivePluginRegistry } from "../plugins/runtime.js";
8+
import { createSuiteTempRootTracker } from "../test-helpers/temp-dir.js";
109
import { createChannelTestPluginBase, createTestRegistry } from "../test-utils/channel-plugins.js";
1110
import { createInboundDebouncer } from "./inbound-debounce.js";
1211
import { resolveGroupRequireMention } from "./reply/groups.js";
@@ -985,9 +984,21 @@ describe("createInboundDebouncer", () => {
985984
});
986985
});
987986

987+
const senderMetaTempDirs = createSuiteTempRootTracker({
988+
prefix: "openclaw-sender-meta-",
989+
});
990+
988991
describe("initSessionState BodyStripped", () => {
992+
beforeAll(async () => {
993+
await senderMetaTempDirs.setup();
994+
});
995+
996+
afterAll(async () => {
997+
await senderMetaTempDirs.cleanup();
998+
});
999+
9891000
it("prefers BodyForAgent over Body for group chats", async () => {
990-
const root = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-sender-meta-"));
1001+
const root = await senderMetaTempDirs.make("group");
9911002
const storePath = path.join(root, "sessions.json");
9921003
const cfg = { session: { store: storePath } } as OpenClawConfig;
9931004

@@ -1009,7 +1020,7 @@ describe("initSessionState BodyStripped", () => {
10091020
});
10101021

10111022
it("prefers BodyForAgent over Body for direct chats", async () => {
1012-
const root = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-sender-meta-direct-"));
1023+
const root = await senderMetaTempDirs.make("direct");
10131024
const storePath = path.join(root, "sessions.json");
10141025
const cfg = { session: { store: storePath } } as OpenClawConfig;
10151026

src/auto-reply/reply/abort.test.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// Tests abort request handling, cutoff persistence, and active run cleanup.
22
import fs from "node:fs/promises";
3-
import os from "node:os";
43
import path from "node:path";
5-
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
4+
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
65
import type { SubagentRunRecord } from "../../agents/subagent-registry.js";
76
import type { OpenClawConfig } from "../../config/config.js";
7+
import { createSuiteTempRootTracker } from "../../test-helpers/temp-dir.js";
88
import type { SessionAbortTargetResult } from "../../config/sessions/session-accessor.js";
99
import {
1010
testing as abortTesting,
@@ -83,7 +83,17 @@ vi.mock("../../acp/control-plane/manager.js", () => ({
8383
}),
8484
}));
8585

86+
const suiteTempDirs = createSuiteTempRootTracker({ prefix: "openclaw-abort-" });
87+
8688
describe("abort detection", () => {
89+
beforeAll(async () => {
90+
await suiteTempDirs.setup();
91+
});
92+
93+
afterAll(async () => {
94+
await suiteTempDirs.cleanup();
95+
});
96+
8797
async function writeSessionStore(
8898
storePath: string,
8999
sessionIdsByKey: Record<string, string>,
@@ -103,7 +113,7 @@ describe("abort detection", () => {
103113
sessionIdsByKey?: Record<string, string>;
104114
nowMs?: number;
105115
}) {
106-
const root = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-abort-"));
116+
const root = await suiteTempDirs.make("case");
107117
const storePath = path.join(root, "sessions.json");
108118
const cfg = {
109119
session: { store: storePath },

src/auto-reply/reply/session-hooks-context.test.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
// Tests context passed to session lifecycle hooks.
22
import fs from "node:fs/promises";
3-
import os from "node:os";
43
import path from "node:path";
5-
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
4+
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
65
import type { OpenClawConfig } from "../../config/config.js";
76
import type { SessionEntry } from "../../config/sessions.js";
87
import type { HookRunner } from "../../plugins/hooks.js";
8+
import { createSuiteTempRootTracker } from "../../test-helpers/temp-dir.js";
99
import { initSessionState } from "./session.js";
1010

1111
const hookRunnerMocks = vi.hoisted(() => ({
@@ -61,8 +61,10 @@ vi.mock("../../agents/session-write-lock.js", async () => {
6161
};
6262
});
6363

64+
const suiteTempDirs = createSuiteTempRootTracker({ prefix: "openclaw-session-hooks-" });
65+
6466
async function createStorePath(prefix: string): Promise<string> {
65-
const root = await fs.mkdtemp(path.join(os.tmpdir(), `${prefix}-`));
67+
const root = await suiteTempDirs.make(prefix);
6668
return path.join(root, "sessions.json");
6769
}
6870

@@ -165,6 +167,14 @@ function requireHookCall(
165167
}
166168

167169
describe("session hook context wiring", () => {
170+
beforeAll(async () => {
171+
await suiteTempDirs.setup();
172+
});
173+
174+
afterAll(async () => {
175+
await suiteTempDirs.cleanup();
176+
});
177+
168178
beforeEach(() => {
169179
hookRunnerMocks.hasHooks.mockReset();
170180
hookRunnerMocks.runSessionStart.mockReset();

src/skills/lifecycle/install-fallback.test.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
// Install fallback tests cover alternate skill install paths when primary paths fail.
2-
import fs from "node:fs/promises";
3-
import os from "node:os";
42
import path from "node:path";
53
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
4+
import { createSuiteTempRootTracker } from "../../test-helpers/temp-dir.js";
65
import { captureEnv } from "../../test-utils/env.js";
76
import { hasBinaryMock, runCommandWithTimeoutMock } from "../test-support/install-test-mocks.js";
87
import type { SkillEntry, SkillInstallSpec } from "../types.js";
@@ -82,11 +81,13 @@ function commandCallAt(
8281
];
8382
}
8483

84+
const suiteTempDirs = createSuiteTempRootTracker({ prefix: "openclaw-fallback-test-" });
85+
8586
describe("skills-install fallback edge cases", () => {
8687
let workspaceDir: string;
8788

8889
beforeAll(async () => {
89-
workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-fallback-test-"));
90+
workspaceDir = await suiteTempDirs.setup();
9091
skillsMocks.loadWorkspaceSkillEntries.mockReturnValue([
9192
makeSkillEntry(workspaceDir, "go-tool-single", {
9293
kind: "go",
@@ -112,7 +113,7 @@ describe("skills-install fallback edge cases", () => {
112113

113114
afterAll(async () => {
114115
skillsInstallTesting.setDepsForTest();
115-
await fs.rm(workspaceDir, { recursive: true, force: true }).catch(() => undefined);
116+
await suiteTempDirs.cleanup();
116117
});
117118

118119
it("handles sudo probe failures for go install without apt fallback", async () => {

0 commit comments

Comments
 (0)