refactor(test): share cron service fixtures

This commit is contained in:
Peter Steinberger
2026-02-14 23:18:17 +00:00
parent 384a2f6a19
commit a6cd7ef49c
3 changed files with 76 additions and 86 deletions

View File

@@ -1,38 +1,17 @@
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { describe, expect, it, vi } from "vitest";
import type { CronEvent } from "./service.js";
import { CronService } from "./service.js";
import {
createCronStoreHarness,
createNoopLogger,
installCronTestHooks,
} from "./service.test-harness.js";
const noopLogger = {
debug: vi.fn(),
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
};
let fixtureRoot = "";
let caseId = 0;
beforeAll(async () => {
fixtureRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-cron-"));
});
afterAll(async () => {
if (fixtureRoot) {
await fs.rm(fixtureRoot, { recursive: true, force: true });
}
});
async function makeStorePath() {
const dir = path.join(fixtureRoot, `case-${caseId++}`);
await fs.mkdir(dir, { recursive: true });
return {
storePath: path.join(dir, "cron", "jobs.json"),
cleanup: async () => {},
};
}
const noopLogger = createNoopLogger();
const { makeStorePath } = createCronStoreHarness();
installCronTestHooks({ logger: noopLogger });
function createFinishedBarrier() {
const resolvers = new Map<string, (evt: CronEvent) => void>();
@@ -56,19 +35,6 @@ function createFinishedBarrier() {
}
describe("CronService interval/cron jobs fire on time", () => {
beforeEach(() => {
vi.useFakeTimers();
vi.setSystemTime(new Date("2025-12-13T00:00:00.000Z"));
noopLogger.debug.mockClear();
noopLogger.info.mockClear();
noopLogger.warn.mockClear();
noopLogger.error.mockClear();
});
afterEach(() => {
vi.useRealTimers();
});
it("fires an every-type main job when the timer fires a few ms late", async () => {
const store = await makeStorePath();
const enqueueSystemEvent = vi.fn();

View File

@@ -1,39 +1,18 @@
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, describe, expect, it, vi } from "vitest";
import type { HeartbeatRunResult } from "../infra/heartbeat-wake.js";
import type { CronJob } from "./types.js";
import { CronService } from "./service.js";
import {
createCronStoreHarness,
createNoopLogger,
installCronTestHooks,
} from "./service.test-harness.js";
const noopLogger = {
debug: vi.fn(),
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
};
let fixtureRoot = "";
let caseId = 0;
beforeAll(async () => {
fixtureRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-cron-"));
});
afterAll(async () => {
if (fixtureRoot) {
await fs.rm(fixtureRoot, { recursive: true, force: true });
}
});
async function makeStorePath() {
const dir = path.join(fixtureRoot, `case-${caseId++}`);
await fs.mkdir(dir, { recursive: true });
return {
storePath: path.join(dir, "cron", "jobs.json"),
cleanup: async () => {},
};
}
const noopLogger = createNoopLogger();
const { makeStorePath } = createCronStoreHarness();
installCronTestHooks({ logger: noopLogger });
async function waitForJobs(cron: CronService, predicate: (jobs: CronJob[]) => boolean) {
let latest: CronJob[] = [];
@@ -48,19 +27,6 @@ async function waitForJobs(cron: CronService, predicate: (jobs: CronJob[]) => bo
}
describe("CronService", () => {
beforeEach(() => {
vi.useFakeTimers();
vi.setSystemTime(new Date("2025-12-13T00:00:00.000Z"));
noopLogger.debug.mockClear();
noopLogger.info.mockClear();
noopLogger.warn.mockClear();
noopLogger.error.mockClear();
});
afterEach(() => {
vi.useRealTimers();
});
it("runs a one-shot main job and disables it after success when requested", async () => {
const store = await makeStorePath();
const enqueueSystemEvent = vi.fn();

View File

@@ -0,0 +1,58 @@
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { afterAll, afterEach, beforeAll, beforeEach, vi } from "vitest";
export function createNoopLogger() {
return {
debug: vi.fn(),
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
};
}
export function createCronStoreHarness(options?: { prefix?: string }) {
let fixtureRoot = "";
let caseId = 0;
beforeAll(async () => {
fixtureRoot = await fs.mkdtemp(path.join(os.tmpdir(), options?.prefix ?? "openclaw-cron-"));
});
afterAll(async () => {
if (!fixtureRoot) {
return;
}
await fs.rm(fixtureRoot, { recursive: true, force: true });
});
async function makeStorePath() {
const dir = path.join(fixtureRoot, `case-${caseId++}`);
await fs.mkdir(dir, { recursive: true });
return {
storePath: path.join(dir, "cron", "jobs.json"),
cleanup: async () => {},
};
}
return { makeStorePath };
}
export function installCronTestHooks(options: {
logger: ReturnType<typeof createNoopLogger>;
baseTimeIso?: string;
}) {
beforeEach(() => {
vi.useFakeTimers();
vi.setSystemTime(new Date(options.baseTimeIso ?? "2025-12-13T00:00:00.000Z"));
options.logger.debug.mockClear();
options.logger.info.mockClear();
options.logger.warn.mockClear();
options.logger.error.mockClear();
});
afterEach(() => {
vi.useRealTimers();
});
}