test: pair cron task state env

This commit is contained in:
Shakker
2026-06-05 16:50:22 +01:00
parent 2514980118
commit a16b6c02ce

View File

@@ -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<T>(
storePath: string,
runWithStateDir: () => Promise<T>,
): Promise<T> {
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();
}
});
});
});