From 80aa6d77fcd60686cb46ccf4dd9edf6b957c3f4f Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Tue, 26 May 2026 02:12:35 +0200 Subject: [PATCH] test(onboard): guard docker e2e resources --- scripts/e2e/onboard-docker.sh | 35 ++++++++++++++++++++++-- test/scripts/docker-build-helper.test.ts | 12 ++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/scripts/e2e/onboard-docker.sh b/scripts/e2e/onboard-docker.sh index 60c62be012b..75f6fd60e90 100755 --- a/scripts/e2e/onboard-docker.sh +++ b/scripts/e2e/onboard-docker.sh @@ -5,12 +5,43 @@ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" source "$ROOT_DIR/scripts/lib/docker-e2e-image.sh" IMAGE_NAME="$(docker_e2e_resolve_image "openclaw-onboard-e2e" OPENCLAW_ONBOARD_E2E_IMAGE)" OPENCLAW_TEST_STATE_FUNCTION_B64="$(docker_e2e_test_state_function_b64)" +MAX_MEMORY_MIB="${OPENCLAW_ONBOARD_MAX_MEMORY_MIB:-2048}" +MAX_CPU_PERCENT="${OPENCLAW_ONBOARD_MAX_CPU_PERCENT:-1200}" +CONTAINER_NAME="openclaw-onboard-e2e-$$" +RUN_LOG="$(mktemp "${TMPDIR:-/tmp}/openclaw-onboard.XXXXXX")" +STATS_LOG="$(mktemp "${TMPDIR:-/tmp}/openclaw-onboard-stats.XXXXXX")" + +cleanup() { + docker rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true +} +trap cleanup EXIT docker_e2e_build_or_reuse "$IMAGE_NAME" onboard echo "Running onboarding E2E..." -docker_e2e_run_with_harness -t \ +docker rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true +docker_e2e_harness_mount_args +docker run --name "$CONTAINER_NAME" "${DOCKER_E2E_HARNESS_ARGS[@]}" -t \ -e "OPENCLAW_TEST_STATE_FUNCTION_B64=$OPENCLAW_TEST_STATE_FUNCTION_B64" \ - "$IMAGE_NAME" bash scripts/e2e/lib/onboard/scenario.sh + "$IMAGE_NAME" bash scripts/e2e/lib/onboard/scenario.sh >"$RUN_LOG" 2>&1 & +docker_pid="$!" +while kill -0 "$docker_pid" 2>/dev/null; do + if docker inspect "$CONTAINER_NAME" >/dev/null 2>&1; then + docker stats --no-stream --format '{{json .}}' "$CONTAINER_NAME" >>"$STATS_LOG" 2>/dev/null || true + fi + sleep 2 +done + +set +e +wait "$docker_pid" +run_status="$?" +set -e + +cat "$RUN_LOG" + +node scripts/e2e/lib/docker-stats/assert-resource-ceiling.mjs "$STATS_LOG" "$MAX_MEMORY_MIB" "$MAX_CPU_PERCENT" onboard + +rm -f "$RUN_LOG" "$STATS_LOG" echo "E2E complete." +exit "$run_status" diff --git a/test/scripts/docker-build-helper.test.ts b/test/scripts/docker-build-helper.test.ts index c7af9cdfd19..0263bb28d65 100644 --- a/test/scripts/docker-build-helper.test.ts +++ b/test/scripts/docker-build-helper.test.ts @@ -18,6 +18,7 @@ const OPENAI_WEB_SEARCH_MINIMAL_SCENARIO_PATH = const OPENAI_WEB_SEARCH_MINIMAL_CLIENT_PATH = "scripts/e2e/lib/openai-web-search-minimal/client.mjs"; const OPENWEBUI_DOCKER_E2E_PATH = "scripts/e2e/openwebui-docker.sh"; +const ONBOARD_DOCKER_E2E_PATH = "scripts/e2e/onboard-docker.sh"; const PLUGIN_BINDING_COMMAND_ESCAPE_DOCKER_E2E_PATH = "scripts/e2e/plugin-binding-command-escape-docker.sh"; const PLUGIN_BINDING_COMMAND_ESCAPE_DOCKERFILE_PATH = @@ -114,6 +115,17 @@ describe("docker build helper", () => { expect(dockerfile).toContain("procps"); }); + it("keeps onboarding Docker E2E resource-guarded", () => { + const runner = readFileSync(ONBOARD_DOCKER_E2E_PATH, "utf8"); + + expect(runner).toContain("OPENCLAW_ONBOARD_MAX_MEMORY_MIB"); + expect(runner).toContain("OPENCLAW_ONBOARD_MAX_CPU_PERCENT"); + expect(runner).toContain("--name \"$CONTAINER_NAME\""); + expect(runner).toContain("docker stats --no-stream"); + expect(runner).toContain("assert-resource-ceiling.mjs"); + expect(runner).not.toContain("docker_e2e_run_with_harness -t"); + }); + it("copies root lifecycle scripts before cleanup-smoke installs dependencies", () => { const dockerfile = readFileSync(CLEANUP_SMOKE_DOCKERFILE_PATH, "utf8"); const installIndex = dockerfile.indexOf("pnpm install --frozen-lockfile");