test(commands): share daemon health setup helpers

This commit is contained in:
Vincent Koc
2026-04-12 09:44:47 +01:00
parent 99e3d4a069
commit b2427bd1f4

View File

@@ -190,6 +190,58 @@ async function expectLocalJsonSetupFailure(stateDir: string, runtimeWithCapture:
).rejects.toThrow("exit should not be reached after runtime.error");
}
function createLocalDaemonSetupOptions(stateDir: string) {
return {
nonInteractive: true,
mode: "local" as const,
workspace: path.join(stateDir, "openclaw"),
authChoice: "skip" as const,
skipSkills: true,
skipHealth: false,
installDaemon: true,
gatewayBind: "loopback" as const,
};
}
async function runLocalDaemonSetup(stateDir: string, runtimeEnv: RuntimeEnv = runtime) {
await runNonInteractiveSetup(createLocalDaemonSetupOptions(stateDir), runtimeEnv);
}
async function withMockedPlatform<T>(platform: NodeJS.Platform, run: () => Promise<T>): Promise<T> {
const platformSpy = vi.spyOn(process, "platform", "get").mockReturnValue(platform);
try {
return await run();
} finally {
platformSpy.mockRestore();
}
}
function mockGatewayReachableWithCapturedTimeouts() {
let capturedDeadlineMs: number | undefined;
let capturedProbeTimeoutMs: number | undefined;
waitForGatewayReachableMock = vi.fn(
async (params: {
url: string;
token?: string;
password?: string;
deadlineMs?: number;
probeTimeoutMs?: number;
}) => {
capturedDeadlineMs = params.deadlineMs;
capturedProbeTimeoutMs = params.probeTimeoutMs;
return { ok: true };
},
);
return {
get deadlineMs() {
return capturedDeadlineMs;
},
get probeTimeoutMs() {
return capturedProbeTimeoutMs;
},
};
}
describe("onboard (non-interactive): gateway and remote auth", () => {
let envSnapshot: ReturnType<typeof captureEnv>;
let tempHome: string | undefined;
@@ -507,82 +559,27 @@ describe("onboard (non-interactive): gateway and remote auth", () => {
it("uses a longer health deadline when daemon install was requested", async () => {
await withStateDir("state-local-daemon-health-", async (stateDir) => {
let capturedDeadlineMs: number | undefined;
let capturedProbeTimeoutMs: number | undefined;
waitForGatewayReachableMock = vi.fn(
async (params: {
url: string;
token?: string;
password?: string;
deadlineMs?: number;
probeTimeoutMs?: number;
}) => {
capturedDeadlineMs = params.deadlineMs;
capturedProbeTimeoutMs = params.probeTimeoutMs;
return { ok: true };
},
);
const captured = mockGatewayReachableWithCapturedTimeouts();
await runNonInteractiveSetup(
{
nonInteractive: true,
mode: "local",
workspace: path.join(stateDir, "openclaw"),
authChoice: "skip",
skipSkills: true,
skipHealth: false,
installDaemon: true,
gatewayBind: "loopback",
},
runtime,
);
await runLocalDaemonSetup(stateDir);
expect(installGatewayDaemonNonInteractiveMock).toHaveBeenCalledTimes(1);
expect(capturedDeadlineMs).toBe(45_000);
expect(capturedProbeTimeoutMs).toBe(10_000);
expect(captured.deadlineMs).toBe(45_000);
expect(captured.probeTimeoutMs).toBe(10_000);
});
}, 60_000);
it("uses a longer Windows health deadline when daemon install was requested", async () => {
await withStateDir("state-local-daemon-health-win-", async (stateDir) => {
let capturedDeadlineMs: number | undefined;
let capturedProbeTimeoutMs: number | undefined;
waitForGatewayReachableMock = vi.fn(
async (params: {
url: string;
token?: string;
password?: string;
deadlineMs?: number;
probeTimeoutMs?: number;
}) => {
capturedDeadlineMs = params.deadlineMs;
capturedProbeTimeoutMs = params.probeTimeoutMs;
return { ok: true };
},
);
const captured = mockGatewayReachableWithCapturedTimeouts();
const platformSpy = vi.spyOn(process, "platform", "get").mockReturnValue("win32");
try {
await runNonInteractiveSetup(
{
nonInteractive: true,
mode: "local",
workspace: path.join(stateDir, "openclaw"),
authChoice: "skip",
skipSkills: true,
skipHealth: false,
installDaemon: true,
gatewayBind: "loopback",
},
runtime,
);
} finally {
platformSpy.mockRestore();
}
await withMockedPlatform("win32", async () => {
await runLocalDaemonSetup(stateDir);
});
expect(installGatewayDaemonNonInteractiveMock).toHaveBeenCalledTimes(1);
expect(capturedDeadlineMs).toBe(90_000);
expect(capturedProbeTimeoutMs).toBe(15_000);
expect(captured.deadlineMs).toBe(90_000);
expect(captured.probeTimeoutMs).toBe(15_000);
});
}, 60_000);
@@ -590,24 +587,9 @@ describe("onboard (non-interactive): gateway and remote auth", () => {
await withStateDir("state-local-daemon-health-command-win-", async (stateDir) => {
waitForGatewayReachableMock = vi.fn(async () => ({ ok: true }));
const platformSpy = vi.spyOn(process, "platform", "get").mockReturnValue("win32");
try {
await runNonInteractiveSetup(
{
nonInteractive: true,
mode: "local",
workspace: path.join(stateDir, "openclaw"),
authChoice: "skip",
skipSkills: true,
skipHealth: false,
installDaemon: true,
gatewayBind: "loopback",
},
runtime,
);
} finally {
platformSpy.mockRestore();
}
await withMockedPlatform("win32", async () => {
await runLocalDaemonSetup(stateDir);
});
expect(healthCommandMock).toHaveBeenCalledTimes(1);
expect(healthCommandMock).toHaveBeenCalledWith(