From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 35C814265D; Thu, 28 Sep 2023 09:27:32 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C759B40296; Thu, 28 Sep 2023 09:27:31 +0200 (CEST) Received: from mail-ed1-f49.google.com (mail-ed1-f49.google.com [209.85.208.49]) by mails.dpdk.org (Postfix) with ESMTP id 6DBE940273 for ; Thu, 28 Sep 2023 09:27:29 +0200 (CEST) Received: by mail-ed1-f49.google.com with SMTP id 4fb4d7f45d1cf-5310a63cf7bso14955952a12.1 for ; Thu, 28 Sep 2023 00:27:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pantheon.tech; s=google; t=1695886049; x=1696490849; darn=dpdk.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=j65qQJjX9cqjBCVTwFxvs4OC6yLOX4+NAtW/Z3ohMN0=; b=TGIrmMIiLO+9xDaxEdSNHLXnEmAOW53jfoe3keFd1wv+lPNZEf4+cufNFNzvTvV9qo TxKDDSiDLiEthg8BdgDZIWoHmYO2wLNdZ6x1CFpq4Je1kLQgWPgdElXwNXuk26g81/Y7 3YPOIIQ21GUAcA3NZO92+AqOCoROM0X+FyfmkNy4H1FujkCLMBhK1UBFZQN4TLq4W+I/ qNdLWo04+NQ9Dcs/LEb9fbwh86fLGOStwLiC18E5DOrrToOYcHE3Z/58WWgf+2DoGIai T9tbgAc4xJGdxykZcY4BLgmazTnQwZdxleHx2eANf+biRW1Pk9JEkfq5l4soO5LOYLF5 Fpvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695886049; x=1696490849; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=j65qQJjX9cqjBCVTwFxvs4OC6yLOX4+NAtW/Z3ohMN0=; b=KEhH0sjJiFxvwOc3JF0tsY2MOVV9FOVVKRfdgOOCWFaOGtZa4STLKPO9L9Q2Y2jks6 RMHMjNoCqt/n9wEtZDqT6cHS7pDP5OilSdmPLCnf9fu/HWVYumeWq46/fGcWQ+9dZvZY nH0TD0iBJIUG49qD8jLX9DJZ8dIA/cTWRQHeOCPNKEkCm6ysXa5ewPkitkqKsWyEeadJ q5ogGGIpOnjQDPI21fxQdLHOhCKdU+Rp3a+wacvePQEN7OUYaXgPpiUzsg4RUOEhDo1b 0zq1TBp5hPDQ7Jf5+tZJP4dOhC14EsQXWjd8kbzIqpZ8KrggZHV3g3UgWJUA+CMrvxl3 ak5A== X-Gm-Message-State: AOJu0YwDLlQ9cDAuW8K217sCORPWV8WpyftufNGXFr9Xgt44CbZ7nmtC ZVP8zk37ASwzub05XWOFcr9+qCSrXrDF4Ap4B43gxg== X-Google-Smtp-Source: AGHT+IF1xQR3AykAfZazaWlvZxRgtha8P8h/Q2IXBKbdzRGxu4oVkIPmTji0ekRdngkSy5RtpibfUsOY6QjY6z7MYgw= X-Received: by 2002:a05:6402:8d8:b0:523:100b:462b with SMTP id d24-20020a05640208d800b00523100b462bmr499453edz.5.1695886048740; Thu, 28 Sep 2023 00:27:28 -0700 (PDT) MIME-Version: 1.0 References: <20221103132926.445627-3-juraj.linkes@pantheon.tech> <20230926121013.23351-1-juraj.linkes@pantheon.tech> <20230926121013.23351-2-juraj.linkes@pantheon.tech> In-Reply-To: From: =?UTF-8?Q?Juraj_Linke=C5=A1?= Date: Thu, 28 Sep 2023 09:27:17 +0200 Message-ID: Subject: Re: [PATCH v2 2/2] dts: reformat to 100 line length To: Jeremy Spewock Cc: thomas@monjalon.net, Honnappa.Nagarahalli@arm.com, bruce.richardson@intel.com, probb@iol.unh.edu, stephen@networkplumber.org, dev@dpdk.org Content-Type: multipart/alternative; boundary="00000000000083dea00606663dde" X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --00000000000083dea00606663dde Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Thanks, Jeremy. I skimmed the changes before submitting them, but I didn't catch this. I'll submit a new version. On Tue, Sep 26, 2023 at 11:52=E2=80=AFPM Jeremy Spewock wrote: > > > I think this is a good idea because of all the weird places we had to > break things up with the 88 character cap. I do however also notice that = in > some cases where these multi-line strings were combined back into one lin= e > it would just have two string literals on the same line rather than them > being just oen string. I tried to point out everywhere I found this > behavoir below as it looks a little awkward in the code. > > It looks good to me otherwise though. > > > On Tue, Sep 26, 2023 at 8:10=E2=80=AFAM Juraj Linke=C5=A1 > wrote: > >> Reformat to 100 from the previous 88 to unify with C recommendations. >> >> Signed-off-by: Juraj Linke=C5=A1 >> --- >> dts/framework/config/__init__.py | 20 ++----- >> dts/framework/dts.py | 12 +--- >> dts/framework/exception.py | 3 +- >> dts/framework/remote_session/__init__.py | 4 +- >> dts/framework/remote_session/linux_session.py | 39 ++++--------- >> dts/framework/remote_session/posix_session.py | 30 +++------- >> .../remote/interactive_remote_session.py | 7 +-- >> .../remote/interactive_shell.py | 4 +- >> .../remote_session/remote/remote_session.py | 8 +-- >> .../remote_session/remote/ssh_session.py | 16 ++---- >> .../remote_session/remote/testpmd_shell.py | 8 +-- >> dts/framework/settings.py | 4 +- >> dts/framework/test_result.py | 16 ++---- >> dts/framework/test_suite.py | 57 +++++-------------- >> .../capturing_traffic_generator.py | 4 +- >> dts/framework/testbed_model/hw/cpu.py | 20 ++----- >> dts/framework/testbed_model/node.py | 8 +-- >> dts/framework/testbed_model/scapy.py | 16 ++---- >> dts/framework/testbed_model/sut_node.py | 38 ++++--------- >> dts/framework/testbed_model/tg_node.py | 7 +-- >> dts/framework/utils.py | 20 ++----- >> dts/pyproject.toml | 4 +- >> dts/tests/TestSuite_hello_world.py | 4 +- >> dts/tests/TestSuite_smoke_tests.py | 11 +--- >> 24 files changed, 93 insertions(+), 267 deletions(-) >> >> diff --git a/dts/framework/config/__init__.py >> b/dts/framework/config/__init__.py >> index cb7e00ba34..9b32cf0532 100644 >> --- a/dts/framework/config/__init__.py >> +++ b/dts/framework/config/__init__.py >> @@ -140,9 +140,7 @@ def from_dict(d: dict) -> >> Union["SutNodeConfiguration", "TGNodeConfiguration"]: >> >> if "traffic_generator" in d: >> return TGNodeConfiguration( >> - traffic_generator=3DTrafficGeneratorConfig.from_dict( >> - d["traffic_generator"] >> - ), >> + >> traffic_generator=3DTrafficGeneratorConfig.from_dict(d["traffic_generato= r"]), >> **common_config, >> ) >> else: >> @@ -249,9 +247,7 @@ def from_dict( >> build_targets: list[BuildTargetConfiguration] =3D list( >> map(BuildTargetConfiguration.from_dict, d["build_targets"]) >> ) >> - test_suites: list[TestSuiteConfig] =3D list( >> - map(TestSuiteConfig.from_dict, d["test_suites"]) >> - ) >> + test_suites: list[TestSuiteConfig] =3D >> list(map(TestSuiteConfig.from_dict, d["test_suites"])) >> sut_name =3D d["system_under_test_node"]["node_name"] >> skip_smoke_tests =3D d.get("skip_smoke_tests", False) >> assert sut_name in node_map, f"Unknown SUT {sut_name} in >> execution {d}" >> @@ -268,9 +264,7 @@ def from_dict( >> ), f"Invalid TG configuration {traffic_generator_node}" >> >> vdevs =3D ( >> - d["system_under_test_node"]["vdevs"] >> - if "vdevs" in d["system_under_test_node"] >> - else [] >> + d["system_under_test_node"]["vdevs"] if "vdevs" in >> d["system_under_test_node"] else [] >> ) >> return ExecutionConfiguration( >> build_targets=3Dbuild_targets, >> @@ -299,9 +293,7 @@ def from_dict(d: dict) -> "Configuration": >> assert len(nodes) =3D=3D len(node_map), "Duplicate node names a= re >> not allowed" >> >> executions: list[ExecutionConfiguration] =3D list( >> - map( >> - ExecutionConfiguration.from_dict, d["executions"], >> [node_map for _ in d] >> - ) >> + map(ExecutionConfiguration.from_dict, d["executions"], >> [node_map for _ in d]) >> ) >> >> return Configuration(executions=3Dexecutions) >> @@ -315,9 +307,7 @@ def load_config() -> Configuration: >> with open(SETTINGS.config_file_path, "r") as f: >> config_data =3D yaml.safe_load(f) >> >> - schema_path =3D os.path.join( >> - pathlib.Path(__file__).parent.resolve(), "conf_yaml_schema.json= " >> - ) >> + schema_path =3D os.path.join(pathlib.Path(__file__).parent.resolve(= ), >> "conf_yaml_schema.json") >> >> with open(schema_path, "r") as f: >> schema =3D json.load(f) >> diff --git a/dts/framework/dts.py b/dts/framework/dts.py >> index f773f0c38d..e2aada5a23 100644 >> --- a/dts/framework/dts.py >> +++ b/dts/framework/dts.py >> @@ -92,9 +92,7 @@ def _run_execution( >> Run the given execution. This involves running the execution setup >> as well as >> running all build targets in the given execution. >> """ >> - dts_logger.info( >> - f"Running execution with SUT '{ >> execution.system_under_test_node.name}'." >> - ) >> + dts_logger.info(f"Running execution with SUT '{ >> execution.system_under_test_node.name}'.") >> execution_result =3D result.add_execution(sut_node.config) >> execution_result.add_sut_info(sut_node.node_info) >> >> @@ -107,9 +105,7 @@ def _run_execution( >> >> else: >> for build_target in execution.build_targets: >> - _run_build_target( >> - sut_node, tg_node, build_target, execution, >> execution_result >> - ) >> + _run_build_target(sut_node, tg_node, build_target, >> execution, execution_result) >> >> finally: >> try: >> @@ -170,9 +166,7 @@ def _run_all_suites( >> execution.test_suites[:0] =3D >> [TestSuiteConfig.from_dict("smoke_tests")] >> for test_suite_config in execution.test_suites: >> try: >> - _run_single_suite( >> - sut_node, tg_node, execution, build_target_result, >> test_suite_config >> - ) >> + _run_single_suite(sut_node, tg_node, execution, >> build_target_result, test_suite_config) >> except BlockingTestSuiteError as e: >> dts_logger.exception( >> f"An error occurred within >> {test_suite_config.test_suite}. " >> diff --git a/dts/framework/exception.py b/dts/framework/exception.py >> index 001a5a5496..59cf9fd12a 100644 >> --- a/dts/framework/exception.py >> +++ b/dts/framework/exception.py >> @@ -117,8 +117,7 @@ def __init__(self, command: str, command_return_code= : >> int): >> >> def __str__(self) -> str: >> return ( >> - f"Command {self.command} returned a non-zero exit code: " >> - f"{self.command_return_code}" >> + f"Command {self.command} returned a non-zero exit code: " >> f"{self.command_return_code}" >> > > If you modify this to be on the same line you actually don't need the > separate string on this line. The line could instead be the following: > > f"Command {self.command} returned a non-zero exit code: > {self.command_return_code}" > > >> ) >> >> >> diff --git a/dts/framework/remote_session/__init__.py >> b/dts/framework/remote_session/__init__.py >> index 00b6d1f03a..6124417bd7 100644 >> --- a/dts/framework/remote_session/__init__.py >> +++ b/dts/framework/remote_session/__init__.py >> @@ -30,9 +30,7 @@ >> ) >> >> >> -def create_session( >> - node_config: NodeConfiguration, name: str, logger: DTSLOG >> -) -> OSSession: >> +def create_session(node_config: NodeConfiguration, name: str, logger: >> DTSLOG) -> OSSession: >> match node_config.os: >> case OS.linux: >> return LinuxSession(node_config, name, logger) >> diff --git a/dts/framework/remote_session/linux_session.py >> b/dts/framework/remote_session/linux_session.py >> index a3f1a6bf3b..aa76e25436 100644 >> --- a/dts/framework/remote_session/linux_session.py >> +++ b/dts/framework/remote_session/linux_session.py >> @@ -82,9 +82,7 @@ def setup_hugepages(self, hugepage_amount: int, >> force_first_numa: bool) -> None: >> self._mount_huge_pages() >> >> def _get_hugepage_size(self) -> int: >> - hugepage_size =3D self.send_command( >> - "awk '/Hugepagesize/ {print $2}' /proc/meminfo" >> - ).stdout >> + hugepage_size =3D self.send_command("awk '/Hugepagesize/ {print >> $2}' /proc/meminfo").stdout >> return int(hugepage_size) >> >> def _get_hugepages_total(self) -> int: >> @@ -120,13 +118,9 @@ def _supports_numa(self) -> bool: >> # there's no reason to do any numa specific configuration) >> return len(self._numa_nodes) > 1 >> >> - def _configure_huge_pages( >> - self, amount: int, size: int, force_first_numa: bool >> - ) -> None: >> + def _configure_huge_pages(self, amount: int, size: int, >> force_first_numa: bool) -> None: >> self._logger.info("Configuring Hugepages.") >> - hugepage_config_path =3D ( >> - f"/sys/kernel/mm/hugepages/hugepages-{size}kB/nr_hugepages" >> - ) >> + hugepage_config_path =3D >> f"/sys/kernel/mm/hugepages/hugepages-{size}kB/nr_hugepages" >> if force_first_numa and self._supports_numa(): >> # clear non-numa hugepages >> self.send_command(f"echo 0 | tee {hugepage_config_path}", >> privileged=3DTrue) >> @@ -135,24 +129,18 @@ def _configure_huge_pages( >> f"/hugepages-{size}kB/nr_hugepages" >> ) >> >> - self.send_command( >> - f"echo {amount} | tee {hugepage_config_path}", >> privileged=3DTrue >> - ) >> + self.send_command(f"echo {amount} | tee {hugepage_config_path}"= , >> privileged=3DTrue) >> >> def update_ports(self, ports: list[Port]) -> None: >> self._logger.debug("Gathering port info.") >> for port in ports: >> - assert ( >> - port.node =3D=3D self.name >> - ), "Attempted to gather port info on the wrong node" >> + assert port.node =3D=3D self.name, "Attempted to gather por= t >> info on the wrong node" >> >> port_info_list =3D self._get_lshw_info() >> for port in ports: >> for port_info in port_info_list: >> if f"pci@{port.pci}" =3D=3D port_info.get("businfo"): >> - self._update_port_attr( >> - port, port_info.get("logicalname"), >> "logical_name" >> - ) >> + self._update_port_attr(port, >> port_info.get("logicalname"), "logical_name") >> self._update_port_attr(port, >> port_info.get("serial"), "mac_address") >> port_info_list.remove(port_info) >> break >> @@ -163,25 +151,18 @@ def _get_lshw_info(self) -> list[LshwOutput]: >> output =3D self.send_command("lshw -quiet -json -C network", >> verify=3DTrue) >> return json.loads(output.stdout) >> >> - def _update_port_attr( >> - self, port: Port, attr_value: str | None, attr_name: str >> - ) -> None: >> + def _update_port_attr(self, port: Port, attr_value: str | None, >> attr_name: str) -> None: >> if attr_value: >> setattr(port, attr_name, attr_value) >> - self._logger.debug( >> - f"Found '{attr_name}' of port {port.pci}: >> '{attr_value}'." >> - ) >> + self._logger.debug(f"Found '{attr_name}' of port {port.pci}= : >> '{attr_value}'.") >> else: >> self._logger.warning( >> - f"Attempted to get '{attr_name}' of port {port.pci}, " >> - f"but it doesn't exist." >> + f"Attempted to get '{attr_name}' of port {port.pci}, " >> f"but it doesn't exist." >> > > This is another case where the two different strings aren't needed > > >> ) >> >> def configure_port_state(self, port: Port, enable: bool) -> None: >> state =3D "up" if enable else "down" >> - self.send_command( >> - f"ip link set dev {port.logical_name} {state}", >> privileged=3DTrue >> - ) >> + self.send_command(f"ip link set dev {port.logical_name} >> {state}", privileged=3DTrue) >> >> def configure_port_ip_address( >> self, >> diff --git a/dts/framework/remote_session/posix_session.py >> b/dts/framework/remote_session/posix_session.py >> index 5da0516e05..eb59252dd1 100644 >> --- a/dts/framework/remote_session/posix_session.py >> +++ b/dts/framework/remote_session/posix_session.py >> @@ -94,8 +94,7 @@ def extract_remote_tarball( >> expected_dir: str | PurePath | None =3D None, >> ) -> None: >> self.send_command( >> - f"tar xfm {remote_tarball_path} " >> - f"-C {PurePosixPath(remote_tarball_path).parent}", >> + f"tar xfm {remote_tarball_path} " f"-C >> {PurePosixPath(remote_tarball_path).parent}", >> > > Double string here as well. > > >> 60, >> ) >> if expected_dir: >> @@ -125,8 +124,7 @@ def build_dpdk( >> self._logger.info("Configuring DPDK build from >> scratch.") >> self.remove_remote_dir(remote_dpdk_build_dir) >> self.send_command( >> - f"meson setup " >> - f"{meson_args} {remote_dpdk_dir} >> {remote_dpdk_build_dir}", >> + f"meson setup " f"{meson_args} {remote_dpdk_dir} >> {remote_dpdk_build_dir}", >> > > Double string. > > >> timeout, >> verify=3DTrue, >> env=3Denv_vars, >> @@ -140,9 +138,7 @@ def build_dpdk( >> raise DPDKBuildError(f"DPDK build failed when doing >> '{e.command}'.") >> >> def get_dpdk_version(self, build_dir: str | PurePath) -> str: >> - out =3D self.send_command( >> - f"cat {self.join_remote_path(build_dir, 'VERSION')}", >> verify=3DTrue >> - ) >> + out =3D self.send_command(f"cat {self.join_remote_path(build_di= r, >> 'VERSION')}", verify=3DTrue) >> return out.stdout >> >> def kill_cleanup_dpdk_apps(self, dpdk_prefix_list: Iterable[str]) -= > >> None: >> @@ -156,9 +152,7 @@ def kill_cleanup_dpdk_apps(self, dpdk_prefix_list: >> Iterable[str]) -> None: >> self._check_dpdk_hugepages(dpdk_runtime_dirs) >> self._remove_dpdk_runtime_dirs(dpdk_runtime_dirs) >> >> - def _get_dpdk_runtime_dirs( >> - self, dpdk_prefix_list: Iterable[str] >> - ) -> list[PurePosixPath]: >> + def _get_dpdk_runtime_dirs(self, dpdk_prefix_list: Iterable[str]) -= > >> list[PurePosixPath]: >> prefix =3D PurePosixPath("/var", "run", "dpdk") >> if not dpdk_prefix_list: >> remote_prefixes =3D self._list_remote_dirs(prefix) >> @@ -174,9 +168,7 @@ def _list_remote_dirs(self, remote_path: str | >> PurePath) -> list[str] | None: >> Return a list of directories of the remote_dir. >> If remote_path doesn't exist, return None. >> """ >> - out =3D self.send_command( >> - f"ls -l {remote_path} | awk '/^d/ {{print $NF}}'" >> - ).stdout >> + out =3D self.send_command(f"ls -l {remote_path} | awk '/^d/ >> {{print $NF}}'").stdout >> if "No such file or directory" in out: >> return None >> else: >> @@ -200,9 +192,7 @@ def _remote_files_exists(self, remote_path: PurePath= ) >> -> bool: >> result =3D self.send_command(f"test -e {remote_path}") >> return not result.return_code >> >> - def _check_dpdk_hugepages( >> - self, dpdk_runtime_dirs: Iterable[str | PurePath] >> - ) -> None: >> + def _check_dpdk_hugepages(self, dpdk_runtime_dirs: Iterable[str | >> PurePath]) -> None: >> for dpdk_runtime_dir in dpdk_runtime_dirs: >> hugepage_info =3D PurePosixPath(dpdk_runtime_dir, >> "hugepage_info") >> if self._remote_files_exists(hugepage_info): >> @@ -213,9 +203,7 @@ def _check_dpdk_hugepages( >> self._logger.warning(out) >> >> self._logger.warning("*******************************************") >> >> - def _remove_dpdk_runtime_dirs( >> - self, dpdk_runtime_dirs: Iterable[str | PurePath] >> - ) -> None: >> + def _remove_dpdk_runtime_dirs(self, dpdk_runtime_dirs: Iterable[str >> | PurePath]) -> None: >> for dpdk_runtime_dir in dpdk_runtime_dirs: >> self.remove_remote_dir(dpdk_runtime_dir) >> >> @@ -245,6 +233,4 @@ def get_node_info(self) -> NodeInfo: >> SETTINGS.timeout, >> ).stdout.split("\n") >> kernel_version =3D self.send_command("uname -r", >> SETTINGS.timeout).stdout >> - return NodeInfo( >> - os_release_info[0].strip(), os_release_info[1].strip(), >> kernel_version >> - ) >> + return NodeInfo(os_release_info[0].strip(), >> os_release_info[1].strip(), kernel_version) >> diff --git >> a/dts/framework/remote_session/remote/interactive_remote_session.py >> b/dts/framework/remote_session/remote/interactive_remote_session.py >> index 9085a668e8..42c99b2525 100644 >> --- a/dts/framework/remote_session/remote/interactive_remote_session.py >> +++ b/dts/framework/remote_session/remote/interactive_remote_session.py >> @@ -73,9 +73,7 @@ def __init__(self, node_config: NodeConfiguration, >> _logger: DTSLOG) -> None: >> f"Initializing interactive connection for {self.username}@ >> {self.hostname}" >> ) >> self._connect() >> - self._logger.info( >> - f"Interactive connection successful for {self.username}@ >> {self.hostname}" >> - ) >> + self._logger.info(f"Interactive connection successful for >> {self.username}@{self.hostname}") >> >> def _connect(self) -> None: >> """Establish a connection to the node. >> @@ -108,8 +106,7 @@ def _connect(self) -> None: >> self._logger.debug(traceback.format_exc()) >> self._logger.warning(e) >> self._logger.info( >> - "Retrying interactive session connection: " >> - f"retry number {retry_attempt +1}" >> + "Retrying interactive session connection: " f"retry >> number {retry_attempt +1}" >> > > Here you can get rid of the double string, but you would have to make sur= e > to add the f to the start to make the whole thing and f-string. > > >> ) >> else: >> break >> diff --git a/dts/framework/remote_session/remote/interactive_shell.py >> b/dts/framework/remote_session/remote/interactive_shell.py >> index c24376b2a8..4db19fb9b3 100644 >> --- a/dts/framework/remote_session/remote/interactive_shell.py >> +++ b/dts/framework/remote_session/remote/interactive_shell.py >> @@ -85,9 +85,7 @@ def __init__( >> self._app_args =3D app_args >> self._start_application(get_privileged_command) >> >> - def _start_application( >> - self, get_privileged_command: Callable[[str], str] | None >> - ) -> None: >> + def _start_application(self, get_privileged_command: Callable[[str]= , >> str] | None) -> None: >> """Starts a new interactive application based on the path to th= e >> app. >> >> This method is often overridden by subclasses as their process >> for >> diff --git a/dts/framework/remote_session/remote/remote_session.py >> b/dts/framework/remote_session/remote/remote_session.py >> index 0647d93de4..719f7d1ef7 100644 >> --- a/dts/framework/remote_session/remote/remote_session.py >> +++ b/dts/framework/remote_session/remote/remote_session.py >> @@ -96,9 +96,7 @@ def send_command( >> If verify is True, check the return code of the executed comman= d >> and raise a RemoteCommandExecutionError if the command failed. >> """ >> - self._logger.info( >> - f"Sending: '{command}'" + (f" with env vars: '{env}'" if en= v >> else "") >> - ) >> + self._logger.info(f"Sending: '{command}'" + (f" with env vars: >> '{env}'" if env else "")) >> result =3D self._send_command(command, timeout, env) >> if verify and result.return_code: >> self._logger.debug( >> @@ -112,9 +110,7 @@ def send_command( >> return result >> >> @abstractmethod >> - def _send_command( >> - self, command: str, timeout: float, env: dict | None >> - ) -> CommandResult: >> + def _send_command(self, command: str, timeout: float, env: dict | >> None) -> CommandResult: >> """ >> Use the underlying protocol to execute the command using >> optional env vars >> and return CommandResult. >> diff --git a/dts/framework/remote_session/remote/ssh_session.py >> b/dts/framework/remote_session/remote/ssh_session.py >> index 8d127f1601..1a7ee649ab 100644 >> --- a/dts/framework/remote_session/remote/ssh_session.py >> +++ b/dts/framework/remote_session/remote/ssh_session.py >> @@ -80,9 +80,7 @@ def _connect(self) -> None: >> if error not in errors: >> errors.append(error) >> >> - self._logger.info( >> - f"Retrying connection: retry number {retry_attempt = + >> 1}." >> - ) >> + self._logger.info(f"Retrying connection: retry number >> {retry_attempt + 1}.") >> >> else: >> break >> @@ -92,9 +90,7 @@ def _connect(self) -> None: >> def is_alive(self) -> bool: >> return self.session.is_connected >> >> - def _send_command( >> - self, command: str, timeout: float, env: dict | None >> - ) -> CommandResult: >> + def _send_command(self, command: str, timeout: float, env: dict | >> None) -> CommandResult: >> """Send a command and return the result of the execution. >> >> Args: >> @@ -107,9 +103,7 @@ def _send_command( >> SSHTimeoutError: The command execution timed out. >> """ >> try: >> - output =3D self.session.run( >> - command, env=3Denv, warn=3DTrue, hide=3DTrue, timeout= =3Dtimeout >> - ) >> + output =3D self.session.run(command, env=3Denv, warn=3DTrue= , >> hide=3DTrue, timeout=3Dtimeout) >> >> except (UnexpectedExit, ThreadException) as e: >> self._logger.exception(e) >> @@ -119,9 +113,7 @@ def _send_command( >> self._logger.exception(e) >> raise SSHTimeoutError(command, e.result.stderr) from e >> >> - return CommandResult( >> - self.name, command, output.stdout, output.stderr, >> output.return_code >> - ) >> + return CommandResult(self.name, command, output.stdout, >> output.stderr, output.return_code) >> >> def copy_from( >> self, >> diff --git a/dts/framework/remote_session/remote/testpmd_shell.py >> b/dts/framework/remote_session/remote/testpmd_shell.py >> index 1455b5a199..08ac311016 100644 >> --- a/dts/framework/remote_session/remote/testpmd_shell.py >> +++ b/dts/framework/remote_session/remote/testpmd_shell.py >> @@ -21,13 +21,9 @@ class TestPmdShell(InteractiveShell): >> path: PurePath =3D PurePath("app", "dpdk-testpmd") >> dpdk_app: bool =3D True >> _default_prompt: str =3D "testpmd>" >> - _command_extra_chars: str =3D ( >> - "\n" # We want to append an extra newline to every command >> - ) >> + _command_extra_chars: str =3D "\n" # We want to append an extra >> newline to every command >> >> - def _start_application( >> - self, get_privileged_command: Callable[[str], str] | None >> - ) -> None: >> + def _start_application(self, get_privileged_command: Callable[[str]= , >> str] | None) -> None: >> """See "_start_application" in InteractiveShell.""" >> self._app_args +=3D " -- -i" >> super()._start_application(get_privileged_command) >> diff --git a/dts/framework/settings.py b/dts/framework/settings.py >> index cfa39d011b..aad444e99c 100644 >> --- a/dts/framework/settings.py >> +++ b/dts/framework/settings.py >> @@ -170,9 +170,7 @@ def _get_settings() -> _Settings: >> timeout=3Dparsed_args.timeout, >> verbose=3D(parsed_args.verbose =3D=3D "Y"), >> skip_setup=3D(parsed_args.skip_setup =3D=3D "Y"), >> - dpdk_tarball_path=3DPath( >> - DPDKGitTarball(parsed_args.tarball, parsed_args.output_dir) >> - ) >> + dpdk_tarball_path=3DPath(DPDKGitTarball(parsed_args.tarball, >> parsed_args.output_dir)) >> if not os.path.exists(parsed_args.tarball) >> else Path(parsed_args.tarball), >> compile_timeout=3Dparsed_args.compile_timeout, >> diff --git a/dts/framework/test_result.py b/dts/framework/test_result.py >> index f0fbe80f6f..4c2e7e2418 100644 >> --- a/dts/framework/test_result.py >> +++ b/dts/framework/test_result.py >> @@ -83,9 +83,7 @@ def __iadd__(self, other: Result) -> "Statistics": >> """ >> self[other.name] +=3D 1 >> self["PASS RATE"] =3D ( >> - float(self[Result.PASS.name]) >> - * 100 >> - / sum(self[result.name] for result in Result) >> + float(self[Result.PASS.name]) * 100 / sum(self[result.name] >> for result in Result) >> ) >> return self >> >> @@ -135,9 +133,7 @@ def _get_setup_teardown_errors(self) -> >> list[Exception]: >> >> def _get_inner_errors(self) -> list[Exception]: >> return [ >> - error >> - for inner_result in self._inner_results >> - for error in inner_result.get_errors() >> + error for inner_result in self._inner_results for error in >> inner_result.get_errors() >> ] >> >> def get_errors(self) -> list[Exception]: >> @@ -174,9 +170,7 @@ def add_stats(self, statistics: Statistics) -> None: >> statistics +=3D self.result >> >> def __bool__(self) -> bool: >> - return ( >> - bool(self.setup_result) and bool(self.teardown_result) and >> bool(self.result) >> - ) >> + return bool(self.setup_result) and bool(self.teardown_result) >> and bool(self.result) >> >> >> class TestSuiteResult(BaseResult): >> @@ -247,9 +241,7 @@ def __init__(self, sut_node: NodeConfiguration): >> super(ExecutionResult, self).__init__() >> self.sut_node =3D sut_node >> >> - def add_build_target( >> - self, build_target: BuildTargetConfiguration >> - ) -> BuildTargetResult: >> + def add_build_target(self, build_target: BuildTargetConfiguration) >> -> BuildTargetResult: >> build_target_result =3D BuildTargetResult(build_target) >> self._inner_results.append(build_target_result) >> return build_target_result >> diff --git a/dts/framework/test_suite.py b/dts/framework/test_suite.py >> index 3b890c0451..46d3de4944 100644 >> --- a/dts/framework/test_suite.py >> +++ b/dts/framework/test_suite.py >> @@ -102,9 +102,7 @@ def _process_links(self) -> None: >> tg_port.peer, >> tg_port.identifier, >> ): >> - self._port_links.append( >> - PortLink(sut_port=3Dsut_port, tg_port=3Dtg_port= ) >> - ) >> + self._port_links.append(PortLink(sut_port=3Dsut_por= t, >> tg_port=3Dtg_port)) >> >> def set_up_suite(self) -> None: >> """ >> @@ -151,9 +149,7 @@ def configure_testbed_ipv4(self, restore: bool =3D >> False) -> None: >> def _configure_ipv4_forwarding(self, enable: bool) -> None: >> self.sut_node.configure_ipv4_forwarding(enable) >> >> - def send_packet_and_capture( >> - self, packet: Packet, duration: float =3D 1 >> - ) -> list[Packet]: >> + def send_packet_and_capture(self, packet: Packet, duration: float = =3D >> 1) -> list[Packet]: >> """ >> Send a packet through the appropriate interface and >> receive on the appropriate interface. >> @@ -202,21 +198,15 @@ def verify(self, condition: bool, >> failure_description: str) -> None: >> self._fail_test_case_verify(failure_description) >> >> def _fail_test_case_verify(self, failure_description: str) -> None: >> - self._logger.debug( >> - "A test case failed, showing the last 10 commands executed >> on SUT:" >> - ) >> + self._logger.debug("A test case failed, showing the last 10 >> commands executed on SUT:") >> for command_res in >> self.sut_node.main_session.remote_session.history[-10:]: >> self._logger.debug(command_res.command) >> - self._logger.debug( >> - "A test case failed, showing the last 10 commands executed >> on TG:" >> - ) >> + self._logger.debug("A test case failed, showing the last 10 >> commands executed on TG:") >> for command_res in >> self.tg_node.main_session.remote_session.history[-10:]: >> self._logger.debug(command_res.command) >> raise TestCaseVerifyError(failure_description) >> >> - def verify_packets( >> - self, expected_packet: Packet, received_packets: list[Packet] >> - ) -> None: >> + def verify_packets(self, expected_packet: Packet, received_packets: >> list[Packet]) -> None: >> for received_packet in received_packets: >> if self._compare_packets(expected_packet, received_packet): >> break >> @@ -225,17 +215,11 @@ def verify_packets( >> f"The expected packet >> {get_packet_summaries(expected_packet)} " >> f"not found among received >> {get_packet_summaries(received_packets)}" >> ) >> - self._fail_test_case_verify( >> - "An expected packet not found among received packets." >> - ) >> + self._fail_test_case_verify("An expected packet not found >> among received packets.") >> >> - def _compare_packets( >> - self, expected_packet: Packet, received_packet: Packet >> - ) -> bool: >> + def _compare_packets(self, expected_packet: Packet, received_packet= : >> Packet) -> bool: >> self._logger.debug( >> - "Comparing packets: \n" >> - f"{expected_packet.summary()}\n" >> - f"{received_packet.summary()}" >> + "Comparing packets: \n" f"{expected_packet.summary()}\n" >> f"{received_packet.summary()}" >> > > Same situation as above where you would want to make sure to put the f at > the start. > > >> ) >> >> l3 =3D IP in expected_packet.layers() >> @@ -262,14 +246,10 @@ def _compare_packets( >> expected_payload =3D expected_payload.payload >> >> if expected_payload: >> - self._logger.debug( >> - f"The expected packet did not contain >> {expected_payload}." >> - ) >> + self._logger.debug(f"The expected packet did not contain >> {expected_payload}.") >> return False >> if received_payload and received_payload.__class__ !=3D Padding= : >> - self._logger.debug( >> - "The received payload had extra layers which were not >> padding." >> - ) >> + self._logger.debug("The received payload had extra layers >> which were not padding.") >> return False >> return True >> >> @@ -296,10 +276,7 @@ def _verify_l2_frame(self, received_packet: Ether, >> l3: bool) -> bool: >> >> def _verify_l3_packet(self, received_packet: IP, expected_packet: >> IP) -> bool: >> self._logger.debug("Looking at the IP layer.") >> - if ( >> - received_packet.src !=3D expected_packet.src >> - or received_packet.dst !=3D expected_packet.dst >> - ): >> + if received_packet.src !=3D expected_packet.src or >> received_packet.dst !=3D expected_packet.dst: >> return False >> return True >> >> @@ -373,9 +350,7 @@ def _get_test_cases(self, test_case_regex: str) -> >> list[MethodType]: >> if self._should_be_executed(test_case_name, test_case_regex= ): >> filtered_test_cases.append(test_case) >> cases_str =3D ", ".join((x.__name__ for x in filtered_test_case= s)) >> - self._logger.debug( >> - f"Found test cases '{cases_str}' in >> {self.__class__.__name__}." >> - ) >> + self._logger.debug(f"Found test cases '{cases_str}' in >> {self.__class__.__name__}.") >> return filtered_test_cases >> >> def _should_be_executed(self, test_case_name: str, test_case_regex: >> str) -> bool: >> @@ -445,9 +420,7 @@ def _execute_test_case( >> self._logger.exception(f"Test case execution ERROR: >> {test_case_name}") >> test_case_result.update(Result.ERROR, e) >> except KeyboardInterrupt: >> - self._logger.error( >> - f"Test case execution INTERRUPTED by user: >> {test_case_name}" >> - ) >> + self._logger.error(f"Test case execution INTERRUPTED by >> user: {test_case_name}") >> test_case_result.update(Result.SKIP) >> raise KeyboardInterrupt("Stop DTS") >> >> @@ -464,9 +437,7 @@ def is_test_suite(object) -> bool: >> try: >> testcase_module =3D importlib.import_module(testsuite_module_pa= th) >> except ModuleNotFoundError as e: >> - raise ConfigurationError( >> - f"Test suite '{testsuite_module_path}' not found." >> - ) from e >> + raise ConfigurationError(f"Test suite '{testsuite_module_path}' >> not found.") from e >> return [ >> test_suite_class >> for _, test_suite_class in inspect.getmembers(testcase_module, >> is_test_suite) >> diff --git a/dts/framework/testbed_model/capturing_traffic_generator.py >> b/dts/framework/testbed_model/capturing_traffic_generator.py >> index ab98987f8e..48d019ab21 100644 >> --- a/dts/framework/testbed_model/capturing_traffic_generator.py >> +++ b/dts/framework/testbed_model/capturing_traffic_generator.py >> @@ -110,9 +110,7 @@ def send_packets_and_capture( >> duration, >> ) >> >> - self._logger.debug( >> - f"Received packets: {get_packet_summaries(received_packets)= }" >> - ) >> + self._logger.debug(f"Received packets: >> {get_packet_summaries(received_packets)}") >> self._write_capture_from_packets(capture_name, received_packets= ) >> return received_packets >> >> diff --git a/dts/framework/testbed_model/hw/cpu.py >> b/dts/framework/testbed_model/hw/cpu.py >> index d1918a12dc..cbc5fe7fff 100644 >> --- a/dts/framework/testbed_model/hw/cpu.py >> +++ b/dts/framework/testbed_model/hw/cpu.py >> @@ -54,9 +54,7 @@ def __init__(self, lcore_list: list[int] | list[str] | >> list[LogicalCore] | str): >> >> # the input lcores may not be sorted >> self._lcore_list.sort() >> - self._lcore_str =3D ( >> - >> f'{",".join(self._get_consecutive_lcores_range(self._lcore_list))}' >> - ) >> + self._lcore_str =3D >> f'{",".join(self._get_consecutive_lcores_range(self._lcore_list))}' >> >> @property >> def lcore_list(self) -> list[int]: >> @@ -70,15 +68,11 @@ def _get_consecutive_lcores_range(self, >> lcore_ids_list: list[int]) -> list[str]: >> segment.append(lcore_id) >> else: >> formatted_core_list.append( >> - f"{segment[0]}-{segment[-1]}" >> - if len(segment) > 1 >> - else f"{segment[0]}" >> + f"{segment[0]}-{segment[-1]}" if len(segment) > 1 >> else f"{segment[0]}" >> ) >> current_core_index =3D lcore_ids_list.index(lcore_id) >> formatted_core_list.extend( >> - self._get_consecutive_lcores_range( >> - lcore_ids_list[current_core_index:] >> - ) >> + >> self._get_consecutive_lcores_range(lcore_ids_list[current_core_index:]) >> ) >> segment.clear() >> break >> @@ -125,9 +119,7 @@ def __init__( >> self._filter_specifier =3D filter_specifier >> >> # sorting by core is needed in case hyperthreading is enabled >> - self._lcores_to_filter =3D sorted( >> - lcore_list, key=3Dlambda x: x.core, reverse=3Dnot ascending >> - ) >> + self._lcores_to_filter =3D sorted(lcore_list, key=3Dlambda x: >> x.core, reverse=3Dnot ascending) >> self.filter() >> >> @abstractmethod >> @@ -220,9 +212,7 @@ def _filter_cores_from_socket( >> else: >> # we have enough lcores per this core >> continue >> - elif self._filter_specifier.cores_per_socket > len( >> - lcore_count_per_core_map >> - ): >> + elif self._filter_specifier.cores_per_socket > >> len(lcore_count_per_core_map): >> # only add cores if we need more >> lcore_count_per_core_map[lcore.core] =3D 1 >> filtered_lcores.append(lcore) >> diff --git a/dts/framework/testbed_model/node.py >> b/dts/framework/testbed_model/node.py >> index fc01e0bf8e..ef700d8114 100644 >> --- a/dts/framework/testbed_model/node.py >> +++ b/dts/framework/testbed_model/node.py >> @@ -103,18 +103,14 @@ def _tear_down_execution(self) -> None: >> is not decorated so that the derived class doesn't have to use >> the decorator. >> """ >> >> - def set_up_build_target( >> - self, build_target_config: BuildTargetConfiguration >> - ) -> None: >> + def set_up_build_target(self, build_target_config: >> BuildTargetConfiguration) -> None: >> """ >> Perform the build target setup that will be done for each build >> target >> tested on this node. >> """ >> self._set_up_build_target(build_target_config) >> >> - def _set_up_build_target( >> - self, build_target_config: BuildTargetConfiguration >> - ) -> None: >> + def _set_up_build_target(self, build_target_config: >> BuildTargetConfiguration) -> None: >> """ >> This method exists to be optionally overwritten by derived >> classes and >> is not decorated so that the derived class doesn't have to use >> the decorator. >> diff --git a/dts/framework/testbed_model/scapy.py >> b/dts/framework/testbed_model/scapy.py >> index af0d4dbb25..7948424951 100644 >> --- a/dts/framework/testbed_model/scapy.py >> +++ b/dts/framework/testbed_model/scapy.py >> @@ -96,9 +96,7 @@ def scapy_send_packets_and_capture( >> return [scapy_packet.build() for scapy_packet in >> sniffer.stop(join=3DTrue)] >> >> >> -def scapy_send_packets( >> - xmlrpc_packets: list[xmlrpc.client.Binary], send_iface: str >> -) -> None: >> +def scapy_send_packets(xmlrpc_packets: list[xmlrpc.client.Binary], >> send_iface: str) -> None: >> """RPC function to send packets. >> >> The function is meant to be executed on the remote TG node. >> @@ -197,9 +195,7 @@ class >> ScapyTrafficGenerator(CapturingTrafficGenerator): >> def __init__(self, tg_node: TGNode, config: >> ScapyTrafficGeneratorConfig): >> self._config =3D config >> self._tg_node =3D tg_node >> - self._logger =3D getLogger( >> - f"{self._tg_node.name} >> {self._config.traffic_generator_type}" >> - ) >> + self._logger =3D getLogger(f"{self._tg_node.name} >> {self._config.traffic_generator_type}") >> >> assert ( >> self._tg_node.config.os =3D=3D OS.linux >> @@ -218,9 +214,7 @@ def __init__(self, tg_node: TGNode, config: >> ScapyTrafficGeneratorConfig): >> >> self._start_xmlrpc_server_in_remote_python(xmlrpc_server_listen_port) >> >> # connect to the server >> - server_url =3D ( >> - f"http:// >> {self._tg_node.config.hostname}:{xmlrpc_server_listen_port}" >> - ) >> + server_url =3D f"http:// >> {self._tg_node.config.hostname}:{xmlrpc_server_listen_port}" >> self.rpc_server_proxy =3D xmlrpc.client.ServerProxy( >> server_url, allow_none=3DTrue, verbose=3DSETTINGS.verbose >> ) >> @@ -240,9 +234,7 @@ def _start_xmlrpc_server_in_remote_python(self, >> listen_port: int): >> src =3D inspect.getsource(QuittableXMLRPCServer) >> # Lines with only whitespace break the repl if in the middle of >> a function >> # or class, so strip all lines containing only whitespace >> - src =3D "\n".join( >> - [line for line in src.splitlines() if not line.isspace() an= d >> line !=3D ""] >> - ) >> + src =3D "\n".join([line for line in src.splitlines() if not >> line.isspace() and line !=3D ""]) >> >> spacing =3D "\n" * 4 >> >> diff --git a/dts/framework/testbed_model/sut_node.py >> b/dts/framework/testbed_model/sut_node.py >> index 202aebfd06..dfd8c755b4 100644 >> --- a/dts/framework/testbed_model/sut_node.py >> +++ b/dts/framework/testbed_model/sut_node.py >> @@ -129,9 +129,7 @@ def remote_dpdk_build_dir(self) -> PurePath: >> @property >> def dpdk_version(self) -> str: >> if self._dpdk_version is None: >> - self._dpdk_version =3D self.main_session.get_dpdk_version( >> - self._remote_dpdk_dir >> - ) >> + self._dpdk_version =3D >> self.main_session.get_dpdk_version(self._remote_dpdk_dir) >> return self._dpdk_version >> >> @property >> @@ -149,8 +147,7 @@ def compiler_version(self) -> str: >> ) >> else: >> self._logger.warning( >> - "Failed to get compiler version because" >> - "_build_target_config is None." >> + "Failed to get compiler version because" >> "_build_target_config is None." >> > > Double string here. > > >> ) >> return "" >> return self._compiler_version >> @@ -163,9 +160,7 @@ def get_build_target_info(self) -> BuildTargetInfo: >> def _guess_dpdk_remote_dir(self) -> PurePath: >> return >> self.main_session.guess_dpdk_remote_dir(self._remote_tmp_dir) >> >> - def _set_up_build_target( >> - self, build_target_config: BuildTargetConfiguration >> - ) -> None: >> + def _set_up_build_target(self, build_target_config: >> BuildTargetConfiguration) -> None: >> """ >> Setup DPDK on the SUT node. >> """ >> @@ -177,22 +172,17 @@ def _set_up_build_target( >> self._copy_dpdk_tarball() >> self._build_dpdk() >> >> - def _configure_build_target( >> - self, build_target_config: BuildTargetConfiguration >> - ) -> None: >> + def _configure_build_target(self, build_target_config: >> BuildTargetConfiguration) -> None: >> """ >> Populate common environment variables and set build target >> config. >> """ >> self._env_vars =3D {} >> self._build_target_config =3D build_target_config >> - self._env_vars.update( >> - >> self.main_session.get_dpdk_build_env_vars(build_target_config.arch) >> - ) >> + >> self._env_vars.update(self.main_session.get_dpdk_build_env_vars(build_ta= rget_config.arch)) >> self._env_vars["CC"] =3D build_target_config.compiler.name >> if build_target_config.compiler_wrapper: >> self._env_vars["CC"] =3D ( >> - f"'{build_target_config.compiler_wrapper} " >> - f"{build_target_config.compiler.name}'" >> + f"'{build_target_config.compiler_wrapper} " f"{ >> build_target_config.compiler.name}'" >> > > Double string here. > > >> ) >> >> @Node.skip_setup >> @@ -224,9 +214,7 @@ def _copy_dpdk_tarball(self) -> None: >> self.main_session.remove_remote_dir(self._remote_dpdk_dir) >> >> # then extract to remote path >> - self.main_session.extract_remote_tarball( >> - remote_tarball_path, self._remote_dpdk_dir >> - ) >> + self.main_session.extract_remote_tarball(remote_tarball_path, >> self._remote_dpdk_dir) >> >> @Node.skip_setup >> def _build_dpdk(self) -> None: >> @@ -263,9 +251,7 @@ def build_dpdk_app(self, app_name: str, >> **meson_dpdk_args: str | bool) -> PurePa >> ) >> >> if app_name =3D=3D "all": >> - return self.main_session.join_remote_path( >> - self.remote_dpdk_build_dir, "examples" >> - ) >> + return >> self.main_session.join_remote_path(self.remote_dpdk_build_dir, "examples= ") >> return self.main_session.join_remote_path( >> self.remote_dpdk_build_dir, "examples", f"dpdk-{app_name}" >> ) >> @@ -319,9 +305,7 @@ def create_eal_parameters( >> '-c 0xf -a 0000:88:00.0 >> --file-prefix=3Ddpdk_1112_20190809143420'; >> """ >> >> - lcore_list =3D LogicalCoreList( >> - self.filter_lcores(lcore_filter_specifier, ascending_cores) >> - ) >> + lcore_list =3D >> LogicalCoreList(self.filter_lcores(lcore_filter_specifier, ascending_cor= es)) >> >> if append_prefix_timestamp: >> prefix =3D f"{prefix}_{self._dpdk_timestamp}" >> @@ -386,6 +370,4 @@ def create_interactive_shell( >> self.remote_dpdk_build_dir, shell_cls.path >> ) >> >> - return super().create_interactive_shell( >> - shell_cls, timeout, privileged, str(eal_parameters) >> - ) >> + return super().create_interactive_shell(shell_cls, timeout, >> privileged, str(eal_parameters)) >> diff --git a/dts/framework/testbed_model/tg_node.py >> b/dts/framework/testbed_model/tg_node.py >> index 27025cfa31..dca4ec0849 100644 >> --- a/dts/framework/testbed_model/tg_node.py >> +++ b/dts/framework/testbed_model/tg_node.py >> @@ -45,9 +45,7 @@ class TGNode(Node): >> >> def __init__(self, node_config: TGNodeConfiguration): >> super(TGNode, self).__init__(node_config) >> - self.traffic_generator =3D create_traffic_generator( >> - self, node_config.traffic_generator >> - ) >> + self.traffic_generator =3D create_traffic_generator(self, >> node_config.traffic_generator) >> self._logger.info(f"Created node: {self.name}") >> >> def send_packet_and_capture( >> @@ -94,6 +92,5 @@ def create_traffic_generator( >> return ScapyTrafficGenerator(tg_node, >> traffic_generator_config) >> case _: >> raise ConfigurationError( >> - "Unknown traffic generator: " >> - f"{traffic_generator_config.traffic_generator_type}" >> + "Unknown traffic generator: " >> f"{traffic_generator_config.traffic_generator_type}" >> > > Double string but one that needs the whole thing to be an f-string. > > >> ) >> diff --git a/dts/framework/utils.py b/dts/framework/utils.py >> index d27c2c5b5f..d098d364ff 100644 >> --- a/dts/framework/utils.py >> +++ b/dts/framework/utils.py >> @@ -19,9 +19,7 @@ >> >> class StrEnum(Enum): >> @staticmethod >> - def _generate_next_value_( >> - name: str, start: int, count: int, last_values: object >> - ) -> str: >> + def _generate_next_value_(name: str, start: int, count: int, >> last_values: object) -> str: >> return name >> >> def __str__(self) -> str: >> @@ -32,9 +30,7 @@ def __str__(self) -> str: >> >> >> def check_dts_python_version() -> None: >> - if sys.version_info.major < 3 or ( >> - sys.version_info.major =3D=3D 3 and sys.version_info.minor < 10 >> - ): >> + if sys.version_info.major < 3 or (sys.version_info.major =3D=3D 3 a= nd >> sys.version_info.minor < 10): >> print( >> RED( >> ( >> @@ -60,9 +56,7 @@ def expand_range(range_str: str) -> list[int]: >> range_boundaries =3D range_str.split("-") >> # will throw an exception when items in range_boundaries can't >> be converted, >> # serving as type check >> - expanded_range.extend( >> - range(int(range_boundaries[0]), int(range_boundaries[-1]) + >> 1) >> - ) >> + expanded_range.extend(range(int(range_boundaries[0]), >> int(range_boundaries[-1]) + 1)) >> >> return expanded_range >> >> @@ -71,9 +65,7 @@ def get_packet_summaries(packets: list[Packet]): >> if len(packets) =3D=3D 1: >> packet_summaries =3D packets[0].summary() >> else: >> - packet_summaries =3D json.dumps( >> - list(map(lambda pkt: pkt.summary(), packets)), indent=3D4 >> - ) >> + packet_summaries =3D json.dumps(list(map(lambda pkt: >> pkt.summary(), packets)), indent=3D4) >> return f"Packet contents: \n{packet_summaries}" >> >> >> @@ -94,9 +86,7 @@ class MesonArgs(object): >> _default_library: str >> >> def __init__(self, default_library: str | None =3D None, **dpdk_arg= s: >> str | bool): >> - self._default_library =3D ( >> - f"--default-library=3D{default_library}" if default_library >> else "" >> - ) >> + self._default_library =3D f"--default-library=3D{default_librar= y}" >> if default_library else "" >> self._dpdk_args =3D " ".join( >> ( >> f"-D{dpdk_arg_name}=3D{dpdk_arg_value}" >> diff --git a/dts/pyproject.toml b/dts/pyproject.toml >> index 6762edfa6b..980ac3c7db 100644 >> --- a/dts/pyproject.toml >> +++ b/dts/pyproject.toml >> @@ -41,7 +41,7 @@ build-backend =3D "poetry.core.masonry.api" >> [tool.pylama] >> linters =3D "mccabe,pycodestyle,pyflakes" >> format =3D "pylint" >> -max_line_length =3D 88 # >> https://black.readthedocs.io/en/stable/the_black_code_style/current_styl= e.html#line-length >> +max_line_length =3D 100 >> >> [tool.mypy] >> python_version =3D "3.10" >> @@ -55,4 +55,4 @@ profile =3D "black" >> [tool.black] >> target-version =3D ['py310'] >> include =3D '\.pyi?$' >> -line-length =3D 88 # >> https://black.readthedocs.io/en/stable/the_black_code_style/current_styl= e.html#line-length >> +line-length >> >> =3D 100 >> diff --git a/dts/tests/TestSuite_hello_world.py >> b/dts/tests/TestSuite_hello_world.py >> index 7e3d95c0cf..768ba1cfa8 100644 >> --- a/dts/tests/TestSuite_hello_world.py >> +++ b/dts/tests/TestSuite_hello_world.py >> @@ -34,9 +34,7 @@ def test_hello_world_single_core(self) -> None: >> # get the first usable core >> lcore_amount =3D LogicalCoreCount(1, 1, 1) >> lcores =3D LogicalCoreCountFilter(self.sut_node.lcores, >> lcore_amount).filter() >> - eal_para =3D self.sut_node.create_eal_parameters( >> - lcore_filter_specifier=3Dlcore_amount >> - ) >> + eal_para =3D >> self.sut_node.create_eal_parameters(lcore_filter_specifier=3Dlcore_amoun= t) >> result =3D self.sut_node.run_dpdk_app(self.app_helloworld_path, >> eal_para) >> self.verify( >> f"hello from core {int(lcores[0])}" in result.stdout, >> diff --git a/dts/tests/TestSuite_smoke_tests.py >> b/dts/tests/TestSuite_smoke_tests.py >> index 4a269df75b..36119e6469 100644 >> --- a/dts/tests/TestSuite_smoke_tests.py >> +++ b/dts/tests/TestSuite_smoke_tests.py >> @@ -45,13 +45,10 @@ def test_driver_tests(self) -> None: >> for dev in self.sut_node.virtual_devices: >> vdev_args +=3D f"--vdev {dev} " >> vdev_args =3D vdev_args[:-1] >> - driver_tests_command =3D ( >> - f"meson test -C {self.dpdk_build_dir_path} --suite >> driver-tests" >> - ) >> + driver_tests_command =3D f"meson test -C >> {self.dpdk_build_dir_path} --suite driver-tests" >> if vdev_args: >> self._logger.info( >> - "Running driver tests with the following virtual " >> - f"devices: {vdev_args}" >> + "Running driver tests with the following virtual " >> f"devices: {vdev_args}" >> > > Double string that should be an f-string. > > >> ) >> driver_tests_command +=3D f' --test-args "{vdev_args}"' >> >> @@ -67,9 +64,7 @@ def test_devices_listed_in_testpmd(self) -> None: >> Test: >> Uses testpmd driver to verify that devices have been found >> by testpmd. >> """ >> - testpmd_driver =3D self.sut_node.create_interactive_shell( >> - TestPmdShell, privileged=3DTrue >> - ) >> + testpmd_driver =3D >> self.sut_node.create_interactive_shell(TestPmdShell, privileged=3DTrue) >> dev_list =3D [str(x) for x in testpmd_driver.get_devices()] >> for nic in self.nics_in_node: >> self.verify( >> -- >> 2.34.1 >> >> --00000000000083dea00606663dde Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Thanks, Jeremy. I skimmed the changes before submitting th= em, but I didn't catch this. I'll submit a new version.

On Tue, Sep = 26, 2023 at 11:52=E2=80=AFPM Jeremy Spewock <jspewock@iol.unh.edu> wrote:


I think this= is a good idea because of all the weird places we had to break things up w= ith the 88 character cap. I do however also notice that in some cases where= these multi-line strings were combined back into one line it would just ha= ve two string literals on the same line rather than them being just oen str= ing. I tried to point out everywhere I found this behavoir below as it look= s a little awkward in the code.

It looks good to me otherwise though.
<= /div>

On Tue, Sep 26, 2023 at 8:10=E2=80=AFAM Juraj Lin= ke=C5=A1 <juraj.linkes@pantheon.tech> wrote:
Reformat to 100 from the previous 88 to = unify with C recommendations.

Signed-off-by: Juraj Linke=C5=A1 <juraj.linkes@pantheon.tech>
---
=C2=A0dts/framework/config/__init__.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 | 20 ++-----
=C2=A0dts/framework/dts.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 | 12 +---
=C2=A0dts/framework/exception.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 3 +-
=C2=A0dts/framework/remote_session/__init__.py=C2=A0 =C2=A0 =C2=A0 |=C2=A0 = 4 +-
=C2=A0dts/framework/remote_session/linux_session.py | 39 ++++---------
=C2=A0dts/framework/remote_session/posix_session.py | 30 +++-------
=C2=A0.../remote/interactive_remote_session.py=C2=A0 =C2=A0 =C2=A0 |=C2=A0 = 7 +--
=C2=A0.../remote/interactive_shell.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0|=C2=A0 4 +-
=C2=A0.../remote_session/remote/remote_session.py=C2=A0 =C2=A0|=C2=A0 8 +--=
=C2=A0.../remote_session/remote/ssh_session.py=C2=A0 =C2=A0 =C2=A0 | 16 ++-= ---
=C2=A0.../remote_session/remote/testpmd_shell.py=C2=A0 =C2=A0 |=C2=A0 8 +--=
=C2=A0dts/framework/settings.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 4 +-
=C2=A0dts/framework/test_result.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 | 16 ++----
=C2=A0dts/framework/test_suite.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0| 57 +++++--------------
=C2=A0.../capturing_traffic_generator.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 |=C2=A0 4 +-
=C2=A0dts/framework/testbed_model/hw/cpu.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0| 20 ++-----
=C2=A0dts/framework/testbed_model/node.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0|=C2=A0 8 +--
=C2=A0dts/framework/testbed_model/scapy.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 | 16 ++----
=C2=A0dts/framework/testbed_model/sut_node.py=C2=A0 =C2=A0 =C2=A0 =C2=A0| 3= 8 ++++---------
=C2=A0dts/framework/testbed_model/tg_node.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 |= =C2=A0 7 +--
=C2=A0dts/framework/utils.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 | 20 ++-----
=C2=A0dts/pyproject.toml=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 4 +-
=C2=A0dts/tests/TestSuite_hello_world.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 |=C2=A0 4 +-
=C2=A0dts/tests/TestSuite_smoke_tests.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 | 11 +---
=C2=A024 files changed, 93 insertions(+), 267 deletions(-)

diff --git a/dts/framework/config/__init__.py b/dts/framework/config/__init= __.py
index cb7e00ba34..9b32cf0532 100644
--- a/dts/framework/config/__init__.py
+++ b/dts/framework/config/__init__.py
@@ -140,9 +140,7 @@ def from_dict(d: dict) -> Union["SutNodeConfigu= ration", "TGNodeConfiguration"]:

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if "traffic_generator" in d: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return TGNodeConfiguration(=
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 traffic_generator= =3DTrafficGeneratorConfig.from_dict(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 d[&q= uot;traffic_generator"]
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ),
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 traffic_generator= =3DTrafficGeneratorConfig.from_dict(d["traffic_generator"]),
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0**common_conf= ig,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else:
@@ -249,9 +247,7 @@ def from_dict(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0build_targets: list[BuildTargetConfigurat= ion] =3D list(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0map(BuildTargetConfiguratio= n.from_dict, d["build_targets"])
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 test_suites: list[TestSuiteConfig] =3D list( -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 map(TestSuiteConfig.from_dict, d= ["test_suites"])
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 test_suites: list[TestSuiteConfig] =3D list(ma= p(TestSuiteConfig.from_dict, d["test_suites"]))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sut_name =3D d["system_under_test_no= de"]["node_name"]
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0skip_smoke_tests =3D d.get("skip_smo= ke_tests", False)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0assert sut_name in node_map, f"Unkno= wn SUT {sut_name} in execution {d}"
@@ -268,9 +264,7 @@ def from_dict(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0), f"Invalid TG configuration {traff= ic_generator_node}"

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0vdevs =3D (
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 d["system_under_test_node&q= uot;]["vdevs"]
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if "vdevs" in d["= system_under_test_node"]
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 else []
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 d["system_under_test_node&q= uot;]["vdevs"] if "vdevs" in d["system_under_test_= node"] else []
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return ExecutionConfiguration(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0build_targets=3Dbuild_targe= ts,
@@ -299,9 +293,7 @@ def from_dict(d: dict) -> "Configuration":=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0assert len(nodes) =3D=3D len(node_map), &= quot;Duplicate node names are not allowed"

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0executions: list[ExecutionConfiguration] = =3D list(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 map(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ExecutionConfigura= tion.from_dict, d["executions"], [node_map for _ in d]
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 map(ExecutionConfiguration.from_= dict, d["executions"], [node_map for _ in d])
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return Configuration(executions=3Dexecuti= ons)
@@ -315,9 +307,7 @@ def load_config() -> Configuration:
=C2=A0 =C2=A0 =C2=A0with open(SETTINGS.config_file_path, "r") as = f:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0config_data =3D yaml.safe_load(f)

-=C2=A0 =C2=A0 schema_path =3D os.path.join(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 pathlib.Path(__file__).parent.resolve(), "= ;conf_yaml_schema.json"
-=C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 schema_path =3D os.path.join(pathlib.Path(__file__).parent.r= esolve(), "conf_yaml_schema.json")

=C2=A0 =C2=A0 =C2=A0with open(schema_path, "r") as f:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0schema =3D json.load(f)
diff --git a/dts/framework/dts.py b/dts/framework/dts.py
index f773f0c38d..e2aada5a23 100644
--- a/dts/framework/dts.py
+++ b/dts/framework/dts.py
@@ -92,9 +92,7 @@ def _run_execution(
=C2=A0 =C2=A0 =C2=A0Run the given execution. This involves running the exec= ution setup as well as
=C2=A0 =C2=A0 =C2=A0running all build targets in the given execution.
=C2=A0 =C2=A0 =C2=A0"""
-=C2=A0 =C2=A0 dts_logger.info(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 f"Running execution with SUT '{execution.system_under_test_node.name}'."
-=C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 dts_logger.info(f"Running execution with SUT '{execution.system_under_test_node.name}'.")
=C2=A0 =C2=A0 =C2=A0execution_result =3D result.add_execution(sut_node.conf= ig)
=C2=A0 =C2=A0 =C2=A0execution_result.add_sut_info(sut_node.node_info)

@@ -107,9 +105,7 @@ def _run_execution(

=C2=A0 =C2=A0 =C2=A0else:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0for build_target in execution.build_targe= ts:
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 _run_build_target(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sut_node, tg_node,= build_target, execution, execution_result
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 _run_build_target(sut_node, tg_n= ode, build_target, execution, execution_result)

=C2=A0 =C2=A0 =C2=A0finally:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0try:
@@ -170,9 +166,7 @@ def _run_all_suites(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0execution.test_suites[:0] =3D [TestSuiteC= onfig.from_dict("smoke_tests")]
=C2=A0 =C2=A0 =C2=A0for test_suite_config in execution.test_suites:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0try:
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 _run_single_suite(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sut_node, tg_node,= execution, build_target_result, test_suite_config
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 _run_single_suite(sut_node, tg_n= ode, execution, build_target_result, test_suite_config)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0except BlockingTestSuiteError as e:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0dts_logger.exception(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0f"An err= or occurred within {test_suite_config.test_suite}. "
diff --git a/dts/framework/exception.py b/dts/framework/exception.py
index 001a5a5496..59cf9fd12a 100644
--- a/dts/framework/exception.py
+++ b/dts/framework/exception.py
@@ -117,8 +117,7 @@ def __init__(self, command: str, command_return_code: i= nt):

=C2=A0 =C2=A0 =C2=A0def __str__(self) -> str:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"Command {self.command} re= turned a non-zero exit code: "
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"{self.command_return_code= }"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"Command {self.command} r= eturned a non-zero exit code: " f"{self.command_return_code}"= ;

If you modify this to be on the same line yo= u actually don't need the separate string on this line. The line could = instead be the following:

f"Command {self.command} returned a non-ze= ro exit code: {self.command_return_code}"
=C2=A0
=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)


diff --git a/dts/framework/remote_session/__init__.py b/dts/framework/remot= e_session/__init__.py
index 00b6d1f03a..6124417bd7 100644
--- a/dts/framework/remote_session/__init__.py
+++ b/dts/framework/remote_session/__init__.py
@@ -30,9 +30,7 @@
=C2=A0)


-def create_session(
-=C2=A0 =C2=A0 node_config: NodeConfiguration, name: str, logger: DTSLOG -) -> OSSession:
+def create_session(node_config: NodeConfiguration, name: str, logger: DTSL= OG) -> OSSession:
=C2=A0 =C2=A0 =C2=A0match node_config.os:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case OS.linux:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return LinuxSession(node_co= nfig, name, logger)
diff --git a/dts/framework/remote_session/linux_session.py b/dts/framework/= remote_session/linux_session.py
index a3f1a6bf3b..aa76e25436 100644
--- a/dts/framework/remote_session/linux_session.py
+++ b/dts/framework/remote_session/linux_session.py
@@ -82,9 +82,7 @@ def setup_hugepages(self, hugepage_amount: int, force_fir= st_numa: bool) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._mount_huge_pages()

=C2=A0 =C2=A0 =C2=A0def _get_hugepage_size(self) -> int:
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 hugepage_size =3D self.send_command(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "awk '/Hugepagesize/ {p= rint $2}' /proc/meminfo"
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 ).stdout
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 hugepage_size =3D self.send_command("awk = '/Hugepagesize/ {print $2}' /proc/meminfo").stdout
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return int(hugepage_size)

=C2=A0 =C2=A0 =C2=A0def _get_hugepages_total(self) -> int:
@@ -120,13 +118,9 @@ def _supports_numa(self) -> bool:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0# there's no reason to do any numa sp= ecific configuration)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return len(self._numa_nodes) > 1

-=C2=A0 =C2=A0 def _configure_huge_pages(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self, amount: int, size: int, force_first_numa= : bool
-=C2=A0 =C2=A0 ) -> None:
+=C2=A0 =C2=A0 def _configure_huge_pages(self, amount: int, size: int, forc= e_first_numa: bool) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._logger.info("Configuring Hugepag= es.")
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 hugepage_config_path =3D (
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"/sys/kernel/mm/hugepages/= hugepages-{size}kB/nr_hugepages"
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 hugepage_config_path =3D f"/sys/kernel/mm= /hugepages/hugepages-{size}kB/nr_hugepages"
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if force_first_numa and self._supports_nu= ma():
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0# clear non-numa hugepages<= br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self.send_command(f"ec= ho 0 | tee {hugepage_config_path}", privileged=3DTrue)
@@ -135,24 +129,18 @@ def _configure_huge_pages(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0f"/hugep= ages-{size}kB/nr_hugepages"
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)

-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.send_command(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"echo {amount} | tee {huge= page_config_path}", privileged=3DTrue
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.send_command(f"echo {amount} | tee {= hugepage_config_path}", privileged=3DTrue)

=C2=A0 =C2=A0 =C2=A0def update_ports(self, ports: list[Port]) -> None: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._logger.debug("Gathering port i= nfo.")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0for port in ports:
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 assert (
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 port.node =3D=3D <= a href=3D"http://self.name" rel=3D"noreferrer" target=3D"_blank">self.name<= /a>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ), "Attempted to gather por= t info on the wrong node"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 assert port.node =3D=3D self.name, &= quot;Attempted to gather port info on the wrong node"

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0port_info_list =3D self._get_lshw_info()<= br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0for port in ports:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0for port_info in port_info_= list:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if f"pci= @{port.pci}" =3D=3D port_info.get("businfo"):
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self= ._update_port_attr(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 port, port_info.get("logicalname"), "logical_name= "
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ) +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self= ._update_port_attr(port, port_info.get("logicalname"), "logi= cal_name")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0self._update_port_attr(port, port_info.get("serial"), "ma= c_address")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0port_info_list.remove(port_info)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0break
@@ -163,25 +151,18 @@ def _get_lshw_info(self) -> list[LshwOutput]:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0output =3D self.send_command("lshw -= quiet -json -C network", verify=3DTrue)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return json.loads(output.stdout)

-=C2=A0 =C2=A0 def _update_port_attr(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self, port: Port, attr_value: str | None, attr= _name: str
-=C2=A0 =C2=A0 ) -> None:
+=C2=A0 =C2=A0 def _update_port_attr(self, port: Port, attr_value: str | No= ne, attr_name: str) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if attr_value:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0setattr(port, attr_name, at= tr_value)
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger.debug(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"Found '= {attr_name}' of port {port.pci}: '{attr_value}'."
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger.debug(f"Found = '{attr_name}' of port {port.pci}: '{attr_value}'.") =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._logger.warning(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"Attempted t= o get '{attr_name}' of port {port.pci}, "
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"but it does= n't exist."
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"Attempted t= o get '{attr_name}' of port {port.pci}, " f"but it doesn&= #39;t exist."

This is another case where = the two different strings aren't needed
=C2=A0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)

=C2=A0 =C2=A0 =C2=A0def configure_port_state(self, port: Port, enable: bool= ) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0state =3D "up" if enable else &= quot;down"
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.send_command(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"ip link set dev {port.log= ical_name} {state}", privileged=3DTrue
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.send_command(f"ip link set dev {port= .logical_name} {state}", privileged=3DTrue)

=C2=A0 =C2=A0 =C2=A0def configure_port_ip_address(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self,
diff --git a/dts/framework/remote_session/posix_session.py b/dts/framework/= remote_session/posix_session.py
index 5da0516e05..eb59252dd1 100644
--- a/dts/framework/remote_session/posix_session.py
+++ b/dts/framework/remote_session/posix_session.py
@@ -94,8 +94,7 @@ def extract_remote_tarball(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0expected_dir: str | PurePath | None =3D N= one,
=C2=A0 =C2=A0 =C2=A0) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self.send_command(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"tar xfm {remote_tarball_p= ath} "
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"-C {PurePosixPath(remote_= tarball_path).parent}",
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"tar xfm {remote_tarball_p= ath} " f"-C {PurePosixPath(remote_tarball_path).parent}",

Double string here as well.
= =C2=A0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A060,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if expected_dir:
@@ -125,8 +124,7 @@ def build_dpdk(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._logger.info("Configuring DPDK build from scratch.")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self.remove_r= emote_dir(remote_dpdk_build_dir)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self.send_com= mand(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f&qu= ot;meson setup "
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f&qu= ot;{meson_args} {remote_dpdk_dir} {remote_dpdk_build_dir}",
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f&qu= ot;meson setup " f"{meson_args} {remote_dpdk_dir} {remote_dpdk_bu= ild_dir}",

=
=C2=A0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0timeout,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0verify=3DTrue,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0env=3Denv_vars,
@@ -140,9 +138,7 @@ def build_dpdk(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0raise DPDKBuildError(f"= ;DPDK build failed when doing '{e.command}'.")

=C2=A0 =C2=A0 =C2=A0def get_dpdk_version(self, build_dir: str | PurePath) -= > str:
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 out =3D self.send_command(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"cat {self.join_remote_pat= h(build_dir, 'VERSION')}", verify=3DTrue
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 out =3D self.send_command(f"cat {self.joi= n_remote_path(build_dir, 'VERSION')}", verify=3DTrue)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return out.stdout

=C2=A0 =C2=A0 =C2=A0def kill_cleanup_dpdk_apps(self, dpdk_prefix_list: Iter= able[str]) -> None:
@@ -156,9 +152,7 @@ def kill_cleanup_dpdk_apps(self, dpdk_prefix_list: Iter= able[str]) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._check_dpdk_hugepages(= dpdk_runtime_dirs)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._remove_dpdk_runtime_d= irs(dpdk_runtime_dirs)

-=C2=A0 =C2=A0 def _get_dpdk_runtime_dirs(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self, dpdk_prefix_list: Iterable[str]
-=C2=A0 =C2=A0 ) -> list[PurePosixPath]:
+=C2=A0 =C2=A0 def _get_dpdk_runtime_dirs(self, dpdk_prefix_list: Iterable[= str]) -> list[PurePosixPath]:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0prefix =3D PurePosixPath("/var"= , "run", "dpdk")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if not dpdk_prefix_list:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0remote_prefixes =3D self._l= ist_remote_dirs(prefix)
@@ -174,9 +168,7 @@ def _list_remote_dirs(self, remote_path: str | PurePath= ) -> list[str] | None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Return a list of directories of the remot= e_dir.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0If remote_path doesn't exist, return = None.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"""
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 out =3D self.send_command(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"ls -l {remote_path} | awk= '/^d/ {{print $NF}}'"
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 ).stdout
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 out =3D self.send_command(f"ls -l {remote= _path} | awk '/^d/ {{print $NF}}'").stdout
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if "No such file or directory" = in out:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return None
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else:
@@ -200,9 +192,7 @@ def _remote_files_exists(self, remote_path: PurePath) -= > bool:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0result =3D self.send_command(f"test = -e {remote_path}")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return not result.return_code

-=C2=A0 =C2=A0 def _check_dpdk_hugepages(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self, dpdk_runtime_dirs: Iterable[str | PurePa= th]
-=C2=A0 =C2=A0 ) -> None:
+=C2=A0 =C2=A0 def _check_dpdk_hugepages(self, dpdk_runtime_dirs: Iterable[= str | PurePath]) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0for dpdk_runtime_dir in dpdk_runtime_dirs= :
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0hugepage_info =3D PurePosix= Path(dpdk_runtime_dir, "hugepage_info")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if self._remote_files_exist= s(hugepage_info):
@@ -213,9 +203,7 @@ def _check_dpdk_hugepages(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0self._logger.warning(out)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0self._logger.warning("*******************************************&q= uot;)

-=C2=A0 =C2=A0 def _remove_dpdk_runtime_dirs(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self, dpdk_runtime_dirs: Iterable[str | PurePa= th]
-=C2=A0 =C2=A0 ) -> None:
+=C2=A0 =C2=A0 def _remove_dpdk_runtime_dirs(self, dpdk_runtime_dirs: Itera= ble[str | PurePath]) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0for dpdk_runtime_dir in dpdk_runtime_dirs= :
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self.remove_remote_dir(dpdk= _runtime_dir)

@@ -245,6 +233,4 @@ def get_node_info(self) -> NodeInfo:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0SETTINGS.timeout,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0).stdout.split("\n")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0kernel_version =3D self.send_command(&quo= t;uname -r", SETTINGS.timeout).stdout
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 return NodeInfo(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 os_release_info[0].strip(), os_r= elease_info[1].strip(), kernel_version
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 return NodeInfo(os_release_info[0].strip(), os= _release_info[1].strip(), kernel_version)
diff --git a/dts/framework/remote_session/remote/interactive_remote_session= .py b/dts/framework/remote_session/remote/interactive_remote_session.py
index 9085a668e8..42c99b2525 100644
--- a/dts/framework/remote_session/remote/interactive_remote_session.py
+++ b/dts/framework/remote_session/remote/interactive_remote_session.py
@@ -73,9 +73,7 @@ def __init__(self, node_config: NodeConfiguration, _logge= r: DTSLOG) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0f"Initializing interac= tive connection for {self.username}@{self.hostname}"
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._connect()
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._
logger.info(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"Interactive connection su= ccessful for {self.username}@{self.hostname}"
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger.info(f"Interactive connection s= uccessful for {self.username}@{self.hostname}")

=C2=A0 =C2=A0 =C2=A0def _connect(self) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"""Establish a connection = to the node.
@@ -108,8 +106,7 @@ def _connect(self) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._logger.= debug(traceback.format_exc())
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._logger.= warning(e)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._logger.info(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &quo= t;Retrying interactive session connection: "
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f&qu= ot;retry number {retry_attempt +1}"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &quo= t;Retrying interactive session connection: " f"retry number {retr= y_attempt +1}"

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break
diff --git a/dts/framework/remote_session/remote/interactive_shell.py b/dts= /framework/remote_session/remote/interactive_shell.py
index c24376b2a8..4db19fb9b3 100644
--- a/dts/framework/remote_session/remote/interactive_shell.py
+++ b/dts/framework/remote_session/remote/interactive_shell.py
@@ -85,9 +85,7 @@ def __init__(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._app_args =3D app_args
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._start_application(get_privileged_co= mmand)

-=C2=A0 =C2=A0 def _start_application(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self, get_privileged_command: Callable[[str], = str] | None
-=C2=A0 =C2=A0 ) -> None:
+=C2=A0 =C2=A0 def _start_application(self, get_privileged_command: Callabl= e[[str], str] | None) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"""Starts a new interactiv= e application based on the path to the app.

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0This method is often overridden by subcla= sses as their process for
diff --git a/dts/framework/remote_session/remote/remote_session.py b/dts/fr= amework/remote_session/remote/remote_session.py
index 0647d93de4..719f7d1ef7 100644
--- a/dts/framework/remote_session/remote/remote_session.py
+++ b/dts/framework/remote_session/remote/remote_session.py
@@ -96,9 +96,7 @@ def send_command(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0If verify is True, check the return code = of the executed command
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0and raise a RemoteCommandExecutionError i= f the command failed.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"""
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._
logger.info(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"Sending: '{command}&#= 39;" + (f" with env vars: '{env}'" if env else "= ;")
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger.info(f"Sending: '{command}&= #39;" + (f" with env vars: '{env}'" if env else &quo= t;"))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0result =3D self._send_command(command, ti= meout, env)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if verify and result.return_code:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._logger.debug(
@@ -112,9 +110,7 @@ def send_command(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return result

=C2=A0 =C2=A0 =C2=A0@abstractmethod
-=C2=A0 =C2=A0 def _send_command(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self, command: str, timeout: float, env: dict = | None
-=C2=A0 =C2=A0 ) -> CommandResult:
+=C2=A0 =C2=A0 def _send_command(self, command: str, timeout: float, env: d= ict | None) -> CommandResult:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"""
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Use the underlying protocol to execute th= e command using optional env vars
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0and return CommandResult.
diff --git a/dts/framework/remote_session/remote/ssh_session.py b/dts/frame= work/remote_session/remote/ssh_session.py
index 8d127f1601..1a7ee649ab 100644
--- a/dts/framework/remote_session/remote/ssh_session.py
+++ b/dts/framework/remote_session/remote/ssh_session.py
@@ -80,9 +80,7 @@ def _connect(self) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if error not = in errors:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0errors.append(error)

-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger.info( -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f&qu= ot;Retrying connection: retry number {retry_attempt + 1}."
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger.info(f&q= uot;Retrying connection: retry number {retry_attempt + 1}.")

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break
@@ -92,9 +90,7 @@ def _connect(self) -> None:
=C2=A0 =C2=A0 =C2=A0def is_alive(self) -> bool:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return self.session.is_connected

-=C2=A0 =C2=A0 def _send_command(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self, command: str, timeout: float, env: dict = | None
-=C2=A0 =C2=A0 ) -> CommandResult:
+=C2=A0 =C2=A0 def _send_command(self, command: str, timeout: float, env: d= ict | None) -> CommandResult:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"""Send a command and retu= rn the result of the execution.

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Args:
@@ -107,9 +103,7 @@ def _send_command(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0SSHTimeoutError: The comman= d execution timed out.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"""
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0try:
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 output =3D self.session.run(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 command, env=3Denv= , warn=3DTrue, hide=3DTrue, timeout=3Dtimeout
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 output =3D self.session.run(comm= and, env=3Denv, warn=3DTrue, hide=3DTrue, timeout=3Dtimeout)

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0except (UnexpectedExit, ThreadException) = as e:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._logger.exception(e) @@ -119,9 +113,7 @@ def _send_command(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._logger.exception(e) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0raise SSHTimeoutError(comma= nd, e.result.stderr) from e

-=C2=A0 =C2=A0 =C2=A0 =C2=A0 return CommandResult(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.name, command, output.stdout, ou= tput.stderr, output.return_code
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 return CommandResult(self.name, command, output.std= out, output.stderr, output.return_code)

=C2=A0 =C2=A0 =C2=A0def copy_from(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self,
diff --git a/dts/framework/remote_session/remote/testpmd_shell.py b/dts/fra= mework/remote_session/remote/testpmd_shell.py
index 1455b5a199..08ac311016 100644
--- a/dts/framework/remote_session/remote/testpmd_shell.py
+++ b/dts/framework/remote_session/remote/testpmd_shell.py
@@ -21,13 +21,9 @@ class TestPmdShell(InteractiveShell):
=C2=A0 =C2=A0 =C2=A0path: PurePath =3D PurePath("app", "dpdk= -testpmd")
=C2=A0 =C2=A0 =C2=A0dpdk_app: bool =3D True
=C2=A0 =C2=A0 =C2=A0_default_prompt: str =3D "testpmd>"
-=C2=A0 =C2=A0 _command_extra_chars: str =3D (
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 "\n"=C2=A0 # We want to append an ex= tra newline to every command
-=C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 _command_extra_chars: str =3D "\n"=C2=A0 # We want= to append an extra newline to every command

-=C2=A0 =C2=A0 def _start_application(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self, get_privileged_command: Callable[[str], = str] | None
-=C2=A0 =C2=A0 ) -> None:
+=C2=A0 =C2=A0 def _start_application(self, get_privileged_command: Callabl= e[[str], str] | None) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"""See "_start_applic= ation" in InteractiveShell."""
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._app_args +=3D " -- -i" =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0super()._start_application(get_privileged= _command)
diff --git a/dts/framework/settings.py b/dts/framework/settings.py
index cfa39d011b..aad444e99c 100644
--- a/dts/framework/settings.py
+++ b/dts/framework/settings.py
@@ -170,9 +170,7 @@ def _get_settings() -> _Settings:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0timeout=3Dparsed_args.timeout,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0verbose=3D(parsed_args.verbose =3D=3D &qu= ot;Y"),
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0skip_setup=3D(parsed_args.skip_setup =3D= =3D "Y"),
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 dpdk_tarball_path=3DPath(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 DPDKGitTarball(parsed_args.tarba= ll, parsed_args.output_dir)
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 dpdk_tarball_path=3DPath(DPDKGitTarball(parsed= _args.tarball, parsed_args.output_dir))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if not os.path.exists(parsed_args.tarball= )
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else Path(parsed_args.tarball),
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0compile_timeout=3Dparsed_args.compile_tim= eout,
diff --git a/dts/framework/test_result.py b/dts/framework/test_result.py index f0fbe80f6f..4c2e7e2418 100644
--- a/dts/framework/test_result.py
+++ b/dts/framework/test_result.py
@@ -83,9 +83,7 @@ def __iadd__(self, other: Result) -> "Statistics&= quot;:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"""
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self[other.name] +=3D 1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self["PASS RATE"] =3D (
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 float(self[Result.PASS.name])<= br> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 * 100
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 / sum(self[result.name] for result = in Result)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 float(self[Result.PASS.name]) = * 100 / sum(self[result.name] for result in Result)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return self

@@ -135,9 +133,7 @@ def _get_setup_teardown_errors(self) -> list[Excepti= on]:

=C2=A0 =C2=A0 =C2=A0def _get_inner_errors(self) -> list[Exception]:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return [
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 error
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for inner_result in self._inner_= results
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for error in inner_result.get_er= rors()
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 error for inner_result in self._= inner_results for error in inner_result.get_errors()
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0]

=C2=A0 =C2=A0 =C2=A0def get_errors(self) -> list[Exception]:
@@ -174,9 +170,7 @@ def add_stats(self, statistics: Statistics) -> None:=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0statistics +=3D self.result

=C2=A0 =C2=A0 =C2=A0def __bool__(self) -> bool:
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 return (
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 bool(self.setup_result) and bool= (self.teardown_result) and bool(self.result)
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 return bool(self.setup_result) and bool(self.t= eardown_result) and bool(self.result)


=C2=A0class TestSuiteResult(BaseResult):
@@ -247,9 +241,7 @@ def __init__(self, sut_node: NodeConfiguration):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0super(ExecutionResult, self).__init__() =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self.sut_node =3D sut_node

-=C2=A0 =C2=A0 def add_build_target(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self, build_target: BuildTargetConfiguration -=C2=A0 =C2=A0 ) -> BuildTargetResult:
+=C2=A0 =C2=A0 def add_build_target(self, build_target: BuildTargetConfigur= ation) -> BuildTargetResult:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0build_target_result =3D BuildTargetResult= (build_target)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._inner_results.append(build_target_r= esult)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return build_target_result
diff --git a/dts/framework/test_suite.py b/dts/framework/test_suite.py
index 3b890c0451..46d3de4944 100644
--- a/dts/framework/test_suite.py
+++ b/dts/framework/test_suite.py
@@ -102,9 +102,7 @@ def _process_links(self) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0tg_port.peer,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0tg_port.identifier,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0):
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self= ._port_links.append(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 PortLink(sut_port=3Dsut_port, tg_port=3Dtg_port)
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ) +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self= ._port_links.append(PortLink(sut_port=3Dsut_port, tg_port=3Dtg_port))

=C2=A0 =C2=A0 =C2=A0def set_up_suite(self) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"""
@@ -151,9 +149,7 @@ def configure_testbed_ipv4(self, restore: bool =3D Fals= e) -> None:
=C2=A0 =C2=A0 =C2=A0def _configure_ipv4_forwarding(self, enable: bool) ->= ; None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self.sut_node.configure_ipv4_forwarding(e= nable)

-=C2=A0 =C2=A0 def send_packet_and_capture(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self, packet: Packet, duration: float =3D 1 -=C2=A0 =C2=A0 ) -> list[Packet]:
+=C2=A0 =C2=A0 def send_packet_and_capture(self, packet: Packet, duration: = float =3D 1) -> list[Packet]:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"""
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Send a packet through the appropriate int= erface and
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0receive on the appropriate interface.
@@ -202,21 +198,15 @@ def verify(self, condition: bool, failure_description= : str) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._fail_test_case_verify= (failure_description)

=C2=A0 =C2=A0 =C2=A0def _fail_test_case_verify(self, failure_description: s= tr) -> None:
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger.debug(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "A test case failed, showin= g the last 10 commands executed on SUT:"
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger.debug("A test case failed, s= howing the last 10 commands executed on SUT:")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0for command_res in self.sut_node.main_ses= sion.remote_session.history[-10:]:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._logger.debug(command_= res.command)
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger.debug(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "A test case failed, showin= g the last 10 commands executed on TG:"
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger.debug("A test case failed, s= howing the last 10 commands executed on TG:")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0for command_res in self.tg_node.main_sess= ion.remote_session.history[-10:]:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._logger.debug(command_= res.command)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0raise TestCaseVerifyError(failure_descrip= tion)

-=C2=A0 =C2=A0 def verify_packets(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self, expected_packet: Packet, received_packet= s: list[Packet]
-=C2=A0 =C2=A0 ) -> None:
+=C2=A0 =C2=A0 def verify_packets(self, expected_packet: Packet, received_p= ackets: list[Packet]) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0for received_packet in received_packets:<= br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if self._compare_packets(ex= pected_packet, received_packet):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break
@@ -225,17 +215,11 @@ def verify_packets(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0f"The ex= pected packet {get_packet_summaries(expected_packet)} "
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0f"not fo= und among received {get_packet_summaries(received_packets)}"
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self._fail_test_case_verify(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "An expected = packet not found among received packets."
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self._fail_test_case_verify(&quo= t;An expected packet not found among received packets.")

-=C2=A0 =C2=A0 def _compare_packets(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self, expected_packet: Packet, received_packet= : Packet
-=C2=A0 =C2=A0 ) -> bool:
+=C2=A0 =C2=A0 def _compare_packets(self, expected_packet: Packet, received= _packet: Packet) -> bool:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._logger.debug(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "Comparing packets: \n"= ;
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"{expected_packet.summary(= )}\n"
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"{received_packet.summary(= )}"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "Comparing packets: \n"= ; f"{expected_packet.summary()}\n" f"{received_packet.summar= y()}"

Same situation as above where you w= ould want to make sure to put the f at the start.
=C2= =A0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0l3 =3D IP in expected_packet.layers()
@@ -262,14 +246,10 @@ def _compare_packets(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0expected_payload =3D expect= ed_payload.payload

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if expected_payload:
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger.debug(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"The expecte= d packet did not contain {expected_payload}."
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger.debug(f"The ex= pected packet did not contain {expected_payload}.")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return False
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if received_payload and received_payload.= __class__ !=3D Padding:
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger.debug(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "The received= payload had extra layers which were not padding."
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger.debug("The rec= eived payload had extra layers which were not padding.")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return False
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return True

@@ -296,10 +276,7 @@ def _verify_l2_frame(self, received_packet: Ether, l3:= bool) -> bool:

=C2=A0 =C2=A0 =C2=A0def _verify_l3_packet(self, received_packet: IP, expect= ed_packet: IP) -> bool:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._logger.debug("Looking at the I= P layer.")
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 received_packet.src !=3D expecte= d_packet.src
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 or received_packet.dst !=3D expe= cted_packet.dst
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 ):
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if received_packet.src !=3D expected_packet.sr= c or received_packet.dst !=3D expected_packet.dst:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return False
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return True

@@ -373,9 +350,7 @@ def _get_test_cases(self, test_case_regex: str) -> l= ist[MethodType]:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if self._should_be_executed= (test_case_name, test_case_regex):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0filtered_test= _cases.append(test_case)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0cases_str =3D ", ".join((x.__na= me__ for x in filtered_test_cases))
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger.debug(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"Found test cases '{ca= ses_str}' in {self.__class__.__name__}."
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger.debug(f"Found test cases = 9;{cases_str}' in {self.__class__.__name__}.")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return filtered_test_cases

=C2=A0 =C2=A0 =C2=A0def _should_be_executed(self, test_case_name: str, test= _case_regex: str) -> bool:
@@ -445,9 +420,7 @@ def _execute_test_case(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._logger.exception(f&qu= ot;Test case execution ERROR: {test_case_name}")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0test_case_result.update(Res= ult.ERROR, e)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0except KeyboardInterrupt:
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger.error(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"Test case e= xecution INTERRUPTED by user: {test_case_name}"
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger.error(f"Test c= ase execution INTERRUPTED by user: {test_case_name}")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0test_case_result.update(Res= ult.SKIP)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0raise KeyboardInterrupt(&qu= ot;Stop DTS")

@@ -464,9 +437,7 @@ def is_test_suite(object) -> bool:
=C2=A0 =C2=A0 =C2=A0try:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0testcase_module =3D importlib.import_modu= le(testsuite_module_path)
=C2=A0 =C2=A0 =C2=A0except ModuleNotFoundError as e:
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 raise ConfigurationError(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"Test suite '{testsuit= e_module_path}' not found."
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 ) from e
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 raise ConfigurationError(f"Test suite = 9;{testsuite_module_path}' not found.") from e
=C2=A0 =C2=A0 =C2=A0return [
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0test_suite_class
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0for _, test_suite_class in inspect.getmem= bers(testcase_module, is_test_suite)
diff --git a/dts/framework/testbed_model/capturing_traffic_generator.py b/d= ts/framework/testbed_model/capturing_traffic_generator.py
index ab98987f8e..48d019ab21 100644
--- a/dts/framework/testbed_model/capturing_traffic_generator.py
+++ b/dts/framework/testbed_model/capturing_traffic_generator.py
@@ -110,9 +110,7 @@ def send_packets_and_capture(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0duration,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)

-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger.debug(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"Received packets: {get_pa= cket_summaries(received_packets)}"
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger.debug(f"Received packets: {g= et_packet_summaries(received_packets)}")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._write_capture_from_packets(capture_= name, received_packets)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return received_packets

diff --git a/dts/framework/testbed_model/hw/cpu.py b/dts/framework/testbed_= model/hw/cpu.py
index d1918a12dc..cbc5fe7fff 100644
--- a/dts/framework/testbed_model/hw/cpu.py
+++ b/dts/framework/testbed_model/hw/cpu.py
@@ -54,9 +54,7 @@ def __init__(self, lcore_list: list[int] | list[str] | li= st[LogicalCore] | str):

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0# the input lcores may not be sorted
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._lcore_list.sort()
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._lcore_str =3D (
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f'{",".join(self._= get_consecutive_lcores_range(self._lcore_list))}'
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._lcore_str =3D f'{",".join(= self._get_consecutive_lcores_range(self._lcore_list))}'

=C2=A0 =C2=A0 =C2=A0@property
=C2=A0 =C2=A0 =C2=A0def lcore_list(self) -> list[int]:
@@ -70,15 +68,11 @@ def _get_consecutive_lcores_range(self, lcore_ids_list:= list[int]) -> list[str]:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0segment.appen= d(lcore_id)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0formatted_cor= e_list.append(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f&qu= ot;{segment[0]}-{segment[-1]}"
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if l= en(segment) > 1
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 else= f"{segment[0]}"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f&qu= ot;{segment[0]}-{segment[-1]}" if len(segment) > 1 else f"{seg= ment[0]}"
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0current_core_= index =3D lcore_ids_list.index(lcore_id)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0formatted_cor= e_list.extend(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self= ._get_consecutive_lcores_range(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 lcore_ids_list[current_core_index:]
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ) +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self= ._get_consecutive_lcores_range(lcore_ids_list[current_core_index:])
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0segment.clear= ()
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break
@@ -125,9 +119,7 @@ def __init__(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._filter_specifier =3D filter_specifi= er

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0# sorting by core is needed in case hyper= threading is enabled
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._lcores_to_filter =3D sorted(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 lcore_list, key=3Dlambda x: x.co= re, reverse=3Dnot ascending
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._lcores_to_filter =3D sorted(lcore_list, = key=3Dlambda x: x.core, reverse=3Dnot ascending)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self.filter()

=C2=A0 =C2=A0 =C2=A0@abstractmethod
@@ -220,9 +212,7 @@ def _filter_cores_from_socket(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0# we have enough lcores per this core
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0continue
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 elif self._filter_specifier.core= s_per_socket > len(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 lcore_count_per_co= re_map
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ):
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 elif self._filter_specifier.core= s_per_socket > len(lcore_count_per_core_map):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0# only add co= res if we need more
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0lcore_count_p= er_core_map[lcore.core] =3D 1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0filtered_lcor= es.append(lcore)
diff --git a/dts/framework/testbed_model/node.py b/dts/framework/testbed_mo= del/node.py
index fc01e0bf8e..ef700d8114 100644
--- a/dts/framework/testbed_model/node.py
+++ b/dts/framework/testbed_model/node.py
@@ -103,18 +103,14 @@ def _tear_down_execution(self) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0is not decorated so that the derived clas= s doesn't have to use the decorator.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"""

-=C2=A0 =C2=A0 def set_up_build_target(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self, build_target_config: BuildTargetConfigur= ation
-=C2=A0 =C2=A0 ) -> None:
+=C2=A0 =C2=A0 def set_up_build_target(self, build_target_config: BuildTarg= etConfiguration) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"""
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Perform the build target setup that will = be done for each build target
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tested on this node.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"""
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._set_up_build_target(build_target_co= nfig)

-=C2=A0 =C2=A0 def _set_up_build_target(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self, build_target_config: BuildTargetConfigur= ation
-=C2=A0 =C2=A0 ) -> None:
+=C2=A0 =C2=A0 def _set_up_build_target(self, build_target_config: BuildTar= getConfiguration) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"""
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0This method exists to be optionally overw= ritten by derived classes and
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0is not decorated so that the derived clas= s doesn't have to use the decorator.
diff --git a/dts/framework/testbed_model/scapy.py b/dts/framework/testbed_m= odel/scapy.py
index af0d4dbb25..7948424951 100644
--- a/dts/framework/testbed_model/scapy.py
+++ b/dts/framework/testbed_model/scapy.py
@@ -96,9 +96,7 @@ def scapy_send_packets_and_capture(
=C2=A0 =C2=A0 =C2=A0return [scapy_packet.build() for scapy_packet in sniffe= r.stop(join=3DTrue)]


-def scapy_send_packets(
-=C2=A0 =C2=A0 xmlrpc_packets: list[xmlrpc.client.Binary], send_iface: str<= br> -) -> None:
+def scapy_send_packets(xmlrpc_packets: list[xmlrpc.client.Binary], send_if= ace: str) -> None:
=C2=A0 =C2=A0 =C2=A0"""RPC function to send packets.

=C2=A0 =C2=A0 =C2=A0The function is meant to be executed on the remote TG n= ode.
@@ -197,9 +195,7 @@ class ScapyTrafficGenerator(CapturingTrafficGenerator):=
=C2=A0 =C2=A0 =C2=A0def __init__(self, tg_node: TGNode, config: ScapyTraffi= cGeneratorConfig):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._config =3D config
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._tg_node =3D tg_node
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger =3D getLogger(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"{self._tg_node.name} {self.= _config.traffic_generator_type}"
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._logger =3D getLogger(f"{self._tg_node.nam= e} {self._config.traffic_generator_type}")

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0assert (
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._tg_node.config.os =3D= =3D OS.linux
@@ -218,9 +214,7 @@ def __init__(self, tg_node: TGNode, config: ScapyTraffi= cGeneratorConfig):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._start_xmlrpc_server_in_remote_pytho= n(xmlrpc_server_listen_port)

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0# connect to the server
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 server_url =3D (
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"http://{self._tg_node.con= fig.hostname}:{xmlrpc_server_listen_port}"
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 server_url =3D f"http://{self._tg_node.co= nfig.hostname}:{xmlrpc_server_listen_port}"
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self.rpc_server_proxy =3D xmlrpc.client.S= erverProxy(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0server_url, allow_none=3DTr= ue, verbose=3DSETTINGS.verbose
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)
@@ -240,9 +234,7 @@ def _start_xmlrpc_server_in_remote_python(self, listen_= port: int):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0src =3D inspect.getsource(QuittableXMLRPC= Server)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0# Lines with only whitespace break the re= pl if in the middle of a function
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0# or class, so strip all lines containing= only whitespace
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 src =3D "\n".join(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 [line for line in src.splitlines= () if not line.isspace() and line !=3D ""]
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 src =3D "\n".join([line for line in = src.splitlines() if not line.isspace() and line !=3D ""])

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0spacing =3D "\n" * 4

diff --git a/dts/framework/testbed_model/sut_node.py b/dts/framework/testbe= d_model/sut_node.py
index 202aebfd06..dfd8c755b4 100644
--- a/dts/framework/testbed_model/sut_node.py
+++ b/dts/framework/testbed_model/sut_node.py
@@ -129,9 +129,7 @@ def remote_dpdk_build_dir(self) -> PurePath:
=C2=A0 =C2=A0 =C2=A0@property
=C2=A0 =C2=A0 =C2=A0def dpdk_version(self) -> str:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if self._dpdk_version is None:
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self._dpdk_version =3D self.main= _session.get_dpdk_version(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self._remote_dpdk_= dir
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self._dpdk_version =3D self.main= _session.get_dpdk_version(self._remote_dpdk_dir)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return self._dpdk_version

=C2=A0 =C2=A0 =C2=A0@property
@@ -149,8 +147,7 @@ def compiler_version(self) -> str:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._logger.= warning(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &quo= t;Failed to get compiler version because"
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &quo= t;_build_target_config is None."
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &quo= t;Failed to get compiler version because" "_build_target_config i= s None."

Double string here.
=C2=A0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return "= "
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return self._compiler_version
@@ -163,9 +160,7 @@ def get_build_target_info(self) -> BuildTargetInfo:<= br> =C2=A0 =C2=A0 =C2=A0def _guess_dpdk_remote_dir(self) -> PurePath:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return self.main_session.guess_dpdk_remot= e_dir(self._remote_tmp_dir)

-=C2=A0 =C2=A0 def _set_up_build_target(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self, build_target_config: BuildTargetConfigur= ation
-=C2=A0 =C2=A0 ) -> None:
+=C2=A0 =C2=A0 def _set_up_build_target(self, build_target_config: BuildTar= getConfiguration) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"""
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Setup DPDK on the SUT node.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"""
@@ -177,22 +172,17 @@ def _set_up_build_target(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._copy_dpdk_tarball()
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._build_dpdk()

-=C2=A0 =C2=A0 def _configure_build_target(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self, build_target_config: BuildTargetConfigur= ation
-=C2=A0 =C2=A0 ) -> None:
+=C2=A0 =C2=A0 def _configure_build_target(self, build_target_config: Build= TargetConfiguration) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"""
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Populate common environment variables and= set build target config.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"""
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._env_vars =3D {}
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._build_target_config =3D build_targe= t_config
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._env_vars.update(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.main_session.get_dpdk_build= _env_vars(build_target_config.arch)
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._env_vars.update(self.main_session.get_dp= dk_build_env_vars(build_target_config.arch))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._env_vars["CC"] =3D build_target_config.compiler.name
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if build_target_config.compiler_wrapper:<= br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._env_vars["CC&quo= t;] =3D (
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"'{build= _target_config.compiler_wrapper} "
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"{build_target_config.compiler.name}'"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"'{build= _target_config.compiler_wrapper} " f"{build_target= _config.compiler.name}'"

<= div style=3D"font-family:arial,sans-serif" class=3D"gmail_default">Double s= tring here.
=C2=A0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)

=C2=A0 =C2=A0 =C2=A0@Node.skip_setup
@@ -224,9 +214,7 @@ def _copy_dpdk_tarball(self) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self.main_session.remove_remote_dir(self.= _remote_dpdk_dir)

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0# then extract to remote path
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.main_session.extract_remote_tarball(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 remote_tarball_path, self._remot= e_dpdk_dir
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.main_session.extract_remote_tarball(remot= e_tarball_path, self._remote_dpdk_dir)

=C2=A0 =C2=A0 =C2=A0@Node.skip_setup
=C2=A0 =C2=A0 =C2=A0def _build_dpdk(self) -> None:
@@ -263,9 +251,7 @@ def build_dpdk_app(self, app_name: str, **meson_dpdk_ar= gs: str | bool) -> PurePa
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if app_name =3D=3D "all":
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return self.main_session.join_re= mote_path(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.remote_dpdk_b= uild_dir, "examples"
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return self.main_session.join_re= mote_path(self.remote_dpdk_build_dir, "examples")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return self.main_session.join_remote_path= (
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self.remote_dpdk_build_dir,= "examples", f"dpdk-{app_name}"
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)
@@ -319,9 +305,7 @@ def create_eal_parameters(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0'-c 0xf -= a 0000:88:00.0 --file-prefix=3Ddpdk_1112_20190809143420';
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"""

-=C2=A0 =C2=A0 =C2=A0 =C2=A0 lcore_list =3D LogicalCoreList(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.filter_lcores(lcore_filter_= specifier, ascending_cores)
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 lcore_list =3D LogicalCoreList(self.filter_lco= res(lcore_filter_specifier, ascending_cores))

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if append_prefix_timestamp:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0prefix =3D f"{prefix}_= {self._dpdk_timestamp}"
@@ -386,6 +370,4 @@ def create_interactive_shell(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self.remote_d= pdk_build_dir, shell_cls.path
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)

-=C2=A0 =C2=A0 =C2=A0 =C2=A0 return super().create_interactive_shell(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 shell_cls, timeout, privileged, = str(eal_parameters)
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 return super().create_interactive_shell(shell_= cls, timeout, privileged, str(eal_parameters))
diff --git a/dts/framework/testbed_model/tg_node.py b/dts/framework/testbed= _model/tg_node.py
index 27025cfa31..dca4ec0849 100644
--- a/dts/framework/testbed_model/tg_node.py
+++ b/dts/framework/testbed_model/tg_node.py
@@ -45,9 +45,7 @@ class TGNode(Node):

=C2=A0 =C2=A0 =C2=A0def __init__(self, node_config: TGNodeConfiguration): =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0super(TGNode, self).__init__(node_config)=
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.traffic_generator =3D create_traffic_gene= rator(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self, node_config.traffic_genera= tor
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.traffic_generator =3D create_traffic_gene= rator(self, node_config.traffic_generator)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._logger.info(f"Created node: {self.name}")

=C2=A0 =C2=A0 =C2=A0def send_packet_and_capture(
@@ -94,6 +92,5 @@ def create_traffic_generator(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return ScapyTrafficGenerato= r(tg_node, traffic_generator_config)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case _:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0raise ConfigurationError( -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "Unknown traf= fic generator: "
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"{traffic_ge= nerator_config.traffic_generator_type}"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "Unknown traf= fic generator: " f"{traffic_generator_config.traffic_generator_ty= pe}"

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)
diff --git a/dts/framework/utils.py b/dts/framework/utils.py
index d27c2c5b5f..d098d364ff 100644
--- a/dts/framework/utils.py
+++ b/dts/framework/utils.py
@@ -19,9 +19,7 @@

=C2=A0class StrEnum(Enum):
=C2=A0 =C2=A0 =C2=A0@staticmethod
-=C2=A0 =C2=A0 def _generate_next_value_(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 name: str, start: int, count: int, last_values= : object
-=C2=A0 =C2=A0 ) -> str:
+=C2=A0 =C2=A0 def _generate_next_value_(name: str, start: int, count: int,= last_values: object) -> str:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return name

=C2=A0 =C2=A0 =C2=A0def __str__(self) -> str:
@@ -32,9 +30,7 @@ def __str__(self) -> str:


=C2=A0def check_dts_python_version() -> None:
-=C2=A0 =C2=A0 if sys.version_info.major < 3 or (
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 sys.version_info.major =3D=3D 3 and sys.versio= n_info.minor < 10
-=C2=A0 =C2=A0 ):
+=C2=A0 =C2=A0 if sys.version_info.major < 3 or (sys.version_info.major = =3D=3D 3 and sys.version_info.minor < 10):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0print(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0RED(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(
@@ -60,9 +56,7 @@ def expand_range(range_str: str) -> list[int]:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0range_boundaries =3D range_str.split(&quo= t;-")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0# will throw an exception when items in r= ange_boundaries can't be converted,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0# serving as type check
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 expanded_range.extend(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 range(int(range_boundaries[0]), = int(range_boundaries[-1]) + 1)
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 expanded_range.extend(range(int(range_boundari= es[0]), int(range_boundaries[-1]) + 1))

=C2=A0 =C2=A0 =C2=A0return expanded_range

@@ -71,9 +65,7 @@ def get_packet_summaries(packets: list[Packet]):
=C2=A0 =C2=A0 =C2=A0if len(packets) =3D=3D 1:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0packet_summaries =3D packets[0].summary()=
=C2=A0 =C2=A0 =C2=A0else:
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 packet_summaries =3D json.dumps(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 list(map(lambda pkt: pkt.summary= (), packets)), indent=3D4
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 packet_summaries =3D json.dumps(list(map(lambd= a pkt: pkt.summary(), packets)), indent=3D4)
=C2=A0 =C2=A0 =C2=A0return f"Packet contents: \n{packet_summaries}&quo= t;


@@ -94,9 +86,7 @@ class MesonArgs(object):
=C2=A0 =C2=A0 =C2=A0_default_library: str

=C2=A0 =C2=A0 =C2=A0def __init__(self, default_library: str | None =3D None= , **dpdk_args: str | bool):
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._default_library =3D (
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"--default-library=3D{defa= ult_library}" if default_library else ""
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._default_library =3D f"--default-lib= rary=3D{default_library}" if default_library else ""
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._dpdk_args =3D " ".join( =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0f"-D{dpd= k_arg_name}=3D{dpdk_arg_value}"
diff --git a/dts/pyproject.toml b/dts/pyproject.toml
index 6762edfa6b..980ac3c7db 100644
--- a/dts/pyproject.toml
+++ b/dts/pyproject.toml
@@ -41,7 +41,7 @@ build-backend =3D "poetry.core.masonry.api"
=C2=A0[tool.pylama]
=C2=A0linters =3D "mccabe,pycodestyle,pyflakes"
=C2=A0format =3D "pylint"
-max_line_length =3D 88 #
https://black.readthedocs.io/en/stable/the_black_code_style= /current_style.html#line-length
+max_line_length =3D 100

=C2=A0[tool.mypy]
=C2=A0python_version =3D "3.10"
@@ -55,4 +55,4 @@ profile =3D "black"
=C2=A0[tool.black]
=C2=A0target-version =3D ['py310']
=C2=A0include =3D '\.pyi?$'
-line-length =3D 88 # https://black.readthedocs.io/en/stable/the_black_co= de_style/current_style.html#line-length
+line-length
=3D 100
diff --git a/dts/tests/TestSuite_hello_world.py b/dts/tests/TestSuite_hello= _world.py
index 7e3d95c0cf..768ba1cfa8 100644
--- a/dts/tests/TestSuite_hello_world.py
+++ b/dts/tests/TestSuite_hello_world.py
@@ -34,9 +34,7 @@ def test_hello_world_single_core(self) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0# get the first usable core
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0lcore_amount =3D LogicalCoreCount(1, 1, 1= )
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0lcores =3D LogicalCoreCountFilter(self.su= t_node.lcores, lcore_amount).filter()
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 eal_para =3D self.sut_node.create_eal_paramete= rs(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 lcore_filter_specifier=3Dlcore_a= mount
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 eal_para =3D self.sut_node.create_eal_paramete= rs(lcore_filter_specifier=3Dlcore_amount)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0result =3D self.sut_node.run_dpdk_app(sel= f.app_helloworld_path, eal_para)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self.verify(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0f"hello from core {int= (lcores[0])}" in result.stdout,
diff --git a/dts/tests/TestSuite_smoke_tests.py b/dts/tests/TestSuite_smoke= _tests.py
index 4a269df75b..36119e6469 100644
--- a/dts/tests/TestSuite_smoke_tests.py
+++ b/dts/tests/TestSuite_smoke_tests.py
@@ -45,13 +45,10 @@ def test_driver_tests(self) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0for dev in self.sut_node.virtual_devices:=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0vdev_args +=3D f"--vde= v {dev} "
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0vdev_args =3D vdev_args[:-1]
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 driver_tests_command =3D (
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"meson test -C {self.dpdk_= build_dir_path} --suite driver-tests"
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 driver_tests_command =3D f"meson test -C = {self.dpdk_build_dir_path} --suite driver-tests"
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if vdev_args:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._logger.info(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "Running driv= er tests with the following virtual "
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f"devices: {v= dev_args}"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "Running driv= er tests with the following virtual " f"devices: {vdev_args}"= ;

Double string that should be an f-string.
=C2=A0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0driver_tests_command +=3D f= ' --test-args "{vdev_args}"'

@@ -67,9 +64,7 @@ def test_devices_listed_in_testpmd(self) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Test:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Uses testpmd driver to veri= fy that devices have been found by testpmd.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"""
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 testpmd_driver =3D self.sut_node.create_intera= ctive_shell(
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 TestPmdShell, privileged=3DTrue<= br> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 testpmd_driver =3D self.sut_node.create_intera= ctive_shell(TestPmdShell, privileged=3DTrue)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0dev_list =3D [str(x) for x in testpmd_dri= ver.get_devices()]
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0for nic in self.nics_in_node:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self.verify(
--
2.34.1

--00000000000083dea00606663dde--