




















@@ -177,6 +177,28 @@ function createTaskRegistryMaintenanceHarness(params: {
177177return { currentTasks };
178178}
179179180+function expectMaintenanceCounts(
181+result: Awaited<ReturnType<typeof runTaskRegistryMaintenance>>,
182+expected: { reconciled: number; recovered?: number },
183+): void {
184+expect(result.reconciled).toBe(expected.reconciled);
185+if (expected.recovered !== undefined) {
186+expect(result.recovered).toBe(expected.recovered);
187+}
188+}
189+190+function expectTaskStatus(
191+tasks: Map<string, TaskRecord>,
192+taskId: string,
193+status: TaskRecord["status"],
194+): void {
195+const task = tasks.get(taskId);
196+if (!task) {
197+throw new Error(`Expected task ${taskId}`);
198+}
199+expect(task.status).toBe(status);
200+}
201+180202describe("task-registry maintenance issue #60299", () => {
181203it("reuses session store reads across stale subagent task checks in one pass", async () => {
182204const tasks = Array.from({ length: 10 }, (_, index) =>
@@ -194,7 +216,7 @@ describe("task-registry maintenance issue #60299", () => {
194216resolveStorePath: () => "/tmp/openclaw-test-sessions-main.json",
195217});
196218197-expect(await runTaskRegistryMaintenance()).toMatchObject({ reconciled: tasks.length });
219+expectMaintenanceCounts(await runTaskRegistryMaintenance(), { reconciled: tasks.length });
198220expect(loadSessionStoreMock).toHaveBeenCalledTimes(1);
199221});
200222@@ -214,7 +236,7 @@ describe("task-registry maintenance issue #60299", () => {
214236deriveSessionChatTypeFromKey: deriveSessionChatTypeMock,
215237});
216238217-expect(await runTaskRegistryMaintenance()).toMatchObject({ reconciled: tasks.length });
239+expectMaintenanceCounts(await runTaskRegistryMaintenance(), { reconciled: tasks.length });
218240expect(deriveSessionChatTypeMock).toHaveBeenCalledTimes(1);
219241});
220242@@ -231,8 +253,8 @@ describe("task-registry maintenance issue #60299", () => {
231253sessionStore: { [childSessionKey]: { sessionId: childSessionKey, updatedAt: Date.now() } },
232254});
233255234-expect(await runTaskRegistryMaintenance()).toMatchObject({ reconciled: 1 });
235-expect(currentTasks.get(task.taskId)).toMatchObject({ status: "lost" });
256+expectMaintenanceCounts(await runTaskRegistryMaintenance(), { reconciled: 1 });
257+expectTaskStatus(currentTasks, task.taskId, "lost");
236258});
237259238260it("keeps active cron tasks live while the cron runtime still owns the job", async () => {
@@ -247,8 +269,8 @@ describe("task-registry maintenance issue #60299", () => {
247269activeCronJobIds: ["cron-job-2"],
248270});
249271250-expect(await runTaskRegistryMaintenance()).toMatchObject({ reconciled: 0 });
251-expect(currentTasks.get(task.taskId)).toMatchObject({ status: "running" });
272+expectMaintenanceCounts(await runTaskRegistryMaintenance(), { reconciled: 0 });
273+expectTaskStatus(currentTasks, task.taskId, "running");
252274});
253275254276it("only treats started non-ended running tasks as restart blockers", () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。