From 8079aa62a23bf3fc24bc40b1fdec84dbe38701b7 Mon Sep 17 00:00:00 2001 From: Shakker Date: Fri, 26 Jun 2026 12:32:39 +0100 Subject: [PATCH] fix: isolate memory index test state --- .../memory-core/src/dreaming-phases.test.ts | 25 +++++------ .../memory-core/src/memory/index.test.ts | 41 ++++++++++++------- 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/extensions/memory-core/src/dreaming-phases.test.ts b/extensions/memory-core/src/dreaming-phases.test.ts index eb5ebba40ac..b4dcf5b66c3 100644 --- a/extensions/memory-core/src/dreaming-phases.test.ts +++ b/extensions/memory-core/src/dreaming-phases.test.ts @@ -2003,8 +2003,7 @@ describe("memory-core dreaming phases", () => { it("skips reset/deleted archive artifacts without active transcripts during session ingestion", async () => { const workspaceDir = await createDreamingWorkspace(); - vi.stubEnv("OPENCLAW_TEST_FAST", "1"); - vi.stubEnv("OPENCLAW_STATE_DIR", path.join(workspaceDir, ".state")); + setDreamingTestEnv(path.join(workspaceDir, ".state")); const sessionsDir = resolveSessionTranscriptsDirForAgent("main"); await fs.mkdir(sessionsDir, { recursive: true }); const archivePath = path.join( @@ -2062,7 +2061,7 @@ describe("memory-core dreaming phases", () => { await triggerLightDreaming(beforeAgentReply, workspaceDir, 5); }); } finally { - vi.unstubAllEnvs(); + restoreDreamingTestEnv(); } await expectPathMissing( @@ -2075,8 +2074,7 @@ describe("memory-core dreaming phases", () => { it("buckets session snippets by per-message day rather than file mtime", async () => { const workspaceDir = await createDreamingWorkspace(); - vi.stubEnv("OPENCLAW_TEST_FAST", "1"); - vi.stubEnv("OPENCLAW_STATE_DIR", path.join(workspaceDir, ".state")); + setDreamingTestEnv(path.join(workspaceDir, ".state")); const sessionsDir = resolveSessionTranscriptsDirForAgent("main"); await fs.mkdir(sessionsDir, { recursive: true }); const transcriptPath = path.join(sessionsDir, "dreaming-main.jsonl"); @@ -2141,7 +2139,7 @@ describe("memory-core dreaming phases", () => { await triggerLightDreaming(beforeAgentReply, workspaceDir, 5); }); } finally { - vi.unstubAllEnvs(); + restoreDreamingTestEnv(); } const corpusDir = path.join(workspaceDir, "memory", ".dreams", "session-corpus"); @@ -2156,8 +2154,7 @@ describe("memory-core dreaming phases", () => { it("drains >80 unseen transcript messages across multiple unchanged sweeps", async () => { const workspaceDir = await createDreamingWorkspace(); - vi.stubEnv("OPENCLAW_TEST_FAST", "1"); - vi.stubEnv("OPENCLAW_STATE_DIR", path.join(workspaceDir, ".state")); + setDreamingTestEnv(path.join(workspaceDir, ".state")); const sessionsDir = resolveSessionTranscriptsDirForAgent("main"); await fs.mkdir(sessionsDir, { recursive: true }); const transcriptPath = path.join(sessionsDir, "dreaming-main.jsonl"); @@ -2214,7 +2211,7 @@ describe("memory-core dreaming phases", () => { await triggerLightDreaming(beforeAgentReply, workspaceDir, 7); }); } finally { - vi.unstubAllEnvs(); + restoreDreamingTestEnv(); } const corpusPath = path.join( @@ -2236,8 +2233,7 @@ describe("memory-core dreaming phases", () => { it("re-ingests rewritten session transcripts after truncate/reset", async () => { const workspaceDir = await createDreamingWorkspace(); - vi.stubEnv("OPENCLAW_TEST_FAST", "1"); - vi.stubEnv("OPENCLAW_STATE_DIR", path.join(workspaceDir, ".state")); + setDreamingTestEnv(path.join(workspaceDir, ".state")); const sessionsDir = resolveSessionTranscriptsDirForAgent("main"); await fs.mkdir(sessionsDir, { recursive: true }); const transcriptPath = path.join(sessionsDir, "dreaming-main.jsonl"); @@ -2314,7 +2310,7 @@ describe("memory-core dreaming phases", () => { await triggerLightDreaming(beforeAgentReply, workspaceDir, 910); }); } finally { - vi.unstubAllEnvs(); + restoreDreamingTestEnv(); } const ranked = await rankShortTermPromotionCandidates({ @@ -2331,8 +2327,7 @@ describe("memory-core dreaming phases", () => { it("ingests sessions when dreaming is enabled even if memorySearch is disabled", async () => { const workspaceDir = await createDreamingWorkspace(); - vi.stubEnv("OPENCLAW_TEST_FAST", "1"); - vi.stubEnv("OPENCLAW_STATE_DIR", path.join(workspaceDir, ".state")); + setDreamingTestEnv(path.join(workspaceDir, ".state")); const sessionsDir = resolveSessionTranscriptsDirForAgent("main"); await fs.mkdir(sessionsDir, { recursive: true }); const transcriptPath = path.join(sessionsDir, "dreaming-main.jsonl"); @@ -2390,7 +2385,7 @@ describe("memory-core dreaming phases", () => { await triggerLightDreaming(beforeAgentReply, workspaceDir, 5); }); } finally { - vi.unstubAllEnvs(); + restoreDreamingTestEnv(); } const ranked = await rankShortTermPromotionCandidates({ diff --git a/extensions/memory-core/src/memory/index.test.ts b/extensions/memory-core/src/memory/index.test.ts index 329612f0831..70e542bc67a 100644 --- a/extensions/memory-core/src/memory/index.test.ts +++ b/extensions/memory-core/src/memory/index.test.ts @@ -43,6 +43,7 @@ let providerCloseGate: Promise | null = null; let providerInitGate: Promise | null = null; let providerCalls: Array<{ provider?: string; model?: string; outputDimensionality?: number }> = []; let forceNoProvider = false; +const originalMemoryIndexStateDir = process.env.OPENCLAW_STATE_DIR; const identityAliasFixture = vi.hoisted(() => ({ provider: "identity-alias-test", @@ -58,6 +59,18 @@ function createLocalWorkerExitError(): Error { }); } +function setMemoryIndexStateDir(stateDir: string): void { + Reflect.set(process.env, "OPENCLAW_STATE_DIR", stateDir); +} + +function restoreMemoryIndexStateDir(): void { + if (originalMemoryIndexStateDir === undefined) { + Reflect.deleteProperty(process.env, "OPENCLAW_STATE_DIR"); + } else { + Reflect.set(process.env, "OPENCLAW_STATE_DIR", originalMemoryIndexStateDir); + } +} + vi.mock("./embeddings.js", () => { const embedText = (text: string) => { const lower = text.toLowerCase(); @@ -276,7 +289,7 @@ describe("memory index", () => { closeOpenClawStateDatabaseForTest(); clearRegistry(); managersForCleanup.clear(); - vi.unstubAllEnvs(); + restoreMemoryIndexStateDir(); }); beforeEach(async () => { @@ -298,7 +311,7 @@ describe("memory index", () => { rmSync(workspaceDir, { recursive: true, force: true }); mkdirSync(memoryDir, { recursive: true }); - vi.stubEnv("OPENCLAW_STATE_DIR", path.join(workspaceDir, ".state-memory-index")); + setMemoryIndexStateDir(path.join(workspaceDir, ".state-memory-index")); await fs.writeFile( path.join(memoryDir, "2026-01-12.md"), "# Log\nAlpha memory line.\nZebra memory line.", @@ -488,7 +501,7 @@ describe("memory index", () => { stateDirName: string; }): Promise { forceNoProvider = true; - vi.stubEnv("OPENCLAW_STATE_DIR", path.join(workspaceDir, params.stateDirName)); + setMemoryIndexStateDir(path.join(workspaceDir, params.stateDirName)); const cfg = createCfg({ sources: ["memory", "sessions"], sessionMemory: true, @@ -573,7 +586,7 @@ describe("memory index", () => { it("reindexes memory tables in place without deleting unrelated agent rows", async () => { const stateDir = path.join(workspaceDir, "managed-memory-state"); - vi.stubEnv("OPENCLAW_STATE_DIR", stateDir); + setMemoryIndexStateDir(stateDir); const agentDbPath = resolveOpenClawAgentSqlitePath({ agentId: "main" }); const agentDb = openOpenClawAgentDatabase({ agentId: "main" }); agentDb.db @@ -1117,7 +1130,7 @@ describe("memory index", () => { it("clears dirty after sessions-only identity reindex", async () => { try { - vi.stubEnv("OPENCLAW_STATE_DIR", path.join(workspaceDir, ".state-sessions-only-reindex")); + setMemoryIndexStateDir(path.join(workspaceDir, ".state-sessions-only-reindex")); const sessionsDir = resolveSessionTranscriptsDirForAgent("main"); await fs.mkdir(sessionsDir, { recursive: true }); await fs.writeFile( @@ -1167,13 +1180,13 @@ describe("memory index", () => { await nextManager.close?.(); } } finally { - vi.unstubAllEnvs(); + restoreMemoryIndexStateDir(); } }); it("marks sessions-only indexes dirty when metadata is missing but chunks exist", async () => { try { - vi.stubEnv("OPENCLAW_STATE_DIR", path.join(workspaceDir, ".state-sessions-missing-meta")); + setMemoryIndexStateDir(path.join(workspaceDir, ".state-sessions-missing-meta")); const sessionsDir = resolveSessionTranscriptsDirForAgent("main"); await fs.mkdir(sessionsDir, { recursive: true }); await fs.writeFile( @@ -1223,13 +1236,13 @@ describe("memory index", () => { await nextManager.close?.(); } } finally { - vi.unstubAllEnvs(); + restoreMemoryIndexStateDir(); } }); it("keeps provider cutover vector search paused during targeted session sync", async () => { try { - vi.stubEnv("OPENCLAW_STATE_DIR", path.join(workspaceDir, ".state-targeted-cutover")); + setMemoryIndexStateDir(path.join(workspaceDir, ".state-targeted-cutover")); const sessionsDir = resolveSessionTranscriptsDirForAgent("main"); await fs.mkdir(sessionsDir, { recursive: true }); const sessionFile = path.join(sessionsDir, "session-targeted-cutover.jsonl"); @@ -1287,13 +1300,13 @@ describe("memory index", () => { await nextManager.close?.(); } } finally { - vi.unstubAllEnvs(); + restoreMemoryIndexStateDir(); } }); it("preserves memory dirty events raised during session identity reindex", async () => { try { - vi.stubEnv("OPENCLAW_STATE_DIR", path.join(workspaceDir, ".state-dirty-during-session")); + setMemoryIndexStateDir(path.join(workspaceDir, ".state-dirty-during-session")); const sessionsDir = resolveSessionTranscriptsDirForAgent("main"); await fs.mkdir(sessionsDir, { recursive: true }); await fs.writeFile( @@ -1351,7 +1364,7 @@ describe("memory index", () => { await nextManager.close?.(); } } finally { - vi.unstubAllEnvs(); + restoreMemoryIndexStateDir(); } }); @@ -2230,7 +2243,7 @@ describe("memory index", () => { expect(results[0]?.source).toBe("sessions"); expect(results[0]?.snippet).toContain("ORBIT-10"); } finally { - vi.unstubAllEnvs(); + restoreMemoryIndexStateDir(); } }); @@ -2274,7 +2287,7 @@ describe("memory index", () => { expect(results[0]?.source).toBe("sessions"); expect(results[0]?.snippet).toContain("ORBIT-10"); } finally { - vi.unstubAllEnvs(); + restoreMemoryIndexStateDir(); } }); });