mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-09 16:21:15 +00:00
132 lines
3.8 KiB
TypeScript
132 lines
3.8 KiB
TypeScript
import fs from "node:fs/promises";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
import {
|
|
readCompactionCount,
|
|
seedSessionStore,
|
|
waitForCompactionCount,
|
|
} from "./pi-embedded-subscribe.compaction-test-helpers.js";
|
|
import {
|
|
handleAutoCompactionEnd,
|
|
reconcileSessionStoreCompactionCountAfterSuccess,
|
|
} from "./pi-embedded-subscribe.handlers.compaction.js";
|
|
import type { EmbeddedPiSubscribeContext } from "./pi-embedded-subscribe.handlers.types.js";
|
|
|
|
function createCompactionContext(params: {
|
|
storePath: string;
|
|
sessionKey: string;
|
|
agentId?: string;
|
|
initialCount: number;
|
|
}): EmbeddedPiSubscribeContext {
|
|
let compactionCount = params.initialCount;
|
|
return {
|
|
params: {
|
|
runId: "run-test",
|
|
session: { messages: [] } as never,
|
|
config: { session: { store: params.storePath } } as never,
|
|
sessionKey: params.sessionKey,
|
|
sessionId: "session-1",
|
|
agentId: params.agentId ?? "test-agent",
|
|
onAgentEvent: undefined,
|
|
},
|
|
state: {
|
|
compactionInFlight: true,
|
|
pendingCompactionRetry: 0,
|
|
} as never,
|
|
log: {
|
|
debug: vi.fn(),
|
|
warn: vi.fn(),
|
|
},
|
|
ensureCompactionPromise: vi.fn(),
|
|
noteCompactionRetry: vi.fn(),
|
|
maybeResolveCompactionWait: vi.fn(),
|
|
resolveCompactionRetry: vi.fn(),
|
|
resetForCompactionRetry: vi.fn(),
|
|
incrementCompactionCount: () => {
|
|
compactionCount += 1;
|
|
},
|
|
getCompactionCount: () => compactionCount,
|
|
} as unknown as EmbeddedPiSubscribeContext;
|
|
}
|
|
|
|
describe("reconcileSessionStoreCompactionCountAfterSuccess", () => {
|
|
it("raises the stored compaction count to the observed value", async () => {
|
|
const tmp = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-compaction-reconcile-"));
|
|
const storePath = path.join(tmp, "sessions.json");
|
|
const sessionKey = "main";
|
|
await seedSessionStore({
|
|
storePath,
|
|
sessionKey,
|
|
compactionCount: 1,
|
|
});
|
|
|
|
const nextCount = await reconcileSessionStoreCompactionCountAfterSuccess({
|
|
sessionKey,
|
|
agentId: "test-agent",
|
|
configStore: storePath,
|
|
observedCompactionCount: 2,
|
|
now: 2_000,
|
|
});
|
|
|
|
expect(nextCount).toBe(2);
|
|
expect(await readCompactionCount(storePath, sessionKey)).toBe(2);
|
|
});
|
|
|
|
it("does not double count when the store is already at or above the observed value", async () => {
|
|
const tmp = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-compaction-idempotent-"));
|
|
const storePath = path.join(tmp, "sessions.json");
|
|
const sessionKey = "main";
|
|
await seedSessionStore({
|
|
storePath,
|
|
sessionKey,
|
|
compactionCount: 3,
|
|
});
|
|
|
|
const nextCount = await reconcileSessionStoreCompactionCountAfterSuccess({
|
|
sessionKey,
|
|
agentId: "test-agent",
|
|
configStore: storePath,
|
|
observedCompactionCount: 2,
|
|
now: 2_000,
|
|
});
|
|
|
|
expect(nextCount).toBe(3);
|
|
expect(await readCompactionCount(storePath, sessionKey)).toBe(3);
|
|
});
|
|
});
|
|
|
|
describe("handleAutoCompactionEnd", () => {
|
|
it("reconciles the session store after a successful compaction end event", async () => {
|
|
const tmp = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-compaction-handler-"));
|
|
const storePath = path.join(tmp, "sessions.json");
|
|
const sessionKey = "main";
|
|
await seedSessionStore({
|
|
storePath,
|
|
sessionKey,
|
|
compactionCount: 1,
|
|
});
|
|
|
|
const ctx = createCompactionContext({
|
|
storePath,
|
|
sessionKey,
|
|
initialCount: 1,
|
|
});
|
|
|
|
handleAutoCompactionEnd(ctx, {
|
|
type: "auto_compaction_end",
|
|
result: { kept: 12 },
|
|
willRetry: false,
|
|
aborted: false,
|
|
} as never);
|
|
|
|
await waitForCompactionCount({
|
|
storePath,
|
|
sessionKey,
|
|
expected: 2,
|
|
});
|
|
|
|
expect(await readCompactionCount(storePath, sessionKey)).toBe(2);
|
|
});
|
|
});
|