Download src/cli/update-cli/update-command-doctor-delegation.test.ts from SaylorTwift/openclaw: direct link, hf CLI and curl.
- Browser
- Download file 6.24 kB
-
https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/cli/update-cli/update-command-doctor-delegation.test.ts
- Command line
-
hf download hf://SaylorTwift/openclaw/src/cli/update-cli/update-command-doctor-delegation.test.ts
-
curl -L -o update-command-doctor-delegation.test.ts https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/cli/update-cli/update-command-doctor-delegation.test.ts
6.24 kB
| import "./update-command-execution.test-support.js"; | |
| import fs from "node:fs/promises"; | |
| import path from "node:path"; | |
| import { pathToFileURL } from "node:url"; | |
| import { expect, it, vi } from "vitest"; | |
| import { runtimeProcessEntrypoints } from "../../infra/runtime-process-entrypoints.js"; | |
| import { resolveRuntimeWorkerUrl } from "../../infra/runtime-worker-url.js"; | |
| import * as tempRoot from "../../infra/tmp-openclaw-dir.js"; | |
| import { createManagedHandoffLeaseStore } from "../../infra/update-managed-service-handoff-lease.js"; | |
| import { createUpdateRun } from "../../infra/update-run-ledger.js"; | |
| import * as processRunner from "../../process/exec.js"; | |
| import { withTestDir } from "../../test-helpers/temp-dir.js"; | |
| import { executeMutableUpdate } from "./update-command-execution.js"; | |
| import { updateExecutorNativeEntrypoints } from "./update-command-executor-native-runtime.test-support.js"; | |
| import { withUpdateCommandExecutor } from "./update-command-executor.js"; | |
| import { runPackageUpdateDoctor } from "./update-command-package.js"; | |
| const { executionParams, mocks, successfulUpdate } = | |
| await import("./update-command-execution.test-support.js"); | |
| it.each( | |
| (["package", "git"] as const).flatMap((kind) => | |
| (["healthy", "requester-revoked", "run-replaced"] as const).map((fault) => ({ kind, fault })), | |
| ), | |
| )( | |
| "delegates $kind Doctor without reusing its suspended parent ($fault)", | |
| async ({ kind, fault }) => { | |
| await withTestDir({ prefix: "update-doctor-delegation-" }, async (dir) => { | |
| const root = await fs.realpath(dir); | |
| const control = path.join(root, "leases"); | |
| await fs.mkdir(control); | |
| vi.spyOn(tempRoot, "resolvePreferredOpenClawTmpDir").mockReturnValue(control); | |
| const env = { | |
| OPENCLAW_STATE_DIR: path.join(root, "state"), | |
| OPENCLAW_CONFIG_PATH: path.join(root, "openclaw.json"), | |
| }; | |
| await fs.writeFile(env.OPENCLAW_CONFIG_PATH, "{}"); | |
| const runId = createUpdateRun({ trigger: "cli" }, { env }).runId; | |
| await fs.mkdir(path.join(root, "dist", "infra"), { recursive: true }); | |
| await fs.writeFile( | |
| path.join(root, "package.json"), | |
| JSON.stringify({ name: "openclaw", type: "module", version: "2026.9.4" }), | |
| ); | |
| await fs.writeFile(path.join(root, "dist", "index.js"), ""); | |
| const owner = resolveRuntimeWorkerUrl(updateExecutorNativeEntrypoints.executor); | |
| const marker = path.join(root, "doctor-ran"); | |
| const received = path.join(root, "doctor-input-received"); | |
| await fs.writeFile( | |
| path.join(root, "dist", runtimeProcessEntrypoints.updateMigratedFinalize.distWorkerPath), | |
| ` | |
| import fs from "node:fs"; | |
| ${owner.pathname.endsWith(".ts") ? `await import(${JSON.stringify(pathToFileURL(path.resolve("scripts/tsx.mjs")).href)});` : ""} | |
| const {withDelegatedUpdateCommandExecutor}=await import(${JSON.stringify(owner.href)}); | |
| const raw=fs.readFileSync(0,"utf8"); | |
| if(raw) fs.writeFileSync(${JSON.stringify(received)},"received"); | |
| const input=JSON.parse(raw); | |
| await withDelegatedUpdateCommandExecutor(input.executor,input.runId,input.root,async fence=>{ | |
| fence.assertCurrent(); | |
| fs.writeFileSync(${JSON.stringify(marker)},"owned"); | |
| }); | |
| `, | |
| ); | |
| let requesterCurrent = true; | |
| let reachedSpawn = false; | |
| const runChild = processRunner.runUtf8CommandWithTimeout; | |
| vi.spyOn(processRunner, "runUtf8CommandWithTimeout").mockImplementation((argv, options) => { | |
| const commandOptions = typeof options === "number" ? { timeoutMs: options } : options; | |
| return runChild(argv, { | |
| ...commandOptions, | |
| beforeInput: (pid, spawnedArgv) => { | |
| reachedSpawn = true; | |
| if (fault === "requester-revoked") { | |
| requesterCurrent = false; | |
| } | |
| if (fault === "run-replaced") { | |
| params.opts.run = { runId: "replacement-run", env }; | |
| } | |
| commandOptions.beforeInput?.(pid, spawnedArgv); | |
| }, | |
| }); | |
| }); | |
| const params = executionParams(kind); | |
| params.root = root; | |
| params.opts.run = { | |
| runId, | |
| env, | |
| requesterAuthority: { requester: {}, isCurrent: () => requesterCurrent }, | |
| }; | |
| mocks.nativeSupport.mockResolvedValue(true); | |
| mocks.validateCanary.mockResolvedValue({ | |
| status: "ok", | |
| phase: "readiness", | |
| steps: [], | |
| durationMs: 1, | |
| logTail: [], | |
| doctorConfigWrites: true, | |
| }); | |
| const runUpdate = async ( | |
| options: Pick<Parameters<typeof runPackageUpdateDoctor>[0], "getDoctorContext"> & { | |
| validateCandidate?: (root: string) => Promise<unknown>; | |
| }, | |
| ) => { | |
| await options.validateCandidate?.(root); | |
| const step = await runPackageUpdateDoctor({ | |
| root, | |
| timeoutMs: 20_000, | |
| progress: {}, | |
| managedServiceEnv: env, | |
| getDoctorContext: options.getDoctorContext, | |
| }); | |
| return { | |
| ...successfulUpdate, | |
| root, | |
| mode: kind === "git" ? ("git" as const) : ("npm" as const), | |
| steps: step ? [step] : [], | |
| status: step?.exitCode === 0 ? ("ok" as const) : ("error" as const), | |
| }; | |
| }; | |
| mocks.runPackageUpdate.mockImplementation(runUpdate); | |
| mocks.runGitUpdate.mockImplementation(runUpdate); | |
| const update = withUpdateCommandExecutor(runId, async (executor) => { | |
| params.opts.run!.executorFence = await executor.enter(root); | |
| return executeMutableUpdate(params); | |
| }); | |
| if (fault !== "healthy") { | |
| await expect(update).rejects.toThrow("requester-revoked"); | |
| await expect(fs.stat(marker)).rejects.toMatchObject({ code: "ENOENT" }); | |
| await expect(fs.stat(received)).rejects.toMatchObject({ code: "ENOENT" }); | |
| } else { | |
| expect((await update)?.result).toMatchObject({ | |
| status: "ok", | |
| steps: [{ name: "openclaw doctor", exitCode: 0 }], | |
| }); | |
| expect(await fs.readFile(marker, "utf8")).toBe("owned"); | |
| } | |
| expect(reachedSpawn).toBe(true); | |
| expect(createManagedHandoffLeaseStore().read(root)).toEqual({ kind: "absent" }); | |
| }); | |
| }, | |
| ); | |