Download src/cron/service/ops.run-execution-binding.test.ts from SaylorTwift/openclaw: direct link, hf CLI and curl.
- Browser
- Download file 8.47 kB
-
https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/cron/service/ops.run-execution-binding.test.ts
- Command line
-
hf download hf://SaylorTwift/openclaw/src/cron/service/ops.run-execution-binding.test.ts
-
curl -L -o ops.run-execution-binding.test.ts https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/cron/service/ops.run-execution-binding.test.ts
8.47 kB
| // Focused proof that manual cron admission binds exact owner-native rows. | |
| import { describe, expect, it, vi } from "vitest"; | |
| import { | |
| createCronRegressionState, | |
| createDueIsolatedJob, | |
| setupCronRegressionFixtures, | |
| } from "../../../test/helpers/cron/service-regression-fixtures.js"; | |
| import type { AdmittedRunContext } from "../../agents/admitted-run-context.js"; | |
| import { createExecutionIdentityAdmissionToken } from "../../audit/execution-identity-admission.js"; | |
| import { tableExists } from "../../state/openclaw-state-db-schema-helpers.js"; | |
| import { | |
| openOpenClawStateDatabase, | |
| runOpenClawStateWriteTransaction, | |
| } from "../../state/openclaw-state-db.js"; | |
| import { createManagedTaskFlow } from "../../tasks/task-flow-registry.js"; | |
| import { | |
| resetTaskFlowRegistryForTests, | |
| resetTaskRegistryForTests, | |
| } from "../../tasks/task-runtime.test-helpers.js"; | |
| import { withOpenClawTestState } from "../../test-utils/openclaw-test-state.js"; | |
| import { saveCronStore } from "../store.js"; | |
| import { | |
| claimCronRunReceiptInDatabase, | |
| finishCronRunReceipt, | |
| prepareCronRunReceiptClaim, | |
| } from "../store/run-receipt-store.js"; | |
| import { run } from "./ops-run.js"; | |
| import { | |
| createCronOwnerExecutionIdentityAdmission, | |
| tryCreateCronTaskRunHandle, | |
| } from "./task-runs.js"; | |
| const fixtures = setupCronRegressionFixtures({ | |
| prefix: "cron-service-execution-binding-", | |
| }); | |
| describe("cron run execution binding", () => { | |
| it("binds the exact admitted execution to the cron receipt and task rows", async () => { | |
| await withOpenClawTestState( | |
| { layout: "state-only", prefix: "openclaw-cron-execution-binding-" }, | |
| async () => { | |
| resetTaskRegistryForTests(); | |
| resetTaskFlowRegistryForTests(); | |
| const store = fixtures.makeStorePath(); | |
| const dueAt = Date.parse("2026-02-06T10:05:06.525Z"); | |
| const job = createDueIsolatedJob({ | |
| id: "exact-owner-binding", | |
| nowMs: dueAt, | |
| nextRunAtMs: dueAt, | |
| }); | |
| await saveCronStore(store.storePath, { version: 1, jobs: [job] }); | |
| const runIsolatedAgentJob = vi.fn( | |
| async (params: { | |
| executionIdentity?: { | |
| ingress: { kind: string }; | |
| onPostAdmission?: (context: AdmittedRunContext) => void; | |
| onExecutionStarted?: () => void; | |
| }; | |
| }) => { | |
| const admitted = { | |
| operationalRunInstance: { instanceId: "instance-exact", runId: "run-exact" }, | |
| executionIdentityToken: createExecutionIdentityAdmissionToken("run-exact", { | |
| contextId: "context-exact", | |
| executionId: "execution-exact", | |
| now: dueAt, | |
| }), | |
| } satisfies AdmittedRunContext; | |
| const beforeAdmissionSettles = openOpenClawStateDatabase().db; | |
| expect(tableExists(beforeAdmissionSettles, "execution_owner_lifecycle_bindings")).toBe( | |
| false, | |
| ); | |
| params.executionIdentity?.onPostAdmission?.(admitted); | |
| expect(tableExists(beforeAdmissionSettles, "execution_owner_lifecycle_bindings")).toBe( | |
| false, | |
| ); | |
| params.executionIdentity?.onExecutionStarted?.(); | |
| return { status: "ok" as const }; | |
| }, | |
| ); | |
| const state = createCronRegressionState({ | |
| storePath: store.storePath, | |
| nowMs: () => dueAt, | |
| runIsolatedAgentJob, | |
| }); | |
| await expect(run(state, job.id, "force")).resolves.toEqual({ ok: true, ran: true }); | |
| expect(runIsolatedAgentJob).toHaveBeenCalledWith( | |
| expect.objectContaining({ | |
| executionIdentity: expect.objectContaining({ | |
| ingress: expect.objectContaining({ kind: "schedule" }), | |
| }), | |
| }), | |
| ); | |
| const db = openOpenClawStateDatabase().db; | |
| expect( | |
| db | |
| .prepare( | |
| `SELECT binding.context_id, binding.execution_id, receipt.status, receipt.error_text | |
| FROM cron_run_receipts AS receipt | |
| JOIN execution_owner_lifecycle_bindings AS binding | |
| ON binding.owner_kind = 'cron' AND binding.owner_id = receipt.receipt_id | |
| WHERE receipt.job_id = ?`, | |
| ) | |
| .get(job.id), | |
| ).toEqual({ | |
| context_id: "context-exact", | |
| execution_id: "execution-exact", | |
| status: "ok", | |
| error_text: null, | |
| }); | |
| expect( | |
| db | |
| .prepare( | |
| `SELECT binding.context_id, binding.execution_id, task.status | |
| FROM task_runs AS task | |
| JOIN execution_owner_lifecycle_bindings AS binding | |
| ON binding.owner_kind = 'task' AND binding.owner_id = task.task_id | |
| WHERE task.source_id = ? AND task.runtime = 'cron'`, | |
| ) | |
| .get(job.id), | |
| ).toEqual({ | |
| context_id: "context-exact", | |
| execution_id: "execution-exact", | |
| status: "succeeded", | |
| }); | |
| }, | |
| ); | |
| }); | |
| it("does not partially bind task or flow rows after the cron owner is replaced", async () => { | |
| await withOpenClawTestState( | |
| { layout: "state-only", prefix: "openclaw-cron-stale-execution-binding-" }, | |
| async () => { | |
| resetTaskRegistryForTests(); | |
| resetTaskFlowRegistryForTests(); | |
| const store = fixtures.makeStorePath(); | |
| const dueAt = Date.parse("2026-02-06T10:06:06.525Z"); | |
| const job = { | |
| ...createDueIsolatedJob({ | |
| id: "stale-owner-binding", | |
| nowMs: dueAt, | |
| nextRunAtMs: dueAt, | |
| }), | |
| agentId: "main", | |
| }; | |
| await saveCronStore(store.storePath, { version: 1, jobs: [job] }); | |
| const state = createCronRegressionState({ | |
| storePath: store.storePath, | |
| nowMs: () => dueAt, | |
| runIsolatedAgentJob: vi.fn(), | |
| }); | |
| const prepared = prepareCronRunReceiptClaim({ | |
| storePath: store.storePath, | |
| job, | |
| agentId: job.agentId!, | |
| startedAtMs: dueAt, | |
| }); | |
| const initial = runOpenClawStateWriteTransaction(({ db }) => | |
| claimCronRunReceiptInDatabase({ | |
| database: db, | |
| prepared, | |
| resolveAgentId: (current) => current.agentId!, | |
| }), | |
| ); | |
| const task = tryCreateCronTaskRunHandle({ state, job, startedAt: dueAt }); | |
| expect(task).toBeDefined(); | |
| const flow = createManagedTaskFlow({ | |
| ownerKey: "agent:main:main", | |
| controllerId: "tests/stale-owner-binding", | |
| goal: "Reject partial stale-owner provenance", | |
| status: "running", | |
| }); | |
| expect(flow).not.toBeNull(); | |
| if (!task || !flow) { | |
| throw new Error("expected live task and flow owners"); | |
| } | |
| const executionIdentity = createCronOwnerExecutionIdentityAdmission({ | |
| state, | |
| runReceipt: initial, | |
| taskId: task.taskId, | |
| flowId: flow.flowId, | |
| }); | |
| const admitted = { | |
| operationalRunInstance: { instanceId: "instance-stale", runId: "run-stale" }, | |
| executionIdentityToken: createExecutionIdentityAdmissionToken("run-stale", { | |
| contextId: "context-stale", | |
| executionId: "execution-stale", | |
| now: dueAt, | |
| }), | |
| } satisfies AdmittedRunContext; | |
| executionIdentity.onPostAdmission?.(admitted); | |
| const db = openOpenClawStateDatabase().db; | |
| db.prepare("UPDATE cron_run_receipts SET owner_pid = ? WHERE receipt_id = ?").run( | |
| 2_147_483_647, | |
| initial.receiptId, | |
| ); | |
| const replacementPrepared = prepareCronRunReceiptClaim({ | |
| storePath: store.storePath, | |
| job, | |
| agentId: job.agentId!, | |
| startedAtMs: dueAt + 1, | |
| }); | |
| const replacement = runOpenClawStateWriteTransaction(({ db: transactionDb }) => | |
| claimCronRunReceiptInDatabase({ | |
| database: transactionDb, | |
| prepared: replacementPrepared, | |
| resolveAgentId: (current) => current.agentId!, | |
| }), | |
| ); | |
| executionIdentity.onExecutionStarted?.(); | |
| expect( | |
| tableExists(openOpenClawStateDatabase().db, "execution_owner_lifecycle_bindings"), | |
| ).toBe(false); | |
| finishCronRunReceipt({ | |
| handle: replacement, | |
| status: "skipped", | |
| finishedAtMs: dueAt + 2, | |
| }); | |
| }, | |
| ); | |
| }); | |
| }); | |