openclaw / src /plugin-state /plugin-blob-store.eviction.test.ts
SaylorTwift's picture
SaylorTwift HF Staff
Add files using upload-large-folder tool
76289e7 verified
Raw
History Blame Contribute Delete
2.44 kB
import { StatementSync } from "node:sqlite";
import { afterEach, expect, it, vi } from "vitest";
import { openOpenClawStateDatabase } from "../state/openclaw-state-db.js";
import { withOpenClawTestState } from "../test-utils/openclaw-test-state.js";
import {
createPluginBlobStoreForTests,
resetPluginBlobStoreForTests,
} from "./plugin-blob-store.js";
afterEach(() => {
vi.restoreAllMocks();
resetPluginBlobStoreForTests();
});
it("fetches only the eviction prefix needed for a bounded blob write", async () => {
await withOpenClawTestState({ label: "blob-eviction-prefix" }, async (state) => {
const store = createPluginBlobStoreForTests(
"diffs",
{
namespace: "artifacts",
maxEntries: 64,
maxBytesPerEntry: 16,
maxBytesPerNamespace: 1024,
},
state.env,
);
const { db } = openOpenClawStateDatabase({ env: state.env });
const insert = db.prepare(`INSERT INTO plugin_blob_entries
(plugin_id, namespace, entry_key, metadata_json, blob, created_at, expires_at)
VALUES ('diffs', 'artifacts', ?, '{}', ?, ?, NULL)`);
for (let index = 0; index < 64; index += 1) {
insert.run(`old-${index}`, new Uint8Array([index]), index);
}
let fetchedRows = 0;
// eslint-disable-next-line @typescript-eslint/unbound-method -- Invoke with the original native receiver.
const iterate = StatementSync.prototype.iterate;
const reads = vi.spyOn(StatementSync.prototype, "iterate").mockImplementation(function (
this: StatementSync,
...args
) {
const iterator = iterate.apply(this, args);
const next = iterator.next.bind(iterator);
vi.spyOn(iterator, "next").mockImplementation((...input) => {
const result = next(...input);
if (!result.done) {
fetchedRows += 1;
}
return result;
});
return iterator;
});
await store.register("new", new Uint8Array([255]), { retained: true });
reads.mockRestore();
expect(fetchedRows).toBeLessThanOrEqual(2);
await expect(store.lookup("old-0")).resolves.toBeUndefined();
await expect(store.lookup("old-1")).resolves.toMatchObject({ bytes: new Uint8Array([1]) });
await expect(store.lookup("new")).resolves.toMatchObject({ metadata: { retained: true } });
expect(await store.entries()).toHaveLength(64);
await store.clear();
expect(await store.entries()).toEqual([]);
});
});