mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:50:43 +00:00
test(heartbeat): cover isolated cron event consumption
This commit is contained in:
@@ -5,7 +5,11 @@ import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveMainSessionKey } from "../config/sessions.js";
|
||||
import { runHeartbeatOnce } from "./heartbeat-runner.js";
|
||||
import { seedSessionStore, withTempHeartbeatSandbox } from "./heartbeat-runner.test-utils.js";
|
||||
import { resetSystemEventsForTest } from "./system-events.js";
|
||||
import {
|
||||
enqueueSystemEvent,
|
||||
peekSystemEventEntries,
|
||||
resetSystemEventsForTest,
|
||||
} from "./system-events.js";
|
||||
|
||||
vi.mock("./outbound/deliver.js", () => ({
|
||||
deliverOutboundPayloads: vi.fn().mockResolvedValue(undefined),
|
||||
@@ -197,6 +201,62 @@ describe("runHeartbeatOnce – isolated session key stability (#59493)", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("consumes base-session cron events when isolated heartbeat runs on a :heartbeat session", async () => {
|
||||
await withTempHeartbeatSandbox(async ({ tmpDir, storePath }) => {
|
||||
const cfg = makeIsolatedHeartbeatConfig(tmpDir, storePath);
|
||||
const baseSessionKey = resolveMainSessionKey(cfg);
|
||||
const replySpy = vi.spyOn(replyModule, "getReplyFromConfig");
|
||||
replySpy
|
||||
.mockResolvedValueOnce({ text: "Relay this cron update now" })
|
||||
.mockResolvedValueOnce({ text: "HEARTBEAT_OK" });
|
||||
|
||||
enqueueSystemEvent("Cron: QMD maintenance completed", {
|
||||
sessionKey: baseSessionKey,
|
||||
contextKey: "cron:qmd-maintenance",
|
||||
});
|
||||
|
||||
await runHeartbeatOnce({
|
||||
cfg,
|
||||
agentId: "main",
|
||||
reason: "interval",
|
||||
deps: {
|
||||
getQueueSize: () => 0,
|
||||
nowMs: () => 0,
|
||||
},
|
||||
});
|
||||
|
||||
expect(peekSystemEventEntries(baseSessionKey)).toEqual([]);
|
||||
|
||||
await runHeartbeatOnce({
|
||||
cfg,
|
||||
agentId: "main",
|
||||
reason: "interval",
|
||||
deps: {
|
||||
getQueueSize: () => 0,
|
||||
nowMs: () => 0,
|
||||
},
|
||||
});
|
||||
|
||||
expect(replySpy).toHaveBeenCalledTimes(2);
|
||||
const firstCtx = replySpy.mock.calls[0]?.[0] as {
|
||||
Body?: string;
|
||||
Provider?: string;
|
||||
SessionKey?: string;
|
||||
};
|
||||
const secondCtx = replySpy.mock.calls[1]?.[0] as {
|
||||
Body?: string;
|
||||
Provider?: string;
|
||||
SessionKey?: string;
|
||||
};
|
||||
|
||||
expect(firstCtx.SessionKey).toBe(`${baseSessionKey}:heartbeat`);
|
||||
expect(firstCtx.Provider).toBe("cron-event");
|
||||
expect(firstCtx.Body).toContain("Cron: QMD maintenance completed");
|
||||
expect(secondCtx.SessionKey).toBe(`${baseSessionKey}:heartbeat`);
|
||||
expect(secondCtx.Body).not.toContain("Cron: QMD maintenance completed");
|
||||
});
|
||||
});
|
||||
|
||||
it("stays stable for wake re-entry when the configured base key already ends with :heartbeat", async () => {
|
||||
await withTempHeartbeatSandbox(async ({ tmpDir, storePath }) => {
|
||||
const cfg = makeNamedIsolatedHeartbeatConfig(tmpDir, storePath, "alerts:heartbeat");
|
||||
|
||||
Reference in New Issue
Block a user