Skip to content

test: run the Python suite in parallel and cut per-app setup (#524) - #550

Merged
antosubash merged 2 commits into
mainfrom
ccr-7c264cfe-blzbew
Oct 18, 2026
Merged

antosubash merged 2 commits into
mainfrom
ccr-7c264cfe-blzbew

Conversation

@antosubash

Copy link
Copy Markdown
Owner

Addresses #524 (items 1 and 3; item 2 partially, see below).

Result (4-core cloud container)

wall time
main, serial (from the issue) 24m12s
-n auto only 7m13s
-n auto + cheap password hashing (make test-py) 5m24s

4468 passed in both parallel runs. All 13 skips are environmental (no node_modules, Postgres or MinIO); none come from parallelism.

Changes

  • pytest-xdist: make test-py runs pytest -n $(PYTEST_WORKERS) (default auto). It isn't in addopts, so uv run pytest path::test still runs in-process without worker start-up cost.
  • Two xdist hazards fixed:
    • test_negative_authz.py used uuid4() in parametrize ids. Each worker collected differently-named tests, and xdist refuses to run in that case. It now uses a fixed UUID; the request must be refused before any lookup, so the id doesn't matter.
    • test_bg_invalidation_redis.py used a fixed pub/sub channel. CI points every worker at one Redis service, so one worker's publish could reach another worker's subscriber and break the delivery and subscriber counts. The channel is now per process.
  • Cheap password hashing in the test plugin: profiling showed argon2 at about 90 ms per app fixture, from hashing the seeded admin at production cost. PasswordHelper() now defaults to minimal Argon2/bcrypt parameters under the plugin. Hashes stay real $argon2/$2b, so the legacy-bcrypt upgrade test still means what it says. This is patched at import because test modules build PasswordHelper() at collection time.
  • Postgres guard: every PG test drops the shared public schema, so the plugin raises UsageError when -n is combined with a Postgres SM_TEST_DATABASE_URL. make test-py-pg stays serial.
  • CI: the pytest totals line goes to the job summary, so suite-time regressions are visible.

Not done, and why

In the profile, about 75% of the remaining app setup is FastAPI building dependants for every route, in create_app and in the route-guard prewarm at lifespan start. Removing that cost means sharing an app between tests. Many tests override settings/env per test, so that trade costs isolation and needs a dedicated design. It doesn't belong in this PR. The route-guard prewarm only moves FastAPI's lazy first-request cost earlier, so removing it would save nothing for tests that make a request.

https://claude.ai/code/session_01LWvhqY9o3KhSo2iAg19cCi


Generated by Claude Code

`make test-py` drops from ~24 min serial to ~5.5 min on 4 cores.

- Add pytest-xdist; `make test-py` passes `-n $(PYTEST_WORKERS)` (default
  auto). Kept out of addopts so a single-test run stays in-process.
- Fix the two things that broke under xdist:
  - test_negative_authz built parametrize ids from `uuid4()`, so workers
    collected differently-named tests and xdist refused to run.
  - test_bg_invalidation_redis used a fixed pub/sub channel on a Redis that
    CI shares between workers; the channel is now per process.
- The test plugin lowers PasswordHelper's Argon2/bcrypt work factor: hashing
  the seeded admin was ~90ms of every `app` fixture.
- The plugin refuses `-n` on Postgres, where every test drops the shared
  `public` schema; `make test-py-pg` stays serial.
- CI writes the pytest totals line (count + wall time) to the job summary.

Claude-Session: https://claude.ai/code/session_01LWvhqY9o3KhSo2iAg19cCi
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Deploying simple-module-python with  Cloudflare Pages  Cloudflare Pages

Latest commit: 1458223
Status: ✅  Deploy successful!
Preview URL: https://2141e778.simple-module-python.pages.dev
Branch Preview URL: https://ccr-7c264cfe-blzbew.simple-module-python.pages.dev

View logs

@antosubash
antosubash marked this pull request as ready for review October 18, 2026 16:03
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
🔒 Security Review ✅ Completed 2026-10-18T16:06:39.060067Z 4701d38 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Review follow-ups on the xdist change (#524):

- test_module_css_build: both tests rewrite the shared tree (generated
  manifests, host/static/dist, an audit_log probe page), so they raced when
  two workers ran them with node_modules present. Grouped with
  xdist_group("repo-build"); `make test-py` now uses --dist loadgroup.
- test_invalidation_cross_process: grouped so the module-scoped subprocess
  stack is built once, not once per worker that draws one of its tests.
- SM_TEST_REAL_PASSWORD_HASHING opts a consumer suite out of the plugin's
  cheap-hashing patch.
- The Postgres + -n UsageError names `make test-py-pg` / PYTEST_WORKERS=0.

Claude-Session: https://claude.ai/code/session_01LWvhqY9o3KhSo2iAg19cCi
@antosubash
antosubash merged commit f524a52 into main Oct 18, 2026
14 checks passed
antosubash pushed a commit that referenced this pull request Oct 19, 2026
Resolve the CLAUDE.md conflict by keeping the rewrite and folding in
main's additions from #550 and #525: pytest-xdist parallel runs
(`-n auto --dist loadgroup`, `PYTEST_WORKERS=0`), the serial Postgres
suite, single tests running in-process, the test plugin's reduced
password-hash work factor and `SM_TEST_REAL_PASSWORD_HASHING`, and the
xdist collection rules (deterministic parametrize ids, per-worker names).

Claude-Session: https://claude.ai/code/session_01TJ3Gy55Ngyuj5o4UakoF2v
@antosubash
antosubash deleted the ccr-7c264cfe-blzbew branch October 19, 2026 11:13
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.

2 participants