144 lines
4.0 KiB
TypeScript
144 lines
4.0 KiB
TypeScript
|
|
import { Command } from "commander";
|
||
|
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||
|
|
|
||
|
|
const startGatewayServer = vi.fn(async () => ({
|
||
|
|
close: vi.fn(async () => {}),
|
||
|
|
}));
|
||
|
|
const setGatewayWsLogStyle = vi.fn();
|
||
|
|
const setVerbose = vi.fn();
|
||
|
|
const forceFreePortAndWait = vi.fn(async () => ({
|
||
|
|
killed: [],
|
||
|
|
waitedMs: 0,
|
||
|
|
escalatedToSigkill: false,
|
||
|
|
}));
|
||
|
|
const ensureDevGatewayConfig = vi.fn(async () => {});
|
||
|
|
const runGatewayLoop = vi.fn(async ({ start }: { start: () => Promise<unknown> }) => {
|
||
|
|
await start();
|
||
|
|
});
|
||
|
|
|
||
|
|
const runtimeLogs: string[] = [];
|
||
|
|
const runtimeErrors: string[] = [];
|
||
|
|
const defaultRuntime = {
|
||
|
|
log: (msg: string) => runtimeLogs.push(msg),
|
||
|
|
error: (msg: string) => runtimeErrors.push(msg),
|
||
|
|
exit: (code: number) => {
|
||
|
|
throw new Error(`__exit__:${code}`);
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
vi.mock("../../config/config.js", () => ({
|
||
|
|
getConfigPath: () => "/tmp/openclaw-test-missing-config.json",
|
||
|
|
loadConfig: () => ({}),
|
||
|
|
readConfigFileSnapshot: async () => ({ exists: false }),
|
||
|
|
resolveStateDir: () => "/tmp",
|
||
|
|
resolveGatewayPort: () => 18789,
|
||
|
|
}));
|
||
|
|
|
||
|
|
vi.mock("../../gateway/auth.js", () => ({
|
||
|
|
resolveGatewayAuth: (params: { authConfig?: { token?: string }; env?: NodeJS.ProcessEnv }) => ({
|
||
|
|
mode: "token",
|
||
|
|
token: params.authConfig?.token ?? params.env?.OPENCLAW_GATEWAY_TOKEN,
|
||
|
|
password: undefined,
|
||
|
|
allowTailscale: false,
|
||
|
|
}),
|
||
|
|
}));
|
||
|
|
|
||
|
|
vi.mock("../../gateway/server.js", () => ({
|
||
|
|
startGatewayServer: (port: number, opts?: unknown) => startGatewayServer(port, opts),
|
||
|
|
}));
|
||
|
|
|
||
|
|
vi.mock("../../gateway/ws-logging.js", () => ({
|
||
|
|
setGatewayWsLogStyle: (style: string) => setGatewayWsLogStyle(style),
|
||
|
|
}));
|
||
|
|
|
||
|
|
vi.mock("../../globals.js", () => ({
|
||
|
|
setVerbose: (enabled: boolean) => setVerbose(enabled),
|
||
|
|
}));
|
||
|
|
|
||
|
|
vi.mock("../../infra/gateway-lock.js", () => ({
|
||
|
|
GatewayLockError: class GatewayLockError extends Error {},
|
||
|
|
}));
|
||
|
|
|
||
|
|
vi.mock("../../infra/ports.js", () => ({
|
||
|
|
formatPortDiagnostics: () => [],
|
||
|
|
inspectPortUsage: async () => ({ status: "free" }),
|
||
|
|
}));
|
||
|
|
|
||
|
|
vi.mock("../../logging/console.js", () => ({
|
||
|
|
setConsoleSubsystemFilter: () => undefined,
|
||
|
|
setConsoleTimestampPrefix: () => undefined,
|
||
|
|
}));
|
||
|
|
|
||
|
|
vi.mock("../../logging/subsystem.js", () => ({
|
||
|
|
createSubsystemLogger: () => ({
|
||
|
|
info: () => undefined,
|
||
|
|
warn: () => undefined,
|
||
|
|
error: () => undefined,
|
||
|
|
}),
|
||
|
|
}));
|
||
|
|
|
||
|
|
vi.mock("../../runtime.js", () => ({
|
||
|
|
defaultRuntime,
|
||
|
|
}));
|
||
|
|
|
||
|
|
vi.mock("../command-format.js", () => ({
|
||
|
|
formatCliCommand: (cmd: string) => cmd,
|
||
|
|
}));
|
||
|
|
|
||
|
|
vi.mock("../ports.js", () => ({
|
||
|
|
forceFreePortAndWait: (port: number, opts: unknown) => forceFreePortAndWait(port, opts),
|
||
|
|
}));
|
||
|
|
|
||
|
|
vi.mock("./dev.js", () => ({
|
||
|
|
ensureDevGatewayConfig: (opts?: unknown) => ensureDevGatewayConfig(opts),
|
||
|
|
}));
|
||
|
|
|
||
|
|
vi.mock("./run-loop.js", () => ({
|
||
|
|
runGatewayLoop: (params: { start: () => Promise<unknown> }) => runGatewayLoop(params),
|
||
|
|
}));
|
||
|
|
|
||
|
|
describe("gateway run option collisions", () => {
|
||
|
|
beforeEach(() => {
|
||
|
|
runtimeLogs.length = 0;
|
||
|
|
runtimeErrors.length = 0;
|
||
|
|
startGatewayServer.mockClear();
|
||
|
|
setGatewayWsLogStyle.mockClear();
|
||
|
|
setVerbose.mockClear();
|
||
|
|
forceFreePortAndWait.mockClear();
|
||
|
|
ensureDevGatewayConfig.mockClear();
|
||
|
|
runGatewayLoop.mockClear();
|
||
|
|
});
|
||
|
|
|
||
|
|
it("forwards parent-captured options to `gateway run` subcommand", async () => {
|
||
|
|
const { addGatewayRunCommand } = await import("./run.js");
|
||
|
|
const program = new Command();
|
||
|
|
const gateway = addGatewayRunCommand(program.command("gateway"));
|
||
|
|
addGatewayRunCommand(gateway.command("run"));
|
||
|
|
|
||
|
|
await program.parseAsync(
|
||
|
|
[
|
||
|
|
"gateway",
|
||
|
|
"run",
|
||
|
|
"--token",
|
||
|
|
"tok_run",
|
||
|
|
"--allow-unconfigured",
|
||
|
|
"--ws-log",
|
||
|
|
"full",
|
||
|
|
"--force",
|
||
|
|
],
|
||
|
|
{ from: "user" },
|
||
|
|
);
|
||
|
|
|
||
|
|
expect(forceFreePortAndWait).toHaveBeenCalledWith(18789, expect.anything());
|
||
|
|
expect(setGatewayWsLogStyle).toHaveBeenCalledWith("full");
|
||
|
|
expect(startGatewayServer).toHaveBeenCalledWith(
|
||
|
|
18789,
|
||
|
|
expect.objectContaining({
|
||
|
|
auth: expect.objectContaining({
|
||
|
|
token: "tok_run",
|
||
|
|
}),
|
||
|
|
}),
|
||
|
|
);
|
||
|
|
});
|
||
|
|
});
|