























@@ -472,6 +472,50 @@ stderr="$(<"$TMPDIR/stderr")"
472472}
473473});
474474475+it("uses a Node watchdog for Docker commands when timeout is unavailable", () => {
476+const workDir = mkdtempSync(join(tmpdir(), "openclaw-docker-node-timeout-"));
477+478+try {
479+const binDir = join(workDir, "bin");
480+mkdirSync(binDir);
481+writeFileSync(
482+join(binDir, "node"),
483+`#!/bin/bash\nexec ${shellQuote(process.execPath)} "$@"\n`,
484+);
485+writeFileSync(
486+join(binDir, "docker"),
487+`#!/bin/bash\ninput="$(/bin/cat)"\nprintf "%s|%s\\n" "$*" "$input" >"$TMPDIR/docker-seen"\nexit 13\n`,
488+);
489+chmodSync(join(binDir, "node"), 0o755);
490+chmodSync(join(binDir, "docker"), 0o755);
491+const rootDir = process.cwd();
492+const script = `
493+set -euo pipefail
494+ROOT_DIR=${shellQuote(rootDir)}
495+TMPDIR=${shellQuote(workDir)}
496+export ROOT_DIR TMPDIR
497+export PATH="$TMPDIR/bin"
498+export DOCKER_COMMAND_TIMEOUT=7s
499+500+source "$ROOT_DIR/scripts/lib/docker-e2e-container.sh"
501+502+set +e
503+printf payload | docker_e2e_docker_cmd run -i demo 2>"$TMPDIR/stderr"
504+status="$?"
505+set -e
506+507+stderr="$(<"$TMPDIR/stderr")"
508+[[ "$status" = "13" ]]
509+[[ "$stderr" = *"timeout command not found; using Node watchdog for Docker command timeout 7s"* ]]
510+[[ "$(<"$TMPDIR/docker-seen")" = "run -i demo|payload" ]]
511+`;
512+513+execFileSync("bash", ["-lc", script], { encoding: "utf8" });
514+} finally {
515+rmSync(workDir, { recursive: true, force: true });
516+}
517+});
518+475519it("uses plain timeout when kill-after is unsupported", () => {
476520const workDir = mkdtempSync(join(tmpdir(), "openclaw-docker-plain-timeout-"));
477521@@ -962,7 +1006,9 @@ grep -qx -- "OPENCLAW_E2E_COMMAND_TIMEOUT=23s" "$TMPDIR/package-args"
9621006expect(runner).toContain(
9631007'DOCKER_ENV_ARGS+=(-e "OPENCLAW_PLUGIN_LIFECYCLE_PHASE_TIMEOUT_MS=$OPENCLAW_PLUGIN_LIFECYCLE_PHASE_TIMEOUT_MS")',
9641008);
965-expect(runner).toContain('if [ -n "${OPENCLAW_PLUGIN_LIFECYCLE_TIMEOUT_KILL_GRACE_MS:-}" ]; then');
1009+expect(runner).toContain(
1010+'if [ -n "${OPENCLAW_PLUGIN_LIFECYCLE_TIMEOUT_KILL_GRACE_MS:-}" ]; then',
1011+);
9661012expect(runner).toContain(
9671013'DOCKER_ENV_ARGS+=(-e "OPENCLAW_PLUGIN_LIFECYCLE_TIMEOUT_KILL_GRACE_MS=$OPENCLAW_PLUGIN_LIFECYCLE_TIMEOUT_KILL_GRACE_MS")',
9681014);
@@ -1043,10 +1089,16 @@ grep -qx -- "OPENCLAW_E2E_COMMAND_TIMEOUT=23s" "$TMPDIR/package-args"
10431089const publishedRunner = readFileSync(UPGRADE_SURVIVOR_RUN_SCRIPT, "utf8");
10441090const updateRestartAuth = readFileSync(UPGRADE_SURVIVOR_UPDATE_RESTART_AUTH_PATH, "utf8");
104510911046-expect(runner).toContain('COMMAND_TIMEOUT="${OPENCLAW_UPGRADE_SURVIVOR_COMMAND_TIMEOUT:-900s}"');
1092+expect(runner).toContain(
1093+'COMMAND_TIMEOUT="${OPENCLAW_UPGRADE_SURVIVOR_COMMAND_TIMEOUT:-900s}"',
1094+);
10471095expect(runner).toContain('-e OPENCLAW_UPGRADE_SURVIVOR_COMMAND_TIMEOUT="$COMMAND_TIMEOUT"');
1048-expect(runner).toContain('command_timeout="${OPENCLAW_UPGRADE_SURVIVOR_COMMAND_TIMEOUT:-900s}"');
1049-expect(runner).toContain('openclaw_e2e_maybe_timeout "$command_timeout" env -u OPENCLAW_GATEWAY_TOKEN');
1096+expect(runner).toContain(
1097+'command_timeout="${OPENCLAW_UPGRADE_SURVIVOR_COMMAND_TIMEOUT:-900s}"',
1098+);
1099+expect(runner).toContain(
1100+'openclaw_e2e_maybe_timeout "$command_timeout" env -u OPENCLAW_GATEWAY_TOKEN',
1101+);
10501102expect(runner).toContain(
10511103'openclaw_e2e_maybe_timeout "$command_timeout" openclaw doctor --fix --non-interactive',
10521104);
@@ -1056,7 +1108,9 @@ grep -qx -- "OPENCLAW_E2E_COMMAND_TIMEOUT=23s" "$TMPDIR/package-args"
10561108expect(runner).toContain(
10571109'openclaw_e2e_maybe_timeout "$command_timeout" openclaw gateway status',
10581110);
1059-expect(runner).toContain('openclaw gateway --port "$PORT" --bind loopback --allow-unconfigured');
1111+expect(runner).toContain(
1112+'openclaw gateway --port "$PORT" --bind loopback --allow-unconfigured',
1113+);
1060111410611115expect(publishedRunner).toContain(
10621116'COMMAND_TIMEOUT="${OPENCLAW_UPGRADE_SURVIVOR_COMMAND_TIMEOUT:-900s}"',
@@ -1233,8 +1287,7 @@ test -f "$TMPDIR/docker-cmd-seen"
12331287{ path: KITCHEN_SINK_RPC_DOCKER_E2E_PATH, label: "kitchen-sink-rpc" },
12341288]) {
12351289const runner = readFileSync(path, "utf8");
1236-const resourceAssertion =
1237-`node scripts/e2e/lib/docker-stats/assert-resource-ceiling.mjs "$STATS_LOG" "$MAX_MEMORY_MIB" "$MAX_CPU_PERCENT" ${label}`;
1290+const resourceAssertion = `node scripts/e2e/lib/docker-stats/assert-resource-ceiling.mjs "$STATS_LOG" "$MAX_MEMORY_MIB" "$MAX_CPU_PERCENT" ${label}`;
1238129112391292expect(runner, path).toContain('RUN_LOG="$(mktemp');
12401293expect(runner, path).toContain('STATS_LOG="$(mktemp');
@@ -1248,7 +1301,9 @@ test -f "$TMPDIR/docker-cmd-seen"
12481301expect(runner, path).not.toMatch(/(^|\n)docker (?:inspect|stats) /u);
12491302expect(runner, path).toMatch(/cleanup\(\) \{[\s\S]*rm -f "\$RUN_LOG" "\$STATS_LOG"/u);
12501303expect(runner, path).toContain(`if [ "$run_status" -eq 0 ]; then\n ${resourceAssertion}`);
1251-expect(runner, path).toContain(`elif [ -s "$STATS_LOG" ]; then\n ${resourceAssertion} || true`);
1304+expect(runner, path).toContain(
1305+`elif [ -s "$STATS_LOG" ]; then\n ${resourceAssertion} || true`,
1306+);
12521307expect(runner, path).not.toContain(`${resourceAssertion}\n\nexit "$run_status"`);
12531308}
12541309});
@@ -1470,11 +1525,21 @@ test -f "$TMPDIR/docker-cmd-seen"
14701525it("routes doctor install switch commands through the E2E timeout helper", () => {
14711526const scenario = readFileSync(DOCTOR_SWITCH_SCENARIO_PATH, "utf8");
147215271473-expect(scenario).toContain('command_timeout="${OPENCLAW_DOCKER_DOCTOR_SWITCH_COMMAND_TIMEOUT:-900s}"');
1474-expect(scenario).toContain('openclaw_e2e_maybe_timeout "$command_timeout" bash -c "$install_cmd"');
1475-expect(scenario).toContain('openclaw_e2e_maybe_timeout "$command_timeout" bash -c "$doctor_cmd"');
1476-expect(scenario).toContain('openclaw_e2e_maybe_timeout "$command_timeout" "$npm_bin" gateway install --wrapper "$wrapper" --force');
1477-expect(scenario).toContain('openclaw_e2e_maybe_timeout "$command_timeout" node "$git_cli" doctor --repair --force --yes');
1528+expect(scenario).toContain(
1529+'command_timeout="${OPENCLAW_DOCKER_DOCTOR_SWITCH_COMMAND_TIMEOUT:-900s}"',
1530+);
1531+expect(scenario).toContain(
1532+'openclaw_e2e_maybe_timeout "$command_timeout" bash -c "$install_cmd"',
1533+);
1534+expect(scenario).toContain(
1535+'openclaw_e2e_maybe_timeout "$command_timeout" bash -c "$doctor_cmd"',
1536+);
1537+expect(scenario).toContain(
1538+'openclaw_e2e_maybe_timeout "$command_timeout" "$npm_bin" gateway install --wrapper "$wrapper" --force',
1539+);
1540+expect(scenario).toContain(
1541+'openclaw_e2e_maybe_timeout "$command_timeout" node "$git_cli" doctor --repair --force --yes',
1542+);
14781543expect(scenario).not.toMatch(/^\s*if ! timeout "\$command_timeout"/mu);
14791544});
14801545此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。