mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-26 20:35:39 -06:00
test(memory-core): release cached databases before removing fixture state dirs (#128310)
* test(memory-core): release cached state handles before removing fixture dirs Six memory-core fixtures remove their temporary state directory while the per-agent or shared SQLite handles opened underneath it are still cached, so Windows fails the removal with EBUSY while Linux unlinks the open files and stays green. Release both handles before each removal, in the ordering merged for this class: the agent close releases its leases through shared state and reopens it, so the shared store has to be released after it. * test(memory-core): release cached handles in the shared fixture harness and cli teardown
This commit is contained in:
@@ -5,6 +5,7 @@ import path from "node:path";
|
||||
import { Command } from "commander";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/memory-core-host-engine-foundation";
|
||||
import { resolveSessionTranscriptsDirForAgent as resolveTestSessionTranscriptsDirForAgent } from "openclaw/plugin-sdk/memory-core-host-runtime-core";
|
||||
import { resetPluginStateStoreForTests } from "openclaw/plugin-sdk/plugin-state-test-runtime";
|
||||
import { upsertSessionEntry } from "openclaw/plugin-sdk/session-store-runtime";
|
||||
import { appendSessionTranscriptMessageByIdentity } from "openclaw/plugin-sdk/session-transcript-runtime";
|
||||
import { resolveOpenClawAgentSqlitePath } from "openclaw/plugin-sdk/sqlite-runtime";
|
||||
@@ -161,6 +162,10 @@ afterAll(async () => {
|
||||
if (!fixtureRoot) {
|
||||
return;
|
||||
}
|
||||
// The agent close releases its leases through shared state and reopens it, so the
|
||||
// shared handle is released second; otherwise Windows fails the removal with EBUSY.
|
||||
closeOpenClawAgentDatabasesForTest();
|
||||
resetPluginStateStoreForTests();
|
||||
await fs.rm(fixtureRoot, { recursive: true, force: true });
|
||||
resetMemoryCoreDreamingStateForTests();
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@ import os from "node:os";
|
||||
import path from "node:path";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
|
||||
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { resetPluginStateStoreForTests } from "openclaw/plugin-sdk/plugin-state-test-runtime";
|
||||
import { getSessionEntry, upsertSessionEntry } from "openclaw/plugin-sdk/session-store-runtime";
|
||||
import {
|
||||
appendSqliteSessionTranscriptEventForTest,
|
||||
@@ -30,6 +31,7 @@ afterEach(async () => {
|
||||
vi.useRealTimers();
|
||||
vi.unstubAllEnvs();
|
||||
vi.restoreAllMocks();
|
||||
resetPluginStateStoreForTests();
|
||||
await fs.rm(stateDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
type MemorySyncParams,
|
||||
type MemorySyncProgressUpdate,
|
||||
} from "openclaw/plugin-sdk/memory-core-host-engine-storage";
|
||||
import { resetPluginStateStoreForTests } from "openclaw/plugin-sdk/plugin-state-test-runtime";
|
||||
import {
|
||||
clearConfigCache,
|
||||
clearRuntimeConfigSnapshot,
|
||||
@@ -413,6 +414,10 @@ describe("session startup catch-up", () => {
|
||||
}
|
||||
startupHarnessDatabases.clear();
|
||||
closeOpenClawAgentDatabasesForTest();
|
||||
// Closing the agent databases releases their leases through shared state, which
|
||||
// reopens it, so the shared handle has to be released after that and before the
|
||||
// removal or Windows fails the unlink with EBUSY.
|
||||
resetPluginStateStoreForTests();
|
||||
await fs.rm(stateDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
|
||||
@@ -4,7 +4,9 @@ import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { DatabaseSync } from "node:sqlite";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/memory-core-host-engine-foundation";
|
||||
import { resetPluginStateStoreForTests } from "openclaw/plugin-sdk/plugin-state-test-runtime";
|
||||
import { resolveOpenClawAgentSqlitePath } from "openclaw/plugin-sdk/sqlite-runtime";
|
||||
import { closeOpenClawAgentDatabasesForTest } from "openclaw/plugin-sdk/sqlite-runtime-testing";
|
||||
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { closeAllMemorySearchManagers, getMemorySearchManager } from "./index.js";
|
||||
import type { MemoryIndexMeta } from "./manager-reindex-state.js";
|
||||
@@ -107,6 +109,10 @@ describe("memory manager FTS-only reindex", () => {
|
||||
|
||||
afterAll(async () => {
|
||||
await closeAllMemorySearchManagers();
|
||||
// The agent close releases its leases through shared state and reopens it, so the
|
||||
// shared handle is released second; otherwise Windows fails the removal with EBUSY.
|
||||
closeOpenClawAgentDatabasesForTest();
|
||||
resetPluginStateStoreForTests();
|
||||
if (fixtureRoot) {
|
||||
await fs.rm(fixtureRoot, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
@@ -4,7 +4,9 @@ import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { DatabaseSync } from "node:sqlite";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/memory-core-host-engine-foundation";
|
||||
import { resetPluginStateStoreForTests } from "openclaw/plugin-sdk/plugin-state-test-runtime";
|
||||
import { resolveOpenClawAgentSqlitePath } from "openclaw/plugin-sdk/sqlite-runtime";
|
||||
import { closeOpenClawAgentDatabasesForTest } from "openclaw/plugin-sdk/sqlite-runtime-testing";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { resetEmbeddingMocks } from "./embedding.test-mocks.js";
|
||||
import { acquireMemoryReindexLock } from "./manager-reindex-lock.js";
|
||||
@@ -52,6 +54,10 @@ describe("memory manager reindex recovery", () => {
|
||||
}
|
||||
const { closeAllMemorySearchManagers } = await import("./index.js");
|
||||
await closeAllMemorySearchManagers();
|
||||
// The agent close releases its leases through shared state and reopens it, so the
|
||||
// shared handle is released second; otherwise Windows fails the removal with EBUSY.
|
||||
closeOpenClawAgentDatabasesForTest();
|
||||
resetPluginStateStoreForTests();
|
||||
await fs.rm(fixtureRoot, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@ import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { DatabaseSync } from "node:sqlite";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/memory-core-host-engine-foundation";
|
||||
import { resetPluginStateStoreForTests } from "openclaw/plugin-sdk/plugin-state-test-runtime";
|
||||
import { resolveOpenClawAgentSqlitePath } from "openclaw/plugin-sdk/sqlite-runtime";
|
||||
import { closeOpenClawAgentDatabasesForTest } from "openclaw/plugin-sdk/sqlite-runtime-testing";
|
||||
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { closeAllMemorySearchManagers, getMemorySearchManager } from "./index.js";
|
||||
import type { MemoryIndexManager } from "./manager.js";
|
||||
@@ -78,6 +80,10 @@ describe("memory manager self-heal missing identity with FTS-only chunks", () =>
|
||||
|
||||
afterAll(async () => {
|
||||
await closeAllMemorySearchManagers();
|
||||
// The agent close releases its leases through shared state and reopens it, so the
|
||||
// shared handle is released second; otherwise Windows fails the removal with EBUSY.
|
||||
closeOpenClawAgentDatabasesForTest();
|
||||
resetPluginStateStoreForTests();
|
||||
if (fixtureRoot) {
|
||||
await fs.rm(fixtureRoot, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import type {
|
||||
MemorySearchConfig,
|
||||
OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/memory-core-host-engine-foundation";
|
||||
import { resetPluginStateStoreForTests } from "openclaw/plugin-sdk/plugin-state-test-runtime";
|
||||
import { closeOpenClawAgentDatabasesForTest } from "openclaw/plugin-sdk/sqlite-runtime-testing";
|
||||
import { afterAll, afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
type WatchIgnoredFn = (watchPath: string, stats?: { isDirectory?: () => boolean }) => boolean;
|
||||
@@ -208,6 +210,10 @@ describe("memory watcher config", () => {
|
||||
await closeAllMemorySearchManagers();
|
||||
clearRegistry();
|
||||
restoreWatcherStateDir();
|
||||
// The agent close releases its leases through shared state and reopens it, so the
|
||||
// shared handle is released second; otherwise Windows fails the removal with EBUSY.
|
||||
closeOpenClawAgentDatabasesForTest();
|
||||
resetPluginStateStoreForTests();
|
||||
if (workspaceDir) {
|
||||
await fs.rm(workspaceDir, { recursive: true, force: true });
|
||||
workspaceDir = "";
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import type { OpenKeyedStoreOptions } from "openclaw/plugin-sdk/plugin-state-runtime";
|
||||
import { createPluginStateKeyedStoreForTests } from "openclaw/plugin-sdk/plugin-state-test-runtime";
|
||||
import {
|
||||
createPluginStateKeyedStoreForTests,
|
||||
resetPluginStateStoreForTests,
|
||||
} from "openclaw/plugin-sdk/plugin-state-test-runtime";
|
||||
import { closeOpenClawAgentDatabasesForTest } from "openclaw/plugin-sdk/sqlite-runtime-testing";
|
||||
import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/temp-path";
|
||||
import { afterAll, beforeAll } from "vitest";
|
||||
@@ -210,6 +214,10 @@ export function createMemoryCoreTestHarness() {
|
||||
if (!fixtureRoot) {
|
||||
return;
|
||||
}
|
||||
// The agent close releases its leases through shared state and reopens it, so the
|
||||
// shared handle is released second; otherwise Windows fails the removal with EBUSY.
|
||||
closeOpenClawAgentDatabasesForTest();
|
||||
resetPluginStateStoreForTests();
|
||||
await fs.rm(fixtureRoot, { recursive: true, force: true });
|
||||
resetMemoryCoreDreamingStateForTests();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user