Skip to content

fix: route around coveragepy#2124 flake in aio finalizer test - #3

Merged
lesnik512 merged 3 commits into
mainfrom
fix/aio-coverage-flake
Jul 13, 2026
Merged

fix: route around coveragepy#2124 flake in aio finalizer test#3
lesnik512 merged 3 commits into
mainfrom
fix/aio-coverage-flake

Conversation

@lesnik512

Copy link
Copy Markdown
Member

Summary

  • CI's pytest (3.11) job intermittently failed the 100%-coverage gate (~1-in-4 runs, reproduced live on GitHub Actions), always on the same two lines of test_aio_app_finalizer_runs_on_root_close, despite all tests passing.
  • Root cause: coveragepy#2124 — on Python 3.11, coverage.py loses trace lines immediately after awaiting a coroutine that cancels a task internally and catches CancelledError. grpc.aio's Server.stop() does exactly that to its own background tasks.
  • Fix: insert a throwaway await asyncio.sleep(0) checkpoint right after server.stop(0) so the tracer's blind spot lands there instead of on the assertions under test.
  • See planning/changes/2026-07-13.01-aio-coverage-flake.md and planning/decisions/2026-07-13-coveragepy-2124-flake.md for full investigation and rejected alternatives.

Test plan

  • just test-ci — 100% coverage, 27 passed, locally
  • just lint-ci — clean
  • Watch this PR's CI across a few runs to confirm the flake no longer reproduces

CI's pytest(3.11) job intermittently failed the 100%-coverage gate on the
same two lines, reproduced live on GitHub Actions (~1-in-4 runs). Traced to
an upstream coverage.py bug on Python 3.11 that loses trace lines right
after awaiting a coroutine that cancels a task internally, which is exactly
what grpc.aio's Server.stop() does. Adds a throwaway scheduling checkpoint
so the tracer's blind spot lands there instead of the assertions under test.
The asyncio.sleep(0) checkpoint from the previous commit didn't work: it
just relocated the tracer's blind spot onto the checkpoint line itself
(confirmed by reproducing the flake again on CI), since the blind spot's
width varies rather than being fixed at one line. Switch to marking the
affected lines with pragma: no cover, which coverage.py resolves via static
parsing rather than runtime tracing, so it's unaffected by the race.
13 consecutive clean pytest(3.11) runs on PR #3 after the pragma-exclusion
fix, versus the original ~1-in-4 failure rate.
@lesnik512
lesnik512 merged commit 1bc24fe into main Jul 13, 2026
6 checks passed
@lesnik512
lesnik512 deleted the fix/aio-coverage-flake branch July 13, 2026 08:25
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