openclaw/src/extension-host/loader-cache.test.ts
2026-03-15 23:15:24 +00:00

120 lines
3.1 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { PluginRegistry } from "../plugins/registry.js";
import {
buildExtensionHostRegistryCacheKey,
clearExtensionHostRegistryCache,
getCachedExtensionHostRegistry,
MAX_EXTENSION_HOST_REGISTRY_CACHE_ENTRIES,
setCachedExtensionHostRegistry,
} from "./loader-cache.js";
function createRegistry(id: string): PluginRegistry {
return {
plugins: [
{
id,
name: id,
source: `/plugins/${id}.js`,
origin: "workspace",
enabled: true,
status: "loaded",
lifecycleState: "registered",
toolNames: [],
hookNames: [],
channelIds: [],
providerIds: [],
gatewayMethods: [],
cliCommands: [],
services: [],
commands: [],
httpRoutes: 0,
hookCount: 0,
configSchema: false,
},
],
tools: [],
hooks: [],
typedHooks: [],
channels: [],
providers: [],
gatewayHandlers: {},
httpRoutes: [],
cliRegistrars: [],
services: [],
commands: [],
diagnostics: [],
};
}
describe("extension host loader cache", () => {
it("normalizes install paths into the cache key", () => {
const env = { ...process.env, HOME: "/tmp/home" };
const first = buildExtensionHostRegistryCacheKey({
workspaceDir: "/workspace",
plugins: {
enabled: true,
allow: [],
loadPaths: ["~/plugins"],
entries: {},
slots: {},
},
installs: {
demo: {
installPath: "~/demo-install",
sourcePath: "~/demo-source",
},
},
env,
});
const second = buildExtensionHostRegistryCacheKey({
workspaceDir: "/workspace",
plugins: {
enabled: true,
allow: [],
loadPaths: ["/tmp/home/plugins"],
entries: {},
slots: {},
},
installs: {
demo: {
installPath: "/tmp/home/demo-install",
sourcePath: "/tmp/home/demo-source",
},
},
env,
});
expect(first).toBe(second);
});
it("evicts least recently used registries", () => {
clearExtensionHostRegistryCache();
for (let index = 0; index < MAX_EXTENSION_HOST_REGISTRY_CACHE_ENTRIES + 1; index += 1) {
setCachedExtensionHostRegistry(`cache-${index}`, createRegistry(`plugin-${index}`));
}
expect(getCachedExtensionHostRegistry("cache-0")).toBeUndefined();
expect(
getCachedExtensionHostRegistry(`cache-${MAX_EXTENSION_HOST_REGISTRY_CACHE_ENTRIES}`),
).toBeDefined();
});
it("refreshes cache insertion order on reads", () => {
clearExtensionHostRegistryCache();
for (let index = 0; index < MAX_EXTENSION_HOST_REGISTRY_CACHE_ENTRIES; index += 1) {
setCachedExtensionHostRegistry(`cache-${index}`, createRegistry(`plugin-${index}`));
}
const refreshed = getCachedExtensionHostRegistry("cache-0");
expect(refreshed).toBeDefined();
setCachedExtensionHostRegistry("cache-new", createRegistry("plugin-new"));
expect(getCachedExtensionHostRegistry("cache-1")).toBeUndefined();
expect(getCachedExtensionHostRegistry("cache-0")).toBe(refreshed);
});
});