DPDK patches and discussions
 help / color / mirror / Atom feed
From: Luca Vizzarro <luca.vizzarro@arm.com>
To: dev@dpdk.org
Cc: "Honnappa Nagarahalli" <honnappa.nagarahalli@arm.com>,
	"Luca Vizzarro" <luca.vizzarro@arm.com>,
	"Paul Szczepanek" <paul.szczepanek@arm.com>,
	"Juraj Linkeš" <juraj.linkes@pantheon.tech>
Subject: [PATCH v3 4/5] dts: add ability to start/stop testpmd ports
Date: Mon,  9 Sep 2024 12:01:57 +0100	[thread overview]
Message-ID: <20240909110158.1009592-5-luca.vizzarro@arm.com> (raw)
In-Reply-To: <20240909110158.1009592-1-luca.vizzarro@arm.com>

Add testpmd commands to start and stop all the ports, so that they can
be configured. Because there is a distinction of commands that require
the ports to be stopped and started, also add decorators for commands
that require a specific state, removing this logic from the test
writer's duty.

Signed-off-by: Luca Vizzarro <luca.vizzarro@arm.com>
Reviewed-by: Paul Szczepanek <paul.szczepanek@arm.com>
---
 dts/framework/remote_session/testpmd_shell.py | 94 ++++++++++++++++++-
 1 file changed, 92 insertions(+), 2 deletions(-)

diff --git a/dts/framework/remote_session/testpmd_shell.py b/dts/framework/remote_session/testpmd_shell.py
index 43e9f56517..57501eae18 100644
--- a/dts/framework/remote_session/testpmd_shell.py
+++ b/dts/framework/remote_session/testpmd_shell.py
@@ -14,16 +14,17 @@
     testpmd_shell.close()
 """
 
+import functools
 import re
 import time
 from dataclasses import dataclass, field
 from enum import Flag, auto
 from pathlib import PurePath
-from typing import ClassVar
+from typing import Any, Callable, ClassVar, Concatenate, ParamSpec
 
 from typing_extensions import Self, Unpack
 
-from framework.exception import InteractiveCommandExecutionError
+from framework.exception import InteractiveCommandExecutionError, InternalError
 from framework.params.testpmd import SimpleForwardingModes, TestPmdParams
 from framework.params.types import TestPmdParamsDict
 from framework.parser import ParserFn, TextParser
@@ -33,6 +34,9 @@
 from framework.testbed_model.sut_node import SutNode
 from framework.utils import StrEnum
 
+P = ParamSpec("P")
+TestPmdShellMethod = Callable[Concatenate["TestPmdShell", P], Any]
+
 
 class TestPmdDevice:
     """The data of a device that testpmd can recognize.
@@ -577,12 +581,57 @@ class TestPmdPortStats(TextParser):
     tx_bps: int = field(metadata=TextParser.find_int(r"Tx-bps:\s+(\d+)"))
 
 
+def requires_stopped_ports(func: TestPmdShellMethod) -> TestPmdShellMethod:
+    """Decorator for :class:`TestPmdShell` commands methods that require stopped ports.
+
+    If the decorated method is called while the ports are started, then these are stopped before
+    continuing.
+
+    Args:
+        func: The :class:`TestPmdShell` method to decorate.
+    """
+
+    @functools.wraps(func)
+    def _wrapper(self: "TestPmdShell", *args: P.args, **kwargs: P.kwargs):
+        if self.ports_started:
+            self._logger.debug("Ports need to be stopped to continue")
+            self.stop_all_ports()
+
+        return func(self, *args, **kwargs)
+
+    return _wrapper
+
+
+def requires_started_ports(func: TestPmdShellMethod) -> TestPmdShellMethod:
+    """Decorator for :class:`TestPmdShell` commands methods that require started ports.
+
+    If the decorated method is called while the ports are stopped, then these are started before
+    continuing.
+
+    Args:
+        func: The :class:`TestPmdShell` method to decorate.
+    """
+
+    @functools.wraps(func)
+    def _wrapper(self: "TestPmdShell", *args: P.args, **kwargs: P.kwargs):
+        if not self.ports_started:
+            self._logger.debug("Ports need to be started to continue")
+            self.start_all_ports()
+
+        return func(self, *args, **kwargs)
+
+    return _wrapper
+
+
 class TestPmdShell(DPDKShell):
     """Testpmd interactive shell.
 
     The testpmd shell users should never use
     the :meth:`~.interactive_shell.InteractiveShell.send_command` method directly, but rather
     call specialized methods. If there isn't one that satisfies a need, it should be added.
+
+    Attributes:
+        ports_started: Indicates whether the ports are started.
     """
 
     _app_params: TestPmdParams
@@ -596,6 +645,8 @@ class TestPmdShell(DPDKShell):
     #: This forces the prompt to appear after sending a command.
     _command_extra_chars: ClassVar[str] = "\n"
 
+    ports_started: bool
+
     def __init__(
         self,
         node: SutNode,
@@ -619,6 +670,9 @@ def __init__(
             name,
         )
 
+        self.ports_started = not self._app_params.disable_device_start
+
+    @requires_started_ports
     def start(self, verify: bool = True) -> None:
         """Start packet forwarding with the current configuration.
 
@@ -723,6 +777,42 @@ def set_forward_mode(self, mode: SimpleForwardingModes, verify: bool = True):
                 f"Test pmd failed to set fwd mode to {mode.value}"
             )
 
+    def stop_all_ports(self, verify: bool = True) -> None:
+        """Stops all the ports.
+
+        Args:
+            verify: If :data:`True`, the output of the command will be checked for a successful
+                execution.
+
+        Raises:
+            InteractiveCommandExecutionError: If `verify` is :data:`True` and the ports were not
+                stopped successfully.
+        """
+        self._logger.debug("Stopping all the ports...")
+        output = self.send_command("port stop all")
+        if verify and not output.strip().endswith("Done"):
+            raise InteractiveCommandExecutionError("Ports were not stopped successfully")
+
+        self.ports_started = False
+
+    def start_all_ports(self, verify: bool = True) -> None:
+        """Starts all the ports.
+
+        Args:
+            verify: If :data:`True`, the output of the command will be checked for a successful
+                execution.
+
+        Raises:
+            InteractiveCommandExecutionError: If `verify` is :data:`True` and the ports were not
+                started successfully.
+        """
+        self._logger.debug("Starting all the ports...")
+        output = self.send_command("port start all")
+        if verify and not output.strip().endswith("Done"):
+            raise InteractiveCommandExecutionError("Ports were not started successfully")
+
+        self.ports_started = True
+
     def show_port_info_all(self) -> list[TestPmdPort]:
         """Returns the information of all the ports.
 
-- 
2.34.1


  parent reply	other threads:[~2024-09-09 11:04 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-06 12:14 [PATCH 0/4] dts: add pktgen and testpmd changes Luca Vizzarro
2024-08-06 12:14 ` [PATCH 1/5] dts: add ability to send/receive multiple packets Luca Vizzarro
2024-08-06 12:14 ` [PATCH 2/5] dts: add random generation seed setting Luca Vizzarro
2024-08-06 12:14 ` [PATCH 3/5] dts: add random packet generator Luca Vizzarro
2024-08-06 12:14 ` [PATCH 4/5] dts: add ability to start/stop ports Luca Vizzarro
2024-08-06 12:14 ` [PATCH 4/5] dts: add ability to start/stop testpmd ports Luca Vizzarro
2024-08-06 12:14 ` [PATCH 5/5] dts: add testpmd set ports queues Luca Vizzarro
2024-08-06 12:46 ` [PATCH v2 0/5] dts: add pktgen and testpmd changes Luca Vizzarro
2024-08-06 12:46   ` [PATCH v2 1/5] dts: add ability to send/receive multiple packets Luca Vizzarro
2024-08-09 15:10     ` Jeremy Spewock
2024-09-06 16:23       ` Luca Vizzarro
2024-09-09 14:12         ` Jeremy Spewock
2024-08-23 10:17     ` Juraj Linkeš
2024-09-06 16:30       ` Luca Vizzarro
2024-08-06 12:46   ` [PATCH v2 2/5] dts: add random generation seed setting Luca Vizzarro
2024-08-09 15:10     ` Jeremy Spewock
2024-08-23 10:30     ` Juraj Linkeš
2024-08-06 12:46   ` [PATCH v2 3/5] dts: add random packet generator Luca Vizzarro
2024-08-09 15:11     ` Jeremy Spewock
2024-08-23 11:58     ` Juraj Linkeš
2024-09-06 16:31       ` Luca Vizzarro
2024-08-06 12:46   ` [PATCH v2 4/5] dts: add ability to start/stop testpmd ports Luca Vizzarro
2024-08-09 15:13     ` Jeremy Spewock
2024-09-06 16:41       ` Luca Vizzarro
2024-08-23 12:16     ` Juraj Linkeš
2024-09-06 16:46       ` Luca Vizzarro
2024-09-09  7:32         ` Juraj Linkeš
2024-09-09 14:20         ` Jeremy Spewock
2024-09-09 15:16           ` Juraj Linkeš
2024-08-06 12:46   ` [PATCH v2 5/5] dts: add testpmd set ports queues Luca Vizzarro
2024-08-09 15:14     ` Jeremy Spewock
2024-08-20 16:04       ` Jeremy Spewock
2024-09-06 16:51       ` Luca Vizzarro
2024-08-23 12:22     ` Juraj Linkeš
2024-09-06 16:53       ` Luca Vizzarro
2024-09-09 11:01 ` [PATCH v3 0/5] dts: add pktgen and testpmd changes Luca Vizzarro
2024-09-09 11:01   ` [PATCH v3 1/5] dts: add ability to send/receive multiple packets Luca Vizzarro
2024-09-09 17:12     ` Patrick Robb
2024-09-09 11:01   ` [PATCH v3 2/5] dts: add random generation seed setting Luca Vizzarro
2024-09-09 11:01   ` [PATCH v3 3/5] dts: add random packet generator Luca Vizzarro
2024-09-09 11:01   ` Luca Vizzarro [this message]
2024-09-09 11:54     ` [PATCH v3 4/5] dts: add ability to start/stop testpmd ports Juraj Linkeš
2024-09-09 14:20     ` Jeremy Spewock
2024-09-09 11:01   ` [PATCH v3 5/5] dts: add testpmd set ports queues Luca Vizzarro
2024-09-09 12:01     ` Juraj Linkeš
2024-09-09 14:20     ` Jeremy Spewock
2024-09-09 15:50 ` [PATCH 0/4] dts: add pktgen and testpmd changes Juraj Linkeš

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240909110158.1009592-5-luca.vizzarro@arm.com \
    --to=luca.vizzarro@arm.com \
    --cc=dev@dpdk.org \
    --cc=honnappa.nagarahalli@arm.com \
    --cc=juraj.linkes@pantheon.tech \
    --cc=paul.szczepanek@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).