summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/net/lib/py/utils.py
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2024-04-08 11:40:41 +0100
committerDavid S. Miller <davem@davemloft.net>2024-04-08 11:40:41 +0100
commita15d80a16dbf697f8953e118eb5099450db2b83c (patch)
treef14ba4546dfd3423aad6315ec710ee8b926ae852 /tools/testing/selftests/net/lib/py/utils.py
parentd7d6e47016bc536b3443fc16ee694743bfb109c7 (diff)
parentf0e6c86e4bab228ca51b863af180ade0a970a393 (diff)
Merge branch 'ynl-tests'
Jakub Kicinski says: ==================== selftests: net: groundwork for YNL-based tests Currently the options for writing networking tests are C, bash or some mix of the two. YAML/Netlink gives us the ability to easily interface with Netlink in higher level laguages. In particular, there is a Python library already available in tree, under tools/net. Add the scaffolding which allows writing tests using this library. The "scaffolding" is needed because the library lives under tools/net and uses YAML files from under Documentation/. So we need a small amount of glue code to find those things and add them to TEST_FILES. This series adds both a basic SW sanity test and driver test which can be run against netdevsim or a real device. When I develop core code I usually test with netdevsim, then a real device, and then a backport to Meta's kernel. Because of the lack of integration, until now I had to throw away the (YNL-based) test script and netdevsim code. Running tests in tree directly: $ ./tools/testing/selftests/net/nl_netdev.py KTAP version 1 1..2 ok 1 nl_netdev.empty_check ok 2 nl_netdev.lo_check # Totals: pass:2 fail:0 xfail:0 xpass:0 skip:0 error:0 in tree via make: $ make -C tools/testing/selftests/ TARGETS=net \ TEST_PROGS=nl_netdev.py TEST_GEN_PROGS="" run_tests [ ... ] and installed externally, all seem to work: $ make -C tools/testing/selftests/ TARGETS=net \ install INSTALL_PATH=/tmp/ksft-net $ /tmp/ksft-net/run_kselftest.sh -t net:nl_netdev.py [ ... ] For driver tests I followed the lead of net/forwarding and get the device name from env and/or a config file. v3: - fix up netdevsim C - various small nits in other patches (see changelog in patches) v2: https://lore.kernel.org/all/20240403023426.1762996-1-kuba@kernel.org/ - don't add to TARGETS, create a deperate variable with deps - support and use with - support and use passing arguments to tests v1: https://lore.kernel.org/all/20240402010520.1209517-1-kuba@kernel.org/ ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'tools/testing/selftests/net/lib/py/utils.py')
-rw-r--r--tools/testing/selftests/net/lib/py/utils.py47
1 files changed, 47 insertions, 0 deletions
diff --git a/tools/testing/selftests/net/lib/py/utils.py b/tools/testing/selftests/net/lib/py/utils.py
new file mode 100644
index 000000000000..f0d425731fd4
--- /dev/null
+++ b/tools/testing/selftests/net/lib/py/utils.py
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: GPL-2.0
+
+import json as _json
+import subprocess
+
+class cmd:
+ def __init__(self, comm, shell=True, fail=True, ns=None, background=False):
+ if ns:
+ if isinstance(ns, NetNS):
+ ns = ns.name
+ comm = f'ip netns exec {ns} ' + comm
+
+ self.stdout = None
+ self.stderr = None
+ self.ret = None
+
+ self.comm = comm
+ self.proc = subprocess.Popen(comm, shell=shell, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ if not background:
+ self.process(terminate=False, fail=fail)
+
+ def process(self, terminate=True, fail=None):
+ if terminate:
+ self.proc.terminate()
+ stdout, stderr = self.proc.communicate()
+ self.stdout = stdout.decode("utf-8")
+ self.stderr = stderr.decode("utf-8")
+ self.proc.stdout.close()
+ self.proc.stderr.close()
+ self.ret = self.proc.returncode
+
+ if self.proc.returncode != 0 and fail:
+ if len(stderr) > 0 and stderr[-1] == "\n":
+ stderr = stderr[:-1]
+ raise Exception("Command failed: %s\n%s" % (self.proc.args, stderr))
+
+
+def ip(args, json=None, ns=None):
+ cmd_str = "ip "
+ if json:
+ cmd_str += '-j '
+ cmd_str += args
+ cmd_obj = cmd(cmd_str, ns=ns)
+ if json:
+ return _json.loads(cmd_obj.stdout)
+ return cmd_obj