From ae87f7800b2a335ca4efada0c9dfc63aef36f7fe Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sun, 3 May 2026 03:18:00 -0700 Subject: [PATCH] test(matrix): isolate IndexedDB persistence fixtures --- .../sdk/idb-persistence.lock-order.test.ts | 15 +++---- .../sdk/idb-persistence.test-helpers.ts | 4 +- .../src/matrix/sdk/idb-persistence.test.ts | 42 ++++++++++++------- 3 files changed, 37 insertions(+), 24 deletions(-) diff --git a/extensions/matrix/src/matrix/sdk/idb-persistence.lock-order.test.ts b/extensions/matrix/src/matrix/sdk/idb-persistence.lock-order.test.ts index a6f47179a26..99c0775b2a4 100644 --- a/extensions/matrix/src/matrix/sdk/idb-persistence.lock-order.test.ts +++ b/extensions/matrix/src/matrix/sdk/idb-persistence.lock-order.test.ts @@ -29,6 +29,8 @@ let persistIdbToDisk: typeof import("./idb-persistence.js").persistIdbToDisk; let restoreIdbFromDisk: typeof import("./idb-persistence.js").restoreIdbFromDisk; type CapturedLockOptions = typeof import("./idb-persistence-lock.js").MATRIX_IDB_SNAPSHOT_LOCK_OPTIONS; +const DATABASE_PREFIX = "openclaw-matrix-lock-order-test"; +const cryptoDatabaseName = `${DATABASE_PREFIX}::matrix-sdk-crypto`; beforeAll(async () => { ({ persistIdbToDisk, restoreIdbFromDisk } = await import("./idb-persistence.js")); @@ -43,33 +45,32 @@ describe("Matrix IndexedDB persistence lock ordering", () => { withFileLockMock.mockImplementation( async (_filePath: string, _options: unknown, fn: () => Promise) => await fn(), ); - await clearAllIndexedDbState(); + await clearAllIndexedDbState({ databasePrefix: DATABASE_PREFIX }); }); afterEach(async () => { - await clearAllIndexedDbState(); + await clearAllIndexedDbState({ databasePrefix: DATABASE_PREFIX }); fs.rmSync(tmpDir, { recursive: true, force: true }); }); it("captures the snapshot after the file lock is acquired", async () => { const snapshotPath = path.join(tmpDir, "crypto-idb-snapshot.json"); - const dbName = "openclaw-matrix-test::matrix-sdk-crypto"; await seedDatabase({ - name: dbName, + name: cryptoDatabaseName, storeName: "sessions", records: [{ key: "room-1", value: { session: "old-session" } }], }); withFileLockMock.mockImplementationOnce(async (_filePath, _options, fn) => { await seedDatabase({ - name: dbName, + name: cryptoDatabaseName, storeName: "sessions", records: [{ key: "room-1", value: { session: "new-session" } }], }); return await fn(); }); - await persistIdbToDisk({ snapshotPath, databasePrefix: "openclaw-matrix-test" }); + await persistIdbToDisk({ snapshotPath, databasePrefix: DATABASE_PREFIX }); const data = JSON.parse(fs.readFileSync(snapshotPath, "utf8")) as Array<{ stores: Array<{ @@ -89,7 +90,7 @@ describe("Matrix IndexedDB persistence lock ordering", () => { capturedOptions.push(options as CapturedLockOptions); return 0; }); - await persistIdbToDisk({ snapshotPath, databasePrefix: "openclaw-matrix-test" }); + await persistIdbToDisk({ snapshotPath, databasePrefix: DATABASE_PREFIX }); fs.writeFileSync(snapshotPath, "[]", "utf8"); withFileLockMock.mockImplementationOnce(async (_filePath, options) => { diff --git a/extensions/matrix/src/matrix/sdk/idb-persistence.test-helpers.ts b/extensions/matrix/src/matrix/sdk/idb-persistence.test-helpers.ts index 516a58dd8bf..eaffafe4859 100644 --- a/extensions/matrix/src/matrix/sdk/idb-persistence.test-helpers.ts +++ b/extensions/matrix/src/matrix/sdk/idb-persistence.test-helpers.ts @@ -1,9 +1,11 @@ -export async function clearAllIndexedDbState(): Promise { +export async function clearAllIndexedDbState(params?: { databasePrefix?: string }): Promise { const databases = await indexedDB.databases(); + const expectedPrefix = params?.databasePrefix ? `${params.databasePrefix}::` : null; await Promise.all( databases .map((entry) => entry.name) .filter((name): name is string => Boolean(name)) + .filter((name) => !expectedPrefix || name.startsWith(expectedPrefix)) .map( (name) => new Promise((resolve, reject) => { diff --git a/extensions/matrix/src/matrix/sdk/idb-persistence.test.ts b/extensions/matrix/src/matrix/sdk/idb-persistence.test.ts index 8a342c4a9a5..6fc425911a8 100644 --- a/extensions/matrix/src/matrix/sdk/idb-persistence.test.ts +++ b/extensions/matrix/src/matrix/sdk/idb-persistence.test.ts @@ -15,6 +15,16 @@ import { } from "./idb-persistence.test-helpers.js"; import { LogService } from "./logger.js"; +const DATABASE_PREFIX = "openclaw-matrix-persistence-test"; +const OTHER_DATABASE_PREFIX = "openclaw-matrix-persistence-other-test"; +const cryptoDatabaseName = `${DATABASE_PREFIX}::matrix-sdk-crypto`; +const otherCryptoDatabaseName = `${OTHER_DATABASE_PREFIX}::matrix-sdk-crypto`; + +async function clearTestIndexedDbState(): Promise { + await clearAllIndexedDbState({ databasePrefix: DATABASE_PREFIX }); + await clearAllIndexedDbState({ databasePrefix: OTHER_DATABASE_PREFIX }); +} + describe("Matrix IndexedDB persistence", () => { let tmpDir: string; let warnSpy: ReturnType; @@ -22,12 +32,12 @@ describe("Matrix IndexedDB persistence", () => { beforeEach(async () => { tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "matrix-idb-persist-")); warnSpy = vi.spyOn(LogService, "warn").mockImplementation(() => {}); - await clearAllIndexedDbState(); + await clearTestIndexedDbState(); }); afterEach(async () => { warnSpy.mockRestore(); - await clearAllIndexedDbState(); + await clearTestIndexedDbState(); resetFileLockStateForTest(); fs.rmSync(tmpDir, { recursive: true, force: true }); }); @@ -35,38 +45,38 @@ describe("Matrix IndexedDB persistence", () => { it("persists and restores database contents for the selected prefix", async () => { const snapshotPath = path.join(tmpDir, "crypto-idb-snapshot.json"); await seedDatabase({ - name: "openclaw-matrix-test::matrix-sdk-crypto", + name: cryptoDatabaseName, storeName: "sessions", records: [{ key: "room-1", value: { session: "abc123" } }], }); await seedDatabase({ - name: "other-prefix::matrix-sdk-crypto", + name: otherCryptoDatabaseName, storeName: "sessions", records: [{ key: "room-2", value: { session: "should-not-restore" } }], }); await persistIdbToDisk({ snapshotPath, - databasePrefix: "openclaw-matrix-test", + databasePrefix: DATABASE_PREFIX, }); expect(fs.existsSync(snapshotPath)).toBe(true); const mode = fs.statSync(snapshotPath).mode & 0o777; expect(mode).toBe(0o600); - await clearAllIndexedDbState(); + await clearTestIndexedDbState(); const restored = await restoreIdbFromDisk(snapshotPath); expect(restored).toBe(true); const restoredRecords = await readDatabaseRecords({ - name: "openclaw-matrix-test::matrix-sdk-crypto", + name: cryptoDatabaseName, storeName: "sessions", }); expect(restoredRecords).toEqual([{ key: "room-1", value: { session: "abc123" } }]); const dbs = await indexedDB.databases(); - expect(dbs.some((entry) => entry.name === "other-prefix::matrix-sdk-crypto")).toBe(false); + expect(dbs.some((entry) => entry.name === otherCryptoDatabaseName)).toBe(false); }); it("returns false and logs a warning for malformed snapshots", async () => { @@ -103,14 +113,14 @@ describe("Matrix IndexedDB persistence", () => { it("serializes concurrent persist operations via file lock", async () => { const snapshotPath = path.join(tmpDir, "concurrent-persist.json"); await seedDatabase({ - name: "openclaw-matrix-test::matrix-sdk-crypto", + name: cryptoDatabaseName, storeName: "sessions", records: [{ key: "room-1", value: { session: "abc123" } }], }); await Promise.all([ - persistIdbToDisk({ snapshotPath, databasePrefix: "openclaw-matrix-test" }), - persistIdbToDisk({ snapshotPath, databasePrefix: "openclaw-matrix-test" }), + persistIdbToDisk({ snapshotPath, databasePrefix: DATABASE_PREFIX }), + persistIdbToDisk({ snapshotPath, databasePrefix: DATABASE_PREFIX }), ]); expect(fs.existsSync(snapshotPath)).toBe(true); @@ -123,12 +133,12 @@ describe("Matrix IndexedDB persistence", () => { it("releases lock after persist completes", async () => { const snapshotPath = path.join(tmpDir, "lock-release.json"); await seedDatabase({ - name: "openclaw-matrix-test::matrix-sdk-crypto", + name: cryptoDatabaseName, storeName: "sessions", records: [{ key: "room-1", value: { session: "abc123" } }], }); - await persistIdbToDisk({ snapshotPath, databasePrefix: "openclaw-matrix-test" }); + await persistIdbToDisk({ snapshotPath, databasePrefix: DATABASE_PREFIX }); const lockPath = `${snapshotPath}.lock`; expect(fs.existsSync(lockPath)).toBe(false); @@ -138,13 +148,13 @@ describe("Matrix IndexedDB persistence", () => { it("releases lock after restore completes", async () => { const snapshotPath = path.join(tmpDir, "lock-release-restore.json"); await seedDatabase({ - name: "openclaw-matrix-test::matrix-sdk-crypto", + name: cryptoDatabaseName, storeName: "sessions", records: [{ key: "room-1", value: { session: "abc123" } }], }); - await persistIdbToDisk({ snapshotPath, databasePrefix: "openclaw-matrix-test" }); - await clearAllIndexedDbState(); + await persistIdbToDisk({ snapshotPath, databasePrefix: DATABASE_PREFIX }); + await clearTestIndexedDbState(); await drainFileLockStateForTest(); await restoreIdbFromDisk(snapshotPath);