From f2c56de955e403a6019eef53e3edc4d189abe219 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 14 Feb 2026 16:03:14 +0000 Subject: [PATCH] perf(test): speed up memory suites --- src/memory/index.test.ts | 6 +- src/memory/manager.batch.test.ts | 57 +++++++++++-------- src/memory/manager.embedding-batches.test.ts | 7 +-- .../manager.embedding-token-limit.test.ts | 4 +- src/memory/qmd-manager.test.ts | 8 ++- 5 files changed, 47 insertions(+), 35 deletions(-) diff --git a/src/memory/index.test.ts b/src/memory/index.test.ts index b49086e5bf9..6581a658b65 100644 --- a/src/memory/index.test.ts +++ b/src/memory/index.test.ts @@ -89,7 +89,7 @@ describe("memory index", () => { throw new Error("manager missing"); } manager = result.manager; - await result.manager.sync({ force: true }); + await result.manager.sync({ reason: "test" }); const results = await result.manager.search("alpha"); expect(results.length).toBeGreaterThan(0); expect(results[0]?.path).toContain("memory/2026-01-12.md"); @@ -141,7 +141,7 @@ describe("memory index", () => { if (!first.manager) { throw new Error("manager missing"); } - await first.manager.sync({ force: true }); + await first.manager.sync({ reason: "test" }); const callsAfterFirstSync = embedBatchCalls; await first.manager.close(); @@ -234,7 +234,7 @@ describe("memory index", () => { return; } - await manager.sync({ force: true }); + await manager.sync({ reason: "test" }); const results = await manager.search("zebra"); expect(results.length).toBeGreaterThan(0); expect(results[0]?.path).toContain("memory/2026-01-12.md"); diff --git a/src/memory/manager.batch.test.ts b/src/memory/manager.batch.test.ts index a3ed97d3a87..8ad9cb27737 100644 --- a/src/memory/manager.batch.test.ts +++ b/src/memory/manager.batch.test.ts @@ -172,7 +172,6 @@ describe("memory indexing with OpenAI batches", () => { manager = result.manager; const labels: string[] = []; await manager.sync({ - force: true, progress: (update) => { if (update.label) { labels.push(update.label); @@ -287,7 +286,7 @@ describe("memory indexing with OpenAI batches", () => { throw new Error("manager missing"); } manager = result.manager; - await manager.sync({ force: true }); + await manager.sync({ reason: "test" }); const status = manager.status(); expect(status.chunks).toBeGreaterThan(0); @@ -300,7 +299,16 @@ describe("memory indexing with OpenAI batches", () => { it("tracks batch failures, resets on success, and disables after repeated failures", async () => { const restoreTimeouts = useFastShortTimeouts(); const content = ["flaky", "batch"].join("\n\n"); - await fs.writeFile(path.join(workspaceDir, "memory", "2026-01-09.md"), content); + const memoryFile = path.join(workspaceDir, "memory", "2026-01-09.md"); + let mtimeMs = Date.now(); + const touch = async () => { + mtimeMs += 1_000; + const date = new Date(mtimeMs); + await fs.utimes(memoryFile, date, date); + }; + + await fs.writeFile(memoryFile, content); + await touch(); let uploadedRequests: Array<{ custom_id?: string }> = []; let mode: "fail" | "ok" = "fail"; @@ -395,20 +403,24 @@ describe("memory indexing with OpenAI batches", () => { manager = result.manager; // First failure: fallback to regular embeddings and increment failure count. - await manager.sync({ force: true }); + await manager.sync({ reason: "test" }); expect(embedBatch).toHaveBeenCalled(); let status = manager.status(); expect(status.batch?.enabled).toBe(true); expect(status.batch?.failures).toBe(1); + const markDirty = () => { + // `sync` only indexes when marked dirty (unless doing a full reindex). + (manager as unknown as { dirty: boolean }).dirty = true; + }; + // Success should reset failure count. embedBatch.mockClear(); mode = "ok"; - await fs.writeFile( - path.join(workspaceDir, "memory", "2026-01-09.md"), - ["flaky", "batch", "recovery"].join("\n\n"), - ); - await manager.sync({ force: true }); + await fs.writeFile(memoryFile, ["flaky", "batch", "recovery"].join("\n\n")); + await touch(); + markDirty(); + await manager.sync({ reason: "test" }); status = manager.status(); expect(status.batch?.enabled).toBe(true); expect(status.batch?.failures).toBe(0); @@ -416,20 +428,18 @@ describe("memory indexing with OpenAI batches", () => { // Two more failures after reset should disable remote batching. mode = "fail"; - await fs.writeFile( - path.join(workspaceDir, "memory", "2026-01-09.md"), - ["flaky", "batch", "fail-a"].join("\n\n"), - ); - await manager.sync({ force: true }); + await fs.writeFile(memoryFile, ["flaky", "batch", "fail-a"].join("\n\n")); + await touch(); + markDirty(); + await manager.sync({ reason: "test" }); status = manager.status(); expect(status.batch?.enabled).toBe(true); expect(status.batch?.failures).toBe(1); - await fs.writeFile( - path.join(workspaceDir, "memory", "2026-01-09.md"), - ["flaky", "batch", "fail-b"].join("\n\n"), - ); - await manager.sync({ force: true }); + await fs.writeFile(memoryFile, ["flaky", "batch", "fail-b"].join("\n\n")); + await touch(); + markDirty(); + await manager.sync({ reason: "test" }); status = manager.status(); expect(status.batch?.enabled).toBe(false); expect(status.batch?.failures).toBeGreaterThanOrEqual(2); @@ -437,11 +447,10 @@ describe("memory indexing with OpenAI batches", () => { // Once disabled, batch endpoints are skipped and fallback embeddings run directly. const fetchCalls = fetchMock.mock.calls.length; embedBatch.mockClear(); - await fs.writeFile( - path.join(workspaceDir, "memory", "2026-01-09.md"), - ["flaky", "batch", "fallback"].join("\n\n"), - ); - await manager.sync({ force: true }); + await fs.writeFile(memoryFile, ["flaky", "batch", "fallback"].join("\n\n")); + await touch(); + markDirty(); + await manager.sync({ reason: "test" }); expect(fetchMock.mock.calls.length).toBe(fetchCalls); expect(embedBatch).toHaveBeenCalled(); } finally { diff --git a/src/memory/manager.embedding-batches.test.ts b/src/memory/manager.embedding-batches.test.ts index 4b530602d7d..466ecacbc07 100644 --- a/src/memory/manager.embedding-batches.test.ts +++ b/src/memory/manager.embedding-batches.test.ts @@ -85,7 +85,6 @@ describe("memory embedding batches", () => { manager = result.manager; const updates: Array<{ completed: number; total: number; label?: string }> = []; await manager.sync({ - force: true, progress: (update) => { updates.push(update); }, @@ -130,7 +129,7 @@ describe("memory embedding batches", () => { throw new Error("manager missing"); } manager = result.manager; - await manager.sync({ force: true }); + await manager.sync({ reason: "test" }); expect(embedBatch.mock.calls.length).toBe(1); }); @@ -191,7 +190,7 @@ describe("memory embedding batches", () => { } manager = result.manager; try { - await manager.sync({ force: true }); + await manager.sync({ reason: "test" }); } finally { setTimeoutSpy.mockRestore(); } @@ -224,7 +223,7 @@ describe("memory embedding batches", () => { throw new Error("manager missing"); } manager = result.manager; - await manager.sync({ force: true }); + await manager.sync({ reason: "test" }); const inputs = embedBatch.mock.calls.flatMap((call) => call[0] ?? []); expect(inputs).not.toContain(""); diff --git a/src/memory/manager.embedding-token-limit.test.ts b/src/memory/manager.embedding-token-limit.test.ts index 7781cd949f9..53e73f897e4 100644 --- a/src/memory/manager.embedding-token-limit.test.ts +++ b/src/memory/manager.embedding-token-limit.test.ts @@ -74,7 +74,7 @@ describe("memory embedding token limits", () => { throw new Error("manager missing"); } manager = result.manager; - await manager.sync({ force: true }); + await manager.sync({ reason: "test" }); const inputs = embedBatch.mock.calls.flatMap((call) => call[0] ?? []); expect(inputs.length).toBeGreaterThan(1); @@ -111,7 +111,7 @@ describe("memory embedding token limits", () => { throw new Error("manager missing"); } manager = result.manager; - await manager.sync({ force: true }); + await manager.sync({ reason: "test" }); const batchSizes = embedBatch.mock.calls.map( (call) => (call[0] as string[] | undefined)?.length ?? 0, diff --git a/src/memory/qmd-manager.test.ts b/src/memory/qmd-manager.test.ts index b6354391d60..e8b78a586e6 100644 --- a/src/memory/qmd-manager.test.ts +++ b/src/memory/qmd-manager.test.ts @@ -1009,12 +1009,16 @@ describe("QmdMemoryManager", () => { }); async function waitForCondition(check: () => boolean, timeoutMs: number): Promise { - const deadline = Date.now() + timeoutMs; - while (Date.now() < deadline) { + // Tests only need to yield the event loop a few times; real-time sleeps slow the suite down. + const maxTicks = Math.max(10, Math.min(5000, timeoutMs * 5)); + for (let tick = 0; tick < maxTicks; tick += 1) { if (check()) { return; } await new Promise((resolve) => setImmediate(resolve)); } + if (check()) { + return; + } throw new Error("condition was not met in time"); }