Files
openclaw/src/infra/sqlite-wal.test.ts
2026-04-27 12:25:10 +01:00

68 lines
1.9 KiB
TypeScript

import type { DatabaseSync } from "node:sqlite";
import { afterEach, describe, expect, it, vi } from "vitest";
import {
DEFAULT_SQLITE_WAL_AUTOCHECKPOINT_PAGES,
configureSqliteWalMaintenance,
} from "./sqlite-wal.js";
function createMockDb(): DatabaseSync {
return {
exec: vi.fn(),
} as unknown as DatabaseSync;
}
describe("sqlite WAL maintenance", () => {
afterEach(() => {
vi.useRealTimers();
});
it("enables WAL mode and explicit autocheckpointing", () => {
const db = createMockDb();
configureSqliteWalMaintenance(db, { checkpointIntervalMs: 0 });
expect(db.exec).toHaveBeenNthCalledWith(1, "PRAGMA journal_mode = WAL;");
expect(db.exec).toHaveBeenNthCalledWith(
2,
`PRAGMA wal_autocheckpoint = ${DEFAULT_SQLITE_WAL_AUTOCHECKPOINT_PAGES};`,
);
});
it("runs periodic TRUNCATE checkpoints and stops them on close", () => {
vi.useFakeTimers();
const db = createMockDb();
const maintenance = configureSqliteWalMaintenance(db, { checkpointIntervalMs: 100 });
expect(db.exec).toHaveBeenCalledTimes(2);
vi.advanceTimersByTime(100);
expect(db.exec).toHaveBeenLastCalledWith("PRAGMA wal_checkpoint(TRUNCATE);");
expect(db.exec).toHaveBeenCalledTimes(3);
expect(maintenance.close()).toBe(true);
expect(db.exec).toHaveBeenCalledTimes(4);
vi.advanceTimersByTime(200);
expect(db.exec).toHaveBeenCalledTimes(4);
});
it("reports checkpoint errors without throwing from background maintenance", () => {
const db = createMockDb();
const error = new Error("busy");
const onCheckpointError = vi.fn();
vi.mocked(db.exec).mockImplementation((sql) => {
if (sql.includes("wal_checkpoint")) {
throw error;
}
});
const maintenance = configureSqliteWalMaintenance(db, {
checkpointIntervalMs: 0,
onCheckpointError,
});
expect(maintenance.checkpoint()).toBe(false);
expect(onCheckpointError).toHaveBeenCalledWith(error);
});
});