Wait for the UDP socket to bind before starting the client, detect server exit, and clean up on skip. Preserve both handshake checks. Add regression checks and document the rationale for upstream submission. Validated on x86-64-v3: 796 passes, 131 existing skips, zero failures. All seven focused checks and the delayed-start reproduction passed.
71 lines
2.1 KiB
Diff
71 lines
2.1 KiB
Diff
Subject: [PATCH] tests: wait for the UDP server socket before connecting
|
|
|
|
A fixed four-second sleep does not guarantee that gnutls-serv has bound
|
|
its UDP socket on a busy builder. Poll the local IPv4 UDP endpoint using
|
|
the existing ss/netstat discovery, with the same retry budget as the TCP
|
|
helper. Fail early if the server exits, and retain the original handshake
|
|
checks in serv-udp.sh.
|
|
|
|
Use flags common to ss and BSD/Linux netstat. Match the local endpoint
|
|
and complete port number, excluding TCP, IPv6-only and peer endpoints.
|
|
|
|
--- a/tests/scripts/common.sh
|
|
+++ b/tests/scripts/common.sh
|
|
@@ -185,10 +185,55 @@
|
|
fi
|
|
}
|
|
|
|
+check_if_udp_port_bound() {
|
|
+ local PORT=$1
|
|
+ have_port_finder
|
|
+ # Use only -an, which is shared by ss and BSD/Linux netstat. UDP has
|
|
+ # no LISTEN state. Match the local IPv4 endpoint, not a peer port or
|
|
+ # a longer port number. serv-udp.sh connects to 127.0.0.1;
|
|
+ # listen_socket() in serv.c binds IPv4 separately and requests
|
|
+ # IPV6_V6ONLY=1 for its IPv6 socket.
|
|
+ $PFCMD -an | awk -v port="$PORT" '
|
|
+ $1 == "udp" || $1 == "udp4" {
|
|
+ # ss includes a state column; netstat does not.
|
|
+ address = ($2 == "UNCONN" || $2 == "ESTAB") ? $5 : $4
|
|
+ if (address ~ ("^[0-9.]+[.:]" port "$") ||
|
|
+ address == "*." port)
|
|
+ found = 1
|
|
+ }
|
|
+ END { exit !found }
|
|
+ '
|
|
+}
|
|
+
|
|
wait_udp_server() {
|
|
local PID=$1
|
|
+ local ret
|
|
trap "test -n \"${PID}\" && kill ${PID};exit 1" 1 15 2
|
|
- sleep 4
|
|
+ local i=0
|
|
+ # Use the same retry budget as wait_for_port(), but also stop if the
|
|
+ # server exits before binding its socket.
|
|
+ while test $i -lt 90; do
|
|
+ if ! kill -0 "$PID" 2>/dev/null; then
|
|
+ fail "" "UDP server $PID exited before binding port $PORT"
|
|
+ fi
|
|
+ # Contain have_port_finder's exit so a skip also stops the server.
|
|
+ if (check_if_udp_port_bound "$PORT"); then
|
|
+ return 0
|
|
+ else
|
|
+ ret=$?
|
|
+ if test "$ret" = 77; then
|
|
+ kill "$PID" 2>/dev/null || :
|
|
+ wait "$PID" 2>/dev/null || :
|
|
+ exit 77
|
|
+ fi
|
|
+ fi
|
|
+ i=$((i + 1))
|
|
+ if test $i -lt 90; then
|
|
+ echo "try $i: waiting for UDP port $PORT"
|
|
+ sleep 2
|
|
+ fi
|
|
+ done
|
|
+ fail "$PID" "UDP server $PORT did not come up"
|
|
}
|
|
|
|
create_testdir() {
|