From a16b6c02ce8854791e04b51fc558e02749f49f7c Mon Sep 17 00:00:00 2001 From: Shakker Date: Fri, 5 Jun 2026 16:50:22 +0100 Subject: [PATCH] test: pair cron task state env --- src/cron/service/ops.test.ts | 51 ++++++++++++++---------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/src/cron/service/ops.test.ts b/src/cron/service/ops.test.ts index 2ea62d3a53e5..137117eff74e 100644 --- a/src/cron/service/ops.test.ts +++ b/src/cron/service/ops.test.ts @@ -6,7 +6,7 @@ import { runOpenClawStateWriteTransaction } from "../../state/openclaw-state-db. import * as detachedTaskRuntime from "../../tasks/detached-task-runtime.js"; import { findTaskByRunId, resetTaskRegistryForTests } from "../../tasks/task-registry.js"; import { formatTaskStatusDetail } from "../../tasks/task-status.js"; -import { captureEnv } from "../../test-utils/env.js"; +import { withEnvAsync } from "../../test-utils/env.js"; import { setupCronServiceSuite, writeCronStoreSnapshot } from "../service.test-harness.js"; import { loadCronJobsStoreWithConfigJobs, loadCronStore } from "../store.js"; import type { CronJob } from "../types.js"; @@ -18,15 +18,17 @@ const { logger, makeStorePath } = setupCronServiceSuite({ prefix: "cron-service-ops-seam", }); -function withStateDirForStorePath(storePath: string) { +async function withStateDirForStorePath( + storePath: string, + runWithStateDir: () => Promise, +): Promise { const stateRoot = path.dirname(path.dirname(storePath)); - const envSnapshot = captureEnv(["OPENCLAW_STATE_DIR"]); - process.env.OPENCLAW_STATE_DIR = stateRoot; resetTaskRegistryForTests(); - return () => { - envSnapshot.restore(); + try { + return await withEnvAsync({ OPENCLAW_STATE_DIR: stateRoot }, runWithStateDir); + } finally { resetTaskRegistryForTests(); - }; + } } function createTimedOutIsolatedCronState(params: { storePath: string; now: number }) { @@ -413,9 +415,8 @@ describe("cron service ops seam coverage", () => { it("keeps manual acknowledgement IDs separate from recoverable task run IDs", async () => { const { storePath } = await makeStorePath(); const now = Date.parse("2026-03-23T12:00:00.000Z"); - const restoreStateDir = withStateDirForStorePath(storePath); - try { + await withStateDirForStorePath(storePath, async () => { await writeDueIsolatedJobSnapshot(storePath, now); const state = createOkIsolatedCronState({ storePath, now, summary: "done" }); @@ -436,17 +437,14 @@ describe("cron service ops seam coverage", () => { progressSummary: "Running cron job.", }); expect(findTaskByRunId(manualRunId)).toBeUndefined(); - } finally { - restoreStateDir(); - } + }); }); it("records timed out manual runs as timed_out in the shared task registry", async () => { const { storePath } = await makeStorePath(); const now = Date.parse("2026-03-23T12:00:00.000Z"); - const restoreStateDir = withStateDirForStorePath(storePath); - try { + await withStateDirForStorePath(storePath, async () => { await writeDueIsolatedJobSnapshot(storePath, now); const state = createTimedOutIsolatedCronState({ @@ -462,9 +460,7 @@ describe("cron service ops seam coverage", () => { status: "timed_out", sourceId: "isolated-timeout", }); - } finally { - restoreStateDir(); - } + }); }); it("keeps manual cron runs progressing when task ledger creation fails", async () => { @@ -495,9 +491,8 @@ describe("cron service ops seam coverage", () => { it("keeps manual cron cleanup progressing when task ledger updates fail", async () => { const { storePath } = await makeStorePath(); const now = Date.parse("2026-03-23T12:00:00.000Z"); - const restoreStateDir = withStateDirForStorePath(storePath); - try { + await withStateDirForStorePath(storePath, async () => { await writeDueIsolatedJobSnapshot(storePath, now); const updateTaskRecordSpy = vi @@ -516,9 +511,7 @@ describe("cron service ops seam coverage", () => { } finally { updateTaskRecordSpy.mockRestore(); } - } finally { - restoreStateDir(); - } + }); }); it("non-schedule edit preserves nextRunAtMs (#63499)", async () => { @@ -586,9 +579,8 @@ describe("cron service ops seam coverage", () => { it("records startup catch-up timeouts as timed_out in the shared task registry", async () => { const { storePath } = await makeStorePath(); const now = Date.parse("2026-03-23T12:00:00.000Z"); - const restoreStateDir = withStateDirForStorePath(storePath); - try { + await withStateDirForStorePath(storePath, async () => { await writeCronStoreSnapshot({ storePath, jobs: [createMissedIsolatedJob(now)], @@ -608,17 +600,14 @@ describe("cron service ops seam coverage", () => { sourceId: "startup-timeout", progressSummary: "Running cron job.", }); - } finally { - restoreStateDir(); - } + }); }); it("seeds active manual cron task progress for status surfaces", async () => { const { storePath } = await makeStorePath(); const now = Date.parse("2026-03-23T12:00:00.000Z"); - const restoreStateDir = withStateDirForStorePath(storePath); - try { + await withStateDirForStorePath(storePath, async () => { await writeDueIsolatedJobSnapshot(storePath, now); let resolveRun: ((value: { status: "ok"; summary: string }) => void) | undefined; const state = createCronServiceState({ @@ -651,8 +640,6 @@ describe("cron service ops seam coverage", () => { resolveRun?.({ status: "ok", summary: "done" }); await manualRun; - } finally { - restoreStateDir(); - } + }); }); });