





















@@ -115,7 +115,7 @@ describe("docker build helper", () => {
115115expect(helper).toContain("docker_build_transient_failure()");
116116expect(helper).toContain("OPENCLAW_DOCKER_BUILD_RETRIES");
117117expect(helper).toContain("OPENCLAW_DOCKER_BUILD_TIMEOUT");
118-expect(helper).toContain('docker_build_run_command "$timeout_value" "${command[@]}"');
118+expect(helper).toContain('docker_build_run_logged "$label" "$timeout_value" "$log_file"');
119119expect(helper).toContain("OPENCLAW_DOCKER_BUILD_REQUIRE_TIMEOUT");
120120expect(helper).toContain("frontend grpc server closed unexpectedly");
121121});
@@ -241,6 +241,104 @@ grep -q '^build -t demo-image .$' "$TMPDIR/docker-seen"
241241}
242242});
243243244+it("prints heartbeat progress for long successful centralized Docker builds", () => {
245+const workDir = mkdtempSync(join(tmpdir(), "openclaw-docker-build-heartbeat-"));
246+247+try {
248+const binDir = join(workDir, "bin");
249+mkdirSync(binDir);
250+writeFileSync(
251+join(binDir, "timeout"),
252+`#!/bin/bash
253+set -euo pipefail
254+if [[ "$1" = "--kill-after=1s" ]]; then
255+ exit 0
256+fi
257+shift 2
258+"$@"
259+`,
260+);
261+chmodSync(join(binDir, "timeout"), 0o755);
262+writeFileSync(
263+join(binDir, "docker"),
264+`#!/bin/sh
265+printf "captured docker build log\\n"
266+/bin/sleep 2
267+`,
268+);
269+chmodSync(join(binDir, "docker"), 0o755);
270+const rootDir = process.cwd();
271+const script = `
272+set -euo pipefail
273+ROOT_DIR=${shellQuote(rootDir)}
274+TMPDIR=${shellQuote(workDir)}
275+export ROOT_DIR TMPDIR
276+export PATH="$TMPDIR/bin:$PATH"
277+export OPENCLAW_DOCKER_BUILD_HEARTBEAT_SECONDS=1
278+279+source "$ROOT_DIR/scripts/lib/docker-build.sh"
280+281+output="$(docker_build_run e2e-build -t demo-image .)"
282+[[ "$output" = *"Docker build e2e-build still running ("* ]]
283+[[ "$output" = *"log bytes captured"* ]]
284+[[ "$output" != *"captured docker build log"* ]]
285+`;
286+287+execFileSync("bash", ["-lc", script], { encoding: "utf8" });
288+} finally {
289+rmSync(workDir, { recursive: true, force: true });
290+}
291+});
292+293+it("does not delay fast successful centralized Docker builds until the next heartbeat", () => {
294+const workDir = mkdtempSync(join(tmpdir(), "openclaw-docker-build-fast-heartbeat-"));
295+296+try {
297+const binDir = join(workDir, "bin");
298+mkdirSync(binDir);
299+writeFileSync(
300+join(binDir, "timeout"),
301+`#!/bin/bash
302+set -euo pipefail
303+if [[ "$1" = "--kill-after=1s" ]]; then
304+ exit 0
305+fi
306+shift 2
307+"$@"
308+`,
309+);
310+chmodSync(join(binDir, "timeout"), 0o755);
311+writeFileSync(
312+join(binDir, "docker"),
313+`#!/bin/sh
314+printf "quick docker build log\\n"
315+`,
316+);
317+chmodSync(join(binDir, "docker"), 0o755);
318+const rootDir = process.cwd();
319+const script = `
320+set -euo pipefail
321+ROOT_DIR=${shellQuote(rootDir)}
322+TMPDIR=${shellQuote(workDir)}
323+export ROOT_DIR TMPDIR
324+export PATH="$TMPDIR/bin:$PATH"
325+export OPENCLAW_DOCKER_BUILD_HEARTBEAT_SECONDS=30
326+327+source "$ROOT_DIR/scripts/lib/docker-build.sh"
328+329+output="$(docker_build_run e2e-build -t demo-image .)"
330+[[ -z "$output" ]]
331+`;
332+const startedAt = Date.now();
333+334+execFileSync("bash", ["-lc", script], { encoding: "utf8" });
335+336+expect(Date.now() - startedAt).toBeLessThan(5_000);
337+} finally {
338+rmSync(workDir, { recursive: true, force: true });
339+}
340+});
341+244342it("fails centralized Docker builds fast when timeout is unavailable", () => {
245343const workDir = mkdtempSync(join(tmpdir(), "openclaw-docker-build-timeout-required-"));
246344此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。