From patchwork Fri Apr 12 23:37:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 13628371 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 14A9D15252C; Fri, 12 Apr 2024 23:37:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712965037; cv=none; b=DN/Cq/WwbTaKojlwZriNKX4f2A3W/rLzIVLQ3F9OkCkATsb/mwuUqsJwhPFeuQDJSjqkXexGykCDm62lVU22d76wGFPkL4bEorccg/HdcxD+zgGkM/kc3f1sIJ1IW/u2aljnI1CuGrz3p97i3hvD0nVfeIn+i0GF4kQ9aHUX2Xk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712965037; c=relaxed/simple; bh=ZwZG8RwbY8C3v4KGuC84Ga0eey7PCYOdI1yJagyEpCo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=suGnAZib5wN06wxhlfxs09GiVIYdVHPcG+igg6tOTzcrlCYMrhsafGDND51yTNibwXQBFQWAhzFv8D8/ImNrxi9R8dDx9ThKQz714FVrLfPga2as0uAYwk0vXbWMuVDGxDocjsVPLn8Fj9VgQJcgddNmGj1CaMuqmowbsgxU2Pg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=a3C4NqRj; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="a3C4NqRj" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5E5D4C4AF07; Fri, 12 Apr 2024 23:37:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712965036; bh=ZwZG8RwbY8C3v4KGuC84Ga0eey7PCYOdI1yJagyEpCo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=a3C4NqRjJo/d9vlFTnQNNB99bLej9/iLEOjx/3N/srum0Rxdpp/aXwtm4VAGasmHb AsDQsOqteZcjBpKn0KWEop9N5ch1ALQYv6euJrY5IhPBHBMRAJ2+ByY/ifBWVCiTwX iHdsLngQ7W6FZBTlYc8aIFV0dE8pMs8+euWJambA2xUWy677Rx685SyoN6B4LPCUJZ CSuzpyQ3qFjK4gNoJSX+lAjjn8Ok0MWR7O+nMr7NQWFjNxhBb4R6EgZQqodK87ndu0 wWDnonTPvIzczdzOZNZ1EpUGVhefuQHg5jnOUVbL7FXLfsi0mqRYRs0oiewxGjrCa2 7dGkVJeGufPbA== From: Jakub Kicinski To: davem@davemloft.net Cc: netdev@vger.kernel.org, edumazet@google.com, pabeni@redhat.com, shuah@kernel.org, petrm@nvidia.com, linux-kselftest@vger.kernel.org, willemb@google.com, Jakub Kicinski Subject: [PATCH net-next 1/5] selftests: drv-net: define endpoint structures Date: Fri, 12 Apr 2024 16:37:01 -0700 Message-ID: <20240412233705.1066444-2-kuba@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240412233705.1066444-1-kuba@kernel.org> References: <20240412233705.1066444-1-kuba@kernel.org> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Define the endpoint "model". To execute most meaningful device driver tests we need to be able to communicate with a remote system, and have it send traffic to the device under test. Various test environments will have different requirements. 0) "Local" netdevsim-based testing can simply use net namespaces. netdevsim supports connecting two devices now, to form a veth-like construct. 1) Similarly on hosts with multiple NICs, the NICs may be connected together with a loopback cable or internal device loopback. One interface may be placed into separate netns, and tests would proceed much like in the netdevsim case. Note that the loopback config or the moving of one interface into a netns is not expected to be part of selftest code. 2) Some systems may need to communicate with the endpoint via SSH. 3) Last but not least environment may have its own custom communication method. Fundamentally we only need two operations: - run a command remotely - deploy a binary (if some tool we need is built as part of kselftests) Wrap these two in a class. Use dynamic loading to load the Endpoint class. This will allow very easy definition of other communication methods without bothering upstream code base. Stick to the "simple" / "no unnecessary abstractions" model for referring to the endpoints. The host / endpoint object are passed as an argument to the usual cmd() or ip() invocation. For example: ip("link show", json=True, host=endpoint) Signed-off-by: Jakub Kicinski --- .../selftests/drivers/net/lib/py/__init__.py | 1 + .../selftests/drivers/net/lib/py/endpoint.py | 13 +++++++ .../selftests/drivers/net/lib/py/ep_netns.py | 15 ++++++++ .../selftests/drivers/net/lib/py/ep_ssh.py | 34 +++++++++++++++++++ tools/testing/selftests/net/lib/py/utils.py | 19 ++++++----- 5 files changed, 73 insertions(+), 9 deletions(-) create mode 100644 tools/testing/selftests/drivers/net/lib/py/endpoint.py create mode 100644 tools/testing/selftests/drivers/net/lib/py/ep_netns.py create mode 100644 tools/testing/selftests/drivers/net/lib/py/ep_ssh.py diff --git a/tools/testing/selftests/drivers/net/lib/py/__init__.py b/tools/testing/selftests/drivers/net/lib/py/__init__.py index 4653dffcd962..0d71ec83135b 100644 --- a/tools/testing/selftests/drivers/net/lib/py/__init__.py +++ b/tools/testing/selftests/drivers/net/lib/py/__init__.py @@ -15,3 +15,4 @@ KSFT_DIR = (Path(__file__).parent / "../../../..").resolve() sys.exit(4) from .env import * +from .endpoint import Endpoint diff --git a/tools/testing/selftests/drivers/net/lib/py/endpoint.py b/tools/testing/selftests/drivers/net/lib/py/endpoint.py new file mode 100644 index 000000000000..9272fdc47a06 --- /dev/null +++ b/tools/testing/selftests/drivers/net/lib/py/endpoint.py @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0 + +import importlib + +_modules = {} + +def Endpoint(ep_type, ep_args): + global _modules + + if ep_type not in _modules: + _modules[ep_type] = importlib.import_module("..ep_" + ep_type, __name__) + + return getattr(_modules[ep_type], "Endpoint")(ep_args) diff --git a/tools/testing/selftests/drivers/net/lib/py/ep_netns.py b/tools/testing/selftests/drivers/net/lib/py/ep_netns.py new file mode 100644 index 000000000000..f5c588bb31f0 --- /dev/null +++ b/tools/testing/selftests/drivers/net/lib/py/ep_netns.py @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0 + +from lib.py import cmd + + +class Endpoint: + def __init__(self, name): + self.name = name + + def cmd(self, *args): + c = cmd(*args, ns=self.name) + return c.stdout, c.stderr, c.ret + + def deploy(self, what): + return what diff --git a/tools/testing/selftests/drivers/net/lib/py/ep_ssh.py b/tools/testing/selftests/drivers/net/lib/py/ep_ssh.py new file mode 100644 index 000000000000..620df0dd8c07 --- /dev/null +++ b/tools/testing/selftests/drivers/net/lib/py/ep_ssh.py @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: GPL-2.0 + +import os +import shlex +import string +import random + +from lib.py import cmd + + +class Endpoint: + def __init__(self, name): + self.name = name + self._tmpdir = None + + def __del__(self): + if self._tmpdir: + self.cmd("rm -rf " + self._tmpdir) + self._tmpdir = None + + def cmd(self, comm, *args): + c = cmd("ssh " + self.name + " " + shlex.quote(comm), *args) + return c.stdout, c.stderr, c.ret + + def _mktmp(self): + return ''.join(random.choice(string.ascii_lowercase) for _ in range(8)) + + def deploy(self, what): + if not self._tmpdir: + self._tmpdir = "/tmp/" + self._mktmp() + self.cmd("mkdir " + self._tmpdir) + file_name = self._tmpdir + "/" + self._mktmp() + os.path.basename(what) + cmd(f"scp {what} {self.name}:{file_name}") + return file_name diff --git a/tools/testing/selftests/net/lib/py/utils.py b/tools/testing/selftests/net/lib/py/utils.py index f0d425731fd4..eff50ddd9a9d 100644 --- a/tools/testing/selftests/net/lib/py/utils.py +++ b/tools/testing/selftests/net/lib/py/utils.py @@ -4,10 +4,8 @@ import json as _json import subprocess class cmd: - def __init__(self, comm, shell=True, fail=True, ns=None, background=False): + def __init__(self, comm, shell=True, fail=True, ns=None, background=False, host=None): if ns: - if isinstance(ns, NetNS): - ns = ns.name comm = f'ip netns exec {ns} ' + comm self.stdout = None @@ -15,10 +13,13 @@ import subprocess 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) + if host: + self.stdout, self.stderr, self.ret = host.cmd(comm) + else: + 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: @@ -36,12 +37,12 @@ import subprocess raise Exception("Command failed: %s\n%s" % (self.proc.args, stderr)) -def ip(args, json=None, ns=None): +def ip(args, json=None, ns=None, host=None): cmd_str = "ip " if json: cmd_str += '-j ' cmd_str += args - cmd_obj = cmd(cmd_str, ns=ns) + cmd_obj = cmd(cmd_str, ns=ns, host=host) if json: return _json.loads(cmd_obj.stdout) return cmd_obj From patchwork Fri Apr 12 23:37:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 13628372 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8BBC615253A; Fri, 12 Apr 2024 23:37:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712965037; cv=none; b=hwlchyp0JtBJgn0adQQQsStanGmlx3n7SE/YL69C/ghzfcMyGONfHuZqweP4Y1/t0SwYPgvXcRpO3NccFiprh6/c4SNM5wDlev2/S/+ihOciQ1kGrKLlvfU2gbgg3jUZPkAiDssk0RqQeimTlDn4+EcafgiX4FbCpubsIlHNfeI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712965037; c=relaxed/simple; bh=P1Yf3n7jFYyThb0whQqN7H3emmofC3ohUKqio9qXgnA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=k+aSnF2AJzx85k275sOUIfoP6opArfDj8pyph+shE2fkHnsGLB2LkrOCeeWzD0YcTl7NoIv8vbFRVWHZ+3EgGXvFsA2NXPJ/lI1jT0TSMratkip9p2IjTPfKgAIM8KEvDfgaU1h52qPkkmSlAQSAwh6RHmLUYcJPweEhCMMZbYw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cfEDRIfx; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cfEDRIfx" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C9ECBC2BD11; Fri, 12 Apr 2024 23:37:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712965037; bh=P1Yf3n7jFYyThb0whQqN7H3emmofC3ohUKqio9qXgnA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cfEDRIfxjW83eQQpT01ovDpUTPxYY9QLZEgvziTolBeFsk8DiCynKJRONini+F+Lb y5rMT/HpHKQh0yCDOw98aQkv7PKABq1UOmabz3ZERPy6pIyG1h/QMZoKNp7ISbb5+m lO+F07ScWGyoUj+agNhwQsf+1Hup74yZva02ADROCcHzOOALMRMwmDL435+jnwUMZf EdyQgFyzN/K0shJadk7PcwDf2eOLnqZv+7JrBhEWP7qR/tvNqAPogjbQdqBC+6B/9O GD0brzJ8Sre6kRrhC9j7XGbbF8knidNrjJNwRwumM33QlgUT3CDcWUpKBhkbXVK0U/ ZbO7SUJ9ClCCQ== From: Jakub Kicinski To: davem@davemloft.net Cc: netdev@vger.kernel.org, edumazet@google.com, pabeni@redhat.com, shuah@kernel.org, petrm@nvidia.com, linux-kselftest@vger.kernel.org, willemb@google.com, Jakub Kicinski Subject: [PATCH net-next 2/5] selftests: drv-net: add stdout to the command failed exception Date: Fri, 12 Apr 2024 16:37:02 -0700 Message-ID: <20240412233705.1066444-3-kuba@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240412233705.1066444-1-kuba@kernel.org> References: <20240412233705.1066444-1-kuba@kernel.org> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 ping prints all the info to stdout. To make debug easier capture stdout in the Exception raised when command unexpectedly fails. Signed-off-by: Jakub Kicinski --- tools/testing/selftests/net/lib/py/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/lib/py/utils.py b/tools/testing/selftests/net/lib/py/utils.py index eff50ddd9a9d..d47d684d9e02 100644 --- a/tools/testing/selftests/net/lib/py/utils.py +++ b/tools/testing/selftests/net/lib/py/utils.py @@ -34,7 +34,8 @@ import subprocess 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)) + raise Exception("Command failed: %s\nSTDOUT: %s\nSTDERR: %s" % + (self.proc.args, stdout, stderr)) def ip(args, json=None, ns=None, host=None): From patchwork Fri Apr 12 23:37:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 13628373 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EDF48152DEE; Fri, 12 Apr 2024 23:37:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712965038; cv=none; b=S3XQTG+CQNTApDarzDW4ARNg05o5BZ35SAYAvuNbncThaD7ZM/VzprxSBTgmArhqJV+lX7rNxs027NFrWusoVD8AqniCMFtcGuHzMrpWDZVZkuFRX2Oy2yXD/hJCgrNZqNfHV+oHxXvkyao4aoV3ebGzjtSQItqYdq+31a1ZEVg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712965038; c=relaxed/simple; bh=U5+EVNFryCl6AbqRDTDECqncYZkgnEzOhvv/pOI/KNg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FgbryvUY7NEKbDGd9jmQP6SxHKVFaWotj1GSuYzSgOuQsmZhQIiQB0pu61Exo3l+ZdB+1qPMnpz1979tP3rGlUzIRz3UWM6HsDgOPrLkmROtD3qOBJ7DIIDqu5vJyRZX6oFEYeYAPt6W5Hej+HqY/q2kx48VQ3gj7iOshnZXODs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lDxTuecH; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="lDxTuecH" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 402D5C4AF0A; Fri, 12 Apr 2024 23:37:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712965037; bh=U5+EVNFryCl6AbqRDTDECqncYZkgnEzOhvv/pOI/KNg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lDxTuecHdLnPQQPQxy6caTBndoq3qkWOnkzSotuUackQPnRK/EVFzMe/i1czRpgla GnxNBlK8CJ9fqZODNbAoCIk4As6fu5MtgwpKZndKfjNVS75pK0h0BK19oTNYyTvLL/ v6fi+Tw/LqSwJF8mW/efxMi9T1u8tjkgtCn+me36gJdNH+mbEcz3PlZfsPZaqZ9Lyp RSXaOmB9mTT+C/dVEre2c9pdx4fZW7/Vix30iKh702KDqrafg0xtXYLSn0GAVRd3ds YEbeUMjm3BLr/vUFHe9XHX7iI/+zO0hU6UBQNBbTR/qUfJQOUK3777CcPg7YIxBP2y lIKYf9Aqr6+Ag== From: Jakub Kicinski To: davem@davemloft.net Cc: netdev@vger.kernel.org, edumazet@google.com, pabeni@redhat.com, shuah@kernel.org, petrm@nvidia.com, linux-kselftest@vger.kernel.org, willemb@google.com, Jakub Kicinski Subject: [PATCH net-next 3/5] selftests: drv-net: factor out parsing of the env Date: Fri, 12 Apr 2024 16:37:03 -0700 Message-ID: <20240412233705.1066444-4-kuba@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240412233705.1066444-1-kuba@kernel.org> References: <20240412233705.1066444-1-kuba@kernel.org> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The tests with a remote end will use a different class, for clarity, but will also need to parse the env. So factor parsing the env out to a function. Signed-off-by: Jakub Kicinski --- .../selftests/drivers/net/lib/py/env.py | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/tools/testing/selftests/drivers/net/lib/py/env.py b/tools/testing/selftests/drivers/net/lib/py/env.py index e1abe9491daf..a081e168f3db 100644 --- a/tools/testing/selftests/drivers/net/lib/py/env.py +++ b/tools/testing/selftests/drivers/net/lib/py/env.py @@ -6,12 +6,36 @@ from pathlib import Path from lib.py import ip from lib.py import NetdevSimDev + +def _load_env_file(src_path): + env = os.environ.copy() + + src_dir = Path(src_path).parent.resolve() + if not (src_dir / "net.config").exists(): + return env + + lexer = shlex.shlex(open((src_dir / "net.config").as_posix(), 'r').read()) + k = None + for token in lexer: + if k is None: + k = token + env[k] = "" + elif token == "=": + pass + else: + env[k] = token + k = None + return env + + class NetDrvEnv: + """ + Class for a single NIC / host env, with no remote end + """ def __init__(self, src_path): self._ns = None - self.env = os.environ.copy() - self._load_env_file(src_path) + self.env = _load_env_file(src_path) if 'NETIF' in self.env: self.dev = ip("link show dev " + self.env['NETIF'], json=True)[0] @@ -34,19 +58,4 @@ from lib.py import NetdevSimDev self._ns.remove() self._ns = None - def _load_env_file(self, src_path): - src_dir = Path(src_path).parent.resolve() - if not (src_dir / "net.config").exists(): - return - lexer = shlex.shlex(open((src_dir / "net.config").as_posix(), 'r').read()) - k = None - for token in lexer: - if k is None: - k = token - self.env[k] = "" - elif token == "=": - pass - else: - self.env[k] = token - k = None From patchwork Fri Apr 12 23:37:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 13628374 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 24129152DF2; Fri, 12 Apr 2024 23:37:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712965038; cv=none; b=hB4YwX6zneZu6GdHoprNrE2VmukB3y+VjvOEUFAXNZbCrnkCfXVLK4elgdZ8eHeykuuh5nfVJ+xEaRUI7hn4cuNWxkA9DUckz2MK6VNqs3GcBI+MZpXEoELUseHNgUhFn01N/ehBvcf6w/9N4I5rmWnLudTpQUYRviHdGNNu4JU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712965038; c=relaxed/simple; bh=PwHVkxz3nBF0PRBY9R8DIP+LWJ54pS+3zPif8AFoQVo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CplciLGxLqS0ZoaajR1LU5lpIwFiTlpI7ITfJv2zBeX14qPSVV+BrX03Alyg3ajxHAfIapIvCSY33+XqStE+Uj45f3iNdXtWfdYMQIMynNmYV6vx1o3eiRKgSLlXcd+TiOYj0qA/YykWqusINmM2z0jbc7fesSEq82lyEkGzeOg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JRXYJ852; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JRXYJ852" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B1FADC4AF14; Fri, 12 Apr 2024 23:37:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712965038; bh=PwHVkxz3nBF0PRBY9R8DIP+LWJ54pS+3zPif8AFoQVo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JRXYJ852u9L7aI0FStuUYOMY+aManO3CSxV4ElCMwSDh5yk2Ca9Nq5pnh0hzrF6uI 1atyCwR4GL8IrJo8E24MXN7Qwk9jQDIgEHXQplB707dlLPGmX6oM6PEX4G8MlvhBzG g4n4O6V9aCER1qzbXaa2w+DEGpgF44ltgrVhNnk/5OFonlyrOYsQxnIAmWyc0CDIlr c7uSFYXrS2h7ZRN4+T0aLMFof7toxt1buo9azNp03KYnNchGbzpJrW5qn+xkpoSsPi sH1A5wH2/5LG9TGEpNqW7nP7JxS1buL9Yhdxv32roiFxgxVEn1YexJOiJSJzKN2otp CoDytpHCg+/2Q== From: Jakub Kicinski To: davem@davemloft.net Cc: netdev@vger.kernel.org, edumazet@google.com, pabeni@redhat.com, shuah@kernel.org, petrm@nvidia.com, linux-kselftest@vger.kernel.org, willemb@google.com, Jakub Kicinski Subject: [PATCH net-next 4/5] selftests: drv-net: construct environment for running tests which require an endpoint Date: Fri, 12 Apr 2024 16:37:04 -0700 Message-ID: <20240412233705.1066444-5-kuba@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240412233705.1066444-1-kuba@kernel.org> References: <20240412233705.1066444-1-kuba@kernel.org> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Nothing surprising here, hopefully. Wrap the variables from the environment into a class or spawn a netdevsim based env and pass it to the tests. Signed-off-by: Jakub Kicinski --- .../testing/selftests/drivers/net/README.rst | 31 +++++++ .../selftests/drivers/net/lib/py/env.py | 93 ++++++++++++++++++- .../testing/selftests/net/lib/py/__init__.py | 1 + tools/testing/selftests/net/lib/py/netns.py | 31 +++++++ 4 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/net/lib/py/netns.py diff --git a/tools/testing/selftests/drivers/net/README.rst b/tools/testing/selftests/drivers/net/README.rst index 5ef7c417d431..ffc15fe5d555 100644 --- a/tools/testing/selftests/drivers/net/README.rst +++ b/tools/testing/selftests/drivers/net/README.rst @@ -23,8 +23,39 @@ Variables can be set in the environment or by creating a net.config # Variable set in a file NETIF=eth0 +Please note that the config parser is very simple, if there are +any non-alphanumeric characters in the value it needs to be in +double quotes. + NETIF ~~~~~ Name of the netdevice against which the test should be executed. When empty or not set software devices will be used. + +LOCAL_V4, LOCAL_V6, EP_V4, EP_V6 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Local and remote (endpoint) IP addresses. + +EP_TYPE +~~~~~~~ + +Communication method used to run commands on the endpoint. +Test framework supports using ``netns`` and ``ssh`` channels. +``netns`` assumes the "remote" interface is part of the same +host, just moved to the specified netns. +``ssh`` communicates with remote endpoint over ``ssh`` and ``scp``. + +Communication methods are defined by classes in ``lib/py/ep_{name}.py``. +It should be possible to add a new method without modifying any of +the framework, by simply adding an appropriately named file to ``lib/py``. + +EP_ARGS +~~~~~~~ + +Arguments used to construct the communication channel. +Communication channel dependent:: + + for netns - name of the "remote" namespace + for ssh - name/address of the remote host diff --git a/tools/testing/selftests/drivers/net/lib/py/env.py b/tools/testing/selftests/drivers/net/lib/py/env.py index a081e168f3db..f63be0a72a53 100644 --- a/tools/testing/selftests/drivers/net/lib/py/env.py +++ b/tools/testing/selftests/drivers/net/lib/py/env.py @@ -4,7 +4,8 @@ import os import shlex from pathlib import Path from lib.py import ip -from lib.py import NetdevSimDev +from lib.py import NetNS, NetdevSimDev +from .endpoint import Endpoint def _load_env_file(src_path): @@ -59,3 +60,93 @@ from lib.py import NetdevSimDev self._ns = None +class NetDrvEpEnv: + """ + Class for an environment with a local device and "remote endpoint" + which can be used to send traffic in. + + For local testing it creates two network namespaces and a pair + of netdevsim devices. + """ + def __init__(self, src_path): + + self.env = _load_env_file(src_path) + + # Things we try to destroy + self.endpoint = None + # These are for local testing state + self._netns = None + self._ns = None + self._ns_peer = None + + if "NETIF" in self.env: + self.dev = ip("link show dev " + self.env['NETIF'], json=True)[0] + + self.v4 = self.env.get("LOCAL_V4") + self.v6 = self.env.get("LOCAL_V6") + self.ep_v4 = self.env.get("EP_V4") + self.ep_v6 = self.env.get("EP_V6") + ep_type = self.env["EP_TYPE"] + ep_args = self.env["EP_ARGS"] + else: + self.create_local() + + self.dev = self._ns.nsims[0].dev + + self.v4 = "192.0.2.1" + self.v6 ="0100::1" + self.ep_v4 = "192.0.2.2" + self.ep_v6 = "0100::2" + ep_type = "netns" + ep_args = self._netns.name + + self.endpoint = Endpoint(ep_type, ep_args) + + self.addr = self.v6 if self.v6 else self.v4 + self.ep_addr = self.ep_v6 if self.ep_v6 else self.ep_v4 + + self.ifname = self.dev['ifname'] + self.ifindex = self.dev['ifindex'] + + def create_local(self): + self._netns = NetNS() + self._ns = NetdevSimDev() + self._ns_peer = NetdevSimDev(ns=self._netns) + + with open("/proc/self/ns/net") as nsfd0, \ + open("/var/run/netns/" + self._netns.name) as nsfd1: + ifi0 = self._ns.nsims[0].ifindex + ifi1 = self._ns_peer.nsims[0].ifindex + NetdevSimDev.ctrl_write('link_device', + f'{nsfd0.fileno()}:{ifi0} {nsfd1.fileno()}:{ifi1}') + + ip(f" addr add dev {self._ns.nsims[0].ifname} 192.0.2.1/24") + ip(f"-6 addr add dev {self._ns.nsims[0].ifname} 0100::1/64 nodad") + ip(f" link set dev {self._ns.nsims[0].ifname} up") + + ip(f" addr add dev {self._ns_peer.nsims[0].ifname} 192.0.2.2/24", ns=self._netns) + ip(f"-6 addr add dev {self._ns_peer.nsims[0].ifname} 0100::2/64 nodad", ns=self._netns) + ip(f" link set dev {self._ns_peer.nsims[0].ifname} up", ns=self._netns) + + def __enter__(self): + return self + + def __exit__(self, ex_type, ex_value, ex_tb): + """ + __exit__ gets called at the end of a "with" block. + """ + self.__del__() + + def __del__(self): + if self._ns: + self._ns.remove() + self._ns = None + if self._ns_peer: + self._ns_peer.remove() + self._ns_peer = None + if self._netns: + del self._netns + self._netns = None + if self.endpoint: + del self.endpoint + self.endpoint = None diff --git a/tools/testing/selftests/net/lib/py/__init__.py b/tools/testing/selftests/net/lib/py/__init__.py index ded7102df18a..b6d498d125fe 100644 --- a/tools/testing/selftests/net/lib/py/__init__.py +++ b/tools/testing/selftests/net/lib/py/__init__.py @@ -2,6 +2,7 @@ from .consts import KSRC from .ksft import * +from .netns import NetNS from .nsim import * from .utils import * from .ynl import NlError, YnlFamily, EthtoolFamily, NetdevFamily, RtnlFamily diff --git a/tools/testing/selftests/net/lib/py/netns.py b/tools/testing/selftests/net/lib/py/netns.py new file mode 100644 index 000000000000..ecff85f9074f --- /dev/null +++ b/tools/testing/selftests/net/lib/py/netns.py @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: GPL-2.0 + +from .utils import ip +import random +import string + + +class NetNS: + def __init__(self, name=None): + if name: + self.name = name + else: + self.name = ''.join(random.choice(string.ascii_lowercase) for _ in range(8)) + ip('netns add ' + self.name) + + def __del__(self): + if self.name: + ip('netns del ' + self.name) + self.name = None + + def __enter__(self): + return self + + def __exit__(self, ex_type, ex_value, ex_tb): + self.__del__() + + def __str__(self): + return self.name + + def __repr__(self): + return f"NetNS({self.name})" From patchwork Fri Apr 12 23:37:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 13628375 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E0ED8152E13; Fri, 12 Apr 2024 23:37:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712965039; cv=none; b=JMZtb9ZQL/F+yjPdFoM8+jhEhIhqAz3SW07taSQCcBjERoIY1gZbcyS58M6e0FoB9tFEPTPrayOmwdAkvGaY39npkAO6uNQGTvWwSrtxVvbBdR7t9sNGjnrrE0qdniQ5u5MDZmxGlamLqm5B3os/WL+xDVKjxREWEXlqI5ETLGU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712965039; c=relaxed/simple; bh=K96RrE3a2mAuVx/wLyxJvrkYyRoHGL9Y3+Zqq4lXbE4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Xx0mF2JG06Cvzjeb8ry2xuBTe6CfgZthDOQ4+EHzTiEqjp65x6JWtT1ldNuLIx5eA8DxVGNCoT6IjdeFGMqfhveLqxK2eUKbn5RprFLcNpJXucP0Q0kiADAFAZXKRBBkm7sradmCyFjZKlx+d9eJdtLidixqqIgug8fbdyRJrT0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QC8jA1KS; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="QC8jA1KS" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 28469C2BD10; Fri, 12 Apr 2024 23:37:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712965038; bh=K96RrE3a2mAuVx/wLyxJvrkYyRoHGL9Y3+Zqq4lXbE4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QC8jA1KSnwazgzYlREm3bldZouYBH+b42653TVyqxgRTr+WFW/is42UNZOoW77Szt EijnfMsu/TMNu5OcMPa52fyls5rn11micY37ogwjkWB27mAARQa338m0NfZgrn5YDG F09x3lWYs7c7P9RgcW/7lXoFzBg3UEfgdZ5uozU/fC/r5tb+t/BNrzJL7ciAfdZdnC N9qJCHOa5LMr2Rzw/k3NBdRJ8vdxIbZuqlMrUZthyrLQYyZXwskdqJXUhjizvV4rK0 iwljkmCfA7dxNP0slydJL0xzX5ZiYUWnW2ps02HufaEzYov/QvrQT2mEbRZVU0Ykzf Np7aIk7WNUuuw== From: Jakub Kicinski To: davem@davemloft.net Cc: netdev@vger.kernel.org, edumazet@google.com, pabeni@redhat.com, shuah@kernel.org, petrm@nvidia.com, linux-kselftest@vger.kernel.org, willemb@google.com, Jakub Kicinski Subject: [PATCH net-next 5/5] selftests: drv-net: add a trivial ping test Date: Fri, 12 Apr 2024 16:37:05 -0700 Message-ID: <20240412233705.1066444-6-kuba@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240412233705.1066444-1-kuba@kernel.org> References: <20240412233705.1066444-1-kuba@kernel.org> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add a very simple test for testing with a remote system. Both IPv4 and IPv6 connectivity is optional so tests will XFail is env doesn't define an address for the given family. Using netdevsim: $ ./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..2 # ok 1 ping.ping_v4 # ok 2 ping.ping_v6 # # Totals: pass:2 fail:0 xfail:0 xpass:0 skip:0 error:0 ok 1 selftests: drivers/net: ping.py Command line SSH: $ NETIF=virbr0 EP_TYPE=ssh EP_ARGS=root@192.168.122.123 \ LOCAL_V4=192.168.122.1 EP_V4=192.168.122.123 \ ./tools/testing/selftests/drivers/net/ping.py KTAP version 1 1..2 ok 1 ping.ping_v4 ok 2 ping.ping_v6 # XFAIL # Totals: pass:1 fail:0 xfail:1 xpass:0 skip:0 error:0 Existing devices placed in netns (and using net.config): $ cat drivers/net/net.config NETIF=veth0 EP_TYPE=netns EP_ARGS=red LOCAL_V4="192.168.1.1" EP_V4="192.168.1.2" $ ./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..2 # ok 1 ping.ping_v4 # ok 2 ping.ping_v6 # XFAIL # # Totals: pass:1 fail:0 xfail:1 xpass:0 skip:0 error:0 Signed-off-by: Jakub Kicinski --- tools/testing/selftests/drivers/net/Makefile | 4 ++- tools/testing/selftests/drivers/net/ping.py | 32 ++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100755 tools/testing/selftests/drivers/net/ping.py diff --git a/tools/testing/selftests/drivers/net/Makefile b/tools/testing/selftests/drivers/net/Makefile index 379cdb1960a7..713ab251cea9 100644 --- a/tools/testing/selftests/drivers/net/Makefile +++ b/tools/testing/selftests/drivers/net/Makefile @@ -2,6 +2,8 @@ TEST_INCLUDES := $(wildcard lib/py/*.py) -TEST_PROGS := stats.py +TEST_PROGS := \ + ping.py \ + stats.py \ include ../../lib.mk diff --git a/tools/testing/selftests/drivers/net/ping.py b/tools/testing/selftests/drivers/net/ping.py new file mode 100755 index 000000000000..df746543f5c3 --- /dev/null +++ b/tools/testing/selftests/drivers/net/ping.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 + +from lib.py import ksft_run, KsftXfailEx +from lib.py import NetDrvEpEnv +from lib.py import cmd + + +def ping_v4(cfg) -> None: + if not cfg.v4: + raise KsftXfailEx() + + cmd(f"ping -c 1 -W0.5 {cfg.ep_v4}") + cmd(f"ping -c 1 -W0.5 {cfg.v4}", host=cfg.endpoint) + + +def ping_v6(cfg) -> None: + if not cfg.v6: + raise KsftXfailEx() + + cmd(f"ping -c 1 -W0.5 {cfg.ep_v6}") + cmd(f"ping -c 1 -W0.5 {cfg.v6}", host=cfg.endpoint) + + +def main() -> None: + with NetDrvEpEnv(__file__) as cfg: + ksft_run([ping_v4, ping_v6], + args=(cfg, )) + + +if __name__ == "__main__": + main()