get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/125444/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 125444,
    "url": "http://patches.dpdk.org/api/patches/125444/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20230323104040.484708-2-juraj.linkes@pantheon.tech/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20230323104040.484708-2-juraj.linkes@pantheon.tech>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230323104040.484708-2-juraj.linkes@pantheon.tech",
    "date": "2023-03-23T10:40:37",
    "name": "[RFC,v1,1/4] dts: code adjustments for sphinx",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "a92a6feb8acc62bfc8f91f6f090b3e87abb88431",
    "submitter": {
        "id": 1626,
        "url": "http://patches.dpdk.org/api/people/1626/?format=api",
        "name": "Juraj Linkeš",
        "email": "juraj.linkes@pantheon.tech"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20230323104040.484708-2-juraj.linkes@pantheon.tech/mbox/",
    "series": [
        {
            "id": 27515,
            "url": "http://patches.dpdk.org/api/series/27515/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=27515",
            "date": "2023-03-23T10:40:36",
            "name": "dts: add dts api docs",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/27515/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/125444/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/125444/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 8E78642813;\n\tThu, 23 Mar 2023 11:40:51 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id EC19A427E9;\n\tThu, 23 Mar 2023 11:40:47 +0100 (CET)",
            "from mail-ed1-f43.google.com (mail-ed1-f43.google.com\n [209.85.208.43]) by mails.dpdk.org (Postfix) with ESMTP id A748A4021D\n for <dev@dpdk.org>; Thu, 23 Mar 2023 11:40:45 +0100 (CET)",
            "by mail-ed1-f43.google.com with SMTP id o12so84379875edb.9\n for <dev@dpdk.org>; Thu, 23 Mar 2023 03:40:45 -0700 (PDT)",
            "from localhost.localdomain (ip-46.34.245.107.o2inet.sk.\n [46.34.245.107]) by smtp.gmail.com with ESMTPSA id\n k10-20020a1709067aca00b009294524ac21sm8472773ejo.60.2023.03.23.03.40.44\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Thu, 23 Mar 2023 03:40:45 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=pantheon-tech.20210112.gappssmtp.com; s=20210112; t=1679568045;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=oz1ozGAfsGcPbj+0Q5e7u1+iFyJENA04XuWWAh1NbH8=;\n b=zZzmUCzGDZ17ULcoJy8IyCy5T7JW0OdX7jQKwu39M905ZEobv45Z/6JT7AxVGW1KVG\n +1TgsrCXPBki9GrVVI0wAppgHFv1JVrTEiNUuJaZ7NjEK9uRL2AUy0bWFIiVVUCGid7k\n +O6GPpY+wceCgdUZNGAnJFZuzXmDmv4AYdcLX0BesAObsU8f04nP7KUfvEFGwj2HbjVj\n rHGahll8bO3RN5XFuNgD+7HtzUsCxi0ApimhyO2eyDo4sm4lsvH7pyryZe3Q5uv+gCFm\n qYli4OzfONhHxmAAQlTEVl43LT6+ElpweB/CZsF8YZ2PzX4EoqBXuuYQ/Z0+XefKW+rI\n rZEw==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20210112; t=1679568045;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc\n :subject:date:message-id:reply-to;\n bh=oz1ozGAfsGcPbj+0Q5e7u1+iFyJENA04XuWWAh1NbH8=;\n b=4gVkGba5aNXYDFn/Psr2dobdUr+aXviJUjxRuHsRDzG7jKjlY15uvxIucW1ChFpDpC\n f8NJUqK3p/1Dx8dVtDmn6j2OpDvsbrB7sYrjBa/ujE77BTarthLtNolhzQJn9XD6CkXl\n 2ELW1twKv0XSSQ0gp7SwuMgPISqPYmQx1PrPBGhcMpZAhON5I2rJyyMMLH/9rATVxW4o\n RNUkrKN0zC1oJF//QQWtwzTSZcAhrHgaq6O4kdA6aBPSh27JvWC/WqLKfO5zVYgSrLNY\n vxX2+hp0TVLDit/G0LEGq5pqIbS76ICwTUgk0n2RZmp8aaLp2pP+ISyMh7gWOtmGur25\n z2MA==",
        "X-Gm-Message-State": "AO0yUKUIueCX/5Go+Rvyg0DvYbbLFx+clbg851lDh03bNk903Z8kXNuw\n sBo0VeBr2neTiT5UFNarTukQAw==",
        "X-Google-Smtp-Source": "\n AK7set/RSq3b/nHuxzGtZGGrMpn1DHsIi5tTTPZL0diIq6eO4B3+YbRYkZPnL/Rz/IhIhhvcOlteNg==",
        "X-Received": "by 2002:a17:907:d8c:b0:926:e917:133c with SMTP id\n go12-20020a1709070d8c00b00926e917133cmr12814205ejc.47.1679568045259;\n Thu, 23 Mar 2023 03:40:45 -0700 (PDT)",
        "From": "=?utf-8?q?Juraj_Linke=C5=A1?= <juraj.linkes@pantheon.tech>",
        "To": "thomas@monjalon.net, Honnappa.Nagarahalli@arm.com, lijuan.tu@intel.com,\n bruce.richardson@intel.com, wathsala.vithanage@arm.com,\n jspewock@iol.unh.edu",
        "Cc": "dev@dpdk.org, =?utf-8?q?Juraj_Linke=C5=A1?= <juraj.linkes@pantheon.tech>",
        "Subject": "[RFC PATCH v1 1/4] dts: code adjustments for sphinx",
        "Date": "Thu, 23 Mar 2023 11:40:37 +0100",
        "Message-Id": "<20230323104040.484708-2-juraj.linkes@pantheon.tech>",
        "X-Mailer": "git-send-email 2.30.2",
        "In-Reply-To": "<20230323104040.484708-1-juraj.linkes@pantheon.tech>",
        "References": "<20230323104040.484708-1-juraj.linkes@pantheon.tech>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "sphinx-build only imports the Python modules when building the\ndocumentation; it doesn't run DTS. This requires changes that make the\ncode importable without running it. This means:\n* properly guarding argument parsing in the if __name__ == '__main__'\n  block.\n* the logger used by DTS runner underwent the same treatment so that it\n  doesn't create unnecessary log files.\n* however, DTS uses the arguments to construct an object holding global\n  variables. The defaults for the global variables needed to be moved\n  from argument parsing elsewhere.\n* importing the remote_session module from framework resulted in\n  circular imports because of one module trying to import another\n  module. This is fixed by more granular imports.\n\nSigned-off-by: Juraj Linkeš <juraj.linkes@pantheon.tech>\n---\n dts/framework/config/__init__.py              | 11 ++++\n .../{testbed_model/hw => config}/cpu.py       | 13 +++++\n dts/framework/dts.py                          |  8 ++-\n dts/framework/remote_session/__init__.py      |  3 +-\n dts/framework/remote_session/linux_session.py |  2 +-\n dts/framework/remote_session/os_session.py    | 12 +++-\n .../remote_session/remote/__init__.py         | 16 ------\n .../{remote => }/remote_session.py            |  0\n .../{remote => }/ssh_session.py               |  0\n dts/framework/settings.py                     | 55 ++++++++++---------\n dts/framework/testbed_model/__init__.py       | 10 +---\n dts/framework/testbed_model/hw/__init__.py    | 27 ---------\n dts/framework/testbed_model/node.py           | 12 ++--\n dts/framework/testbed_model/sut_node.py       |  9 ++-\n .../testbed_model/{hw => }/virtual_device.py  |  0\n dts/main.py                                   |  3 +-\n dts/tests/TestSuite_hello_world.py            |  6 +-\n 17 files changed, 88 insertions(+), 99 deletions(-)\n rename dts/framework/{testbed_model/hw => config}/cpu.py (95%)\n delete mode 100644 dts/framework/remote_session/remote/__init__.py\n rename dts/framework/remote_session/{remote => }/remote_session.py (100%)\n rename dts/framework/remote_session/{remote => }/ssh_session.py (100%)\n delete mode 100644 dts/framework/testbed_model/hw/__init__.py\n rename dts/framework/testbed_model/{hw => }/virtual_device.py (100%)",
    "diff": "diff --git a/dts/framework/config/__init__.py b/dts/framework/config/__init__.py\nindex ebb0823ff5..293c4cb15b 100644\n--- a/dts/framework/config/__init__.py\n+++ b/dts/framework/config/__init__.py\n@@ -7,6 +7,8 @@\n Yaml config parsing methods\n \"\"\"\n \n+# pylama:ignore=W0611\n+\n import json\n import os.path\n import pathlib\n@@ -19,6 +21,15 @@\n \n from framework.settings import SETTINGS\n \n+from .cpu import (\n+    LogicalCore,\n+    LogicalCoreCount,\n+    LogicalCoreCountFilter,\n+    LogicalCoreList,\n+    LogicalCoreListFilter,\n+    lcore_filter,\n+)\n+\n \n class StrEnum(Enum):\n     @staticmethod\ndiff --git a/dts/framework/testbed_model/hw/cpu.py b/dts/framework/config/cpu.py\nsimilarity index 95%\nrename from dts/framework/testbed_model/hw/cpu.py\nrename to dts/framework/config/cpu.py\nindex d1918a12dc..8fe785dfe4 100644\n--- a/dts/framework/testbed_model/hw/cpu.py\n+++ b/dts/framework/config/cpu.py\n@@ -272,3 +272,16 @@ def filter(self) -> list[LogicalCore]:\n             )\n \n         return filtered_lcores\n+\n+\n+def lcore_filter(\n+    core_list: list[LogicalCore],\n+    filter_specifier: LogicalCoreCount | LogicalCoreList,\n+    ascending: bool,\n+) -> LogicalCoreFilter:\n+    if isinstance(filter_specifier, LogicalCoreList):\n+        return LogicalCoreListFilter(core_list, filter_specifier, ascending)\n+    elif isinstance(filter_specifier, LogicalCoreCount):\n+        return LogicalCoreCountFilter(core_list, filter_specifier, ascending)\n+    else:\n+        raise ValueError(f\"Unsupported filter r{filter_specifier}\")\ndiff --git a/dts/framework/dts.py b/dts/framework/dts.py\nindex 0502284580..22a09b7e34 100644\n--- a/dts/framework/dts.py\n+++ b/dts/framework/dts.py\n@@ -3,6 +3,7 @@\n # Copyright(c) 2022-2023 PANTHEON.tech s.r.o.\n # Copyright(c) 2022-2023 University of New Hampshire\n \n+import logging\n import sys\n \n from .config import CONFIGURATION, BuildTargetConfiguration, ExecutionConfiguration\n@@ -12,7 +13,8 @@\n from .testbed_model import SutNode\n from .utils import check_dts_python_version\n \n-dts_logger: DTSLOG = getLogger(\"DTSRunner\")\n+# dummy defaults to satisfy linters\n+dts_logger: DTSLOG | logging.Logger = logging.getLogger(\"DTSRunner\")\n result: DTSResult = DTSResult(dts_logger)\n \n \n@@ -24,6 +26,10 @@ def run_all() -> None:\n     global dts_logger\n     global result\n \n+    # create a regular DTS logger and create a new result with it\n+    dts_logger = getLogger(\"DTSRunner\")\n+    result = DTSResult(dts_logger)\n+\n     # check the python version of the server that run dts\n     check_dts_python_version()\n \ndiff --git a/dts/framework/remote_session/__init__.py b/dts/framework/remote_session/__init__.py\nindex ee221503df..17ca1459f7 100644\n--- a/dts/framework/remote_session/__init__.py\n+++ b/dts/framework/remote_session/__init__.py\n@@ -17,7 +17,8 @@\n \n from .linux_session import LinuxSession\n from .os_session import OSSession\n-from .remote import CommandResult, RemoteSession, SSHSession\n+from .remote_session import CommandResult, RemoteSession\n+from .ssh_session import SSHSession\n \n \n def create_session(\ndiff --git a/dts/framework/remote_session/linux_session.py b/dts/framework/remote_session/linux_session.py\nindex a1e3bc3a92..c8ce5fe6da 100644\n--- a/dts/framework/remote_session/linux_session.py\n+++ b/dts/framework/remote_session/linux_session.py\n@@ -2,8 +2,8 @@\n # Copyright(c) 2023 PANTHEON.tech s.r.o.\n # Copyright(c) 2023 University of New Hampshire\n \n+from framework.config import LogicalCore\n from framework.exception import RemoteCommandExecutionError\n-from framework.testbed_model import LogicalCore\n from framework.utils import expand_range\n \n from .posix_session import PosixSession\ndiff --git a/dts/framework/remote_session/os_session.py b/dts/framework/remote_session/os_session.py\nindex 4c48ae2567..246f0358ea 100644\n--- a/dts/framework/remote_session/os_session.py\n+++ b/dts/framework/remote_session/os_session.py\n@@ -6,13 +6,13 @@\n from collections.abc import Iterable\n from pathlib import PurePath\n \n-from framework.config import Architecture, NodeConfiguration\n+from framework.config import Architecture, LogicalCore, NodeConfiguration\n from framework.logger import DTSLOG\n from framework.settings import SETTINGS\n-from framework.testbed_model import LogicalCore\n from framework.utils import EnvVarsDict, MesonArgs\n \n-from .remote import CommandResult, RemoteSession, create_remote_session\n+from .remote_session import CommandResult, RemoteSession\n+from .ssh_session import SSHSession\n \n \n class OSSession(ABC):\n@@ -173,3 +173,9 @@ def setup_hugepages(self, hugepage_amount: int, force_first_numa: bool) -> None:\n         if needed and mount the hugepages if needed.\n         If force_first_numa is True, configure hugepages just on the first socket.\n         \"\"\"\n+\n+\n+def create_remote_session(\n+    node_config: NodeConfiguration, name: str, logger: DTSLOG\n+) -> RemoteSession:\n+    return SSHSession(node_config, name, logger)\ndiff --git a/dts/framework/remote_session/remote/__init__.py b/dts/framework/remote_session/remote/__init__.py\ndeleted file mode 100644\nindex 8a1512210a..0000000000\n--- a/dts/framework/remote_session/remote/__init__.py\n+++ /dev/null\n@@ -1,16 +0,0 @@\n-# SPDX-License-Identifier: BSD-3-Clause\n-# Copyright(c) 2023 PANTHEON.tech s.r.o.\n-\n-# pylama:ignore=W0611\n-\n-from framework.config import NodeConfiguration\n-from framework.logger import DTSLOG\n-\n-from .remote_session import CommandResult, RemoteSession\n-from .ssh_session import SSHSession\n-\n-\n-def create_remote_session(\n-    node_config: NodeConfiguration, name: str, logger: DTSLOG\n-) -> RemoteSession:\n-    return SSHSession(node_config, name, logger)\ndiff --git a/dts/framework/remote_session/remote/remote_session.py b/dts/framework/remote_session/remote_session.py\nsimilarity index 100%\nrename from dts/framework/remote_session/remote/remote_session.py\nrename to dts/framework/remote_session/remote_session.py\ndiff --git a/dts/framework/remote_session/remote/ssh_session.py b/dts/framework/remote_session/ssh_session.py\nsimilarity index 100%\nrename from dts/framework/remote_session/remote/ssh_session.py\nrename to dts/framework/remote_session/ssh_session.py\ndiff --git a/dts/framework/settings.py b/dts/framework/settings.py\nindex 71955f4581..144f9dea62 100644\n--- a/dts/framework/settings.py\n+++ b/dts/framework/settings.py\n@@ -6,7 +6,7 @@\n import argparse\n import os\n from collections.abc import Callable, Iterable, Sequence\n-from dataclasses import dataclass\n+from dataclasses import dataclass, field\n from pathlib import Path\n from typing import Any, TypeVar\n \n@@ -59,15 +59,18 @@ def __call__(\n \n @dataclass(slots=True, frozen=True)\n class _Settings:\n-    config_file_path: str\n-    output_dir: str\n-    timeout: float\n-    verbose: bool\n-    skip_setup: bool\n-    dpdk_tarball_path: Path\n-    compile_timeout: float\n-    test_cases: list\n-    re_run: int\n+    config_file_path: Path = Path(Path(__file__).parent.parent, \"conf.yaml\")\n+    output_dir: str = \"output\"\n+    timeout: float = 15\n+    verbose: bool = False\n+    skip_setup: bool = False\n+    dpdk_tarball_path: Path | str = \"dpdk.tar.xz\"\n+    compile_timeout: float = 1200\n+    test_cases: list[str] = field(default_factory=list)\n+    re_run: int = 0\n+\n+\n+SETTINGS: _Settings = _Settings()\n \n \n def _get_parser() -> argparse.ArgumentParser:\n@@ -81,7 +84,8 @@ def _get_parser() -> argparse.ArgumentParser:\n     parser.add_argument(\n         \"--config-file\",\n         action=_env_arg(\"DTS_CFG_FILE\"),\n-        default=\"conf.yaml\",\n+        default=SETTINGS.config_file_path,\n+        type=Path,\n         help=\"[DTS_CFG_FILE] configuration file that describes the test cases, SUTs \"\n         \"and targets.\",\n     )\n@@ -90,7 +94,7 @@ def _get_parser() -> argparse.ArgumentParser:\n         \"--output-dir\",\n         \"--output\",\n         action=_env_arg(\"DTS_OUTPUT_DIR\"),\n-        default=\"output\",\n+        default=SETTINGS.output_dir,\n         help=\"[DTS_OUTPUT_DIR] Output directory where dts logs and results are saved.\",\n     )\n \n@@ -98,7 +102,7 @@ def _get_parser() -> argparse.ArgumentParser:\n         \"-t\",\n         \"--timeout\",\n         action=_env_arg(\"DTS_TIMEOUT\"),\n-        default=15,\n+        default=SETTINGS.timeout,\n         type=float,\n         help=\"[DTS_TIMEOUT] The default timeout for all DTS operations except for \"\n         \"compiling DPDK.\",\n@@ -108,7 +112,7 @@ def _get_parser() -> argparse.ArgumentParser:\n         \"-v\",\n         \"--verbose\",\n         action=_env_arg(\"DTS_VERBOSE\"),\n-        default=\"N\",\n+        default=SETTINGS.verbose,\n         help=\"[DTS_VERBOSE] Set to 'Y' to enable verbose output, logging all messages \"\n         \"to the console.\",\n     )\n@@ -117,7 +121,7 @@ def _get_parser() -> argparse.ArgumentParser:\n         \"-s\",\n         \"--skip-setup\",\n         action=_env_arg(\"DTS_SKIP_SETUP\"),\n-        default=\"N\",\n+        default=SETTINGS.skip_setup,\n         help=\"[DTS_SKIP_SETUP] Set to 'Y' to skip all setup steps on SUT and TG nodes.\",\n     )\n \n@@ -125,7 +129,7 @@ def _get_parser() -> argparse.ArgumentParser:\n         \"--tarball\",\n         \"--snapshot\",\n         action=_env_arg(\"DTS_DPDK_TARBALL\"),\n-        default=\"dpdk.tar.xz\",\n+        default=SETTINGS.dpdk_tarball_path,\n         type=Path,\n         help=\"[DTS_DPDK_TARBALL] Path to DPDK source code tarball \"\n         \"which will be used in testing.\",\n@@ -134,7 +138,7 @@ def _get_parser() -> argparse.ArgumentParser:\n     parser.add_argument(\n         \"--compile-timeout\",\n         action=_env_arg(\"DTS_COMPILE_TIMEOUT\"),\n-        default=1200,\n+        default=SETTINGS.compile_timeout,\n         type=float,\n         help=\"[DTS_COMPILE_TIMEOUT] The timeout for compiling DPDK.\",\n     )\n@@ -142,8 +146,9 @@ def _get_parser() -> argparse.ArgumentParser:\n     parser.add_argument(\n         \"--test-cases\",\n         action=_env_arg(\"DTS_TESTCASES\"),\n-        default=\"\",\n-        help=\"[DTS_TESTCASES] Comma-separated list of test cases to execute. \"\n+        nargs=\"*\",\n+        default=SETTINGS.test_cases,\n+        help=\"[DTS_TESTCASES] A list of test cases to execute. \"\n         \"Unknown test cases will be silently ignored.\",\n     )\n \n@@ -151,7 +156,7 @@ def _get_parser() -> argparse.ArgumentParser:\n         \"--re-run\",\n         \"--re_run\",\n         action=_env_arg(\"DTS_RERUN\"),\n-        default=0,\n+        default=SETTINGS.re_run,\n         type=int,\n         help=\"[DTS_RERUN] Re-run each test case the specified amount of times \"\n         \"if a test failure occurs\",\n@@ -165,10 +170,11 @@ def _check_tarball_path(parsed_args: argparse.Namespace) -> None:\n         raise ConfigurationError(f\"DPDK tarball '{parsed_args.tarball}' doesn't exist.\")\n \n \n-def _get_settings() -> _Settings:\n+def set_settings() -> None:\n+    global SETTINGS\n     parsed_args = _get_parser().parse_args()\n     _check_tarball_path(parsed_args)\n-    return _Settings(\n+    SETTINGS = _Settings(\n         config_file_path=parsed_args.config_file,\n         output_dir=parsed_args.output_dir,\n         timeout=parsed_args.timeout,\n@@ -176,9 +182,6 @@ def _get_settings() -> _Settings:\n         skip_setup=(parsed_args.skip_setup == \"Y\"),\n         dpdk_tarball_path=parsed_args.tarball,\n         compile_timeout=parsed_args.compile_timeout,\n-        test_cases=parsed_args.test_cases.split(\",\") if parsed_args.test_cases else [],\n+        test_cases=parsed_args.test_cases,\n         re_run=parsed_args.re_run,\n     )\n-\n-\n-SETTINGS: _Settings = _get_settings()\ndiff --git a/dts/framework/testbed_model/__init__.py b/dts/framework/testbed_model/__init__.py\nindex f54a947051..148f81993d 100644\n--- a/dts/framework/testbed_model/__init__.py\n+++ b/dts/framework/testbed_model/__init__.py\n@@ -9,14 +9,6 @@\n \n # pylama:ignore=W0611\n \n-from .hw import (\n-    LogicalCore,\n-    LogicalCoreCount,\n-    LogicalCoreCountFilter,\n-    LogicalCoreList,\n-    LogicalCoreListFilter,\n-    VirtualDevice,\n-    lcore_filter,\n-)\n from .node import Node\n from .sut_node import SutNode\n+from .virtual_device import VirtualDevice\ndiff --git a/dts/framework/testbed_model/hw/__init__.py b/dts/framework/testbed_model/hw/__init__.py\ndeleted file mode 100644\nindex 88ccac0b0e..0000000000\n--- a/dts/framework/testbed_model/hw/__init__.py\n+++ /dev/null\n@@ -1,27 +0,0 @@\n-# SPDX-License-Identifier: BSD-3-Clause\n-# Copyright(c) 2023 PANTHEON.tech s.r.o.\n-\n-# pylama:ignore=W0611\n-\n-from .cpu import (\n-    LogicalCore,\n-    LogicalCoreCount,\n-    LogicalCoreCountFilter,\n-    LogicalCoreFilter,\n-    LogicalCoreList,\n-    LogicalCoreListFilter,\n-)\n-from .virtual_device import VirtualDevice\n-\n-\n-def lcore_filter(\n-    core_list: list[LogicalCore],\n-    filter_specifier: LogicalCoreCount | LogicalCoreList,\n-    ascending: bool,\n-) -> LogicalCoreFilter:\n-    if isinstance(filter_specifier, LogicalCoreList):\n-        return LogicalCoreListFilter(core_list, filter_specifier, ascending)\n-    elif isinstance(filter_specifier, LogicalCoreCount):\n-        return LogicalCoreCountFilter(core_list, filter_specifier, ascending)\n-    else:\n-        raise ValueError(f\"Unsupported filter r{filter_specifier}\")\ndiff --git a/dts/framework/testbed_model/node.py b/dts/framework/testbed_model/node.py\nindex d48fafe65d..90467981c3 100644\n--- a/dts/framework/testbed_model/node.py\n+++ b/dts/framework/testbed_model/node.py\n@@ -12,19 +12,17 @@\n from framework.config import (\n     BuildTargetConfiguration,\n     ExecutionConfiguration,\n-    NodeConfiguration,\n-)\n-from framework.logger import DTSLOG, getLogger\n-from framework.remote_session import OSSession, create_session\n-from framework.settings import SETTINGS\n-\n-from .hw import (\n     LogicalCore,\n     LogicalCoreCount,\n     LogicalCoreList,\n     LogicalCoreListFilter,\n+    NodeConfiguration,\n     lcore_filter,\n )\n+from framework.logger import DTSLOG, getLogger\n+from framework.remote_session import create_session\n+from framework.remote_session.os_session import OSSession\n+from framework.settings import SETTINGS\n \n \n class Node(object):\ndiff --git a/dts/framework/testbed_model/sut_node.py b/dts/framework/testbed_model/sut_node.py\nindex 2b2b50d982..6db4a505bb 100644\n--- a/dts/framework/testbed_model/sut_node.py\n+++ b/dts/framework/testbed_model/sut_node.py\n@@ -7,13 +7,18 @@\n import time\n from pathlib import PurePath\n \n-from framework.config import BuildTargetConfiguration, NodeConfiguration\n+from framework.config import (\n+    BuildTargetConfiguration,\n+    LogicalCoreCount,\n+    LogicalCoreList,\n+    NodeConfiguration,\n+)\n from framework.remote_session import CommandResult, OSSession\n from framework.settings import SETTINGS\n from framework.utils import EnvVarsDict, MesonArgs\n \n-from .hw import LogicalCoreCount, LogicalCoreList, VirtualDevice\n from .node import Node\n+from .virtual_device import VirtualDevice\n \n \n class SutNode(Node):\ndiff --git a/dts/framework/testbed_model/hw/virtual_device.py b/dts/framework/testbed_model/virtual_device.py\nsimilarity index 100%\nrename from dts/framework/testbed_model/hw/virtual_device.py\nrename to dts/framework/testbed_model/virtual_device.py\ndiff --git a/dts/main.py b/dts/main.py\nindex 43311fa847..060ff1b19a 100755\n--- a/dts/main.py\n+++ b/dts/main.py\n@@ -10,10 +10,11 @@\n \n import logging\n \n-from framework import dts\n+from framework import dts, settings\n \n \n def main() -> None:\n+    settings.set_settings()\n     dts.run_all()\n \n \ndiff --git a/dts/tests/TestSuite_hello_world.py b/dts/tests/TestSuite_hello_world.py\nindex 7e3d95c0cf..96c31a6c8c 100644\n--- a/dts/tests/TestSuite_hello_world.py\n+++ b/dts/tests/TestSuite_hello_world.py\n@@ -6,12 +6,8 @@\n No other EAL parameters apart from cores are used.\n \"\"\"\n \n+from framework.config import LogicalCoreCount, LogicalCoreCountFilter, LogicalCoreList\n from framework.test_suite import TestSuite\n-from framework.testbed_model import (\n-    LogicalCoreCount,\n-    LogicalCoreCountFilter,\n-    LogicalCoreList,\n-)\n \n \n class TestHelloWorld(TestSuite):\n",
    "prefixes": [
        "RFC",
        "v1",
        "1/4"
    ]
}