fix(doctor): bound legacy crontab inspection (#109107)

This commit is contained in:
Alix-007
2026-07-16 08:57:28 -07:00
committed by GitHub
parent 5a4004dfb7
commit 7a18a781bc
2 changed files with 30 additions and 3 deletions
+25 -2
View File
@@ -1,16 +1,25 @@
// Doctor cron delivery-target advisory tests cover concrete-vs-pseudo channel detection.
import { describe, expect, it, vi } from "vitest";
import { noteCronDeliveryTargetAdvisory } from "./warnings.js";
import { afterEach, describe, expect, it, vi } from "vitest";
import {
collectLegacyWhatsAppCrontabHealthWarning,
noteCronDeliveryTargetAdvisory,
} from "./warnings.js";
const mocks = vi.hoisted(() => ({
listReadOnlyChannelPluginsForConfig: vi.fn(),
note: vi.fn(),
runExec: vi.fn(),
}));
vi.mock("../../../channels/plugins/read-only.js", () => ({
listReadOnlyChannelPluginsForConfig: mocks.listReadOnlyChannelPluginsForConfig,
}));
vi.mock("../../../../packages/terminal-core/src/note.js", () => ({ note: mocks.note }));
vi.mock("../../../process/exec.js", () => ({ runExec: mocks.runExec }));
afterEach(() => {
vi.clearAllMocks();
});
const STORE_PATH = "/tmp/openclaw/cron/jobs.sqlite";
@@ -166,3 +175,17 @@ describe("collectCronDeliveryTargetAdvisory", () => {
expect(advisory).toContain("<unnamed> -> ghost");
});
});
describe("collectLegacyWhatsAppCrontabHealthWarning", () => {
it("bounds the best-effort crontab read", async () => {
mocks.runExec.mockRejectedValueOnce(new Error("crontab timed out"));
await expect(
collectLegacyWhatsAppCrontabHealthWarning({ platform: "linux" }),
).resolves.toBeNull();
expect(mocks.runExec).toHaveBeenCalledWith("crontab", ["-l"], {
logOutput: false,
timeoutMs: 5_000,
});
});
});
+5 -1
View File
@@ -17,6 +17,7 @@ const LEGACY_WHATSAPP_HEALTH_SCRIPT_RE =
/(?:^|\s)(?:"[^"]*ensure-whatsapp\.sh"|'[^']*ensure-whatsapp\.sh'|[^\s#;|&]*ensure-whatsapp\.sh)\b/u;
const CRON_MODEL_OVERRIDE_EXAMPLE_LIMIT = 3;
const CRON_DELIVERY_TARGET_ADVISORY_EXAMPLE_LIMIT = 3;
const CRONTAB_READ_TIMEOUT_MS = 5_000;
function pluralize(count: number, noun: string) {
return `${count} ${noun}${count === 1 ? "" : "s"}`;
@@ -242,7 +243,10 @@ export function noteCronDeliveryTargetAdvisory(params: {
}
async function readUserCrontab(): Promise<{ stdout: string; stderr?: string }> {
const result = await runExec("crontab", ["-l"], { logOutput: false });
const result = await runExec("crontab", ["-l"], {
logOutput: false,
timeoutMs: CRONTAB_READ_TIMEOUT_MS,
});
return {
stdout: result.stdout,
stderr: result.stderr,