import { describe, expect, it } from "vitest"; import { createMockCronStateForJobs } from "./service.test-harness.js"; import { recomputeNextRunsForMaintenance } from "./service/jobs.js"; import type { CronJob } from "./types.js";
describe("issue #13992 regression - cron jobs skip execution", () => {
it("should NOT recompute nextRunAtMs for past-due jobs by default", () => { const now = Date.now(); const pastDue = now - 60_000; // 1 minute ago
const job = createCronSystemEventJob(now, {
createdAtMs: now - 3600_000,
updatedAtMs: now - 3600_000,
state: {
nextRunAtMs: pastDue, // This is in the past and should NOT be recomputed
},
});
const state = createMockCronStateForJobs({ jobs: [job], nowMs: now });
recomputeNextRunsForMaintenance(state);
// Should not have changed the past-due nextRunAtMs
expect(job.state.nextRunAtMs).toBe(pastDue);
});
it("should recompute past-due nextRunAtMs with recomputeExpired when slot already executed", () => { // NOTE: in onTimer this recovery branch is used only when due scan found no // runnable jobs; this unit test validates the maintenance helper contract. const now = Date.now(); const pastDue = now - 60_000;
it("should NOT recompute past-due nextRunAtMs for running jobs even with recomputeExpired", () => { const now = Date.now(); const pastDue = now - 60_000;
const job = createCronSystemEventJob(now, {
createdAtMs: now - 3600_000,
updatedAtMs: now - 3600_000,
state: {
nextRunAtMs: pastDue,
runningAtMs: now - 500,
},
});
const state = createMockCronStateForJobs({ jobs: [job], nowMs: now });
recomputeNextRunsForMaintenance(state, { recomputeExpired: true });
expect(job.state.nextRunAtMs).toBe(pastDue);
});
it("should compute missing nextRunAtMs during maintenance", () => { const now = Date.now();
const state = createMockCronStateForJobs({ jobs: [job], nowMs: now });
recomputeNextRunsForMaintenance(state);
// Should have cleared stuck running marker
expect(job.state.runningAtMs).toBeUndefined(); // But should NOT have changed nextRunAtMs (it's still future)
expect(job.state.nextRunAtMs).toBe(futureTime);
});
it("isolates schedule errors while filling missing nextRunAtMs", () => { const now = Date.now(); const pastDue = now - 1_000;
it("does not advance overdue never-executed jobs when stale running marker is cleared", () => { const now = Date.now(); const pastDue = now - 60_000; const staleRunningAt = now - 3 * 60 * 60_000;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.