Skip to content

test: run suite in parallel with pytest-xdist#680

Merged
janbjorge merged 5 commits into
mainfrom
claude/pytest-xdist-integration-4pe3mk
Jul 11, 2026
Merged

test: run suite in parallel with pytest-xdist#680
janbjorge merged 5 commits into
mainfrom
claude/pytest-xdist-integration-4pe3mk

Conversation

@janbjorge

Copy link
Copy Markdown
Owner

Summary

  • Add pytest-xdist>=3.8.0 (latest stable) to the dev extras and update uv.lock.
  • Default pytest to 4 workers via addopts = "--durations=15 -n 4" in pyproject.toml.
  • Session-scoped fixtures run once per xdist worker, so each worker spins up its own Postgres container and template database — the speedup comes from scaling out to a few extra Postgres servers, not aggressive process-level concurrency. Per-test databases already use UUID names (CREATE DATABASE ... TEMPLATE), so the suite is parallel-safe with no fixture changes.
  • Document the parallel default in AGENTS.md, including -n 0 to run serially and -n <N> to change the worker count.

Timing (full suite, 777 passed / 11 skipped):

Mode Wall time
Serial (-n 0) 5m20s
4 workers (new default) 1m52s

Testing

  • make check passed (ruff check, ruff format, lint-imports, mypy, full pytest suite)
  • Full suite run both serially (-n 0) and with the new 4-worker default against Postgres 16 — identical results

Checklist

  • I have read the Contributing Guide
  • I have added or updated tests
  • I have updated documentation if necessary

Generated by Claude Code

Add pytest-xdist (latest stable, 3.8.0) to the dev extras and default
pytest to 4 workers via addopts. Session-scoped fixtures are per-worker
under xdist, so each worker starts its own Postgres container and
template database — the speedup comes from a few extra Postgres servers
rather than aggressive process-level concurrency. Per-test databases
already use UUID names, so the suite is parallel-safe as-is.

Use `-n 0` to run serially.
@janbjorge janbjorge force-pushed the claude/pytest-xdist-integration-4pe3mk branch from e4a4ff0 to f0ee256 Compare July 11, 2026 14:20
The postgres image logs "database system is ready to accept
connections" twice: once from the initdb bootstrap server (unix socket
only) and once from the real server. The wait strategy matched the
first occurrence, so fixtures connected before TCP was listening and
got connection resets. With 4 workers running initdb concurrently on a
4-vCPU runner the bootstrap window stretches to seconds, making the
race near-certain; the failed session fixture is then cached by pytest,
erroring every DB test in that worker. Wait for the second occurrence,
as testcontainers-java does.

Also bound per-container memory (shared_buffers 128MB, max_wal_size
512MB, tmpfs capped at 1g) since each xdist worker now runs its own
container with its data dir on tmpfs (RAM).
LogMessageWaitStrategy in testcontainers 4.13 ignores its `times`
argument, so the previous fix still matched the initdb bootstrap
server's ready line and fixtures connected before TCP was listening.
Anchor the wait on the bootstrap shutdown line followed by the real
ready line instead, and retry the session fixture's first connection
for up to a minute as belt and braces.
The bootstrap server's log output is split across stdout and stderr,
so both the "ready to accept connections" line and the shutdown+ready
sequence are ambiguous stream-wise. "PostgreSQL init process complete"
appears exactly once, on stdout, after the bootstrap server is gone;
the remaining gap until the real server listens on TCP is bridged by
the connection retry in the migrated_db fixture.
Replace log-line matching and the fixture-level connection retry with a
docker healthcheck probing pg_isready over TCP, mirroring the service
container setup in ci.yml. The initdb bootstrap server only listens on
the unix socket, so the container cannot report healthy before the real
server accepts TCP connections — readiness is decided by the
infrastructure instead of log heuristics or client retries.
@janbjorge janbjorge merged commit d18f429 into main Jul 11, 2026
22 checks passed
@janbjorge janbjorge deleted the claude/pytest-xdist-integration-4pe3mk branch July 11, 2026 16:28
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.

1 participant