Commit ff9ddaa4 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'selftests-drv-net-round-some-sharp-edges'

Jakub Kicinski says:

====================
selftests: drv-net: round some sharp edges

I had to explain how to run the driver tests twice already.
Improve the README so we can just point to it.
Improve the config validation.

v1: https://lore.kernel.org/r/20240424221444.4194069-1-kuba@kernel.org/
====================

Link: https://lore.kernel.org/r/20240425222341.309778-1-kuba@kernel.orgSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 1bede0a1 340ab206
Running tests .. SPDX-License-Identifier: GPL-2.0
=============
Tests are executed within kselftest framework like any other tests. Running driver tests
By default tests execute against software drivers such as netdevsim. ====================
All tests must support running against a real device (SW-only tests
should instead be placed in net/ or drivers/net/netdevsim, HW-only
tests in drivers/net/hw).
Set appropriate variables to point the tests at a real device. Networking driver tests are executed within kselftest framework like any
other tests. They support testing both real device drivers and emulated /
software drivers (latter mostly to test the core parts of the stack).
SW mode
~~~~~~~
By default, when no extra parameters are set or exported, tests execute
against software drivers such as netdevsim. No extra preparation is required
the software devices are created and destroyed as part of the test.
In this mode the tests are indistinguishable from other selftests and
(for example) can be run under ``virtme-ng`` like the core networking selftests.
HW mode
~~~~~~~
Executing tests against a real device requires external preparation.
The netdevice against which tests will be run must exist, be running
(in UP state) and be configured with an IP address.
Refer to list of :ref:`Variables` later in this file to set up running
the tests against a real device.
Both modes required
~~~~~~~~~~~~~~~~~~~
All tests in drivers/net must support running both against a software device
and a real device. SW-only tests should instead be placed in net/ or
drivers/net/netdevsim, HW-only tests in drivers/net/hw.
Variables Variables
========= =========
Variables can be set in the environment or by creating a net.config The variables can be set in the environment or by creating a net.config
file in the same directory as this README file. Example:: file in the same directory as this README file. Example::
$ NETIF=eth0 ./some_test.sh $ NETIF=eth0 ./some_test.sh
...@@ -23,9 +47,9 @@ or:: ...@@ -23,9 +47,9 @@ or::
# Variable set in a file # Variable set in a file
NETIF=eth0 NETIF=eth0
Please note that the config parser is very simple, if there are Local test (which don't require endpoint for sending / receiving traffic)
any non-alphanumeric characters in the value it needs to be in need only the ``NETIF`` variable. Remaining variables define the endpoint
double quotes. and communication method.
NETIF NETIF
~~~~~ ~~~~~
...@@ -61,3 +85,52 @@ Communication channel dependent:: ...@@ -61,3 +85,52 @@ Communication channel dependent::
for netns - name of the "remote" namespace for netns - name of the "remote" namespace
for ssh - name/address of the remote host for ssh - name/address of the remote host
Example
=======
Build the selftests::
# make -C tools/testing/selftests/ TARGETS="drivers/net drivers/net/hw"
"Install" the tests and copy them over to the target machine::
# make -C tools/testing/selftests/ TARGETS="drivers/net drivers/net/hw" \
install INSTALL_PATH=/tmp/ksft-net-drv
# rsync -ra --delete /tmp/ksft-net-drv root@192.168.1.1:/root/
On the target machine, running the tests will use netdevsim by default::
[/root] # ./ksft-net-drv/run_kselftest.sh -t drivers/net:ping.py
TAP version 13
1..1
# timeout set to 45
# selftests: drivers/net: ping.py
# KTAP version 1
# 1..3
# ok 1 ping.test_v4
# ok 2 ping.test_v6
# ok 3 ping.test_tcp
# # Totals: pass:3 fail:0 xfail:0 xpass:0 skip:0 error:0
ok 1 selftests: drivers/net: ping.py
Create a config with remote info::
[/root] # cat > ./ksft-net-drv/drivers/net/net.config <<EOF
NETIF=eth0
LOCAL_V4=192.168.1.1
REMOTE_V4=192.168.1.2
REMOTE_TYPE=ssh
REMOTE_ARGS=root@192.168.1.2
EOF
Run the test::
[/root] # ./ksft-net-drv/drivers/net/ping.py
KTAP version 1
1..3
ok 1 ping.test_v4
ok 2 ping.test_v6 # SKIP Test requires IPv6 connectivity
ok 3 ping.test_tcp
# Totals: pass:2 fail:0 xfail:0 xpass:0 skip:1 error:0
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
import os import os
import shlex
from pathlib import Path from pathlib import Path
from lib.py import KsftSkipEx from lib.py import KsftSkipEx
from lib.py import cmd, ip from lib.py import cmd, ip
...@@ -16,17 +15,20 @@ def _load_env_file(src_path): ...@@ -16,17 +15,20 @@ def _load_env_file(src_path):
if not (src_dir / "net.config").exists(): if not (src_dir / "net.config").exists():
return env return env
lexer = shlex.shlex(open((src_dir / "net.config").as_posix(), 'r').read()) with open((src_dir / "net.config").as_posix(), 'r') as fp:
k = None for line in fp.readlines():
for token in lexer: full_file = line
if k is None: # Strip comments
k = token pos = line.find("#")
env[k] = "" if pos >= 0:
elif token == "=": line = line[:pos]
pass line = line.strip()
else: if not line:
env[k] = token continue
k = None pair = line.split('=', maxsplit=1)
if len(pair) != 2:
raise Exception("Can't parse configuration line:", full_file)
env[pair[0]] = pair[1]
return env return env
...@@ -86,6 +88,7 @@ class NetDrvEpEnv: ...@@ -86,6 +88,7 @@ class NetDrvEpEnv:
self._ns_peer = None self._ns_peer = None
if "NETIF" in self.env: if "NETIF" in self.env:
self._check_env()
self.dev = ip("link show dev " + self.env['NETIF'], json=True)[0] self.dev = ip("link show dev " + self.env['NETIF'], json=True)[0]
self.v4 = self.env.get("LOCAL_V4") self.v4 = self.env.get("LOCAL_V4")
...@@ -141,6 +144,30 @@ class NetDrvEpEnv: ...@@ -141,6 +144,30 @@ class NetDrvEpEnv:
ip(f"-6 addr add dev {self._ns_peer.nsims[0].ifname} {self.nsim_v6_pfx}2/64 nodad", ns=self._netns) ip(f"-6 addr add dev {self._ns_peer.nsims[0].ifname} {self.nsim_v6_pfx}2/64 nodad", ns=self._netns)
ip(f" link set dev {self._ns_peer.nsims[0].ifname} up", ns=self._netns) ip(f" link set dev {self._ns_peer.nsims[0].ifname} up", ns=self._netns)
def _check_env(self):
vars_needed = [
["LOCAL_V4", "LOCAL_V6"],
["REMOTE_V4", "REMOTE_V6"],
["REMOTE_TYPE"],
["REMOTE_ARGS"]
]
missing = []
for choice in vars_needed:
for entry in choice:
if entry in self.env:
break
else:
missing.append(choice)
# Make sure v4 / v6 configs are symmetric
if ("LOCAL_V6" in self.env) != ("REMOTE_V6" in self.env):
missing.append(["LOCAL_V6", "REMOTE_V6"])
if ("LOCAL_V4" in self.env) != ("REMOTE_V4" in self.env):
missing.append(["LOCAL_V4", "REMOTE_V4"])
if missing:
raise Exception("Invalid environment, missing configuration:", missing,
"Please see tools/testing/selftests/drivers/net/README.rst")
def __enter__(self): def __enter__(self):
return self return self
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment