mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-17 00:41:37 +00:00
* fix(cli): retry logs.tail after journal fallback in logs follow Rebase #88159 onto current main and keep systemd journal fallback temporary in follow mode. Preserve the journal cursor across repeated fallback outages, but retry logs.tail on the next loop so recovered Gateway RPC returns to normal log output. This refresh also replaces the stale red checks-node-core-fast result from the old head with a current-head CI run. * Keep log source metadata explicit * ci: retrigger checks for PR #88159 * docs: clarify logs follow JSON source transitions * fix(cli): keep journal logs responsive during recovery --------- Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
92 lines
2.9 KiB
TypeScript
92 lines
2.9 KiB
TypeScript
// Gateway RPC runtime tests cover CLI gateway RPC calls and runtime error handling.
|
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
const callGatewayMock = vi.fn(async () => ({ ok: true }));
|
|
vi.mock("../gateway/call.js", () => ({
|
|
callGateway: callGatewayMock,
|
|
}));
|
|
|
|
vi.mock("./progress.js", () => ({
|
|
withProgress: async (_options: unknown, action: () => Promise<unknown>) => await action(),
|
|
}));
|
|
|
|
const { callGatewayFromCliRuntime } = await import("./gateway-rpc.runtime.js");
|
|
|
|
describe("callGatewayFromCliRuntime", () => {
|
|
beforeEach(() => {
|
|
callGatewayMock.mockClear().mockResolvedValue({ ok: true });
|
|
});
|
|
|
|
it("uses the 30s Gateway RPC default timeout when --timeout is omitted", async () => {
|
|
await callGatewayFromCliRuntime("cron.status", {});
|
|
|
|
expect(callGatewayMock).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
method: "cron.status",
|
|
timeoutMs: 30_000,
|
|
}),
|
|
);
|
|
});
|
|
|
|
it.each([
|
|
["cron status", "cron.status"],
|
|
["cron list", "cron.list"],
|
|
["cron add", "cron.add"],
|
|
["cron update", "cron.update"],
|
|
["cron remove", "cron.remove"],
|
|
["cron get", "cron.get"],
|
|
["cron runs", "cron.runs"],
|
|
["cron run", "cron.run"],
|
|
["logs", "logs.tail"],
|
|
["secrets reload", "secrets.reload"],
|
|
])("rejects malformed shared --timeout before gateway call for %s", async (_name, method) => {
|
|
await expect(callGatewayFromCliRuntime(method, { timeout: "10ms" })).rejects.toThrow(
|
|
'Invalid --timeout. Use a positive millisecond value, e.g. --timeout 30000. Received: "10ms".',
|
|
);
|
|
|
|
expect(callGatewayMock).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it.each(["", " "])("rejects explicit empty shared --timeout value %j", async (timeout) => {
|
|
await expect(callGatewayFromCliRuntime("cron.status", { timeout })).rejects.toThrow(
|
|
"Invalid --timeout",
|
|
);
|
|
|
|
expect(callGatewayMock).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it.each(["0", "-1", "1.5"])("rejects invalid shared --timeout value %j", async (timeout) => {
|
|
await expect(callGatewayFromCliRuntime("cron.status", { timeout })).rejects.toThrow(
|
|
`Received: "${timeout}"`,
|
|
);
|
|
|
|
expect(callGatewayMock).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("passes strict integer timeouts to the gateway call", async () => {
|
|
await callGatewayFromCliRuntime("cron.status", { timeout: "15000" });
|
|
|
|
expect(callGatewayMock).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
method: "cron.status",
|
|
timeoutMs: 15_000,
|
|
}),
|
|
);
|
|
});
|
|
|
|
it("forwards caller cancellation to the gateway call", async () => {
|
|
const controller = new AbortController();
|
|
|
|
await callGatewayFromCliRuntime("logs.tail", {}, undefined, {
|
|
signal: controller.signal,
|
|
});
|
|
|
|
expect(callGatewayMock).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
method: "logs.tail",
|
|
signal: controller.signal,
|
|
}),
|
|
);
|
|
});
|
|
});
|