From 67516f0ba1c77d817eaa584b939d39d63e6fbdcf Mon Sep 17 00:00:00 2001 From: ethernet Date: Thu, 30 Jul 2026 17:19:22 -0400 Subject: [PATCH] fix(tests): auto-cap docker-suite workers in the runner itself MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the dockerd-bound worker cap from a workflow env var into run_tests_parallel.py: when every file in the run is under tests/docker/, cap -j at 4 (the suite shares one docker daemon; width beyond that thrashes it — files stretch ~100s -> ~900s and teardown docker-rm calls blow their 10s timeout). Explicit -j or HERMES_TEST_WORKERS always wins; mixed file lists are unaffected. Verified: docker-only list caps 32->4, -j 12 respected, mixed list uncapped. Drops the HERMES_TEST_WORKERS=4 pin from docker.yml. --- .github/workflows/docker.yml | 10 ++++------ scripts/run_tests_parallel.py | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index bd686604e8c..cb63a0e13df 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -119,15 +119,13 @@ jobs: command: uv sync --locked --python 3.11 --extra dev - name: Run docker integration tests - # HERMES_TEST_WORKERS=4: this suite shares ONE dockerd — parallel - # width is bounded by the daemon, not CPU. At cpu*2 workers (16 on - # the 8-CPU ARC pods) dockerd thrashes: every file takes ~900s and - # teardown `docker rm` blows its 10s timeout. arm64 (2 CPU → -j4) - # passes for exactly this reason. + # The test runner auto-caps workers for tests/docker (the suite is + # bounded by the single dind dockerd, not CPU — see + # run_tests_parallel.py's docker-suite auto-cap). uses: ./.github/actions/profile with: label: docker-tests - command: HERMES_TEST_WORKERS=4 scripts/run_tests.sh tests/docker/ --file-timeout 600 + command: scripts/run_tests.sh tests/docker/ --file-timeout 600 # --------------------------------------------------------------------------- # Rebuild and push each architecture only after the unprivileged build/test diff --git a/scripts/run_tests_parallel.py b/scripts/run_tests_parallel.py index 2042247d8bb..a1eff6e27fa 100755 --- a/scripts/run_tests_parallel.py +++ b/scripts/run_tests_parallel.py @@ -967,6 +967,27 @@ def main() -> int: test_counts = {f: test_counts[f] for f in files if f in test_counts} approx_total_tests = sum(test_counts.values()) + # Docker-suite auto-cap: tests/docker files all funnel through a single + # docker daemon, so parallel width is bounded by dockerd, not CPU. + # Running the suite at cpu*2 width thrashes the daemon (files stretch + # from ~100s to ~900s, teardown `docker rm` blows its timeout). Cap at + # 4 unless the user explicitly chose a width (-j or HERMES_TEST_WORKERS). + _DOCKERD_BOUND_JOBS = 4 + jobs_explicit = ( + os.environ.get("HERMES_TEST_WORKERS") + or any(a == "-j" or a.startswith(("--jobs", "-j")) for a in sys.argv[1:]) + ) + if not jobs_explicit and files and all( + "tests/docker/" in str(f).replace(os.sep, "/") for f in files + ): + if args.jobs > _DOCKERD_BOUND_JOBS: + print( + f"Docker suite detected (single dockerd bottleneck): " + f"capping workers {args.jobs} -> {_DOCKERD_BOUND_JOBS}", + flush=True, + ) + args.jobs = _DOCKERD_BOUND_JOBS + if roots: roots_str = [str(r.relative_to(repo_root)) if r.is_relative_to(repo_root) else str(r) for r in roots] print(