netns-tunnel-test: two intermittent failures (cert-revocation budget vs documented discovery time; ARQ floor inside noise band) #157
Labels
No labels
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
femboy/yip#157
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What happened
Two tests in
netns-tunnel-testfail intermittently on the privileged runner:hardening.41cert-revocation andarq_recovers_bulk_loss.Both became visible only after #156 fixed the missing
iproute2— the job previously died atrun-netns-tunnel.sh:86withip: command not foundbefore reaching either. Newly-observed, not newly-broken.Expected: a green job on an unchanged tree. Observed: the same commit failing two different tests on two runs.
41c2b3a3cf588fhardening.41cert-revocation3cf588farq_recovers_bulk_loss305 and 306 are the same tree. That is flakiness, not a regression.
1. cert-revocation: the budget is smaller than the documented need
bin/yipd/tests/run-netns-cert-revocation.shmints a 60s cert, then retries discovery until 5s before expiry:That is 55 seconds of usable convergence window.
bin/yipd/tests/run-netns-discovery.sh:287— the sibling this was forked from — documents what discovery needs:55s allocated for something documented to need up to 60s. The comment above
CERT_A_SECSasserts 60s is "generous enough to comfortably cover ... gossip discovery warm-up (run-netns-discovery.sh documents up to a 60s budget for that warm-up)" — which contradicts itself: the cert lifetime equals the warm-up it is meant to contain, and the retry loop then gives back another 5s. Runner load does not cause this; it only decides which side of the line a run lands on.Suggested fix: raise
CERT_A_SECSto ~150. Semantics unchanged — the cert still expires mid-test, which is the point of the revocation assertion. Cost ~+90s on a job already running ~31 min, since the later "wait for expiry" phase grows too.Alternative worth considering: establish A<->B first, then start the expiry clock — decoupling the assertion (revocation works) from the load-dependent part (discovery convergence) rather than budgeting around it.
2.
arq_recovers_bulk_loss: the threshold sits inside the noise bandDelivery against a
min: 98%floor, same code each run:ARQ demonstrably fires (72 retransmits in the 290 run), so the machinery works. A spread of 81.5%–99.4% under a nominally identical 5% bulk-loss profile is too wide for a fixed 98% floor to gate on.
Two readings, and which one is true changes the fix:
Worth deciding before touching the number: moving a threshold to make a test green is only correct under the first reading.
Repro
Run
netns-tunnel-test(poll driver) on the privileged runner repeatedly against an unchanged tree; expect an intermittent failure in one of the two tests above. Config is the workflow's own — no local changes.Environment
3cf588f(also seen ona207ba1,01b307f)catthehacker/ubuntu:act-22.04container on a Void Linux host, kernel 6.18.35_1, 24 threads, other CI jobs running concurrentlyLogs
cert-revocation failure:
The failing run's root-node log also carries a large volume of:
I could not establish whether this is normal for this test: the passing run's log (task 1660) has
log_in_storage=fin Forgejo's DB — 4689 lines recorded, never flushed to disk — so there is no baseline to compare against. Flagging rather than diagnosing. Thetun write error: Invalid argumentlooks least like noise; EINVAL on a TUN write usually means a malformed packet reached the device.Third intermittent failure in this job, seen on PR #158's run (commit
49bdcc6):flowshape_not_obviously_constant.The run's own gate (b) contradicts gate (a)'s diagnosis. 7 distinct counts means the Jc junk burst is reaching the wire and randomizing the opener. If it genuinely were not, all 8 sessions would sit at the baseline — not 1 of 8.
Session 1 is the outlier (4 against 10-23 for the rest, mean ~16), and session 1 is the cold one.
run-flowshape-check.sh:194-197starts tcpdump and then waits a flatsleep 0.3before launching the daemons:The comment above it states the intent exactly — tcpdump must be capturing "BEFORE either daemon starts, so packet zero ... is captured" — but 300ms is a guess, not a readiness check. On the first iteration (tcpdump not in page cache, netns freshly created, pcap being created) that can be short; iterations 2-8 are warm. Missing the opening datagrams shows up precisely as a low count on session 1.
Suggested fix: wait for readiness instead of guessing. tcpdump writes
listening on <iface>to stderr once attached, and the script already redirects that to$TMPDIR_TEST/tcpdump-$i.log— poll that file for the line with a timeout, then start the daemons.Same shape as the cert-revocation item above: a fixed time budget standing in for a condition that should be waited on.
Also from that run, for the record:
arq_recovers_bulk_losspassed at 99.3% with 137 retransmits, and cert-revocation never ran — flowshape aborts the step before it.Resolved — both intermittent
netns-tunnel-testfailures tracked here are fixed:cert-revocation budget → #158 (merged):
CERT_A_SECS60→150, so the convergence window (~145s) comfortably exceeds the documented ~60s discovery warm-up. Assertion unchanged (cert still expires mid-test).arq_recovers_bulk_loss"inside the noise band" → #161 (merged). Root cause was NOT a too-tight 98% threshold but a real io_uring RX drop: the driver kept onlyUDP_RECV_DEPTH=16single-shot recvs outstanding, so under the CI container's contention the underlay socket receive queue overflowed (UdpRcvbufErrorsclimbing) while the poll driver — which drains the whole backlog per wakeup — did not. Confirmed via/proc/net/snmpinstrumentation (#160 → #161) and an independent driver review. Fix:UDP_RECV_DEPTH16→256 (+ ring headroom). Post-fix CI: uring delivery 80.1% → 99.2%,RcvbufErrors=0; poll 98.7%.A third flake in the same job,
flowshape_not_obviously_constant, was fixed alongside: #159 (dense-cluster span replacing a stall-fragile gap cutoff) and #161 (spread-based gate replacing an absolute floor that CI contention violated).netns-tunnel-testis green on the post-#161 tree (all 26 tests, both poll and uring drivers).Follow-ups found during the io_uring investigation (NOT fixed here) are worth tracking separately — chiefly: a single bad UDP recv CQE tears down the whole driver and drops the rest of the batch, reachable by any peer sending a >2048-byte datagram.