mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-04 08:00:21 +00:00
* fix(cron): avoid overwriting .bak during normalization Fixes openclaw/openclaw#35195 * test(cron): preserve pre-edit bak snapshot in normalization path --------- Co-authored-by: 0xsline <sline@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
82 lines
2.6 KiB
TypeScript
82 lines
2.6 KiB
TypeScript
import fs from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
import { writeCronStoreSnapshot } from "./service.issue-regressions.test-helpers.js";
|
|
import { CronService } from "./service.js";
|
|
import { createCronStoreHarness, createNoopLogger } from "./service.test-harness.js";
|
|
|
|
const noopLogger = createNoopLogger();
|
|
const { makeStorePath } = createCronStoreHarness({ prefix: "openclaw-cron-issue-35195-" });
|
|
|
|
describe("cron backup timing for edit", () => {
|
|
it("keeps .bak as the pre-edit store even after later normalization persists", async () => {
|
|
const store = await makeStorePath();
|
|
const base = Date.now();
|
|
|
|
await fs.mkdir(path.dirname(store.storePath), { recursive: true });
|
|
await writeCronStoreSnapshot(store.storePath, [
|
|
{
|
|
id: "job-35195",
|
|
name: "job-35195",
|
|
enabled: true,
|
|
createdAtMs: base,
|
|
updatedAtMs: base,
|
|
schedule: { kind: "every", everyMs: 60_000, anchorMs: base },
|
|
sessionTarget: "main",
|
|
wakeMode: "next-heartbeat",
|
|
payload: { kind: "systemEvent", text: "hello" },
|
|
state: {},
|
|
},
|
|
]);
|
|
|
|
const service = new CronService({
|
|
storePath: store.storePath,
|
|
cronEnabled: true,
|
|
log: noopLogger,
|
|
enqueueSystemEvent: vi.fn(),
|
|
requestHeartbeatNow: vi.fn(),
|
|
runIsolatedAgentJob: vi.fn(async () => ({ status: "ok" as const })),
|
|
});
|
|
|
|
await service.start();
|
|
|
|
const beforeEditRaw = await fs.readFile(store.storePath, "utf-8");
|
|
|
|
await service.update("job-35195", {
|
|
payload: { kind: "systemEvent", text: "edited" },
|
|
});
|
|
|
|
const backupRaw = await fs.readFile(`${store.storePath}.bak`, "utf-8");
|
|
expect(JSON.parse(backupRaw)).toEqual(JSON.parse(beforeEditRaw));
|
|
|
|
const diskAfterEdit = JSON.parse(await fs.readFile(store.storePath, "utf-8"));
|
|
const normalizedJob = {
|
|
...diskAfterEdit.jobs[0],
|
|
payload: {
|
|
...diskAfterEdit.jobs[0].payload,
|
|
channel: "telegram",
|
|
},
|
|
};
|
|
|
|
await writeCronStoreSnapshot(store.storePath, [normalizedJob]);
|
|
|
|
service.stop();
|
|
const service2 = new CronService({
|
|
storePath: store.storePath,
|
|
cronEnabled: true,
|
|
log: noopLogger,
|
|
enqueueSystemEvent: vi.fn(),
|
|
requestHeartbeatNow: vi.fn(),
|
|
runIsolatedAgentJob: vi.fn(async () => ({ status: "ok" as const })),
|
|
});
|
|
|
|
await service2.start();
|
|
|
|
const backupAfterNormalize = await fs.readFile(`${store.storePath}.bak`, "utf-8");
|
|
expect(JSON.parse(backupAfterNormalize)).toEqual(JSON.parse(beforeEditRaw));
|
|
|
|
service2.stop();
|
|
await store.cleanup();
|
|
});
|
|
});
|