Skip to content

CI: stop running the .exar1 sweeps twice per job - #25

Merged
bbfrederick merged 1 commit into
mainfrom
ci-drop-duplicate-exar-run
Sep 29, 2026
Merged

bbfrederick merged 1 commit into
mainfrom
ci-drop-duplicate-exar-run

Conversation

@bbfrederick

Copy link
Copy Markdown
Owner

The measurement

One job on ubuntu-latest / Python 3.14 was 1817 s, split almost exactly in half:

step secs %
Test (pytest -q -n auto) 940 51.7
The .exar1 archives must be present and exercised 835 46.0
everything else 42 2.3

That second step ran pytest tests/test_exar.py tests/test_exar_patch.py serially, and the Test step then re-ran all of it in parallel. It tested nothing the Test step did not — it existed only to tee its output and grep -q skipped, because xdist workers interleave stdout.

test_exar_patch.py carries the two corpus sweeps (400 s and 199 s), so that one guard was carrying nearly the whole cost. The OCR and front-end guards do exactly the same thing for 4 s and 3 s, because their files are small.

The change

Test now writes a JUnit report, and one new step asserts from it that each guarded group ran. The report is written by the xdist controller and aggregates the workers, so it carries per-test skip status that interleaved stdout cannot — which is precisely what let the serial runs go.

Every environment-discovery check is untouched and still fails fast: tesseract must be findable, node --version must work, EXAR_FILES must be non-empty. Only the "and were then exercised" half moved to after the suite.

It is stricter than what it replaces

grep -q skipped ocr.log asks whether a file's output holds that word anywhere. The new guard names the tests that must have run, counts them, and reports which ones skipped.

Against the real full-suite report it sees 3 OCR, 12 front-end and 709 .exar1 tests ran, none skipped, and correctly ignores the suite's 26 legitimate skips, which are all in tests.test_scans and outside the guarded groups.

Verification

  • xdist + --junit-xml records skips correctly — checked rather than assumed: under -n 4, the XML carries a per-test <skipped> with its reason plus a suite-level count.
  • The guard, extracted verbatim from the workflow, falsified four ways: healthy → exit 0; exar skipped → exit 1 naming the tests; exar not collected at all → exit 1 with a distinct message; one OCR test skipping among several → exit 1 naming it.
  • Run against the real 3878-case report from a green local suite (3852 passed, 26 skipped) → exit 0 with the counts above.
  • Emits ::error:: so --log-failed surfaces the one useful line.

Expected effect

~835 s off each of the six matrix jobs — ubuntu/3.14 from 1817 s to roughly 985 s. This PR's own CI run is the measurement; a workflow change cannot be checked any other way, so compare its step timings against the numbers above before merging.

Not addressed here: the Test step's own 940 s, of which the single 400 s self-drive sweep is 42%. Both big sweeps loop EXAR_PROTOCOL_FILES internally over 26 evenly-sized pairs, so parametrising them would let xdist distribute the work — but they assert global tallies for non-vacuity, and splitting them needs a separate pin on the pair count or a corpus that shrank to zero cases would pass as 0 passed.

.gitignore swaps ocr.log, which nothing writes now, for results.xml.

🤖 Generated with Claude Code

Measured on ubuntu-latest / Python 3.14, one job was 1817 s and split
almost exactly in half:

    Test (pytest -q -n auto)                        940 s   51.7%
    The .exar1 archives must be present and ...     835 s   46.0%
    everything else                                  42 s    2.3%

The second step ran `pytest tests/test_exar.py tests/test_exar_patch.py`
serially and then the first re-ran all of it in parallel.  It tested
nothing the Test step did not; it existed only to tee its output and grep
it for `skipped`, because xdist workers interleave stdout.  test_exar_patch
carries the two corpus sweeps (400 s and 199 s), so that guard was
carrying almost the whole cost -- the OCR and front-end guards do the same
thing for 4 s and 3 s because their files are small.

The Test step now writes a JUnit report and one new step asserts from it
that each guarded group ran.  The report is written by the xdist
*controller* and aggregates the workers, so it carries per-test skip
status that interleaved stdout cannot, which is what lets the serial runs
go.  Verified: under -n 4 the XML records a skip per test with its reason
and a suite-level count.

Every environment-discovery check is untouched and still fails fast --
tesseract must be findable, node --version must work, EXAR_FILES must be
non-empty.  Only the "and were then exercised" half moved.

The new guard is stricter than the greps it replaces.  `grep -q skipped
ocr.log` asks whether a file's output holds that word anywhere; this names
the tests that must have run, counts them, and reports which ones skipped.
Against the real full-suite report it sees 3 OCR, 12 front-end and 709
.exar1 tests ran with none skipped, and correctly ignores the suite's 26
legitimate skips in tests.test_scans.  Falsified four ways: healthy exits
0; exar skipped exits 1 naming the tests; exar not collected at all exits
1 with a distinct message; one OCR test skipping among several exits 1
naming it.

Expected effect is ~835 s off each of the six matrix jobs.  This run is
the measurement -- a workflow change cannot be checked any other way.

.gitignore swaps ocr.log, which nothing writes now, for results.xml.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@bbfrederick
bbfrederick merged commit 5a9666d into main Sep 29, 2026
9 checks passed
@bbfrederick
bbfrederick deleted the ci-drop-duplicate-exar-run branch September 29, 2026 23:05
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