mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 08:30:42 +00:00
fix: reject stale plugin metadata inventory
This commit is contained in:
@@ -289,4 +289,70 @@ describe("loadPluginLookUpTable", () => {
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("rebuilds when a provided metadata snapshot has stale plugin inventory", async () => {
|
||||
const snapshotPlugins = [
|
||||
createManifestRecord({
|
||||
id: "telegram",
|
||||
origin: "bundled",
|
||||
channels: ["telegram"],
|
||||
}),
|
||||
];
|
||||
const requestedPlugins = [
|
||||
createManifestRecord({
|
||||
id: "telegram",
|
||||
origin: "bundled",
|
||||
channels: ["telegram"],
|
||||
}),
|
||||
createManifestRecord({
|
||||
id: "discord",
|
||||
origin: "bundled",
|
||||
channels: ["discord"],
|
||||
}),
|
||||
];
|
||||
const config = {
|
||||
channels: {
|
||||
telegram: { token: "configured" },
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
const policyHash = resolveInstalledPluginIndexPolicyHash(config);
|
||||
const snapshotIndex = createIndex(snapshotPlugins, { policyHash });
|
||||
const requestedIndex = createIndex(requestedPlugins, { policyHash });
|
||||
const snapshotRegistry: PluginManifestRegistry = {
|
||||
plugins: snapshotPlugins,
|
||||
diagnostics: [],
|
||||
};
|
||||
const requestedRegistry: PluginManifestRegistry = {
|
||||
plugins: requestedPlugins,
|
||||
diagnostics: [],
|
||||
};
|
||||
loadPluginManifestRegistryForInstalledIndex
|
||||
.mockReturnValueOnce(snapshotRegistry)
|
||||
.mockReturnValueOnce(requestedRegistry);
|
||||
const { loadPluginMetadataSnapshot } = await import("./plugin-metadata-snapshot.js");
|
||||
const { loadPluginLookUpTable } = await import("./plugin-lookup-table.js");
|
||||
|
||||
const metadataSnapshot = loadPluginMetadataSnapshot({
|
||||
config,
|
||||
env: {},
|
||||
index: snapshotIndex,
|
||||
});
|
||||
loadPluginManifestRegistryForInstalledIndex.mockClear();
|
||||
|
||||
const table = loadPluginLookUpTable({
|
||||
config,
|
||||
env: {},
|
||||
index: requestedIndex,
|
||||
metadataSnapshot,
|
||||
});
|
||||
|
||||
expect(loadPluginManifestRegistryForInstalledIndex).toHaveBeenCalledOnce();
|
||||
expect(loadPluginManifestRegistryForInstalledIndex).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
index: requestedIndex,
|
||||
config,
|
||||
}),
|
||||
);
|
||||
expect(table.manifestRegistry).toBe(requestedRegistry);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -60,6 +60,7 @@ export function loadPluginLookUpTable(params: LoadPluginLookUpTableParams): Plug
|
||||
snapshot: params.metadataSnapshot,
|
||||
config: requestedSnapshotConfig,
|
||||
workspaceDir: params.workspaceDir,
|
||||
index: params.index,
|
||||
})
|
||||
? params.metadataSnapshot
|
||||
: loadPluginMetadataSnapshot({
|
||||
|
||||
@@ -51,14 +51,48 @@ export type LoadPluginMetadataSnapshotParams = {
|
||||
index?: PluginRegistrySnapshot;
|
||||
};
|
||||
|
||||
function indexesMatch(
|
||||
left: PluginRegistrySnapshot | undefined,
|
||||
right: PluginRegistrySnapshot | undefined,
|
||||
): boolean {
|
||||
if (!left || !right) {
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
left.version !== right.version ||
|
||||
left.hostContractVersion !== right.hostContractVersion ||
|
||||
left.compatRegistryVersion !== right.compatRegistryVersion ||
|
||||
left.migrationVersion !== right.migrationVersion ||
|
||||
left.policyHash !== right.policyHash ||
|
||||
left.plugins.length !== right.plugins.length
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
for (let index = 0; index < left.plugins.length; index += 1) {
|
||||
const leftPlugin = left.plugins[index];
|
||||
const rightPlugin = right.plugins[index];
|
||||
if (
|
||||
!rightPlugin ||
|
||||
leftPlugin.pluginId !== rightPlugin.pluginId ||
|
||||
leftPlugin.manifestHash !== rightPlugin.manifestHash ||
|
||||
leftPlugin.installRecordHash !== rightPlugin.installRecordHash
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export function isPluginMetadataSnapshotCompatible(params: {
|
||||
snapshot: Pick<PluginMetadataSnapshot, "policyHash" | "workspaceDir">;
|
||||
snapshot: Pick<PluginMetadataSnapshot, "index" | "policyHash" | "workspaceDir">;
|
||||
config: OpenClawConfig;
|
||||
workspaceDir?: string;
|
||||
index?: PluginRegistrySnapshot;
|
||||
}): boolean {
|
||||
return (
|
||||
params.snapshot.policyHash === resolveInstalledPluginIndexPolicyHash(params.config) &&
|
||||
(params.snapshot.workspaceDir ?? "") === (params.workspaceDir ?? "")
|
||||
(params.snapshot.workspaceDir ?? "") === (params.workspaceDir ?? "") &&
|
||||
indexesMatch(params.snapshot.index, params.index)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user