Skip to content

Commit 83a267e

Browse files
committed
fix(ci): reset deep test runtime state
1 parent ae02f40 commit 83a267e

File tree

6 files changed

+39
-31
lines changed

6 files changed

+39
-31
lines changed

extensions/feishu/src/monitor.reply-once.lifecycle.test.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,14 @@ const monitorWebSocketMock = vi.hoisted(() => vi.fn(async () => {}));
1010
const monitorWebhookMock = vi.hoisted(() => vi.fn(async () => {}));
1111
const createFeishuThreadBindingManagerMock = vi.hoisted(() => vi.fn(() => ({ stop: vi.fn() })));
1212
const createFeishuReplyDispatcherMock = vi.hoisted(() => vi.fn());
13-
const resolveBoundConversationMock = vi.hoisted(() => vi.fn(() => null));
13+
const resolveBoundConversationMock = vi.hoisted(() =>
14+
vi.fn<
15+
() => {
16+
bindingId: string;
17+
targetSessionKey: string;
18+
} | null
19+
>(() => null),
20+
);
1421
const touchBindingMock = vi.hoisted(() => vi.fn());
1522
const resolveAgentRouteMock = vi.hoisted(() => vi.fn());
1623
const dispatchReplyFromConfigMock = vi.hoisted(() => vi.fn());
@@ -110,6 +117,7 @@ function createLifecycleConfig(): ClawdbotConfig {
110117
function createLifecycleAccount(): ResolvedFeishuAccount {
111118
return {
112119
accountId: "acct-lifecycle",
120+
selectionSource: "explicit",
113121
enabled: true,
114122
configured: true,
115123
appId: "cli_test",
@@ -129,7 +137,7 @@ function createLifecycleAccount(): ResolvedFeishuAccount {
129137
},
130138
},
131139
},
132-
} as ResolvedFeishuAccount;
140+
} as unknown as ResolvedFeishuAccount;
133141
}
134142

135143
function createRuntimeEnv(): RuntimeEnv {

src/memory/index.test.ts

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ import { mkdirSync, rmSync } from "node:fs";
33
import fs from "node:fs/promises";
44
import os from "node:os";
55
import path from "node:path";
6-
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
6+
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
77
import "./test-runtime-mocks.js";
88
import type { MemoryIndexManager } from "./index.js";
99

1010
type MemoryIndexModule = typeof import("./index.js");
1111

1212
let getMemorySearchManager: MemoryIndexModule["getMemorySearchManager"];
13+
let closeAllMemorySearchManagers: MemoryIndexModule["closeAllMemorySearchManagers"];
1314

1415
let embedBatchCalls = 0;
1516
let embedBatchInputCalls = 0;
@@ -125,14 +126,12 @@ describe("memory index", () => {
125126
}),
126127
].join("\n");
127128

128-
// Perf: keep managers open across tests, but only reset the one a test uses.
129-
const managersByCacheKey = new Map<string, MemoryIndexManager>();
130129
const managersForCleanup = new Set<MemoryIndexManager>();
131130

132131
beforeAll(async () => {
133132
vi.resetModules();
134133
await import("./test-runtime-mocks.js");
135-
({ getMemorySearchManager } = await import("./index.js"));
134+
({ getMemorySearchManager, closeAllMemorySearchManagers } = await import("./index.js"));
136135
fixtureRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-mem-fixtures-"));
137136
workspaceDir = path.join(fixtureRoot, "workspace");
138137
memoryDir = path.join(workspaceDir, "memory");
@@ -158,6 +157,11 @@ describe("memory index", () => {
158157
await fs.rm(fixtureRoot, { recursive: true, force: true });
159158
});
160159

160+
afterEach(async () => {
161+
await closeAllMemorySearchManagers();
162+
managersForCleanup.clear();
163+
});
164+
161165
beforeEach(async () => {
162166
// Perf: most suites don't need atomic swap behavior for full reindexes.
163167
// Keep atomic reindex tests on the safe path.
@@ -166,7 +170,6 @@ describe("memory index", () => {
166170
embedBatchInputCalls = 0;
167171
providerCalls = [];
168172

169-
// Keep the workspace stable to allow manager reuse across tests.
170173
mkdirSync(memoryDir, { recursive: true });
171174

172175
// Clean additional paths that may have been created by earlier cases.
@@ -243,30 +246,9 @@ describe("memory index", () => {
243246
return result.manager as MemoryIndexManager;
244247
}
245248

246-
function getManagerCacheKey(cfg: TestCfg): string {
247-
const memorySearch = cfg.agents?.defaults?.memorySearch;
248-
const storePath = memorySearch?.store?.path;
249-
if (!storePath) {
250-
throw new Error("store path missing");
251-
}
252-
return JSON.stringify({
253-
workspaceDir,
254-
storePath,
255-
memorySearch,
256-
});
257-
}
258-
259249
async function getPersistentManager(cfg: TestCfg): Promise<MemoryIndexManager> {
260-
const cacheKey = getManagerCacheKey(cfg);
261-
const cached = managersByCacheKey.get(cacheKey);
262-
if (cached) {
263-
resetManagerForTest(cached);
264-
return cached;
265-
}
266-
267250
const result = await getMemorySearchManager({ cfg, agentId: "main" });
268251
const manager = requireManager(result);
269-
managersByCacheKey.set(cacheKey, manager);
270252
managersForCleanup.add(manager);
271253
resetManagerForTest(manager);
272254
return manager;

src/plugins/http-registry.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { createEmptyPluginRegistry } from "./registry.js";
44
import {
55
pinActivePluginHttpRouteRegistry,
66
releasePinnedPluginHttpRouteRegistry,
7+
resetPluginRuntimeStateForTest,
78
setActivePluginRegistry,
89
} from "./runtime.js";
910

@@ -45,7 +46,7 @@ function expectRouteRegistrationDenied(params: {
4546
describe("registerPluginHttpRoute", () => {
4647
afterEach(() => {
4748
releasePinnedPluginHttpRouteRegistry();
48-
setActivePluginRegistry(createEmptyPluginRegistry());
49+
resetPluginRuntimeStateForTest();
4950
});
5051

5152
it("registers route and unregisters it", () => {

src/plugins/runtime.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ import { createEmptyPluginRegistry } from "./registry.js";
33
import {
44
pinActivePluginHttpRouteRegistry,
55
releasePinnedPluginHttpRouteRegistry,
6+
resetPluginRuntimeStateForTest,
67
resolveActivePluginHttpRouteRegistry,
78
setActivePluginRegistry,
89
} from "./runtime.js";
910

1011
describe("plugin runtime route registry", () => {
1112
afterEach(() => {
1213
releasePinnedPluginHttpRouteRegistry();
13-
setActivePluginRegistry(createEmptyPluginRegistry());
14+
resetPluginRuntimeStateForTest();
1415
});
1516

1617
it("keeps the pinned route registry when the active plugin registry changes", () => {

src/plugins/runtime.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,12 @@ export function getActivePluginRegistryKey(): string | null {
9898
export function getActivePluginRegistryVersion(): number {
9999
return state.version;
100100
}
101+
102+
export function resetPluginRuntimeStateForTest(): void {
103+
const emptyRegistry = createEmptyPluginRegistry();
104+
state.registry = emptyRegistry;
105+
state.httpRouteRegistry = emptyRegistry;
106+
state.httpRouteRegistryPinned = false;
107+
state.key = null;
108+
state.version += 1;
109+
}

src/secrets/runtime.test.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@ import os from "node:os";
33
import path from "node:path";
44
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
55
import { ensureAuthProfileStore, type AuthProfileStore } from "../agents/auth-profiles.js";
6-
import { loadConfig, type OpenClawConfig, writeConfigFile } from "../config/config.js";
6+
import {
7+
clearConfigCache,
8+
loadConfig,
9+
type OpenClawConfig,
10+
writeConfigFile,
11+
} from "../config/config.js";
712
import { withTempHome } from "../config/home-env.test-harness.js";
813
import type { PluginWebSearchProviderEntry } from "../plugins/types.js";
914
import {
@@ -121,6 +126,8 @@ describe("secrets runtime snapshot", () => {
121126

122127
afterEach(() => {
123128
clearSecretsRuntimeSnapshot();
129+
clearConfigCache();
130+
resolvePluginWebSearchProvidersMock.mockReset();
124131
});
125132

126133
const allowInsecureTempSecretFile = process.platform === "win32";

0 commit comments

Comments
 (0)