fix(cron): avoid 30s timeout for cron run --expect-final (#29942)

* fix(cron): use longer default timeout for cron run --expect-final

* test(cron-cli): stabilize cron run timeout assertions with explicit run exits

---------

Co-authored-by: Kelly Baker <kelly@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
kleebaker
2026-03-02 08:24:42 -05:00
committed by GitHub
parent 254bb7ceee
commit b40d5817a2
2 changed files with 28 additions and 5 deletions

View File

@@ -156,7 +156,7 @@ async function expectCronEditWithScheduleLookupExit(
).rejects.toThrow("__exit__:1"); ).rejects.toThrow("__exit__:1");
} }
async function runCronRunAndCaptureExit(params: { ran: boolean }) { async function runCronRunAndCaptureExit(params: { ran: boolean; args?: string[] }) {
resetGatewayMock(); resetGatewayMock();
callGatewayFromCli.mockImplementation( callGatewayFromCli.mockImplementation(
async (method: string, _opts: unknown, callParams?: unknown) => { async (method: string, _opts: unknown, callParams?: unknown) => {
@@ -177,11 +177,15 @@ async function runCronRunAndCaptureExit(params: { ran: boolean }) {
runtime.exit = exitSpy; runtime.exit = exitSpy;
try { try {
const program = buildProgram(); const program = buildProgram();
await program.parseAsync(["cron", "run", "job-1"], { from: "user" }); await program.parseAsync(params.args ?? ["cron", "run", "job-1"], { from: "user" });
} finally { } finally {
runtime.exit = originalExit; runtime.exit = originalExit;
} }
return exitSpy; const runCall = callGatewayFromCli.mock.calls.find((call) => call[0] === "cron.run");
return {
exitSpy,
runOpts: (runCall?.[1] ?? {}) as { timeout?: string },
};
} }
describe("cron cli", () => { describe("cron cli", () => {
@@ -197,7 +201,7 @@ describe("cron cli", () => {
expectedExitCode: 1, expectedExitCode: 1,
}, },
])("$name", async ({ ran, expectedExitCode }) => { ])("$name", async ({ ran, expectedExitCode }) => {
const exitSpy = await runCronRunAndCaptureExit({ ran }); const { exitSpy } = await runCronRunAndCaptureExit({ ran });
expect(exitSpy).toHaveBeenCalledWith(expectedExitCode); expect(exitSpy).toHaveBeenCalledWith(expectedExitCode);
}); });
@@ -674,4 +678,20 @@ describe("cron cli", () => {
const patch = updateCall?.[2] as { patch?: { failureAlert?: boolean } }; const patch = updateCall?.[2] as { patch?: { failureAlert?: boolean } };
expect(patch?.patch?.failureAlert).toBe(false); expect(patch?.patch?.failureAlert).toBe(false);
}); });
it("uses a longer default timeout for cron run", async () => {
const { runOpts } = await runCronRunAndCaptureExit({
ran: true,
args: ["cron", "run", "job-1", "--expect-final"],
});
expect(runOpts.timeout).toBe("600000");
});
it("preserves explicit --timeout for cron run", async () => {
const { runOpts } = await runCronRunAndCaptureExit({
ran: true,
args: ["cron", "run", "job-1", "--expect-final", "--timeout", "45000"],
});
expect(runOpts.timeout).toBe("45000");
});
}); });

View File

@@ -93,8 +93,11 @@ export function registerCronSimpleCommands(cron: Command) {
.description("Run a cron job now (debug)") .description("Run a cron job now (debug)")
.argument("<id>", "Job id") .argument("<id>", "Job id")
.option("--due", "Run only when due (default behavior in older versions)", false) .option("--due", "Run only when due (default behavior in older versions)", false)
.action(async (id, opts) => { .action(async (id, opts, command) => {
try { try {
if (command.getOptionValueSource("timeout") === "default") {
opts.timeout = "600000";
}
const res = await callGatewayFromCli("cron.run", opts, { const res = await callGatewayFromCli("cron.run", opts, {
id, id,
mode: opts.due ? "due" : "force", mode: opts.due ? "due" : "force",