selftests: rds: Make rds selftests TAP compliant

This patch updates the rds selftests output to be TAP compliant.

Use ksft_pr() to mark debug output with a leading '# ' so that TAP
parsers treat it as commentary, and convert all informational print()
calls to use ksft_pr(). sys.exit(0) is changed to os._exit(0) to
avoid duplicate prints from the buffered TAP output. The console
output from the tcpdump subprocess is silenced, and the gcov console
output is redirected to a gcovr.log.

Finally adjust the exit path so that the hash check loop sets a
return code instead exiting directly. Then print the TAP results
and totals lines before exiting.

Signed-off-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20260504054143.4027538-11-achender@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Allison Henderson 2026-05-03 22:41:43 -07:00 committed by Jakub Kicinski
parent c8781c61fd
commit 06d5c34517
2 changed files with 43 additions and 26 deletions

View File

@ -197,14 +197,14 @@ if [[ -n "$LOG_DIR" ]]; then
mkdir -p "$LOG_DIR"
mkdir -p "$COVR_DIR"
echo Traces will be logged to "${TRACE_FILE}"
echo "#Traces will be logged to ${TRACE_FILE}"
rm -f "$TRACE_FILE"
TRACE_CMD=(strace -T -tt -o "${TRACE_FILE}")
fi
set +e
echo running RDS tests...
echo "#running RDS tests..."
"${TRACE_CMD[@]}" python3 "$(dirname "$0")/test.py" "${FLAGS[@]}" -t "$TIMEOUT"
test_rc=$?
@ -214,7 +214,7 @@ if [[ -n "$LOG_DIR" ]]; then
fi
if [[ -n "$LOG_DIR" ]] && [ "$GENERATE_GCOV_REPORT" -eq 1 ]; then
echo saving coverage data...
echo "# saving coverage data..."
# Ensure debugfs is mounted before reading gcov data.
if ! mountpoint -q /sys/kernel/debug 2>/dev/null; then
@ -227,17 +227,19 @@ if [[ -n "$LOG_DIR" ]] && [ "$GENERATE_GCOV_REPORT" -eq 1 ]; then
cat < "/sys/kernel/debug/gcov/$f" > "/$f"
done)
echo running gcovr...
echo "# running gcovr..."
gcovr -s --html-details --gcov-executable "$GCOV_CMD" --gcov-ignore-parse-errors \
--root "${ksrc_dir}" -o "${COVR_DIR}/gcovr" "${ksrc_dir}/net/rds/"
--root "${ksrc_dir}" -o "${COVR_DIR}/gcovr" "${ksrc_dir}/net/rds/" \
> "${LOG_DIR}/gcovr.log" 2>&1
echo "# gcovr log: ${LOG_DIR}/gcovr.log"
else
echo "Coverage report will be skipped"
echo "# Coverage report will be skipped"
fi
if [ "$test_rc" -eq 0 ]; then
echo "PASS: Test completed successfully"
echo "# PASS: Test completed successfully"
else
echo "FAIL: Test failed"
echo "# FAIL: Test failed"
fi
exit "$test_rc"

View File

@ -20,6 +20,8 @@ this_dir = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(this_dir, "../"))
# pylint: disable-next=wrong-import-position,import-error,no-name-in-module
from lib.py.utils import ip # noqa: E402
# pylint: disable-next=wrong-import-position,import-error,no-name-in-module
from lib.py.ksft import ksft_pr # noqa: E402
libc = ctypes.cdll.LoadLibrary('libc.so.6')
setns = libc.setns
@ -59,7 +61,7 @@ def netns_socket(netns, *sock_args):
# send resulting socket to parent
socket.send_fds(u0, [], [sock.fileno()])
sys.exit(0)
os._exit(0)
# receive socket from child
_, fds, _, _ = socket.recv_fds(u1, 0, 1)
@ -75,7 +77,7 @@ def stop_pcaps():
completes after the signal handler is fired. List will be empty
if logdir is not set
"""
print("Stopping network packet captures")
ksft_pr("Stopping network packet captures")
while tcpdump_procs:
proc = tcpdump_procs.pop()
proc.terminate()
@ -89,8 +91,9 @@ def signal_handler(_sig, _frame):
"""
Test timed out signal handler
"""
print('Test timed out')
ksft_pr("Test timed out")
stop_pcaps()
print("not ok 1 rds selftest")
sys.exit(1)
#Parse out command line arguments. We take an optional
@ -157,7 +160,8 @@ if logdir is not None:
tcpdump_cmd.extend(['-i', 'any', '-w', pcap])
# pylint: disable-next=consider-using-with
p = subprocess.Popen(tcpdump_cmd)
p = subprocess.Popen(tcpdump_cmd,
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
tcpdump_procs.append(p)
# simulate packet loss, duplication and corruption
@ -166,6 +170,9 @@ for net, iface in [(NET0, VETH0), (NET1, VETH1)]:
corrupt {PACKET_CORRUPTION} loss {PACKET_LOSS} duplicate \
{PACKET_DUPLICATE}")
print("TAP version 13")
print("1..1")
# add a timeout
if args.timeout > 0:
signal.alarm(args.timeout)
@ -204,7 +211,7 @@ nr_recv = 0
while nr_send < NUM_PACKETS:
# Send as much as we can without blocking
print("sending...", nr_send, nr_recv)
ksft_pr("sending...", nr_send, nr_recv)
while nr_send < NUM_PACKETS:
send_data = hashlib.sha256(
f'packet {nr_send}'.encode('utf-8')).hexdigest().encode('utf-8')
@ -226,7 +233,7 @@ while nr_send < NUM_PACKETS:
raise
# Receive as much as we can without blocking
print("receiving...", nr_send, nr_recv)
ksft_pr("receiving...", nr_send, nr_recv)
while nr_recv < nr_send:
for fileno, eventmask in ep.poll():
receiver = fileno_to_socket[fileno]
@ -248,7 +255,7 @@ while nr_send < NUM_PACKETS:
ip(f"netns exec {net} /usr/sbin/sysctl net.rds.tcp.rds_tcp_rcvbuf=10000")
ip(f"netns exec {net} /usr/sbin/sysctl net.rds.tcp.rds_tcp_sndbuf=10000")
print("done", nr_send, nr_recv)
ksft_pr("done", nr_send, nr_recv)
# the Python socket module doesn't know these
RDS_INFO_FIRST = 10000
@ -271,26 +278,34 @@ for s in sockets:
# ignore
pass
print(f"getsockopt(): {nr_success}/{nr_error}")
ksft_pr(f"getsockopt(): {nr_success}/{nr_error}")
stop_pcaps()
# We're done sending and receiving stuff, now let's check if what
# we received is what we sent.
ret = 0
for (sender, receiver), send_hash in send_hashes.items():
recv_hash = recv_hashes.get((sender, receiver))
if recv_hash is None:
print("FAIL: No data received")
sys.exit(1)
ksft_pr("FAIL: No data received")
ret = 1
break
if send_hash.hexdigest() != recv_hash.hexdigest():
print("FAIL: Send/recv mismatch")
print("hash expected:", send_hash.hexdigest())
print("hash received:", recv_hash.hexdigest())
sys.exit(1)
ksft_pr("FAIL: Send/recv mismatch")
ksft_pr("hash expected:", send_hash.hexdigest())
ksft_pr("hash received:", recv_hash.hexdigest())
ret = 1
break
print(f"{sender}/{receiver}: ok")
ksft_pr(f"{sender}/{receiver}: ok")
print("Success")
sys.exit(0)
if ret == 0:
ksft_pr("Success")
print("ok 1 rds selftest")
else:
print("not ok 1 rds selftest")
ksft_pr(f"Totals: pass:{1-ret} fail:{ret} skip:0")
sys.exit(ret)