mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-05-15 22:30:38 +08:00
174 lines
5.3 KiB
JavaScript
174 lines
5.3 KiB
JavaScript
import assert from "node:assert/strict";
|
|
|
|
import {
|
|
installResolveHooks,
|
|
toDataModuleUrl,
|
|
} from "../helpers/register-hooks-compat.mjs";
|
|
|
|
installResolveHooks([
|
|
{
|
|
specifiers: ["../../../../../script.js"],
|
|
url: toDataModuleUrl("export function getRequestHeaders() { return {}; }"),
|
|
},
|
|
{
|
|
specifiers: ["../../../../extensions.js"],
|
|
url: toDataModuleUrl("export const extension_settings = { st_bme: {} };"),
|
|
},
|
|
]);
|
|
|
|
import {
|
|
createAuthorityE2eContext,
|
|
createAuthorityE2eContractGraph,
|
|
runAuthorityE2eStep,
|
|
} from "../helpers/authority-e2e-context.mjs";
|
|
|
|
const { buildLukerGraphCheckpointV2 } = await import("../../graph/graph-persistence.js");
|
|
const {
|
|
applyAuthorityCheckpointToStore,
|
|
buildAuthorityConsistencyAudit,
|
|
buildAuthorityCheckpointImportSnapshot,
|
|
} = await import("../../maintenance/authority-consistency.js");
|
|
const { createAuthorityBlobAdapter } = await import("../../maintenance/authority-blob-adapter.js");
|
|
const { AuthorityGraphStore } = await import("../../sync/authority-graph-store.js");
|
|
|
|
const context = createAuthorityE2eContext({
|
|
skipMessage:
|
|
"authority checkpoint restore E2E skipped: set AUTHORITY_E2E_BASE_URL to run against a real Authority server",
|
|
});
|
|
|
|
if (context.skip) {
|
|
console.log(context.skipMessage);
|
|
process.exit(0);
|
|
}
|
|
|
|
const checkpointPath = String(
|
|
context.env.AUTHORITY_E2E_CHECKPOINT_PATH ||
|
|
`user/files/ST-BME_luker_checkpoint_${context.runId}-restore.json`,
|
|
);
|
|
const graph = createAuthorityE2eContractGraph(context.chatId, `${context.runId}-restore`, {
|
|
revision: 5,
|
|
});
|
|
const checkpoint = buildLukerGraphCheckpointV2(graph, {
|
|
revision: graph.meta.revision,
|
|
chatId: context.chatId,
|
|
integrity: `${context.runId}-integrity`,
|
|
reason: "authority-e2e-checkpoint-restore",
|
|
storageTier: "authority-e2e",
|
|
});
|
|
|
|
console.log(
|
|
`authority-checkpoint-restore E2E started: ${JSON.stringify({
|
|
baseUrl: context.baseUrl,
|
|
chatId: context.chatId,
|
|
checkpointPath,
|
|
})}`,
|
|
);
|
|
|
|
await runAuthorityE2eStep("checkpoint-restore-roundtrip", async () => {
|
|
const adapter = createAuthorityBlobAdapter(
|
|
{
|
|
authorityBaseUrl: context.baseUrl,
|
|
authorityBlobNamespace: context.namespace,
|
|
},
|
|
{
|
|
fetchImpl: context.fetchImpl,
|
|
headerProvider: context.headerProvider,
|
|
},
|
|
);
|
|
const store = new AuthorityGraphStore(context.chatId, {
|
|
baseUrl: context.baseUrl,
|
|
fetchImpl: context.fetchImpl,
|
|
headerProvider: context.headerProvider,
|
|
});
|
|
let deleteResult = null;
|
|
try {
|
|
const prepared = buildAuthorityCheckpointImportSnapshot(checkpoint, {
|
|
chatId: context.chatId,
|
|
path: checkpointPath,
|
|
source: "authority-e2e-checkpoint-restore",
|
|
});
|
|
assert.equal(prepared.ok, true);
|
|
|
|
const writeResult = await adapter.writeJson(checkpointPath, checkpoint, {
|
|
metadata: {
|
|
chatId: context.chatId,
|
|
revision: graph.meta.revision,
|
|
reason: "authority-e2e-checkpoint-restore",
|
|
kind: "luker-checkpoint",
|
|
},
|
|
});
|
|
assert.equal(writeResult.ok, true);
|
|
|
|
await store.open();
|
|
await store.clearAll();
|
|
const restoreResult = await applyAuthorityCheckpointToStore(store, checkpoint, {
|
|
chatId: context.chatId,
|
|
path: checkpointPath,
|
|
source: "authority-e2e-checkpoint-restore",
|
|
markSyncDirty: false,
|
|
});
|
|
assert.equal(restoreResult.ok, true);
|
|
assert.equal(restoreResult.restored, true);
|
|
|
|
const snapshot = await store.exportSnapshot({ includeTombstones: false });
|
|
assert.equal(snapshot.meta.chatId, context.chatId);
|
|
assert.equal(snapshot.meta.revision, graph.meta.revision);
|
|
assert.equal(snapshot.nodes.length, graph.nodes.length);
|
|
assert.ok(snapshot.nodes.some((node) => node.id === graph.nodes[0].id));
|
|
|
|
const blobRead = await adapter.readJson(checkpointPath);
|
|
assert.equal(blobRead.exists, true);
|
|
const audit = buildAuthorityConsistencyAudit({
|
|
chatId: context.chatId,
|
|
collectionId: context.collectionId,
|
|
capability: {
|
|
blobReady: true,
|
|
},
|
|
runtimeGraph: {
|
|
meta: { revision: graph.meta.revision },
|
|
nodes: graph.nodes,
|
|
edges: graph.edges,
|
|
vectorIndexState: {
|
|
collectionId: context.collectionId,
|
|
dirty: false,
|
|
},
|
|
},
|
|
graphPersistenceState: {
|
|
chatId: context.chatId,
|
|
revision: graph.meta.revision,
|
|
authorityBlobCheckpointPath: checkpointPath,
|
|
authorityBlobCheckpointRevision: graph.meta.revision,
|
|
},
|
|
sqlSnapshot: snapshot,
|
|
blobResult: {
|
|
ok: true,
|
|
exists: true,
|
|
path: checkpointPath,
|
|
checkpoint: blobRead.payload,
|
|
},
|
|
triviumStat: {
|
|
revision: graph.meta.revision,
|
|
namespace: context.collectionId,
|
|
itemCount: graph.nodes.length,
|
|
linkCount: graph.edges.length,
|
|
},
|
|
});
|
|
assert.equal(audit.summary.level, "success");
|
|
assert.equal(audit.drift.checkpointRestorable, true);
|
|
return {
|
|
revision: snapshot.meta.revision,
|
|
nodes: snapshot.nodes.length,
|
|
actions: audit.actions,
|
|
};
|
|
} finally {
|
|
await store.clearAll().catch(() => null);
|
|
await store.close().catch(() => null);
|
|
deleteResult = await adapter.delete(checkpointPath).catch(() => null);
|
|
if (deleteResult) {
|
|
assert.equal(deleteResult.ok, true);
|
|
}
|
|
}
|
|
});
|
|
|
|
console.log("authority-checkpoint-restore E2E passed");
|