mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 09:30:43 +00:00
111 lines
3.7 KiB
TypeScript
111 lines
3.7 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import type { InstalledPluginIndex } from "./installed-plugin-index.js";
|
|
import {
|
|
resolvePluginControlPlaneContext,
|
|
resolvePluginControlPlaneFingerprint,
|
|
resolvePluginDiscoveryContext,
|
|
resolvePluginDiscoveryFingerprint,
|
|
} from "./plugin-control-plane-context.js";
|
|
|
|
function createIndex(pluginId: string): InstalledPluginIndex {
|
|
return {
|
|
version: 1,
|
|
hostContractVersion: "test",
|
|
compatRegistryVersion: "test",
|
|
migrationVersion: 1,
|
|
policyHash: "policy",
|
|
generatedAtMs: 1,
|
|
installRecords: {},
|
|
diagnostics: [],
|
|
plugins: [
|
|
{
|
|
pluginId,
|
|
manifestPath: `/plugins/${pluginId}/openclaw.plugin.json`,
|
|
manifestHash: `${pluginId}-manifest-hash`,
|
|
rootDir: `/plugins/${pluginId}`,
|
|
origin: "global",
|
|
enabled: true,
|
|
startup: {
|
|
sidecar: false,
|
|
memory: false,
|
|
deferConfiguredChannelFullLoadUntilAfterListen: false,
|
|
agentHarnesses: [],
|
|
},
|
|
compat: [],
|
|
},
|
|
],
|
|
};
|
|
}
|
|
|
|
describe("plugin control-plane context", () => {
|
|
it("resolves env-sensitive discovery roots and load paths before fingerprinting", () => {
|
|
const config = { plugins: { load: { paths: ["~/plugins", "/opt/shared"] } } };
|
|
const envA = { HOME: "/home/a", OPENCLAW_HOME: "/openclaw/a" } as NodeJS.ProcessEnv;
|
|
const envB = { HOME: "/home/b", OPENCLAW_HOME: "/openclaw/b" } as NodeJS.ProcessEnv;
|
|
|
|
const contextA = resolvePluginDiscoveryContext({ config, env: envA });
|
|
const contextB = resolvePluginDiscoveryContext({ config, env: envB });
|
|
|
|
expect(contextA.loadPaths).toEqual(["/openclaw/a/plugins", "/opt/shared"]);
|
|
expect(contextB.loadPaths).toEqual(["/openclaw/b/plugins", "/opt/shared"]);
|
|
expect(resolvePluginDiscoveryFingerprint({ config, env: envA })).not.toBe(
|
|
resolvePluginDiscoveryFingerprint({ config, env: envB }),
|
|
);
|
|
});
|
|
|
|
it("includes policy, inventory, and activation in one control-plane fingerprint", () => {
|
|
const config = { plugins: { allow: ["demo"] } };
|
|
const base = resolvePluginControlPlaneFingerprint({
|
|
config,
|
|
env: { HOME: "/home/a", OPENCLAW_HOME: "/openclaw/a" } as NodeJS.ProcessEnv,
|
|
index: createIndex("demo"),
|
|
activationFingerprint: "activation-a",
|
|
});
|
|
|
|
expect(
|
|
resolvePluginControlPlaneFingerprint({
|
|
config,
|
|
env: { HOME: "/home/a", OPENCLAW_HOME: "/openclaw/a" } as NodeJS.ProcessEnv,
|
|
index: createIndex("other"),
|
|
activationFingerprint: "activation-a",
|
|
}),
|
|
).not.toBe(base);
|
|
expect(
|
|
resolvePluginControlPlaneFingerprint({
|
|
config,
|
|
env: { HOME: "/home/a", OPENCLAW_HOME: "/openclaw/a" } as NodeJS.ProcessEnv,
|
|
index: createIndex("demo"),
|
|
activationFingerprint: "activation-b",
|
|
}),
|
|
).not.toBe(base);
|
|
expect(
|
|
resolvePluginControlPlaneFingerprint({
|
|
config: { plugins: { deny: ["demo"] } },
|
|
env: { HOME: "/home/a", OPENCLAW_HOME: "/openclaw/a" } as NodeJS.ProcessEnv,
|
|
index: createIndex("demo"),
|
|
activationFingerprint: "activation-a",
|
|
}),
|
|
).not.toBe(base);
|
|
});
|
|
|
|
it("keeps the canonical context inspectable for cache diagnostics", () => {
|
|
const context = resolvePluginControlPlaneContext({
|
|
config: { plugins: { load: { paths: ["/opt/plugins"] } } },
|
|
env: { HOME: "/home/a", OPENCLAW_HOME: "/openclaw/a" } as NodeJS.ProcessEnv,
|
|
inventoryFingerprint: "inventory",
|
|
policyHash: "policy",
|
|
});
|
|
|
|
expect(context).toMatchObject({
|
|
discovery: {
|
|
loadPaths: ["/opt/plugins"],
|
|
roots: {
|
|
global: "/openclaw/a/.openclaw/extensions",
|
|
},
|
|
},
|
|
inventoryFingerprint: "inventory",
|
|
policyFingerprint: "policy",
|
|
});
|
|
});
|
|
});
|