testsuite: daemon-proxy-protocol drop-leg tolerates EPIPE on send

The probe() helper sends the @RSYNCD greeting after the PROXY header, then
reads the daemon's response.  For a `want='drop'` leg (untrusted peer / a
daemon with no `proxy protocol hosts`) the daemon closes the connection,
which on some CI runners surfaces as EPIPE/ECONNRESET on our sendall() before
we ever read -- an uncaught BrokenPipeError that failed the test (seen on
AlmaLinux 8 and Ubuntu 22.04, a timing race; other runners closed read-side).
Wrap the send/recv in `except OSError` and leave `out` empty: for want='drop'
the absent greeting is the expected outcome; want='ok'/'denied' still fail
correctly on an absent greeting.
This commit is contained in:
Andrew Tridgell committed 2026-07-20 14:05:31 +10:00
1 parent fe69ae7a7d
commit 68ff15e35c
1 file changed
+8 -1
+8 -1
View File
@@ -115,6 +115,7 @@ def probe(port, hdr, label, *, want):
"""
s = socket.create_connection(('127.0.0.1', port), timeout=10)
s.settimeout(10)
out = b''
try:
if hdr:
s.sendall(hdr)
@@ -122,7 +123,6 @@ def probe(port, hdr, label, *, want):
# list-only request. Protocol 30, no capabilities, no auth.
s.sendall(b'@RSYNCD: 30.0\nmod\n')
# Slurp everything the daemon writes before it closes.
out = b''
try:
s.shutdown(socket.SHUT_WR)
except OSError:
@@ -135,6 +135,13 @@ def probe(port, hdr, label, *, want):
if not chunk:
break
out += chunk
except OSError:
# A 'drop' daemon closes the connection, which can surface as
# EPIPE/ECONNRESET on our sendall() before we ever read -- a timing
# race seen on some CI runners. Leave `out` empty and let the
# want-check below decide: for want='drop' the absent greeting is the
# expected outcome; for want='ok'/'denied' it still fails correctly.
pass
finally:
s.close()