Download src/plugin-state/plugin-state-store.fresh-store.test.ts from SaylorTwift/openclaw: direct link, hf CLI and curl.
- Browser
- Download file 4.32 kB
-
https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/plugin-state/plugin-state-store.fresh-store.test.ts
- Command line
-
hf download hf://SaylorTwift/openclaw/src/plugin-state/plugin-state-store.fresh-store.test.ts
-
curl -L -o plugin-state-store.fresh-store.test.ts https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/plugin-state/plugin-state-store.fresh-store.test.ts
4.32 kB
| // Fresh-store reads remain empty after checkpoint bootstrap; missing canonical tables stay errors. | |
| import { DatabaseSync } from "node:sqlite"; | |
| import { afterEach, describe, expect, it } from "vitest"; | |
| import { OPENCLAW_STATE_SCHEMA_VERSION } from "../state/openclaw-state-db-contract.js"; | |
| import { withOpenClawStateStartupMigrationCheckpointDatabase } from "../state/openclaw-state-db.js"; | |
| import { resolveOpenClawStateSqlitePath } from "../state/openclaw-state-db.paths.js"; | |
| import { withOpenClawTestState } from "../test-utils/openclaw-test-state.js"; | |
| import { | |
| countPluginStateLiveEntries, | |
| createPluginStateKeyedStore, | |
| pluginStateEntriesInKeyRange, | |
| resetPluginStateStoreForTests, | |
| } from "./plugin-state-store.js"; | |
| import { PluginStateStoreError } from "./plugin-state-store.types.js"; | |
| afterEach(() => { | |
| resetPluginStateStoreForTests({ closeDatabase: false }); | |
| }); | |
| async function expectPluginStateReadFailure( | |
| promise: Promise<unknown>, | |
| expected: { operation: "entries" | "lookup" | "count"; path: string }, | |
| ): Promise<void> { | |
| let storeError: unknown; | |
| try { | |
| await promise; | |
| } catch (error) { | |
| storeError = error; | |
| } | |
| expect(storeError).toBeInstanceOf(PluginStateStoreError); | |
| expect(storeError).toMatchObject({ | |
| code: "PLUGIN_STATE_READ_FAILED", | |
| operation: expected.operation, | |
| path: expected.path, | |
| }); | |
| } | |
| describe("plugin state fresh-store reads", () => { | |
| it("initializes an empty canonical plugin-state store before startup checkpoint reads", async () => { | |
| await withOpenClawTestState( | |
| { label: "plugin-state-read-only-table-missing", applyEnv: false }, | |
| async (state) => { | |
| const databasePath = resolveOpenClawStateSqlitePath(state.env); | |
| withOpenClawStateStartupMigrationCheckpointDatabase(() => undefined, { env: state.env }); | |
| const store = createPluginStateKeyedStore("discord", { | |
| namespace: "read-only-table-missing", | |
| maxEntries: 10, | |
| env: state.env, | |
| }); | |
| await expect(store.lookup("k")).resolves.toBeUndefined(); | |
| await expect(store.lookupMany(["k"])).resolves.toEqual([{ ok: true, value: undefined }]); | |
| await expect(store.entries()).resolves.toEqual([]); | |
| await expect(store.count()).resolves.toBe(0); | |
| expect( | |
| await pluginStateEntriesInKeyRange({ | |
| pluginId: "discord", | |
| namespace: "read-only-table-missing", | |
| keyStartInclusive: "a", | |
| keyEndExclusive: "z", | |
| limit: 1, | |
| env: state.env, | |
| }), | |
| ).toEqual([]); | |
| expect(countPluginStateLiveEntries("discord", state.env)).toBe(0); | |
| const verify = new DatabaseSync(databasePath, { readOnly: true }); | |
| try { | |
| expect(verify.prepare("PRAGMA user_version").get()).toEqual({ | |
| user_version: OPENCLAW_STATE_SCHEMA_VERSION, | |
| }); | |
| expect( | |
| verify | |
| .prepare("SELECT name FROM sqlite_schema WHERE name = 'plugin_state_entries'") | |
| .get(), | |
| ).toEqual({ name: "plugin_state_entries" }); | |
| } finally { | |
| verify.close(); | |
| } | |
| }, | |
| ); | |
| }); | |
| it("rejects a missing plugin-state table after another state table has been initialized", async () => { | |
| await withOpenClawTestState( | |
| { label: "plugin-state-read-only-table-damaged", applyEnv: false }, | |
| async (state) => { | |
| const databasePath = resolveOpenClawStateSqlitePath(state.env); | |
| withOpenClawStateStartupMigrationCheckpointDatabase(() => undefined, { env: state.env }); | |
| const database = new DatabaseSync(databasePath); | |
| database.exec("DROP TABLE plugin_state_entries"); | |
| database.close(); | |
| const store = createPluginStateKeyedStore("discord", { | |
| namespace: "read-only-table-damaged", | |
| maxEntries: 10, | |
| env: state.env, | |
| }); | |
| await expectPluginStateReadFailure(store.lookup("k"), { | |
| operation: "lookup", | |
| path: databasePath, | |
| }); | |
| await expectPluginStateReadFailure(store.entries(), { | |
| operation: "entries", | |
| path: databasePath, | |
| }); | |
| await expectPluginStateReadFailure(store.count(), { | |
| operation: "count", | |
| path: databasePath, | |
| }); | |
| }, | |
| ); | |
| }); | |
| }); | |