fix(ci): restore cli runtime mocks and timeout exits

This commit is contained in:
Peter Steinberger
2026-03-22 23:43:16 +00:00
parent 85f8437399
commit 4e531d382b
11 changed files with 59 additions and 17 deletions

View File

@@ -34,13 +34,19 @@ const mockExit = vi.fn((code: number) => {
throw new Error(`__exit__:${code} - ${errorMessages}`);
});
vi.mock("../runtime.js", () => ({
defaultRuntime: {
log: (...args: unknown[]) => mockLog(...args),
error: (...args: unknown[]) => mockError(...args),
exit: (code: number) => mockExit(code),
},
}));
vi.mock("../runtime.js", async (importOriginal) => {
const actual = await importOriginal<typeof import("../runtime.js")>();
return {
...actual,
defaultRuntime: {
log: (...args: unknown[]) => mockLog(...args),
error: (...args: unknown[]) => mockError(...args),
writeJson: (value: unknown, space = 2) =>
mockLog(JSON.stringify(value, null, space > 0 ? space : undefined)),
exit: (code: number) => mockExit(code),
},
};
});
function buildSnapshot(params: {
resolved: OpenClawConfig;

View File

@@ -29,6 +29,7 @@ vi.mock("../runtime.js", () => ({
defaultRuntime: {
log: vi.fn(),
error: vi.fn(),
writeJson: vi.fn(),
exit: (code: number) => {
throw new Error(`__exit__:${code}`);
},

View File

@@ -28,6 +28,8 @@ vi.mock("../../runtime.js", () => ({
defaultRuntime: {
log: (message: string) => runtimeLogs.push(message),
error: (message: string) => runtimeErrors.push(message),
writeJson: (value: unknown, space = 2) =>
runtimeLogs.push(JSON.stringify(value, null, space > 0 ? space : undefined)),
exit: (code: number) => {
throw new Error(`__exit__:${code}`);
},

View File

@@ -1,13 +1,13 @@
import { vi } from "vitest";
import type { GatewayService } from "../../../daemon/service.js";
import type { RuntimeEnv } from "../../../runtime.js";
import type { OutputRuntimeEnv } from "../../../runtime.js";
import type { MockFn } from "../../../test-utils/vitest-mock-fn.js";
export const runtimeLogs: string[] = [];
type LifecycleRuntimeHarness = RuntimeEnv & {
error: MockFn<RuntimeEnv["error"]>;
exit: MockFn<RuntimeEnv["exit"]>;
type LifecycleRuntimeHarness = OutputRuntimeEnv & {
error: MockFn<OutputRuntimeEnv["error"]>;
exit: MockFn<OutputRuntimeEnv["exit"]>;
};
type LifecycleServiceHarness = GatewayService & {
@@ -24,6 +24,12 @@ export const defaultRuntime: LifecycleRuntimeHarness = {
log: (...args: unknown[]) => {
runtimeLogs.push(args.map((arg) => String(arg)).join(" "));
},
writeStdout: (value: string) => {
runtimeLogs.push(value);
},
writeJson: (value: unknown, space = 2) => {
runtimeLogs.push(JSON.stringify(value, null, space > 0 ? space : undefined));
},
error: vi.fn(),
exit: vi.fn((code: number) => {
throw new Error(`__exit__:${code}`);

View File

@@ -14,6 +14,7 @@ const withProgress = vi.fn(async (_opts: unknown, fn: () => Promise<unknown>) =>
const runtime = {
log: vi.fn(),
error: vi.fn(),
writeJson: vi.fn(),
exit: vi.fn(),
};

View File

@@ -39,6 +39,8 @@ vi.mock("../runtime.js", () => ({
defaultRuntime: {
log: (...args: unknown[]) => mocks.log(...args),
error: (...args: unknown[]) => mocks.error(...args),
writeJson: (value: unknown, space = 2) =>
mocks.log(JSON.stringify(value, null, space > 0 ? space : undefined)),
exit: (...args: unknown[]) => mocks.exit(...args),
},
}));

View File

@@ -15,6 +15,8 @@ vi.mock("../runtime.js", () => ({
defaultRuntime: {
log: (...args: unknown[]) => mockLog(...args),
error: (...args: unknown[]) => mockError(...args),
writeJson: (value: unknown, space = 2) =>
mockLog(JSON.stringify(value, null, space > 0 ? space : undefined)),
exit: (code: number) => mockExit(code),
},
}));

View File

@@ -6,6 +6,9 @@ const mocks = vi.hoisted(() => ({
runtime: {
log: vi.fn(),
error: vi.fn(),
writeJson: vi.fn((value: unknown, space = 2) => {
mocks.runtime.log(JSON.stringify(value, null, space > 0 ? space : undefined));
}),
exit: vi.fn(() => {
throw new Error("exit");
}),

View File

@@ -1,9 +1,9 @@
import type { RuntimeEnv } from "../runtime.js";
import type { OutputRuntimeEnv } from "../runtime.js";
export type CliRuntimeCapture = {
runtimeLogs: string[];
runtimeErrors: string[];
defaultRuntime: Pick<RuntimeEnv, "log" | "error" | "exit">;
defaultRuntime: Pick<OutputRuntimeEnv, "log" | "error" | "exit" | "writeJson" | "writeStdout">;
resetRuntimeCapture: () => void;
};
@@ -21,6 +21,12 @@ export function createCliRuntimeCapture(): CliRuntimeCapture {
error: (...args: unknown[]) => {
runtimeErrors.push(stringifyArgs(args));
},
writeStdout: (value: string) => {
runtimeLogs.push(value);
},
writeJson: (value: unknown, space = 2) => {
runtimeLogs.push(JSON.stringify(value, null, space > 0 ? space : undefined));
},
exit: (code: number) => {
throw new Error(`__exit__:${code}`);
},

View File

@@ -25,6 +25,12 @@ const formatPortDiagnostics = vi.fn();
const pathExists = vi.fn();
const syncPluginsForUpdateChannel = vi.fn();
const updateNpmInstalledPlugins = vi.fn();
const runtimeLog = vi.fn();
const runtimeError = vi.fn();
const runtimeExit = vi.fn();
const runtimeWriteJson = vi.fn((value: unknown, space = 2) =>
runtimeLog(JSON.stringify(value, null, space > 0 ? space : undefined)),
);
vi.mock("@clack/prompts", () => ({
confirm,
@@ -131,9 +137,10 @@ vi.mock("./daemon-cli.js", () => ({
// Mock the runtime
vi.mock("../runtime.js", () => ({
defaultRuntime: {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn(),
log: runtimeLog,
error: runtimeError,
writeJson: runtimeWriteJson,
exit: runtimeExit,
},
}));

View File

@@ -320,11 +320,17 @@ export async function runCommandWithTimeout(
: signal != null
? "signal"
: "exit";
const normalizedCode =
termination === "timeout" || termination === "no-output-timeout"
? code === 0
? 124
: code
: code;
resolve({
pid: child.pid ?? undefined,
stdout,
stderr,
code,
code: normalizedCode,
signal,
killed: child.killed,
termination,