Skip to content

Give each live staging test its own pytest worker in the release run - #4127

Merged
anth-volk merged 2 commits into
masterfrom
live-staging-test-workers
Oct 29, 2026
Merged

anth-volk merged 2 commits into
masterfrom
live-staging-test-workers

Conversation

@anth-volk

@anth-volk anth-volk commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #4126

Stacked on #4125.

Summary

  • .github/scripts/run_live_staging_tests.sh runs the 9 live staging tests with -n 9 instead of -n 2: one pytest worker per test. --dist load --maxschedchunk=1 and the test files are unchanged.
  • The step in parallel-live-simulation-tests-staging-cloud-run is renamed "Run live staging tests, one pytest worker per test".
  • A new structure test, test_live_staging_tests_get_one_pytest_worker_each, collects the tests the script selects (pytest --collect-only) and checks that -n equals their number. A new live test therefore fails it until -n is raised with it.

Nothing stops being checked; the same tests run against the same candidate.

No inline ruff suppressions are added.

Load on the staging candidate

The candidate is one Cloud Run instance (CLOUD_RUN_MAX_INSTANCES: "1") that admits 6 requests at a time (CLOUD_RUN_CONCURRENCY 6, two gunicorn workers, cloud_run_env.sh). Each test sends one request at a time, so 9 workers can have at most 9 requests in flight, and at most 3 of them wait at the Cloud Run front end for a free slot.

  • Queueing: yes, at the start. All 9 tests begin at once: the 5 household calculations and 4 /us/metadata requests. After that, the 4 simulation tests send one short status request every 5 seconds while the simulation API computes.
  • Timeouts: unlikely. Cloud Run holds a waiting request for the longer of 10 seconds and 3.5 times the average instance startup time (about 3 minutes here). The tests' client allows each request 90 seconds. The slowest requests are the two US household calculations, measured at about 28 to 30 seconds each when they ran one after the other. Running together on the instance's two GIL-bound workers, they could take up to about 60 seconds if both land on the same worker. That is inside 90 seconds, with less spare time than today.
  • Memory: the instance never runs more than 6 requests at once, the limit the July 2026 soak qualified (docs/migration/cloud-run-operations.md).
  • Staging simulation API: it receives the 4 society-wide runs at once instead of at most 2. Its capacity for that is unverified.

I chose one worker per test (-n 9) over a lower count. -n 6 would avoid the queueing, but the calculations would still overlap, so the timeout risk would be about the same, and the two longest tests would start up to a minute later.

The count is a fixed number, not derived from the number of tests: #4092 adds live test files to this script, and a derived count would raise the load on the one-instance candidate without anyone choosing to.

Job dependencies

Unchanged. Only the step inside parallel-live-simulation-tests-staging-cloud-run changes:

before: worker 0: budget-window cache (4.0) -> budget-window multi-year (7.4)
        worker 1: 5 calculations (1.0) -> Utah (3.6) -> California EITC (6.7)      step: 11.4
after:  9 workers, one test each, all starting at once                             step: about the longest test, 7.4

(Minutes from release #2608.) Expected saving: up to about 4 minutes per release (estimate). In each of the five releases I checked (#2596, #2600, #2602, #2604, #2608), the multi-year budget-window test and the California EITC test finished within 0.2 seconds of each other, on different workers. That suggests they wait on something shared on the staging side, so the saving may be smaller.

Environment variables

None move or change. The job keeps what it had:

Variable Provider How it reaches the step
API_BASE_URL output url of deploy-cloud-run-staging step env: from needs.deploy-cloud-run-staging.outputs.url
STAGING_API_TEST_PROBE_ID output tag of deploy-cloud-run-staging, github.run_id and github.run_attempt (event context) step env:
UV_PYTHON literal "3.12" job env:
OLD_SIMULATION_GATEWAY_URL repository variable workflow-level env:

Each pytest worker is its own session, so integration_probe_id adds a different random suffix in each worker; probe identifiers stay unique.

No Google Cloud sign-in in this job, before or after.

Unverified until the first release after merge

push.yml runs only on pushes to master, so this pull request's CI does not run the live tests.

  • The step time with 9 workers, and so the saving (about 4 minutes is an estimate).
  • That the staging candidate serves the start of the step, with up to 9 requests at once, inside the client's 90-second limit.
  • That the staging simulation API handles 4 society-wide runs at once without slowing each of them down.

Testing

  • Red: 8b5f355 (tests only). pytest tests/unit/test_cloud_run_push_workflow.py: 2 failed, 14 passed (run_live_staging_tests.sh runs 9 tests in 2 pytest workers, and the step name).
  • Green: e615bf3. The same command: 16 passed.
  • The structure tests for the workflow and its scripts (test_cloud_run_push_workflow.py, test_alembic_workflows.py, test_app_engine_decommission.py, test_cloud_run_workflow_configuration.py, test_deploy_pipeline_scripts.py, test_locked_test_environments.py, v2/test_metadata_deployment.py, test_policyengine_live_since.py): 106 passed.
  • ruff format --check . and ruff check . with the ruff version uv.lock pins (0.15.12): clean.
  • python scripts/run_quality_guards.py: passed. python -m scripts.rules guard --base-ref origin/master: passed. The rules tool's tests: OK. python -m scripts.rules render: no diff.
  • uv lock --check: passed. shellcheck .github/scripts/run_live_staging_tests.sh: clean. push.yml parses as YAML and passes actionlint.

🤖 Generated with Claude Code

anth-volk and others added 2 commits October 29, 2026 23:32
run_live_staging_tests.sh runs the 9 live staging tests in two pytest
workers, so the step takes about as long as the tests on the busier
worker (11.4 minutes in release #2608) rather than the longest test
(about 7.4). These tests ask for one worker per collected test, and for
the step name that says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
run_live_staging_tests.sh passes -n 9 instead of -n 2, one worker per
test, so the step takes about as long as the longest test instead of the
tests on the busier worker. The step is renamed to say so.

The staging candidate is one Cloud Run instance with a concurrency of 6,
and each test sends one request at a time, so at most 3 requests wait at
the Cloud Run front end for a free slot. Cloud Run holds a request for
the longer of 10 seconds and 3.5 times the average instance startup
time, and the tests' client allows 90 seconds per request. The script's
comment says this, and asks for -n to be raised, after checking the
candidate's capacity, whenever a live test is added.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@anth-volk
anth-volk added this pull request to stack #4128 October 29, 2026 19:33
@anth-volk anth-volk changed the title live staging test workers Give each live staging test its own pytest worker in the release run Oct 29, 2026
Base automatically changed from release-tests-own-job to master October 29, 2026 19:52
@anth-volk
anth-volk force-pushed the live-staging-test-workers branch from e615bf3 to bd67c6e Compare October 29, 2026 19:52
@anth-volk
anth-volk force-pushed the live-staging-test-workers branch from bd67c6e to e615bf3 Compare October 29, 2026 20:13
@codecov

codecov Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.13%. Comparing base (aa410b7) to head (e615bf3).
⚠️ Report is 10 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4127      +/-   ##
==========================================
+ Coverage   88.07%   88.13%   +0.05%     
==========================================
  Files         272      273       +1     
  Lines       16235    16299      +64     
  Branches     2654     2668      +14     
==========================================
+ Hits        14299    14365      +66     
+ Misses       1270     1268       -2     
  Partials      666      666              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@anth-volk
anth-volk marked this pull request as ready for review October 29, 2026 21:00
@anth-volk
anth-volk merged commit 426ed09 into master Oct 29, 2026
27 of 28 checks passed
@anth-volk
anth-volk deleted the live-staging-test-workers branch October 29, 2026 21:01

This branch was successfully deployed

1 active deployment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Give each live staging test its own pytest worker in the release run

1 participant