

























@@ -0,0 +1,104 @@
1+import { afterEach, describe, expect, it, vi } from "vitest";
2+3+const { runtimeRegistry } = vi.hoisted(() => ({
4+runtimeRegistry: new Map<string, { runtime: unknown }>(),
5+}));
6+7+const { realRuntime, realServiceStartMock, realServiceStopMock, createRealServiceMock } =
8+vi.hoisted(() => {
9+const runtime = { isHealthy: vi.fn(() => true), probeAvailability: vi.fn(async () => {}) };
10+const start = vi.fn(async () => {
11+runtimeRegistry.set("acpx", { runtime });
12+});
13+const stop = vi.fn(async () => {
14+runtimeRegistry.delete("acpx");
15+});
16+return {
17+realRuntime: runtime,
18+realServiceStartMock: start,
19+realServiceStopMock: stop,
20+createRealServiceMock: vi.fn(() => ({ id: "real-acpx-runtime", start, stop })),
21+};
22+});
23+24+vi.mock("openclaw/plugin-sdk/acp-runtime-backend", () => ({
25+getAcpRuntimeBackend: (id: string) => runtimeRegistry.get(id),
26+unregisterAcpRuntimeBackend: (id: string) => {
27+runtimeRegistry.delete(id);
28+},
29+}));
30+31+vi.mock("./src/service.js", () => ({
32+createAcpxRuntimeService: createRealServiceMock,
33+}));
34+35+import { createAcpxRuntimeService } from "./register.runtime.js";
36+37+const previousSkipRuntime = process.env.OPENCLAW_SKIP_ACPX_RUNTIME;
38+39+function restoreEnv(): void {
40+if (previousSkipRuntime === undefined) {
41+delete process.env.OPENCLAW_SKIP_ACPX_RUNTIME;
42+} else {
43+process.env.OPENCLAW_SKIP_ACPX_RUNTIME = previousSkipRuntime;
44+}
45+}
46+47+function createServiceContext() {
48+return {
49+workspaceDir: "/tmp/openclaw-acpx-register-test",
50+stateDir: "/tmp/openclaw-acpx-register-test/state",
51+config: {},
52+logger: {
53+info: vi.fn(),
54+warn: vi.fn(),
55+error: vi.fn(),
56+debug: vi.fn(),
57+},
58+};
59+}
60+61+describe("acpx register runtime service", () => {
62+afterEach(() => {
63+runtimeRegistry.clear();
64+realServiceStartMock.mockClear();
65+realServiceStopMock.mockClear();
66+createRealServiceMock.mockClear();
67+restoreEnv();
68+});
69+70+it("starts the real service by default while leaving probe policy to the inner service", async () => {
71+delete process.env.OPENCLAW_SKIP_ACPX_RUNTIME;
72+const ctx = createServiceContext();
73+const service = createAcpxRuntimeService({
74+pluginConfig: { timeoutSeconds: 10 },
75+});
76+77+await service.start(ctx as never);
78+79+expect(createRealServiceMock).toHaveBeenCalledWith({
80+pluginConfig: { timeoutSeconds: 10 },
81+});
82+expect(realServiceStartMock).toHaveBeenCalledWith(ctx);
83+expect(runtimeRegistry.get("acpx")?.runtime).toBe(realRuntime);
84+85+await service.stop?.(ctx as never);
86+87+expect(realServiceStopMock).toHaveBeenCalledWith(ctx);
88+expect(runtimeRegistry.get("acpx")).toBeUndefined();
89+});
90+91+it("keeps the explicit runtime skip env as the only outer startup skip", async () => {
92+process.env.OPENCLAW_SKIP_ACPX_RUNTIME = "1";
93+const ctx = createServiceContext();
94+const service = createAcpxRuntimeService();
95+96+await service.start(ctx as never);
97+98+expect(createRealServiceMock).not.toHaveBeenCalled();
99+expect(runtimeRegistry.get("acpx")).toBeUndefined();
100+expect(ctx.logger.info).toHaveBeenCalledWith(
101+"skipping embedded acpx runtime backend (OPENCLAW_SKIP_ACPX_RUNTIME=1)",
102+);
103+});
104+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。