Commit ff07c1f
authored
test infra: backend suite speedup (Phase A1) — Python 3.12 + sysmon coverage (#1767)
* test infra: backend suite speedup — Python 3.12 + sysmon coverage + worksteal
Two changes that together produced a 4x speedup on the hot test files in
local A/B measurement (19:34 -> 4:50 on the WebSocket / extract /
structured-response cluster; see plan §6). Targets the two highest-ROI
findings from a CI runtime audit of the ~47-min backend job:
A1. Bump test/runtime Python image from 3.11.15 to 3.12.7 and set
COVERAGE_CORE=sysmon in the test env. Coverage on 3.11 was measured at
+156% over the no-cov baseline on the hot files; sys.monitoring is
~5-10x cheaper. Codecov receives the same coverage.xml — only the
collection path changes. Dropped django_coverage_plugin from setup.cfg
because Coverage 7.x silently falls back to the C-trace path whenever
any file-tracer plugin is configured, which would defeat sysmon (the
project owns 7 templates total, all 4xx/5xx pages plus a couple of
admin views — a trivial coverage slice for a ~150% wall-time tax).
B1. Switch the pytest CI invocation from --dist loadscope to
--dist worksteal so large classes like TestStructuredResponseAPI
(843 s / 27 tests) can fan out across all workers instead of pinning
to one. Conftest gains an auto-tag that pins django.test.TestCase
subclasses with class-scoped state (setUpTestData overridden or
fixtures set) to a per-class xdist_group, so worksteal still respects
that binding where it matters. TransactionTestCase subclasses are
deliberately not pinned — they rebuild per-test regardless, so they
benefit from free redistribution.
Plan also covers Phase A2 (drop redundant migrate step), A3 (ghcr image
cache), A4 (explicit -n), B2 (slim 17 MB fixture), B3 (class-once fixture
load), B4 (TransactionTestCase audit). Tracked in
docs/refactor_plans/2026-05-23-test-suite-speedup-A1-B1.md so we can
re-measure after this lands and decide which further phases are needed.
* test infra: revert Phase B1 (worksteal + auto-tag); keep A1 only
The combined PR #1767 ran in ~31:53 (vs 41-min baseline, −22%) but failed
with 39 tests broken — psycopg2 UniqueViolation on the `admin` user
across plain TestCase subclasses (UserTypePrivacyTestCase,
TestSearchAgentsForMention, TestOpenContractsAnalyzers, etc).
Root cause: worksteal interleaved tests from these classes with tests
from other classes on the same worker, exposing state leaks that
loadscope's class-pinning was hiding. The auto-tag only pinned
TestCase subclasses with setUpTestData/fixtures, leaving plain
TestCase classes vulnerable to interleave-on-worker pollution from
sibling classes' uncommitted state.
This commit:
- Reverts .github/workflows/backend.yml to `--dist loadscope`.
- Reverts conftest.py::pytest_collection_modifyitems to its prior shape
(serial marker handling only).
- Keeps the Phase A1 changes (Python 3.12.7 image, COVERAGE_CORE=sysmon,
dropped django_coverage_plugin) — they ran cleanly and account for the
~22% wall-time reduction independently.
- Updates the plan doc (§10 post-mortem) with what we learned: the local
A/B 4× speedup was specific to the 3 hottest files (~30% of CI time),
not a sound extrapolation to the full suite. Coverage cost was a
multiplier on the per-test 17 MB fixture-reload base cost, not the
base itself. After A1, that fixture reload is the binding constraint
and Phase B3 is the right next lever.
Worksteal can be re-attempted only after a dedicated test-isolation
sweep that finds and fixes the admin-user collision pattern (probably
in factories + Celery-eager + migration seeds).
* test: accept text/javascript or application/javascript in storage test
Python 3.12's mimetypes module returns ``text/javascript`` for ``.js``
files (per RFC 9239, which deprecates ``application/javascript``). The
test was hardcoded to the legacy value and broke when CI bumped the
django image to Python 3.12 in this PR. Both forms are RFC-valid and
both browsers serve them identically — relax the assertion so the test
passes on either runtime.
---------
Signed-off-by: JSIV <5049984+JSv4@users.noreply.github.com>1 parent 1fbc69e commit ff07c1f
8 files changed
Lines changed: 310 additions & 15 deletions
File tree
- .envs/.test
- .github/workflows
- compose
- local/django
- production/django
- docs/refactor_plans
- opencontractserver/tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
51 | 51 | | |
52 | 52 | | |
53 | 53 | | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
54 | 63 | | |
55 | 64 | | |
56 | 65 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
164 | 164 | | |
165 | 165 | | |
166 | 166 | | |
167 | | - | |
168 | | - | |
169 | | - | |
170 | | - | |
171 | | - | |
172 | | - | |
173 | | - | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
174 | 180 | | |
175 | 181 | | |
176 | 182 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
12 | 17 | | |
13 | 18 | | |
14 | 19 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
5 | 10 | | |
6 | 11 | | |
7 | 12 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
6 | 9 | | |
7 | 10 | | |
8 | 11 | | |
| |||
0 commit comments