From: Nicholas Pratte <npratte@iol.unh.edu>
To: Luca Vizzarro <luca.vizzarro@arm.com>
Cc: dev@dpdk.org, Paul Szczepanek <paul.szczepanek@arm.com>,
Patrick Robb <probb@iol.unh.edu>
Subject: Re: [PATCH v2 7/7] dts: enable shell pooling
Date: Fri, 25 Apr 2025 14:50:08 -0400 [thread overview]
Message-ID: <CAKXZ7ehaZwJ2QG2QVCcCgBX6J5Vpfe_scp2RwM6YP218LYqidg@mail.gmail.com> (raw)
In-Reply-To: <20250314131857.1298247-8-luca.vizzarro@arm.com>
Reviewed-by: Nicholas Pratte <npratte@iol.unh.edu>
On Fri, Mar 14, 2025 at 9:19 AM Luca Vizzarro <luca.vizzarro@arm.com> wrote:
>
> Enable the ShellPool class to be used in the test run, and let
> InteractiveShells register themselves to the pool upon shell startup.
> Moreover, to avoid the ShellPool to call InteractiveShell.close more
> than once if the shell was not unregistered correctly, add a way to
> prevent the method to be called if the shell has already been closed.
>
> Signed-off-by: Luca Vizzarro <luca.vizzarro@arm.com>
> Reviewed-by: Paul Szczepanek <paul.szczepanek@arm.com>
> ---
> .../remote_session/interactive_shell.py | 24 ++++++++++++++++++-
> dts/framework/remote_session/python_shell.py | 3 ++-
> dts/framework/remote_session/testpmd_shell.py | 2 ++
> dts/framework/test_run.py | 5 ++++
> 4 files changed, 32 insertions(+), 2 deletions(-)
>
> diff --git a/dts/framework/remote_session/interactive_shell.py b/dts/framework/remote_session/interactive_shell.py
> index d7e566e5c4..ba8489eafa 100644
> --- a/dts/framework/remote_session/interactive_shell.py
> +++ b/dts/framework/remote_session/interactive_shell.py
> @@ -22,12 +22,14 @@
> """
>
> from abc import ABC, abstractmethod
> +from collections.abc import Callable
> from pathlib import PurePath
> -from typing import ClassVar
> +from typing import ClassVar, Concatenate, ParamSpec, TypeAlias, TypeVar
>
> from paramiko import Channel, channel
> from typing_extensions import Self
>
> +from framework.context import get_ctx
> from framework.exception import (
> InteractiveCommandExecutionError,
> InteractiveSSHSessionDeadError,
> @@ -38,6 +40,23 @@
> from framework.settings import SETTINGS
> from framework.testbed_model.node import Node
>
> +P = ParamSpec("P")
> +T = TypeVar("T", bound="InteractiveShell")
> +R = TypeVar("R")
> +InteractiveShellMethod = Callable[Concatenate[T, P], R]
> +InteractiveShellDecorator: TypeAlias = Callable[[InteractiveShellMethod], InteractiveShellMethod]
> +
> +
> +def only_active(func: InteractiveShellMethod) -> InteractiveShellMethod:
> + """This decorator will skip running the method if the SSH channel is not active."""
> +
> + def _wrapper(self: "InteractiveShell", *args: P.args, **kwargs: P.kwargs) -> R | None:
> + if self._ssh_channel.active:
> + return func(self, *args, **kwargs)
> + return None
> +
> + return _wrapper
> +
>
> class InteractiveShell(ABC):
> """The base class for managing interactive shells.
> @@ -155,6 +174,7 @@ def start_application(self, prompt: str | None = None) -> None:
> self.is_alive = False # update state on failure to start
> raise InteractiveCommandExecutionError("Failed to start application.")
> self._ssh_channel.settimeout(self._timeout)
> + get_ctx().shell_pool.register_shell(self)
>
> def send_command(
> self, command: str, prompt: str | None = None, skip_first_line: bool = False
> @@ -219,6 +239,7 @@ def send_command(
> self._logger.debug(f"Got output: {out}")
> return out
>
> + @only_active
> def close(self) -> None:
> """Close the shell.
>
> @@ -234,6 +255,7 @@ def close(self) -> None:
> self._logger.debug("Application failed to exit before set timeout.")
> raise InteractiveSSHTimeoutError("Application 'exit' command") from e
> self._ssh_channel.close()
> + get_ctx().shell_pool.unregister_shell(self)
>
> @property
> @abstractmethod
> diff --git a/dts/framework/remote_session/python_shell.py b/dts/framework/remote_session/python_shell.py
> index 6331d047c4..5b380a5c7a 100644
> --- a/dts/framework/remote_session/python_shell.py
> +++ b/dts/framework/remote_session/python_shell.py
> @@ -15,7 +15,7 @@
> from pathlib import PurePath
> from typing import ClassVar
>
> -from .interactive_shell import InteractiveShell
> +from .interactive_shell import InteractiveShell, only_active
>
>
> class PythonShell(InteractiveShell):
> @@ -32,6 +32,7 @@ def path(self) -> PurePath:
> """Path to the Python3 executable."""
> return PurePath("python3")
>
> + @only_active
> def close(self):
> """Close Python shell."""
> return super().close()
> diff --git a/dts/framework/remote_session/testpmd_shell.py b/dts/framework/remote_session/testpmd_shell.py
> index 19437b6233..b1939e4a51 100644
> --- a/dts/framework/remote_session/testpmd_shell.py
> +++ b/dts/framework/remote_session/testpmd_shell.py
> @@ -33,6 +33,7 @@
> )
>
> from framework.context import get_ctx
> +from framework.remote_session.interactive_shell import only_active
> from framework.testbed_model.topology import TopologyType
>
> if TYPE_CHECKING or environ.get("DTS_DOC_BUILD"):
> @@ -2314,6 +2315,7 @@ def rx_vxlan(self, vxlan_id: int, port_id: int, enable: bool, verify: bool = Tru
> self._logger.debug(f"Failed to set VXLAN:\n{vxlan_output}")
> raise InteractiveCommandExecutionError(f"Failed to set VXLAN:\n{vxlan_output}")
>
> + @only_active
> def close(self) -> None:
> """Overrides :meth:`~.interactive_shell.close`."""
> self.stop()
> diff --git a/dts/framework/test_run.py b/dts/framework/test_run.py
> index f9cfe5e908..7708fe31bd 100644
> --- a/dts/framework/test_run.py
> +++ b/dts/framework/test_run.py
> @@ -430,6 +430,7 @@ def description(self) -> str:
>
> def next(self) -> State | None:
> """Next state."""
> + self.test_run.ctx.shell_pool.terminate_current_pool()
> self.test_run.ctx.tg.teardown(self.test_run.ctx.topology.tg_ports)
> self.test_run.ctx.dpdk.teardown(self.test_run.ctx.topology.sut_ports)
> self.test_run.ctx.tg_node.teardown()
> @@ -473,6 +474,7 @@ def description(self) -> str:
>
> def next(self) -> State | None:
> """Next state."""
> + self.test_run.ctx.shell_pool.start_new_pool()
> self.test_suite.set_up_suite()
> self.result.update_setup(Result.PASS)
> return TestSuiteExecution(self.test_run, self.test_suite, self.result)
> @@ -544,6 +546,7 @@ def next(self) -> State | None:
> """Next state."""
> self.test_suite.tear_down_suite()
> self.test_run.ctx.dpdk.kill_cleanup_dpdk_apps()
> + self.test_run.ctx.shell_pool.terminate_current_pool()
> self.result.update_teardown(Result.PASS)
> return TestRunExecution(self.test_run, self.test_run.result)
>
> @@ -594,6 +597,7 @@ def description(self) -> str:
>
> def next(self) -> State | None:
> """Next state."""
> + self.test_run.ctx.shell_pool.start_new_pool()
> self.test_suite.set_up_test_case()
> self.result.update_setup(Result.PASS)
> return TestCaseExecution(
> @@ -670,6 +674,7 @@ def description(self) -> str:
> def next(self) -> State | None:
> """Next state."""
> self.test_suite.tear_down_test_case()
> + self.test_run.ctx.shell_pool.terminate_current_pool()
> self.result.update_teardown(Result.PASS)
> return TestSuiteExecution(self.test_run, self.test_suite, self.test_suite_result)
>
> --
> 2.43.0
>
next prev parent reply other threads:[~2025-04-25 18:50 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-20 17:23 [RFC PATCH 0/2] dts: add basic scope to improve shell handling Luca Vizzarro
2024-12-20 17:24 ` [RFC PATCH 1/2] dts: add scoping and shell registration to Node Luca Vizzarro
2024-12-20 17:24 ` [RFC PATCH 2/2] dts: revert back shell split Luca Vizzarro
2025-03-14 13:18 ` [PATCH v2 0/7] dts: shell improvements Luca Vizzarro
2025-03-14 13:18 ` [PATCH v2 1/7] dts: escape single quotes Luca Vizzarro
2025-04-24 17:55 ` Dean Marx
2025-04-25 2:20 ` Patrick Robb
2025-04-25 16:15 ` Nicholas Pratte
2025-03-14 13:18 ` [PATCH v2 2/7] dts: add blocking dpdk app class Luca Vizzarro
2025-04-24 18:01 ` Dean Marx
2025-04-25 2:38 ` Patrick Robb
2025-04-25 16:56 ` Nicholas Pratte
2025-03-14 13:18 ` [PATCH v2 3/7] dts: add shells pool Luca Vizzarro
2025-04-24 18:15 ` Dean Marx
2025-04-25 3:06 ` Patrick Robb
2025-03-14 13:18 ` [PATCH v2 4/7] dts: revert back to a single InteractiveShell Luca Vizzarro
2025-04-24 18:22 ` Dean Marx
2025-04-25 3:26 ` Patrick Robb
2025-04-25 18:17 ` Nicholas Pratte
2025-03-14 13:18 ` [PATCH v2 5/7] dts: make shells path dynamic Luca Vizzarro
2025-04-24 18:29 ` Dean Marx
2025-04-25 3:31 ` Patrick Robb
2025-04-25 18:35 ` Nicholas Pratte
2025-03-14 13:18 ` [PATCH v2 6/7] dts: remove multi-inheritance classes Luca Vizzarro
2025-04-24 18:36 ` Dean Marx
2025-04-25 3:36 ` Patrick Robb
2025-04-25 18:39 ` Nicholas Pratte
2025-03-14 13:18 ` [PATCH v2 7/7] dts: enable shell pooling Luca Vizzarro
2025-04-24 18:40 ` Dean Marx
2025-04-25 3:41 ` Patrick Robb
2025-04-25 18:50 ` Nicholas Pratte [this message]
2025-04-25 3:49 ` [PATCH v2 0/7] dts: shell improvements Patrick Robb
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=CAKXZ7ehaZwJ2QG2QVCcCgBX6J5Vpfe_scp2RwM6YP218LYqidg@mail.gmail.com \
--to=npratte@iol.unh.edu \
--cc=dev@dpdk.org \
--cc=luca.vizzarro@arm.com \
--cc=paul.szczepanek@arm.com \
--cc=probb@iol.unh.edu \
/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).