Repository navigation
ci(integration): split the slow tier and the gateway tests across runners - #362
Merged
Merged
Conversation
…ners The slow tier runs its tests serially, since they share image tags and artifact ids, and it has grown to its 40-minute timeout. Each runner has its own Docker daemon, so split it across runners instead: AGENTENV_TEST_SHARD=i/N keeps the i-th of N groups, keeping a file's tests together and balancing the groups by the seconds in tst/integration/slow_durations.json. The slow tier runs on four runners and gateway_test.py on two; integration-local-slow and integration-local-gateway are now jobs that pass when all of their shards do, so the required check keeps its name. Each shard uploads its JUnit report, from which .github/scripts/slow_test_durations.py rewrites the table. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… the CI shards' local commands In a file split by test, tests that pytest.mark.dependency links now share one unit, which weighs their sum, so gateway_test.py's test_load_from_snapshot runs on the same runner as test_snapshot_cli. The Makefile names the exact selections the CI shards use, since a share depends on what is selected. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…an't reach the next A module that runs under its own state root (run_role_models_test.py) starts the process's grant server with that root's CA and leaves it running. The next module's containers trust the session's CA, so its agents fail to reach the server (transfer_unavailable). The old serial order hid this, because a module that closes the server happened to run in between; the shards run other orders. The per-module fixture now closes every grant server, and the next grant starts one afresh. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This was referenced Oct 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
integration-local-slowruns its tests serially, because they build the same image tags and use the same artifact ids, so parallel workers on one Docker daemon race. Onmainit took 31–36 minutes last week, and it now reaches its 40-minute timeout: three of the last four runs onmainwere cancelled.integration-local-gateway(gateway_test.pyalone) takes about 19 minutes.Almost all of that is per-test deploys of envs and agents, 30–130 seconds each. The setup steps (install, base images, registry) take under a minute.
What
Split both across runners. Each runner has its own Docker daemon, so the races that keep the tier serial can't happen between runners. The tests stay serial on each one.
AGENTENV_TEST_SHARD=i/N(tst/util/shards.py, atrylasthook intst/conftest.py) keeps the i-th of N groups of the selected tests.-mand the other filters, so only the selected tests are split.gateway_test.py, a single file, is split by test.tst/integration/slow_durations.json, and a unit the table doesn't know weighs the median.integration-local-slow (1/4)to(4/4), and the gateway tests on two.integration-local-slowandintegration-local-gatewayare now small jobs that pass when every shard of theirs did. So the required check keeps its name, and the gateway tests stay a separate check that doesn't block the merge.junit-integration-local-*, kept 14 days)..github/scripts/slow_test_durations.pyrewrites the table from those reports, summing each file's tests, and each test's own time for a file insplit_by_test.mainrun's logs.AGENTENV_TEST_SHARD=2/4 make int-test-slow.Expected: about 10 minutes of tests per slow shard and about 9.5 per gateway shard. On top of that, each runner adds about a minute of setup plus its own first image builds.
Tests
.venv/bin/python -m pytest tst/unit/test_shards.py tst/unit/test_slow_test_durations_script.py.venv/bin/python -m pytest tst/unit -n auto.venv/bin/ruff checkpytest --collect-only -m int_test_slow tst/integration --ignore=tst/integration/env/gateway/gateway_test.py, unsharded and withAGENTENV_TEST_SHARD=1/4…4/4gateway_test.pywith1/2and2/2This PR's own CI run is the end-to-end check of the shards' times.
🤖 Generated with Claude Code


Confidence Score: 5/5
The PR appears safe to merge; the refresh example has a non-blocking filename mismatch.Fix with agent prompt
Summary
Splits slow integration tests across four runners and gateway tests across two, while keeping tests serial within each runner.
Diagram
%%{init: {'theme': 'neutral'}}%% flowchart TD Tests[Selected slow tests] --> Selection{Test selection} Selection --> Slow[Non-gateway tests] Selection --> Gateway[Gateway tests] Table[Saved durations] --> Groups[Assign weighted groups] Slow --> Groups Gateway --> Groups Groups --> Four[Four slow runners] Groups --> Two[Two gateway runners] Four --> SlowCheck[Existing slow check] Two --> GatewayCheck[Existing gateway check] Four --> Reports[JUnit artifacts] Two --> Reports Reports --> Refresh[Manual table refresh] Refresh --> TableReviews (4) · Last reviewed commit: "Merge branch 'main' into ci/shard-slow-i..." · Reviewed by Greptile