From d2e55b01f2b0284c5fe1e0273a7313035d44608b Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Wed, 29 Apr 2026 20:24:05 +0100 Subject: [PATCH] perf(tests): speed up channel plugin id tests --- src/plugins/channel-plugin-ids.test.ts | 81 +++++++++-------------- src/plugins/gateway-startup-plugin-ids.ts | 36 ++++++---- 2 files changed, 54 insertions(+), 63 deletions(-) diff --git a/src/plugins/channel-plugin-ids.test.ts b/src/plugins/channel-plugin-ids.test.ts index 55f2dbc66fa..d89fd770189 100644 --- a/src/plugins/channel-plugin-ids.test.ts +++ b/src/plugins/channel-plugin-ids.test.ts @@ -43,36 +43,17 @@ vi.mock("../channels/config-presence.js", () => ({ hasMeaningfulChannelConfig, })); -vi.mock("./manifest-registry.js", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - loadPluginManifestRegistry, - }; -}); +vi.mock("./manifest-registry-installed.js", () => ({ + loadPluginManifestRegistryForInstalledIndex, +})); -vi.mock("./manifest-registry-installed.js", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - loadPluginManifestRegistryForInstalledIndex, - }; -}); +vi.mock("./plugin-registry-snapshot.js", () => ({ loadPluginRegistrySnapshot })); -vi.mock("./plugin-registry.js", async (importOriginal) => { - const actual = await importOriginal(); +vi.mock("./plugin-registry-contributions.js", async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, loadPluginManifestRegistryForPluginRegistry, - loadPluginRegistrySnapshot, - }; -}); - -vi.mock("./installed-plugin-index-store.js", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - readPersistedInstalledPluginIndexSync: vi.fn(() => null), }; }); @@ -87,7 +68,9 @@ import { resolveGatewayStartupPluginIds, } from "./channel-plugin-ids.js"; -function withManifestLoadPaths(plugin: T): T { +function withManifestLoadPaths( + plugin: T, +): T & Pick { return { rootDir: `/tmp/plugins/${plugin.id}`, source: `/tmp/plugins/${plugin.id}/index.ts`, @@ -98,7 +81,7 @@ function withManifestLoadPaths(plugin: T): T { }; } -function createManifestRegistryFixture() { +function createManifestRegistryFixture(): PluginManifestRegistry { return { plugins: [ { @@ -282,18 +265,18 @@ function createManifestRegistryFixture() { providers: [], cliBackends: [], }, - ].map(withManifestLoadPaths), + ].map(withManifestLoadPaths) as PluginManifestRecord[], diagnostics: [], }; } -function createManifestRegistryFixtureWithWorkspaceDemoChannel() { +function createManifestRegistryFixtureWithWorkspaceDemoChannel(): PluginManifestRegistry { const fixture = createManifestRegistryFixture(); return { ...fixture, plugins: [ ...fixture.plugins, - { + withManifestLoadPaths({ id: "workspace-demo-channel-plugin", channels: ["demo-channel"], startupDeferConfiguredChannelFullLoadUntilAfterListen: true, @@ -301,8 +284,8 @@ function createManifestRegistryFixtureWithWorkspaceDemoChannel() { enabledByDefault: undefined, providers: [], cliBackends: [], - }, - ].map(withManifestLoadPaths), + }), + ], }; } @@ -379,6 +362,15 @@ function filterManifestRegistryForInstalledIndex(params: { }; } +function useManifestRegistryFixture( + registry: PluginManifestRegistry = createManifestRegistryFixture(), +) { + const index = createInstalledPluginIndexFixture(registry); + loadPluginManifestRegistry.mockReset().mockReturnValue(registry); + loadPluginRegistrySnapshot.mockReset().mockReturnValue(index); + return { registry, index }; +} + function expectStartupPluginIds(params: { config: OpenClawConfig; activationSourceConfig?: OpenClawConfig; @@ -544,10 +536,7 @@ describe("resolveGatewayStartupPluginIds", () => { } return true; }); - loadPluginManifestRegistry.mockReset().mockReturnValue(createManifestRegistryFixture()); - loadPluginRegistrySnapshot - .mockReset() - .mockImplementation(() => createInstalledPluginIndexFixture()); + useManifestRegistryFixture(); loadPluginManifestRegistryForInstalledIndex .mockReset() .mockImplementation(filterManifestRegistryForInstalledIndex); @@ -778,9 +767,7 @@ describe("resolveGatewayStartupPluginIds", () => { }); it("does not let weak channel presence start untrusted workspace channel owners", () => { - loadPluginManifestRegistry - .mockReset() - .mockReturnValue(createManifestRegistryFixtureWithWorkspaceDemoChannel()); + useManifestRegistryFixture(createManifestRegistryFixtureWithWorkspaceDemoChannel()); listPotentialConfiguredChannelIds.mockReturnValue(["demo-channel"]); listPotentialConfiguredChannelPresenceSignals.mockReturnValue([ { channelId: "demo-channel", source: "env" }, @@ -807,9 +794,7 @@ describe("resolveGatewayStartupPluginIds", () => { }); it("keeps explicitly trusted deferred channel owners eligible at startup", () => { - loadPluginManifestRegistry - .mockReset() - .mockReturnValue(createManifestRegistryFixtureWithWorkspaceDemoChannel()); + useManifestRegistryFixture(createManifestRegistryFixtureWithWorkspaceDemoChannel()); expect( resolveConfiguredDeferredChannelPluginIds({ config: { @@ -879,9 +864,7 @@ describe("resolveGatewayStartupPluginIds", () => { }); it("does not treat persisted auth alone as deferred channel startup intent", () => { - loadPluginManifestRegistry - .mockReset() - .mockReturnValue(createManifestRegistryFixtureWithWorkspaceDemoChannel()); + useManifestRegistryFixture(createManifestRegistryFixtureWithWorkspaceDemoChannel()); listPotentialConfiguredChannelIds.mockImplementation( ( _config: OpenClawConfig, @@ -906,9 +889,7 @@ describe("resolveGatewayStartupPluginIds", () => { }); it("does not treat explicitly disabled stale channel config as deferred startup intent", () => { - loadPluginManifestRegistry - .mockReset() - .mockReturnValue(createManifestRegistryFixtureWithWorkspaceDemoChannel()); + useManifestRegistryFixture(createManifestRegistryFixtureWithWorkspaceDemoChannel()); expect( resolveConfiguredDeferredChannelPluginIds({ @@ -1090,7 +1071,7 @@ describe("resolveConfiguredChannelPluginIds", () => { } return false; }); - loadPluginManifestRegistry.mockReset().mockReturnValue(createManifestRegistryFixture()); + useManifestRegistryFixture(); }); it("uses manifest activation channel ownership before falling back to direct channel lists", () => { @@ -1268,7 +1249,7 @@ describe("listConfiguredChannelIdsForReadOnlyScope", () => { listPotentialConfiguredChannelPresenceSignals.mockReset().mockReturnValue([]); hasPotentialConfiguredChannels.mockReset().mockReturnValue(false); hasMeaningfulChannelConfig.mockClear(); - loadPluginManifestRegistry.mockReset().mockReturnValue(createManifestRegistryFixture()); + useManifestRegistryFixture(); }); it("filters bundled ambient channel triggers through effective activation", () => { diff --git a/src/plugins/gateway-startup-plugin-ids.ts b/src/plugins/gateway-startup-plugin-ids.ts index 9b72b65a04b..8523aa9845a 100644 --- a/src/plugins/gateway-startup-plugin-ids.ts +++ b/src/plugins/gateway-startup-plugin-ids.ts @@ -146,26 +146,34 @@ function shouldConsiderForGatewayStartup(params: { function hasConfiguredStartupChannel(params: { plugin: InstalledPluginIndexRecord; - manifestRegistry: PluginManifestRegistry; + manifestLookup: ManifestRegistryLookup; configuredChannelIds: ReadonlySet; }): boolean { - return listManifestChannelIds(params.manifestRegistry, params.plugin.pluginId).some((channelId) => + return listManifestChannelIds(params.manifestLookup, params.plugin.pluginId).some((channelId) => params.configuredChannelIds.has(channelId), ); } -function listManifestChannelIds( +type ManifestRegistryLookup = ReadonlyMap; + +function createManifestRegistryLookup( manifestRegistry: PluginManifestRegistry, +): ManifestRegistryLookup { + return new Map(manifestRegistry.plugins.map((plugin) => [plugin.id, plugin])); +} + +function listManifestChannelIds( + manifestLookup: ManifestRegistryLookup, pluginId: string, ): readonly string[] { - return manifestRegistry.plugins.find((plugin) => plugin.id === pluginId)?.channels ?? []; + return manifestLookup.get(pluginId)?.channels ?? []; } function findManifestPlugin( - manifestRegistry: PluginManifestRegistry, + manifestLookup: ManifestRegistryLookup, pluginId: string, ): PluginManifestRecord | undefined { - return manifestRegistry.plugins.find((plugin) => plugin.id === pluginId); + return manifestLookup.get(pluginId); } function hasConfiguredActivationPath(params: { @@ -223,7 +231,7 @@ function canStartConfiguredChannelPlugin(params: { plugins: ReturnType; rootConfig?: OpenClawConfig; }; - manifestRegistry: PluginManifestRegistry; + manifestLookup: ManifestRegistryLookup; }): boolean { if (!params.pluginsConfig.enabled) { return false; @@ -236,7 +244,7 @@ function canStartConfiguredChannelPlugin(params: { } const explicitBundledChannelConfig = params.plugin.origin === "bundled" && - listManifestChannelIds(params.manifestRegistry, params.plugin.pluginId).some((channelId) => + listManifestChannelIds(params.manifestLookup, params.plugin.pluginId).some((channelId) => hasExplicitChannelConfig({ config: params.activationSource.rootConfig ?? params.config, channelId, @@ -309,12 +317,13 @@ export function resolveConfiguredDeferredChannelPluginIdsFromRegistry(params: { plugins: pluginsConfig, rootConfig: params.config, }; + const manifestLookup = createManifestRegistryLookup(params.manifestRegistry); return params.index.plugins .filter( (plugin) => hasConfiguredStartupChannel({ plugin, - manifestRegistry: params.manifestRegistry, + manifestLookup, configuredChannelIds, }) && plugin.startup.deferConfiguredChannelFullLoadUntilAfterListen && @@ -323,7 +332,7 @@ export function resolveConfiguredDeferredChannelPluginIdsFromRegistry(params: { config: params.config, pluginsConfig, activationSource, - manifestRegistry: params.manifestRegistry, + manifestLookup, }), ) .map((plugin) => plugin.pluginId); @@ -385,6 +394,7 @@ export function resolveGatewayStartupPluginIdsFromRegistry(params: { const disableLegacyImplicitStartupSidecars = shouldDisableLegacyImplicitStartupSidecars( params.env, ); + const manifestLookup = createManifestRegistryLookup(params.manifestRegistry); const memorySlotStartupPluginId = resolveMemorySlotStartupPluginId({ activationSourceConfig, activationSourcePlugins, @@ -394,11 +404,11 @@ export function resolveGatewayStartupPluginIdsFromRegistry(params: { }); return params.index.plugins .filter((plugin) => { - const manifest = findManifestPlugin(params.manifestRegistry, plugin.pluginId); + const manifest = findManifestPlugin(manifestLookup, plugin.pluginId); if ( hasConfiguredStartupChannel({ plugin, - manifestRegistry: params.manifestRegistry, + manifestLookup, configuredChannelIds, }) ) { @@ -407,7 +417,7 @@ export function resolveGatewayStartupPluginIdsFromRegistry(params: { config: params.config, pluginsConfig, activationSource, - manifestRegistry: params.manifestRegistry, + manifestLookup, }); } if (