fix(qa): preserve active mac restart locks

This commit is contained in:
Vincent Koc 2026-06-23 13:02:39 +02:00
parent 300b09b33f
commit d980f2555a
No known key found for this signature in database
2 changed files with 69 additions and 1 deletions

View file

@ -14,6 +14,7 @@ LAUNCH_AGENT="${HOME}/Library/LaunchAgents/ai.openclaw.mac.plist"
LOCK_KEY="$(printf '%s' "${ROOT_DIR}" | shasum -a 256 | cut -c1-8)"
LOCK_DIR="${TMPDIR:-/tmp}/openclaw-restart-${LOCK_KEY}"
LOCK_PID_FILE="${LOCK_DIR}/pid"
LOCK_HELD=0
WAIT_FOR_LOCK=0
LOG_PATH="${OPENCLAW_RESTART_LOG:-${TMPDIR:-/tmp}/openclaw-restart-${LOCK_KEY}.log}"
NO_SIGN=0
@ -38,7 +39,14 @@ run_step() {
}
cleanup() {
if [[ -d "${LOCK_DIR}" ]]; then
if [[ "${LOCK_HELD}" != "1" || ! -d "${LOCK_DIR}" ]]; then
return 0
fi
local owner_pid=""
if [[ -f "${LOCK_PID_FILE}" ]]; then
owner_pid="$(cat "${LOCK_PID_FILE}" 2>/dev/null || true)"
fi
if [[ -z "${owner_pid}" || "${owner_pid}" == "$$" ]]; then
rm -rf "${LOCK_DIR}"
fi
}
@ -46,6 +54,7 @@ cleanup() {
acquire_lock() {
while true; do
if mkdir "${LOCK_DIR}" 2>/dev/null; then
LOCK_HELD=1
echo "$$" > "${LOCK_PID_FILE}"
return 0
fi

View file

@ -163,6 +163,36 @@ function runRestartArgParser(...args: string[]) {
return spawnSync("bash", [harnessPath, ...args], { encoding: "utf8" });
}
function runRestartLockHarness(lockDir: string) {
const root = mkdtempSync(join(tmpdir(), "openclaw-restart-mac-test-"));
tempRoots.push(root);
const script = readFileSync(restartScriptPath, "utf8");
const lockBlock = script.slice(
script.indexOf("cleanup()"),
script.indexOf("check_signing_keys()"),
);
const harnessPath = join(root, "lock-harness.sh");
writeFileSync(
harnessPath,
[
"#!/usr/bin/env bash",
"set -euo pipefail",
`LOCK_DIR=${shellQuote(lockDir)}`,
'LOCK_PID_FILE="${LOCK_DIR}/pid"',
"LOCK_HELD=0",
"WAIT_FOR_LOCK=0",
'log() { printf "%s\\n" "$*"; }',
lockBlock,
"trap cleanup EXIT",
"acquire_lock",
].join("\n"),
);
chmodSync(harnessPath, 0o755);
return spawnSync("bash", [harnessPath], { encoding: "utf8" });
}
afterEach(() => {
for (const root of tempRoots.splice(0)) {
rmSync(root, { force: true, recursive: true });
@ -227,6 +257,35 @@ describe("scripts/restart-mac.sh", () => {
expect(script).not.toContain('LOG_PATH="${OPENCLAW_RESTART_LOG:-/tmp/openclaw-restart.log}"');
});
it("does not remove a live restart lock it did not acquire", () => {
const root = mkdtempSync(join(tmpdir(), "openclaw-restart-mac-test-"));
tempRoots.push(root);
const lockDir = join(root, "openclaw-restart-lock");
mkdirSync(lockDir);
writeFileSync(join(lockDir, "pid"), String(process.pid), "utf8");
const result = runRestartLockHarness(lockDir);
expect(result.status).toBe(0);
expect(result.stdout).toContain(`Another restart is running (pid ${process.pid}); re-run with --wait.`);
expect(result.stderr).toBe("");
expect(existsSync(lockDir)).toBe(true);
expect(readFileSync(join(lockDir, "pid"), "utf8")).toBe(String(process.pid));
});
it("removes the restart lock it acquired", () => {
const root = mkdtempSync(join(tmpdir(), "openclaw-restart-mac-test-"));
tempRoots.push(root);
const lockDir = join(root, "openclaw-restart-lock");
const result = runRestartLockHarness(lockDir);
expect(result.status).toBe(0);
expect(result.stdout).toBe("");
expect(result.stderr).toBe("");
expect(existsSync(lockDir)).toBe(false);
});
it("prefers the freshly packaged app unless an explicit app bundle is set", () => {
const script = readFileSync(restartScriptPath, "utf8");
const chooseBlock = script.slice(