mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
test: pair cron task state env
This commit is contained in:
@@ -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();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user