diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index d007b66b96f..2e27ae97262 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -150,10 +150,16 @@ jobs: command: uv sync --locked --python 3.11 --extra dev - name: Run docker integration tests + # HERMES_TEST_WORKERS=8: this suite shares ONE dockerd, so width + # is daemon-bound, not CPU-bound. Width sweep with prewarmed image + # + split files (2026-07): -j4 58-62s, -j8 39s, -j12 35s but with + # ~2x per-file contention inflation at 12. 8 is the knee. + # run_tests.sh forwards HERMES_TEST_WORKERS through its hermetic + # env -i into the parallel runner. uses: ./.github/actions/profile with: label: docker-tests - command: HERMES_TEST_IMAGE="${{ env.IMAGE_NAME }}:test" scripts/run_tests.sh tests/docker/ --file-timeout 600 + command: HERMES_TEST_WORKERS=8 HERMES_TEST_IMAGE="${{ env.IMAGE_NAME }}:test" 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.sh b/scripts/run_tests.sh index 0db80ffb13e..b3222c7be64 100755 --- a/scripts/run_tests.sh +++ b/scripts/run_tests.sh @@ -149,6 +149,7 @@ exec env -i \ LC_ALL=C.UTF-8 \ PYTHONHASHSEED=0 \ PYTHONUTF8=1 \ + ${HERMES_TEST_WORKERS:+HERMES_TEST_WORKERS="$HERMES_TEST_WORKERS"} \ ${HERMES_RUN_SLOW_PET_TESTS:+HERMES_RUN_SLOW_PET_TESTS="$HERMES_RUN_SLOW_PET_TESTS"} \ ${HERMES_E2E_BROWSER:+HERMES_E2E_BROWSER="$HERMES_E2E_BROWSER"} \ ${EXTRA_PYTHONPATH:+PYTHONPATH="$EXTRA_PYTHONPATH"} \ diff --git a/scripts/run_tests_parallel.py b/scripts/run_tests_parallel.py index a1eff6e27fa..2042247d8bb 100755 --- a/scripts/run_tests_parallel.py +++ b/scripts/run_tests_parallel.py @@ -967,27 +967,6 @@ 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(