File size: 3,987 Bytes
4c76b0d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import { afterEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../../config/types.openclaw.js";
import {
  getCurrentPluginMetadataSnapshot,
  setGatewayPluginMetadataSnapshot,
} from "../current-plugin-metadata-snapshot.js";
import { getGatewayPluginMetadataSnapshot } from "../current-plugin-metadata-state.js";
import { resolveInstalledPluginIndexPolicyHash } from "../installed-plugin-index-policy.js";
import { clearPluginMetadataLifecycleCaches } from "../plugin-metadata-lifecycle.js";
import type { PluginMetadataSnapshot } from "../plugin-metadata-snapshot.types.js";
import { resolvePluginRuntimeLoadContext } from "./load-context.resolve.js";

const resolvePluginMetadataSnapshotMock = vi.hoisted(() => vi.fn());

vi.mock("../plugin-metadata-snapshot.js", async (importOriginal) => ({
  ...(await importOriginal<typeof import("../plugin-metadata-snapshot.js")>()),
  resolvePluginMetadataSnapshot: resolvePluginMetadataSnapshotMock,
}));

function createSnapshot(params: {
  config: OpenClawConfig;
  workspaceDir: string;
}): PluginMetadataSnapshot {
  const policyHash = resolveInstalledPluginIndexPolicyHash(params.config);
  const index: PluginMetadataSnapshot["index"] = {
    version: 1,
    hostContractVersion: "test",
    compatRegistryVersion: "test",
    migrationVersion: 1,
    policyHash,
    generatedAtMs: 1,
    installRecords: {},
    plugins: [],
    diagnostics: [],
  };
  return {
    policyHash,
    workspaceDir: params.workspaceDir,
    index,
    registryIndex: index,
    registryDiagnostics: [],
    manifestRegistry: { plugins: [], diagnostics: [] },
    plugins: [],
    diagnostics: [],
    byPluginId: new Map(),
    normalizePluginId: (pluginId) => pluginId,
    declaredProviderOwners: new Map(),
    owners: {
      channels: new Map(),
      channelConfigs: new Map(),
      providers: new Map(),
      modelCatalogProviders: new Map(),
      cliBackends: new Map(),
      setupProviders: new Map(),
      commandAliases: new Map(),
      contracts: new Map(),
      modelIdNormalizationPolicies: new Map(),
    },
    metrics: {
      registrySnapshotMs: 0,
      manifestRegistryMs: 0,
      ownerMapsMs: 0,
      totalMs: 0,
      indexPluginCount: 0,
      manifestPluginCount: 0,
    },
    discovery: { candidates: [], diagnostics: [] },
  };
}

describe("plugin runtime load context current snapshot ownership", () => {
  afterEach(() => {
    resolvePluginMetadataSnapshotMock.mockReset();
    clearPluginMetadataLifecycleCaches();
  });

  it("keeps explicit operation metadata from replacing the Gateway startup inventory", () => {
    const lifecycleConfig = { plugins: { allow: ["lifecycle"] } };
    const operationConfig = { plugins: { allow: ["operation"] } };
    const lifecycleWorkspace = "/workspace/lifecycle";
    const operationWorkspace = "/workspace/operation";
    const lifecycleSnapshot = createSnapshot({
      config: lifecycleConfig,
      workspaceDir: lifecycleWorkspace,
    });
    const operationSnapshot = createSnapshot({
      config: operationConfig,
      workspaceDir: operationWorkspace,
    });
    setGatewayPluginMetadataSnapshot(lifecycleSnapshot, {
      config: lifecycleConfig,
      workspaceDir: lifecycleWorkspace,
    });
    const context = resolvePluginRuntimeLoadContext({
      config: operationConfig,
      workspaceDir: operationWorkspace,
      metadataSnapshot: operationSnapshot,
    });

    expect(context.metadataSnapshot).toBe(operationSnapshot);
    expect(resolvePluginMetadataSnapshotMock).not.toHaveBeenCalled();
    expect(getGatewayPluginMetadataSnapshot()).toBe(lifecycleSnapshot);
    expect(
      getCurrentPluginMetadataSnapshot({
        config: lifecycleConfig,
        workspaceDir: lifecycleWorkspace,
      }),
    ).toBe(lifecycleSnapshot);
    expect(
      getCurrentPluginMetadataSnapshot({
        config: operationConfig,
        workspaceDir: operationWorkspace,
      }),
    ).toBe(lifecycleSnapshot);
  });
});