mirror of
https://github.com/farcasclaudiu/openclaw.git
synced 2026-06-28 19:01:47 +03:00
perf(test): speed up cron read ops test
This commit is contained in:
@@ -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();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user