perf(test): speed up cron read ops test

This commit is contained in:
Peter Steinberger
2026-02-14 17:55:47 +00:00
parent d3483590fb
commit 240cdd3749
+45 -30
View File
@@ -1,7 +1,6 @@
import fs from "node:fs/promises"; import fs from "node:fs/promises";
import os from "node:os"; import os from "node:os";
import path from "node:path"; import path from "node:path";
import { setTimeout as delay } from "node:timers/promises";
import { describe, expect, it, vi } from "vitest"; import { describe, expect, it, vi } from "vitest";
import { CronService } from "./service.js"; import { CronService } from "./service.js";
@@ -34,11 +33,13 @@ describe("CronService read ops while job is running", () => {
const runIsolatedAgentJob = vi.fn( const runIsolatedAgentJob = vi.fn(
async () => async () =>
await new Promise<{ status: "ok" | "error" | "skipped"; summary?: string; error?: string }>( await new Promise<{
(resolve) => { status: "ok" | "error" | "skipped";
summary?: string;
error?: string;
}>((resolve) => {
resolveRun = resolve; resolveRun = resolve;
}, }),
),
); );
const cron = new CronService({ const cron = new CronService({
@@ -50,55 +51,69 @@ describe("CronService read ops while job is running", () => {
runIsolatedAgentJob, runIsolatedAgentJob,
}); });
const timeout = async <T>(promise: Promise<T>, ms: number): Promise<T> => {
let t: NodeJS.Timeout;
const timeoutPromise = new Promise<never>((_, reject) => {
t = setTimeout(() => reject(new Error("timeout")), ms);
});
return await Promise.race([promise.finally(() => clearTimeout(t!)), timeoutPromise]);
};
try {
await cron.start(); await cron.start();
const runAt = Date.now() + 30; // Schedule the job in the past so the cron timer fires immediately.
await cron.add({ await cron.add({
name: "slow isolated", name: "slow isolated",
enabled: true, enabled: true,
deleteAfterRun: false, deleteAfterRun: false,
schedule: { kind: "at", at: new Date(runAt).toISOString() }, schedule: { kind: "at", at: new Date(Date.now() - 1).toISOString() },
sessionTarget: "isolated", sessionTarget: "isolated",
wakeMode: "next-heartbeat", wakeMode: "next-heartbeat",
payload: { kind: "agentTurn", message: "long task" }, payload: { kind: "agentTurn", message: "long task" },
delivery: { mode: "none" }, delivery: { mode: "none" },
}); });
for (let i = 0; i < 25 && runIsolatedAgentJob.mock.calls.length === 0; i++) { // Let the scheduler tick and start the job.
await delay(20); await timeout(
(async () => {
for (;;) {
if (runIsolatedAgentJob.mock.calls.length > 0) {
return;
} }
await new Promise<void>((resolve) => setTimeout(resolve, 0));
}
})(),
200,
);
expect(runIsolatedAgentJob).toHaveBeenCalledTimes(1); expect(runIsolatedAgentJob).toHaveBeenCalledTimes(1);
const listRace = await Promise.race([ await expect(timeout(cron.list({ includeDisabled: true }), 100)).resolves.toBeTypeOf(
cron.list({ includeDisabled: true }).then(() => "ok"), "object",
delay(200).then(() => "timeout"), );
]); await expect(timeout(cron.status(), 100)).resolves.toBeTypeOf("object");
expect(listRace).toBe("ok");
const statusRace = await Promise.race([
cron.status().then(() => "ok"),
delay(200).then(() => "timeout"),
]);
expect(statusRace).toBe("ok");
const running = await cron.list({ includeDisabled: true }); const running = await cron.list({ includeDisabled: true });
expect(running[0]?.state.runningAtMs).toBeTypeOf("number"); expect(running[0]?.state.runningAtMs).toBeTypeOf("number");
resolveRun?.({ status: "ok", summary: "done" }); resolveRun?.({ status: "ok", summary: "done" });
for (let i = 0; i < 25; i++) { await timeout(
const jobs = await cron.list({ includeDisabled: true }); (async () => {
if (jobs[0]?.state.lastStatus === "ok") { for (;;) {
break;
}
await delay(20);
}
const finished = await cron.list({ includeDisabled: true }); const finished = await cron.list({ includeDisabled: true });
expect(finished[0]?.state.lastStatus).toBe("ok"); if (finished[0]?.state.lastStatus === "ok") {
return;
}
await new Promise<void>((resolve) => setTimeout(resolve, 0));
}
})(),
500,
);
} finally {
cron.stop(); cron.stop();
await store.cleanup(); await store.cleanup();
}
}); });
}); });