fix(e2e): kill timed live docker runs

This commit is contained in:
Vincent Koc
2026-05-26 17:03:57 +02:00
parent d54c90699f
commit dc0d4c263e
2 changed files with 100 additions and 1 deletions

View File

@@ -206,6 +206,11 @@ openclaw_live_append_array() {
eval "${target_array}+=(\"\${${source_array}[@]}\")"
}
openclaw_live_timeout_supports_kill_after() {
command -v timeout >/dev/null 2>&1 || return 1
timeout --kill-after=1s 1s true >/dev/null 2>&1
}
openclaw_live_init_docker_run_args() {
local target_array="${1:?target array required}"
local timeout_value="${2:-${OPENCLAW_LIVE_DOCKER_RUN_TIMEOUT:-2700s}}"
@@ -213,7 +218,11 @@ openclaw_live_init_docker_run_args() {
if command -v timeout >/dev/null 2>&1; then
quoted_timeout="$(printf '%q' "$timeout_value")"
eval "${target_array}=(timeout ${quoted_timeout} docker run)"
if openclaw_live_timeout_supports_kill_after; then
eval "${target_array}=(timeout --kill-after=30s ${quoted_timeout} docker run)"
else
eval "${target_array}=(timeout ${quoted_timeout} docker run)"
fi
return
fi
eval "${target_array}=(docker run)"

View File

@@ -0,0 +1,90 @@
import { execFileSync } from "node:child_process";
import { chmodSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import { afterEach, describe, expect, it } from "vitest";
const tempDirs: string[] = [];
function makeTempBin(prefix: string) {
const dir = mkdtempSync(path.join(tmpdir(), prefix));
tempDirs.push(dir);
return dir;
}
function writeExecutable(filePath: string, contents: string) {
writeFileSync(filePath, contents, "utf8");
chmodSync(filePath, 0o755);
}
function resolveDockerRunArgs(pathPrefix: string) {
const script = [
"source scripts/lib/live-docker-auth.sh",
"ARGS=()",
"openclaw_live_init_docker_run_args ARGS 42s",
"printf '%s\\n' \"${ARGS[@]}\"",
].join("\n");
return execFileSync("/bin/bash", ["-c", script], {
cwd: process.cwd(),
encoding: "utf8",
env: {
...process.env,
PATH: pathPrefix,
},
}).trimEnd().split("\n");
}
afterEach(() => {
while (tempDirs.length > 0) {
rmSync(tempDirs.pop()!, { force: true, recursive: true });
}
});
describe("scripts/lib/live-docker-auth.sh", () => {
it("adds a kill-after grace period when timeout supports it", () => {
const binDir = makeTempBin("openclaw-live-docker-auth-gnu-");
writeExecutable(
path.join(binDir, "timeout"),
[
"#!/bin/sh",
'if [ "$1" = "--kill-after=1s" ] && [ "$2" = "1s" ] && [ "$3" = "true" ]; then',
" exit 0",
"fi",
"exit 64",
"",
].join("\n"),
);
expect(resolveDockerRunArgs(binDir)).toEqual([
"timeout",
"--kill-after=30s",
"42s",
"docker",
"run",
]);
});
it("falls back to plain timeout when kill-after is unavailable", () => {
const binDir = makeTempBin("openclaw-live-docker-auth-plain-");
writeExecutable(
path.join(binDir, "timeout"),
[
"#!/bin/sh",
'if [ "$1" = "--kill-after=1s" ]; then',
" exit 1",
"fi",
"exit 0",
"",
].join("\n"),
);
expect(resolveDockerRunArgs(binDir)).toEqual(["timeout", "42s", "docker", "run"]);
});
it("uses docker directly when timeout is unavailable", () => {
const binDir = makeTempBin("openclaw-live-docker-auth-no-timeout-");
expect(resolveDockerRunArgs(binDir)).toEqual(["docker", "run"]);
});
});