Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/138828/?format=api
http://patches.dpdk.org/api/patches/138828/?format=api", "web_url": "http://patches.dpdk.org/project/dpdk/patch/20240326190422.577028-3-luca.vizzarro@arm.com/", "project": { "id": 1, "url": "http://patches.dpdk.org/api/projects/1/?format=api", "name": "DPDK", "link_name": "dpdk", "list_id": "dev.dpdk.org", "list_email": "dev@dpdk.org", "web_url": "http://core.dpdk.org", "scm_url": "git://dpdk.org/dpdk", "webscm_url": "http://git.dpdk.org/dpdk", "list_archive_url": "https://inbox.dpdk.org/dev", "list_archive_url_format": "https://inbox.dpdk.org/dev/{}", "commit_url_format": "" }, "msgid": "<20240326190422.577028-3-luca.vizzarro@arm.com>", "list_archive_url": "https://inbox.dpdk.org/dev/20240326190422.577028-3-luca.vizzarro@arm.com", "date": "2024-03-26T19:04:18", "name": "[2/6] dts: use Params for interactive shells", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "c013ddf7158af74e088430dea37f50031f8adf37", "submitter": { "id": 3197, "url": "http://patches.dpdk.org/api/people/3197/?format=api", "name": "Luca Vizzarro", "email": "luca.vizzarro@arm.com" }, "delegate": { "id": 1, "url": "http://patches.dpdk.org/api/users/1/?format=api", "username": "tmonjalo", "first_name": "Thomas", "last_name": "Monjalon", "email": "thomas@monjalon.net" }, "mbox": "http://patches.dpdk.org/project/dpdk/patch/20240326190422.577028-3-luca.vizzarro@arm.com/mbox/", "series": [ { "id": 31622, "url": "http://patches.dpdk.org/api/series/31622/?format=api", "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=31622", "date": "2024-03-26T19:04:16", "name": "dts: add testpmd params and statefulness", "version": 1, "mbox": "http://patches.dpdk.org/series/31622/mbox/" } ], "comments": "http://patches.dpdk.org/api/patches/138828/comments/", "check": "success", "checks": "http://patches.dpdk.org/api/patches/138828/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<dev-bounces@dpdk.org>", "X-Original-To": "patchwork@inbox.dpdk.org", "Delivered-To": "patchwork@inbox.dpdk.org", "Received": [ "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 034C043D5B;\n\tTue, 26 Mar 2024 20:04:48 +0100 (CET)", "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 0EAB0410E6;\n\tTue, 26 Mar 2024 20:04:36 +0100 (CET)", "from foss.arm.com (foss.arm.com [217.140.110.172])\n by mails.dpdk.org (Postfix) with ESMTP id 46028410D3\n for <dev@dpdk.org>; Tue, 26 Mar 2024 20:04:34 +0100 (CET)", "from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14])\n by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 6E5952F4;\n Tue, 26 Mar 2024 12:05:07 -0700 (PDT)", "from localhost.localdomain (unknown [10.57.16.115])\n by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id AB0643F64C;\n Tue, 26 Mar 2024 12:04:32 -0700 (PDT)" ], "From": "Luca Vizzarro <luca.vizzarro@arm.com>", "To": "dev@dpdk.org", "Cc": "=?utf-8?q?Juraj_Linke=C5=A1?= <juraj.linkes@pantheon.tech>,\n Luca Vizzarro <luca.vizzarro@arm.com>,\n Jack Bond-Preston <jack.bond-preston@arm.com>,\n Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>", "Subject": "[PATCH 2/6] dts: use Params for interactive shells", "Date": "Tue, 26 Mar 2024 19:04:18 +0000", "Message-Id": "<20240326190422.577028-3-luca.vizzarro@arm.com>", "X-Mailer": "git-send-email 2.34.1", "In-Reply-To": "<20240326190422.577028-1-luca.vizzarro@arm.com>", "References": "<20240326190422.577028-1-luca.vizzarro@arm.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-BeenThere": "dev@dpdk.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "DPDK patches and discussions <dev.dpdk.org>", "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>", "List-Archive": "<http://mails.dpdk.org/archives/dev/>", "List-Post": "<mailto:dev@dpdk.org>", "List-Help": "<mailto:dev-request@dpdk.org?subject=help>", "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>", "Errors-To": "dev-bounces@dpdk.org" }, "content": "Make it so that interactive shells accept an implementation of `Params`\nfor app arguments. Convert EalParameters to use `Params` instead.\n\nString command line parameters can still be supplied by using the\n`StrParams` implementation.\n\nSigned-off-by: Luca Vizzarro <luca.vizzarro@arm.com>\nReviewed-by: Jack Bond-Preston <jack.bond-preston@arm.com>\nReviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>\n---\n .../remote_session/interactive_shell.py | 8 +-\n dts/framework/remote_session/testpmd_shell.py | 12 +-\n dts/framework/testbed_model/__init__.py | 2 +-\n dts/framework/testbed_model/node.py | 4 +-\n dts/framework/testbed_model/os_session.py | 4 +-\n dts/framework/testbed_model/sut_node.py | 106 ++++++++----------\n dts/tests/TestSuite_pmd_buffer_scatter.py | 3 +-\n 7 files changed, 73 insertions(+), 66 deletions(-)", "diff": "diff --git a/dts/framework/remote_session/interactive_shell.py b/dts/framework/remote_session/interactive_shell.py\nindex 5cfe202e15..a2c7b30d9f 100644\n--- a/dts/framework/remote_session/interactive_shell.py\n+++ b/dts/framework/remote_session/interactive_shell.py\n@@ -1,5 +1,6 @@\n # SPDX-License-Identifier: BSD-3-Clause\n # Copyright(c) 2023 University of New Hampshire\n+# Copyright(c) 2024 Arm Limited\n \n \"\"\"Common functionality for interactive shell handling.\n \n@@ -21,6 +22,7 @@\n from paramiko import Channel, SSHClient, channel # type: ignore[import]\n \n from framework.logger import DTSLogger\n+from framework.params import Params\n from framework.settings import SETTINGS\n \n \n@@ -40,7 +42,7 @@ class InteractiveShell(ABC):\n _ssh_channel: Channel\n _logger: DTSLogger\n _timeout: float\n- _app_args: str\n+ _app_args: Params | None\n \n #: Prompt to expect at the end of output when sending a command.\n #: This is often overridden by subclasses.\n@@ -63,7 +65,7 @@ def __init__(\n interactive_session: SSHClient,\n logger: DTSLogger,\n get_privileged_command: Callable[[str], str] | None,\n- app_args: str = \"\",\n+ app_args: Params | None = None,\n timeout: float = SETTINGS.timeout,\n ) -> None:\n \"\"\"Create an SSH channel during initialization.\n@@ -100,7 +102,7 @@ def _start_application(self, get_privileged_command: Callable[[str], str] | None\n get_privileged_command: A function (but could be any callable) that produces\n the version of the command with elevated privileges.\n \"\"\"\n- start_command = f\"{self.path} {self._app_args}\"\n+ start_command = f\"{self.path} {self._app_args or ''}\"\n if get_privileged_command is not None:\n start_command = get_privileged_command(start_command)\n self.send_command(start_command)\ndiff --git a/dts/framework/remote_session/testpmd_shell.py b/dts/framework/remote_session/testpmd_shell.py\nindex cb2ab6bd00..db3abb7600 100644\n--- a/dts/framework/remote_session/testpmd_shell.py\n+++ b/dts/framework/remote_session/testpmd_shell.py\n@@ -21,6 +21,7 @@\n from typing import Callable, ClassVar\n \n from framework.exception import InteractiveCommandExecutionError\n+from framework.params import StrParams\n from framework.settings import SETTINGS\n from framework.utils import StrEnum\n \n@@ -118,8 +119,15 @@ def _start_application(self, get_privileged_command: Callable[[str], str] | None\n Also find the number of pci addresses which were allowed on the command line when the app\n was started.\n \"\"\"\n- self._app_args += \" -i --mask-event intr_lsc\"\n- self.number_of_ports = self._app_args.count(\"-a \")\n+ from framework.testbed_model.sut_node import EalParameters\n+\n+ assert isinstance(self._app_args, EalParameters)\n+\n+ if isinstance(self._app_args.app_params, StrParams):\n+ self._app_args.app_params.value += \" -i --mask-event intr_lsc\"\n+\n+ self.number_of_ports = len(self._app_args.ports) if self._app_args.ports is not None else 0\n+\n super()._start_application(get_privileged_command)\n \n def start(self, verify: bool = True) -> None:\ndiff --git a/dts/framework/testbed_model/__init__.py b/dts/framework/testbed_model/__init__.py\nindex 6086512ca2..ef9520df4c 100644\n--- a/dts/framework/testbed_model/__init__.py\n+++ b/dts/framework/testbed_model/__init__.py\n@@ -23,6 +23,6 @@\n from .cpu import LogicalCoreCount, LogicalCoreCountFilter, LogicalCoreList\n from .node import Node\n from .port import Port, PortLink\n-from .sut_node import SutNode\n+from .sut_node import SutNode, EalParameters\n from .tg_node import TGNode\n from .virtual_device import VirtualDevice\ndiff --git a/dts/framework/testbed_model/node.py b/dts/framework/testbed_model/node.py\nindex 74061f6262..ec9512d618 100644\n--- a/dts/framework/testbed_model/node.py\n+++ b/dts/framework/testbed_model/node.py\n@@ -2,6 +2,7 @@\n # Copyright(c) 2010-2014 Intel Corporation\n # Copyright(c) 2022-2023 PANTHEON.tech s.r.o.\n # Copyright(c) 2022-2023 University of New Hampshire\n+# Copyright(c) 2024 Arm Limited\n \n \"\"\"Common functionality for node management.\n \n@@ -24,6 +25,7 @@\n )\n from framework.exception import ConfigurationError\n from framework.logger import DTSLogger, get_dts_logger\n+from framework.params import Params\n from framework.settings import SETTINGS\n \n from .cpu import (\n@@ -199,7 +201,7 @@ def create_interactive_shell(\n shell_cls: Type[InteractiveShellType],\n timeout: float = SETTINGS.timeout,\n privileged: bool = False,\n- app_args: str = \"\",\n+ app_args: Params | None = None,\n ) -> InteractiveShellType:\n \"\"\"Factory for interactive session handlers.\n \ndiff --git a/dts/framework/testbed_model/os_session.py b/dts/framework/testbed_model/os_session.py\nindex d5bf7e0401..7234c975c8 100644\n--- a/dts/framework/testbed_model/os_session.py\n+++ b/dts/framework/testbed_model/os_session.py\n@@ -1,6 +1,7 @@\n # SPDX-License-Identifier: BSD-3-Clause\n # Copyright(c) 2023 PANTHEON.tech s.r.o.\n # Copyright(c) 2023 University of New Hampshire\n+# Copyright(c) 2024 Arm Limited\n \n \"\"\"OS-aware remote session.\n \n@@ -29,6 +30,7 @@\n \n from framework.config import Architecture, NodeConfiguration, NodeInfo\n from framework.logger import DTSLogger\n+from framework.params import Params\n from framework.remote_session import (\n CommandResult,\n InteractiveRemoteSession,\n@@ -134,7 +136,7 @@ def create_interactive_shell(\n shell_cls: Type[InteractiveShellType],\n timeout: float,\n privileged: bool,\n- app_args: str,\n+ app_args: Params | None,\n ) -> InteractiveShellType:\n \"\"\"Factory for interactive session handlers.\n \ndiff --git a/dts/framework/testbed_model/sut_node.py b/dts/framework/testbed_model/sut_node.py\nindex 97aa26d419..3f8c3807b3 100644\n--- a/dts/framework/testbed_model/sut_node.py\n+++ b/dts/framework/testbed_model/sut_node.py\n@@ -2,6 +2,7 @@\n # Copyright(c) 2010-2014 Intel Corporation\n # Copyright(c) 2023 PANTHEON.tech s.r.o.\n # Copyright(c) 2023 University of New Hampshire\n+# Copyright(c) 2024 Arm Limited\n \n \"\"\"System under test (DPDK + hardware) node.\n \n@@ -11,6 +12,7 @@\n \"\"\"\n \n \n+from dataclasses import dataclass, field\n import os\n import tarfile\n import time\n@@ -23,6 +25,8 @@\n NodeInfo,\n SutNodeConfiguration,\n )\n+from framework import params\n+from framework.params import Params, StrParams\n from framework.remote_session import CommandResult\n from framework.settings import SETTINGS\n from framework.utils import MesonArgs\n@@ -34,62 +38,51 @@\n from .virtual_device import VirtualDevice\n \n \n-class EalParameters(object):\n+def _port_to_pci(port: Port) -> str:\n+ return port.pci\n+\n+\n+@dataclass(kw_only=True)\n+class EalParameters(Params):\n \"\"\"The environment abstraction layer parameters.\n \n The string representation can be created by converting the instance to a string.\n \"\"\"\n \n- def __init__(\n- self,\n- lcore_list: LogicalCoreList,\n- memory_channels: int,\n- prefix: str,\n- no_pci: bool,\n- vdevs: list[VirtualDevice],\n- ports: list[Port],\n- other_eal_param: str,\n- ):\n- \"\"\"Initialize the parameters according to inputs.\n-\n- Process the parameters into the format used on the command line.\n+ lcore_list: LogicalCoreList = field(metadata=params.short(\"l\"))\n+ \"\"\"The list of logical cores to use.\"\"\"\n \n- Args:\n- lcore_list: The list of logical cores to use.\n- memory_channels: The number of memory channels to use.\n- prefix: Set the file prefix string with which to start DPDK, e.g.: ``prefix='vf'``.\n- no_pci: Switch to disable PCI bus e.g.: ``no_pci=True``.\n- vdevs: Virtual devices, e.g.::\n+ memory_channels: int = field(metadata=params.short(\"n\"))\n+ \"\"\"The number of memory channels to use.\"\"\"\n \n- vdevs=[\n- VirtualDevice('net_ring0'),\n- VirtualDevice('net_ring1')\n- ]\n- ports: The list of ports to allow.\n- other_eal_param: user defined DPDK EAL parameters, e.g.:\n- ``other_eal_param='--single-file-segments'``\n- \"\"\"\n- self._lcore_list = f\"-l {lcore_list}\"\n- self._memory_channels = f\"-n {memory_channels}\"\n- self._prefix = prefix\n- if prefix:\n- self._prefix = f\"--file-prefix={prefix}\"\n- self._no_pci = \"--no-pci\" if no_pci else \"\"\n- self._vdevs = \" \".join(f\"--vdev {vdev}\" for vdev in vdevs)\n- self._ports = \" \".join(f\"-a {port.pci}\" for port in ports)\n- self._other_eal_param = other_eal_param\n-\n- def __str__(self) -> str:\n- \"\"\"Create the EAL string.\"\"\"\n- return (\n- f\"{self._lcore_list} \"\n- f\"{self._memory_channels} \"\n- f\"{self._prefix} \"\n- f\"{self._no_pci} \"\n- f\"{self._vdevs} \"\n- f\"{self._ports} \"\n- f\"{self._other_eal_param}\"\n- )\n+ prefix: str = field(metadata=params.long(\"file-prefix\"))\n+ \"\"\"Set the file prefix string with which to start DPDK, e.g.: ``prefix=\"vf\"``.\"\"\"\n+\n+ no_pci: params.Option\n+ \"\"\"Switch to disable PCI bus e.g.: ``no_pci=True``.\"\"\"\n+\n+ vdevs: list[VirtualDevice] | None = field(\n+ default=None, metadata=params.multiple(params.long(\"vdev\"))\n+ )\n+ \"\"\"Virtual devices, e.g.::\n+\n+ vdevs=[\n+ VirtualDevice(\"net_ring0\"),\n+ VirtualDevice(\"net_ring1\")\n+ ]\n+ \"\"\"\n+\n+ ports: list[Port] | None = field(\n+ default=None,\n+ metadata=params.field_mixins(_port_to_pci, metadata=params.multiple(params.short(\"a\"))),\n+ )\n+ \"\"\"The list of ports to allow.\"\"\"\n+\n+ other_eal_param: StrParams | None = None\n+ \"\"\"Any other EAL parameter(s).\"\"\"\n+\n+ app_params: Params | None = field(default=None, metadata=params.options_end())\n+ \"\"\"Parameters to pass to the underlying DPDK app.\"\"\"\n \n \n class SutNode(Node):\n@@ -350,7 +343,7 @@ def create_eal_parameters(\n ascending_cores: bool = True,\n prefix: str = \"dpdk\",\n append_prefix_timestamp: bool = True,\n- no_pci: bool = False,\n+ no_pci: params.Option = None,\n vdevs: list[VirtualDevice] | None = None,\n ports: list[Port] | None = None,\n other_eal_param: str = \"\",\n@@ -393,9 +386,6 @@ def create_eal_parameters(\n if prefix:\n self._dpdk_prefix_list.append(prefix)\n \n- if vdevs is None:\n- vdevs = []\n-\n if ports is None:\n ports = self.ports\n \n@@ -406,7 +396,7 @@ def create_eal_parameters(\n no_pci=no_pci,\n vdevs=vdevs,\n ports=ports,\n- other_eal_param=other_eal_param,\n+ other_eal_param=StrParams(other_eal_param),\n )\n \n def run_dpdk_app(\n@@ -442,7 +432,7 @@ def create_interactive_shell(\n shell_cls: Type[InteractiveShellType],\n timeout: float = SETTINGS.timeout,\n privileged: bool = False,\n- app_parameters: str = \"\",\n+ app_parameters: Params | None = None,\n eal_parameters: EalParameters | None = None,\n ) -> InteractiveShellType:\n \"\"\"Extend the factory for interactive session handlers.\n@@ -459,6 +449,7 @@ def create_interactive_shell(\n reading from the buffer and don't receive any data within the timeout\n it will throw an error.\n privileged: Whether to run the shell with administrative privileges.\n+ app_args: The arguments to be passed to the application.\n eal_parameters: List of EAL parameters to use to launch the app. If this\n isn't provided or an empty string is passed, it will default to calling\n :meth:`create_eal_parameters`.\n@@ -470,9 +461,10 @@ def create_interactive_shell(\n \"\"\"\n # We need to append the build directory and add EAL parameters for DPDK apps\n if shell_cls.dpdk_app:\n- if not eal_parameters:\n+ if eal_parameters is None:\n eal_parameters = self.create_eal_parameters()\n- app_parameters = f\"{eal_parameters} -- {app_parameters}\"\n+ eal_parameters.app_params = app_parameters\n+ app_parameters = eal_parameters\n \n shell_cls.path = self.main_session.join_remote_path(\n self.remote_dpdk_build_dir, shell_cls.path\ndiff --git a/dts/tests/TestSuite_pmd_buffer_scatter.py b/dts/tests/TestSuite_pmd_buffer_scatter.py\nindex 3701c47408..4cdbdc4272 100644\n--- a/dts/tests/TestSuite_pmd_buffer_scatter.py\n+++ b/dts/tests/TestSuite_pmd_buffer_scatter.py\n@@ -22,6 +22,7 @@\n from scapy.packet import Raw # type: ignore[import]\n from scapy.utils import hexstr # type: ignore[import]\n \n+from framework.params import StrParams\n from framework.remote_session.testpmd_shell import TestPmdForwardingModes, TestPmdShell\n from framework.test_suite import TestSuite\n \n@@ -103,7 +104,7 @@ def pmd_scatter(self, mbsize: int) -> None:\n \"\"\"\n testpmd = self.sut_node.create_interactive_shell(\n TestPmdShell,\n- app_parameters=(\n+ app_parameters=StrParams(\n \"--mbcache=200 \"\n f\"--mbuf-size={mbsize} \"\n \"--max-pkt-len=9000 \"\n", "prefixes": [ "2/6" ] }{ "id": 138828, "url": "