This patch adds a teardown_tcp() helper that removes net0/net1. The cmd calls here use fail=False so they can be called from completed or partially-setup states on error. Also call teardown_tcp() at the top of setup_tcp() so a previous interrupted run does not leave net0/net1 lingering and break a subsequent ip netns add. Register teardown_tcp() with atexit before setup_tcp() is invoked.
Likewise, we can simpliy stop_pcaps() handling by registering it with atexit instead of calling it from the signal handler. atexit handlers run on any exit path - normal completion, raised exception, and sys.exit() from the timeout signal handler. This guarantees cleanup are called without further wrapping the test body in a try/finally blocks. atexit LIFO ordering keeps stop_pcaps before teardown_tcp so tcpdumps are killed cleanly before their namespaces go away. This is a preparatory cleanup for the upcoming ROCE patch which will also register a teardown_rdma() alongside teardown_tcp() Signed-off-by: Allison Henderson <[email protected]> --- tools/testing/selftests/net/rds/test.py | 27 +++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/net/rds/test.py b/tools/testing/selftests/net/rds/test.py index f7d0dba85131..7738c7e2af36 100755 --- a/tools/testing/selftests/net/rds/test.py +++ b/tools/testing/selftests/net/rds/test.py @@ -5,6 +5,7 @@ This module provides functional testing for the net/rds component. """ import argparse +import atexit import ctypes import errno import hashlib @@ -19,7 +20,7 @@ import sys 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 +from lib.py.utils import ip, cmd # noqa: E402 # pylint: disable-next=wrong-import-position,import-error,no-name-in-module from lib.py.ksft import ksft_pr # noqa: E402 @@ -246,7 +247,6 @@ def signal_handler(_sig, _frame): Test timed out signal handler """ ksft_pr("Test timed out") - stop_pcaps() print("not ok 1 rds selftest") sys.exit(1) @@ -255,6 +255,9 @@ def setup_tcp(): Configure tcp network """ + # clean up any leftovers from a previously interrupted run + teardown_tcp() + ip(f"netns add {NET0}") ip(f"netns add {NET1}") ip("link add type veth") @@ -299,6 +302,17 @@ def setup_tcp(): corrupt {PACKET_CORRUPTION} loss {PACKET_LOSS} duplicate \ {PACKET_DUPLICATE}") +def teardown_tcp(): + """ + Tear down the tcp network configured by setup_tcp(). + + Removing the namespaces also removes the veth pair, addresses, + routes, and netem qdisc that live inside them. fail=False so + this is safe to call in error paths after a partial or complete setup. + """ + cmd(f"ip netns del {NET0}", fail=False) + cmd(f"ip netns del {NET1}", fail=False) + #Parse out command line arguments. We take an optional # timeout parameter and an optional log output folder parser = argparse.ArgumentParser(description="init script args", @@ -319,6 +333,13 @@ PACKET_LOSS=str(args.loss)+'%' PACKET_CORRUPTION=str(args.corruption)+'%' PACKET_DUPLICATE=str(args.duplicate)+'%' +# Register cleanup before setup so a partial-setup crash still tears down +# whatever state did get created. atexit runs LIFO, so registering +# teardown_tcp first means stop_pcaps (registered second) runs first, +# killing tcpdumps before their namespaces go away. +atexit.register(teardown_tcp) +atexit.register(stop_pcaps) + setup_tcp() print("TAP version 13") @@ -334,8 +355,6 @@ ret = snd_rcv_packets(tcp_addrs, [NET0, NET1]) # cancel timeout signal.alarm(0) -stop_pcaps() - if ret == 0: ksft_pr("Success") print("ok 1 rds selftest") -- 2.25.1
