@@ -5,6 +5,7 @@ import {
|
5 | 5 | chmodSync, |
6 | 6 | copyFileSync, |
7 | 7 | existsSync, |
| 8 | +mkdirSync, |
8 | 9 | mkdtempSync, |
9 | 10 | readFileSync, |
10 | 11 | rmSync, |
@@ -43,6 +44,7 @@ import { testing as hostServerTesting } from "../../scripts/e2e/parallels/host-s
|
43 | 44 | import { parseArgs as parseLinuxSmokeArgs } from "../../scripts/e2e/parallels/linux-smoke.ts"; |
44 | 45 | import { parseArgs as parseMacosSmokeArgs } from "../../scripts/e2e/parallels/macos-smoke.ts"; |
45 | 46 | import { parseArgs as parseNpmUpdateSmokeArgs } from "../../scripts/e2e/parallels/npm-update-smoke.ts"; |
| 47 | +import { testing as packageArtifactTesting } from "../../scripts/e2e/parallels/package-artifact.ts"; |
46 | 48 | import { PhaseRunner } from "../../scripts/e2e/parallels/phase-runner.ts"; |
47 | 49 | import { |
48 | 50 | posixCodexPlatformPackageRepairFunction, |
@@ -432,6 +434,21 @@ describe("Parallels smoke model selection", () => {
|
432 | 434 | expect(retained).toBe(`${"a".repeat(2)}${"b".repeat(10)}`); |
433 | 435 | }); |
434 | 436 | |
| 437 | +it("reclaims package locks with malformed owner pids", async () => { |
| 438 | +const lockDir = makeTempDir(tempDirs, "openclaw-parallels-package-lock-"); |
| 439 | +mkdirSync(lockDir, { recursive: true }); |
| 440 | +writeFileSync(join(lockDir, "owner.json"), '{"pid":-1,"token":"stale"}\n'); |
| 441 | + |
| 442 | +await expect(packageArtifactTesting.readLockOwner(lockDir)).resolves.toEqual({ |
| 443 | +pid: undefined, |
| 444 | +token: "stale", |
| 445 | +}); |
| 446 | + |
| 447 | +await packageArtifactTesting.removeStalePackageLock(lockDir, 2 * 60 * 60_000); |
| 448 | + |
| 449 | +expect(existsSync(lockDir)).toBe(false); |
| 450 | +}); |
| 451 | + |
435 | 452 | it("keeps JSON-mode progress off stdout", async () => { |
436 | 453 | const stdoutWrite = vi.spyOn(process.stdout, "write").mockImplementation(() => true); |
437 | 454 | const stderrWrite = vi.spyOn(process.stderr, "write").mockImplementation(() => true); |
|