Skip to content

fix: Replace get_nowait() with get(timeout=5) in multiprocessing test#45

Merged
cnsnyder merged 1 commit into
mainfrom
fix/flaky-multiprocessing-test
Jul 9, 2026
Merged

fix: Replace get_nowait() with get(timeout=5) in multiprocessing test#45
cnsnyder merged 1 commit into
mainfrom
fix/flaky-multiprocessing-test

Conversation

@Lorquas

@Lorquas Lorquas commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Problem

TestIni.test_queue in tests/test_multiprocessing.py is flaky. The child process calls _q.get_nowait(), which raises _queue.Empty if the serialized INIConfig object hasn't arrived in the queue yet. This is a race condition between Process.start() and the queue's internal pipe/buffer.

The failure is rare on a normal workstation but triggers consistently (~20% failure rate) in resource-constrained or containerized build environments — specifically Koji mock builds using systemd-nspawn, which is how CentOS Stream / RHEL RPMs are built. The %check phase runs runtests.py, hits this race, and fails the entire package build.

ERROR: test_queue (tests.test_multiprocessing.TestIni.test_queue)
  File "tests/test_multiprocessing.py", line 62, in getxy
    _cfg = _q.get_nowait()
_queue.Empty

Fix

One-line change: replace _q.get_nowait() with _q.get(timeout=5) in the child process. This gives the forked process time to receive the serialized object through the queue, matching the pattern already used by the parent on the result queue (w.get(timeout=1)).

Reproducer

Stress test with 200 parallel runs under CPU contention:

# Saturate all cores to simulate Koji builder pressure
stress-ng --cpu $(nproc) --timeout 120s &

# Run 200 parallel test invocations
for i in $(seq 1 200); do
  python3 -m pytest tests/test_multiprocessing.py -x -q > /tmp/mp_test_$i.out 2>&1 &
done
wait

grep -l "FAILED" /tmp/mp_test_*.out | wc -l
Before After
Failures (out of 200) 39 (20%) 0

get_nowait() raises _queue.Empty when the forked child process tries
to read from the queue before serialized data is available. This is a
race condition that triggers ~20% of the time under CPU pressure
(e.g. Koji mock/nspawn builds).

Using get(timeout=5) gives the child process time to receive the
serialized INIConfig object, matching the pattern already used by the
parent process on the result queue.

Reproducer: 200 parallel stress runs — 39/200 failed before fix,
0/200 failed after.

Assisted-by: AI
@cnsnyder cnsnyder self-assigned this Jul 9, 2026

@cnsnyder cnsnyder left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@cnsnyder cnsnyder merged commit 30072f7 into main Jul 9, 2026
8 checks passed
@cnsnyder cnsnyder deleted the fix/flaky-multiprocessing-test branch July 9, 2026 15: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.

2 participants