DPDK patches and discussions
 help / color / mirror / Atom feed
From: "Juraj Linkeš" <juraj.linkes@pantheon.tech>
To: thomas@monjalon.net, david.marchand@redhat.com,
	ronan.randles@intel.com, Honnappa.Nagarahalli@arm.com,
	ohilyard@iol.unh.edu, lijuan.tu@intel.com
Cc: dev@dpdk.org, "Juraj Linkeš" <juraj.linkes@pantheon.tech>
Subject: [RFC PATCH v1 05/10] dts: add system under test node
Date: Wed, 24 Aug 2022 16:24:49 +0000	[thread overview]
Message-ID: <20220824162454.394285-6-juraj.linkes@pantheon.tech> (raw)
In-Reply-To: <20220824162454.394285-1-juraj.linkes@pantheon.tech>

The SUT node contains methods to configure the node and build and
configure DPDK.

Signed-off-by: Juraj Linkeš <juraj.linkes@pantheon.tech>
---
 dts/framework/sut_node.py | 603 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 603 insertions(+)
 create mode 100644 dts/framework/sut_node.py

diff --git a/dts/framework/sut_node.py b/dts/framework/sut_node.py
new file mode 100644
index 0000000000..c9f5e69d73
--- /dev/null
+++ b/dts/framework/sut_node.py
@@ -0,0 +1,603 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2010-2014 Intel Corporation
+# Copyright(c) 2022 PANTHEON.tech s.r.o.
+#
+
+import os
+import re
+import tarfile
+import time
+from typing import List, Optional, Union
+
+from framework.config import NodeConfiguration
+
+from .exception import ParameterInvalidException
+from .node import Node
+from .settings import SETTINGS
+
+
+class SutNode(Node):
+    """
+    A class for managing connections to the System under test, providing
+    methods that retrieve the necessary information about the node (such as
+    cpu, memory and NIC details) and configuration capabilities.
+    """
+
+    def __init__(self, node_config: NodeConfiguration):
+        super(SutNode, self).__init__(node_config)
+        self.tg_node = None
+        self.architecture = node_config.arch
+        self.prefix_subfix = (
+            str(os.getpid()) + "_" + time.strftime("%Y%m%d%H%M%S", time.localtime())
+        )
+        self.hugepage_path = None
+        self.dpdk_version = ""
+        self.testpmd = None
+
+    def prerequisites(self):
+        """
+        Copy DPDK package to SUT and apply patch files.
+        """
+        self.prepare_package()
+        self.sut_prerequisites()
+
+    def prepare_package(self):
+        if not self.skip_setup:
+            assert os.path.isfile(SETTINGS.dpdk_ref) is True, "Invalid package"
+
+            out = self.send_expect(
+                "ls -d %s" % SETTINGS.remote_dpdk_dir, "# ", verify=True
+            )
+            if out == 2:
+                self.send_expect("mkdir -p %s" % SETTINGS.remote_dpdk_dir, "# ")
+
+            out = self.send_expect(
+                "ls %s && cd %s" % (SETTINGS.remote_dpdk_dir, SETTINGS.remote_dpdk_dir),
+                "#",
+                verify=True,
+            )
+            if out == -1:
+                raise IOError(
+                    f"A failure occurred when creating {SETTINGS.remote_dpdk_dir} on "
+                    f"{self}."
+                )
+            self.main_session.copy_file_to(SETTINGS.dpdk_ref, SETTINGS.remote_dpdk_dir)
+            self.kill_all()
+
+            # enable core dump
+            self.send_expect("ulimit -c unlimited", "#")
+
+            with tarfile.open(SETTINGS.dpdk_ref) as dpdk_tar:
+                dpdk_top_dir = dpdk_tar.getnames()[0]
+
+            remote_dpdk_top_dir = os.path.join(SETTINGS.remote_dpdk_dir, dpdk_top_dir)
+
+            # unpack the code and change to the working folder
+            self.send_expect("rm -rf %s" % remote_dpdk_top_dir, "#")
+
+            remote_dpdk_path = os.path.join(
+                SETTINGS.remote_dpdk_dir, os.path.basename(SETTINGS.dpdk_ref)
+            )
+
+            # unpack dpdk
+            out = self.send_expect(
+                f"tar xfm {remote_dpdk_path} -C {SETTINGS.remote_dpdk_dir}",
+                "# ",
+                60,
+                verify=True,
+            )
+            if out == -1:
+                raise IOError(
+                    f"Extracting remote DPDK package {remote_dpdk_path} to "
+                    f"{SETTINGS.remote_dpdk_dir} failed."
+                )
+
+            # check dpdk dir name is expect
+            out = self.send_expect("ls %s" % remote_dpdk_top_dir, "# ", 20, verify=True)
+            if out == -1:
+                raise FileNotFoundError(
+                    f"Remote DPDK dir {remote_dpdk_top_dir} not found."
+                )
+
+    def set_target(self, target):
+        """
+        Set env variable, these have to be setup all the time. Some tests
+        need to compile example apps by themselves and will fail otherwise.
+        Set hugepage on SUT and install modules required by DPDK.
+        Configure default ixgbe PMD function.
+        """
+        self.target = target
+
+        self.set_toolchain(target)
+
+        # set env variable
+        self.set_env_variable()
+
+        if not self.skip_setup:
+            self.build_install_dpdk(target)
+
+        self.setup_memory()
+
+    def set_env_variable(self):
+        # These have to be setup all the time. Some tests need to compile
+        # example apps by themselves and will fail otherwise.
+        self.send_expect("export RTE_TARGET=" + self.target, "#")
+        self.send_expect("export RTE_SDK=`pwd`", "#")
+
+    def build_install_dpdk(self, target):
+        """
+        Build DPDK source code with specified target.
+        """
+        if self.get_os() == "linux":
+            self.build_install_dpdk_linux_meson(target)
+
+    def build_install_dpdk_linux_meson(self, target):
+        """
+        Build DPDK source code on linux use meson
+        """
+        build_time = 1800
+        target_info = target.split("-")
+        arch = target_info[0]
+        toolchain = target_info[3]
+
+        default_library = "static"
+        if arch == "i686":
+            # find the pkg-config path and set the PKG_CONFIG_LIBDIR environmental variable to point it
+            out = self.send_expect("find /usr -type d -name pkgconfig", "# ")
+            pkg_path = ""
+            res_path = out.split("\r\n")
+            for cur_path in res_path:
+                if "i386" in cur_path:
+                    pkg_path = cur_path
+                    break
+            assert (
+                pkg_path != ""
+            ), "please make sure you env have the i386 pkg-config path"
+
+            self.send_expect("export CFLAGS=-m32", "# ")
+            self.send_expect("export PKG_CONFIG_LIBDIR=%s" % pkg_path, "# ")
+
+        self.send_expect("rm -rf " + target, "#")
+        out = self.send_expect(
+            "CC=%s meson -Denable_kmods=True -Dlibdir=lib --default-library=%s %s"
+            % (toolchain, default_library, target),
+            "[~|~\]]# ",
+            build_time,
+        )
+        assert "FAILED" not in out, "meson setup failed ..."
+
+        out = self.send_expect("ninja -C %s" % target, "[~|~\]]# ", build_time)
+        assert "FAILED" not in out, "ninja complie failed ..."
+
+        # copy kmod file to the folder same as make
+        out = self.send_expect(
+            "find ./%s/kernel/ -name *.ko" % target, "# ", verify=True
+        )
+        self.send_expect("mkdir -p %s/kmod" % target, "# ")
+        if not isinstance(out, int) and len(out) > 0:
+            kmod = out.split("\r\n")
+            for mod in kmod:
+                self.send_expect("cp %s %s/kmod/" % (mod, target), "# ")
+
+    def build_dpdk_apps(self, folder):
+        """
+        Build dpdk sample applications.
+        """
+        if self.get_os() == "linux":
+            return self.build_dpdk_apps_linux_meson(folder)
+
+    def build_dpdk_apps_linux_meson(self, folder):
+        """
+        Build dpdk sample applications on linux use meson
+        """
+        # icc compile need more time
+        if "icc" in self.target:
+            timeout = 300
+        else:
+            timeout = 90
+
+        target_info = self.target.split("-")
+        arch = target_info[0]
+        if arch == "i686":
+            # find the pkg-config path and set the PKG_CONFIG_LIBDIR environmental variable to point it
+            out = self.send_expect("find /usr -type d -name pkgconfig", "# ")
+            pkg_path = ""
+            res_path = out.split("\r\n")
+            for cur_path in res_path:
+                if "i386" in cur_path:
+                    pkg_path = cur_path
+                    break
+            assert (
+                pkg_path != ""
+            ), "please make sure you env have the i386 pkg-config path"
+
+            self.send_expect("export CFLAGS=-m32", "# ", alt_session=True)
+            self.send_expect(
+                "export PKG_CONFIG_LIBDIR=%s" % pkg_path, "# ", alt_session=True
+            )
+
+        folder_info = folder.split("/")
+        name = folder_info[-1]
+
+        if name == "examples":
+            example = "all"
+        else:
+            example = "/".join(folder_info[folder_info.index("examples") + 1 :])
+        out = self.send_expect(
+            "meson configure -Dexamples=%s %s" % (example, self.target), "# "
+        )
+        assert "FAILED" not in out, "Compilation error..."
+        out = self.send_expect("ninja -C %s" % self.target, "[~|~\]]# ", timeout)
+        assert "FAILED" not in out, "Compilation error..."
+
+        # verify the app build in the config path
+        if example != "all":
+            out = self.send_expect("ls %s" % self.apps_name[name], "# ", verify=True)
+            assert isinstance(out, str), (
+                "please confirm %s app path and name in app_name.cfg" % name
+            )
+
+        return out
+
+    def filter_cores_from_node_cfg(self) -> None:
+        # get core list from conf.yaml
+        core_list = []
+        all_core_list = [str(core.core) for core in self.cores]
+        core_list_str = self._config.cores
+        if core_list_str == "":
+            core_list = all_core_list
+        split_by_comma = core_list_str.split(",")
+        range_cores = []
+        for item in split_by_comma:
+            if "-" in item:
+                tmp = item.split("-")
+                range_cores.extend(
+                    [str(i) for i in range(int(tmp[0]), int(tmp[1]) + 1)]
+                )
+            else:
+                core_list.append(item)
+        core_list.extend(range_cores)
+
+        abnormal_core_list = []
+        for core in core_list:
+            if core not in all_core_list:
+                abnormal_core_list.append(core)
+
+        if abnormal_core_list:
+            self.logger.info(
+                "those %s cores are out of range system, all core list of system are %s"
+                % (abnormal_core_list, all_core_list)
+            )
+            raise Exception("configured cores out of range system")
+
+        core_list = [core for core in self.cores if str(core.core) in core_list]
+        self.cores = core_list
+        self.number_of_cores = len(self.cores)
+
+    def create_eal_parameters(
+        self,
+        fixed_prefix: bool = False,
+        socket: Optional[int] = None,
+        cores: Union[str, List[int], List[str]] = "default",
+        prefix: str = "",
+        no_pci: bool = False,
+        vdevs: List[str] = None,
+        other_eal_param: str = "",
+    ) -> str:
+        """
+        generate eal parameters character string;
+        :param fixed_prefix: use fixed file-prefix or not, when it is true,
+                             the file-prefix will not be added a timestamp
+        :param socket: the physical CPU socket index, -1 means no care cpu socket;
+        :param cores: set the core info, eg:
+                        cores=[0,1,2,3],
+                        cores=['0', '1', '2', '3'],
+                        cores='default',
+                        cores='1S/4C/1T',
+                        cores='all';
+        :param prefix: set file prefix string, eg:
+                        prefix='vf';
+        :param no_pci: switch of disable PCI bus eg:
+                        no_pci=True;
+        :param vdevs: virtual device list, eg:
+                        vdevs=['net_ring0', 'net_ring1'];
+        :param other_eal_param: user defined DPDK eal parameters, eg:
+                        other_eal_param='--single-file-segments';
+        :return: eal param string, eg:
+                '-c 0xf -a 0000:88:00.0 --file-prefix=dpdk_1112_20190809143420';
+        if DPDK version < 20.11-rc4, eal_str eg:
+                '-c 0xf -w 0000:88:00.0 --file-prefix=dpdk_1112_20190809143420';
+        """
+        if vdevs is None:
+            vdevs = []
+
+        if socket is None:
+            socket = -1
+
+        config = {
+            "cores": cores,
+            "prefix": prefix,
+            "no_pci": no_pci,
+            "vdevs": vdevs,
+            "other_eal_param": other_eal_param,
+        }
+
+        eal_parameter_creator = _EalParameter(
+            sut_node=self, fixed_prefix=fixed_prefix, socket=socket, **config
+        )
+        eal_str = eal_parameter_creator.make_eal_param()
+
+        return eal_str
+
+    def set_toolchain(self, target):
+        """
+        This looks at the current target and instantiates an attribute to
+        be either a NodeLinuxApp or NodeBareMetal object. These latter two
+        classes are private and should not be used directly by client code.
+        """
+        self.kill_all()
+        self.target = target
+        [arch, _, _, toolchain] = target.split("-")
+
+        if toolchain == "icc":
+            icc_vars = os.getenv("ICC_VARS", "/opt/intel/composer_xe_2013/bin/")
+            icc_vars += "compilervars.sh"
+
+            if arch == "x86_64":
+                icc_arch = "intel64"
+            elif arch == "i686":
+                icc_arch = "ia32"
+            self.send_expect("source " + icc_vars + " " + icc_arch, "# ")
+
+        self.architecture = arch
+
+    def sut_prerequisites(self):
+        """
+        Prerequest function should be called before execute any test case.
+        Will call function to scan all lcore's information which on SUT.
+        Then call pci scan function to collect nic device information.
+        At last setup SUT' environment for validation.
+        """
+        out = self.send_expect(f"cd {SETTINGS.remote_dpdk_dir}", "# ")
+        assert "No such file or directory" not in out, "Can't switch to dpdk folder!!!"
+        out = self.send_expect("cat VERSION", "# ")
+        if "No such file or directory" in out:
+            self.logger.error("Can't get DPDK version due to VERSION not exist!!!")
+        else:
+            self.dpdk_version = out
+        self.send_expect("alias ls='ls --color=none'", "#")
+
+        self.init_core_list()
+        self.filter_cores_from_node_cfg()
+
+    def setup_memory(self, hugepages=-1):
+        """
+        Setup hugepage on SUT.
+        """
+        function_name = "setup_memory_%s" % self.get_os()
+        try:
+            setup_memory = getattr(self, function_name)
+            setup_memory(hugepages)
+        except AttributeError:
+            self.logger.error("%s is not implemented" % function_name)
+
+    def setup_memory_linux(self, hugepages=-1):
+        """
+        Setup Linux hugepages.
+        """
+        hugepages_size = self.send_expect(
+            "awk '/Hugepagesize/ {print $2}' /proc/meminfo", "# "
+        )
+        total_huge_pages = self.get_total_huge_pages()
+        numa_nodes = self.send_expect("ls /sys/devices/system/node | grep node*", "# ")
+        if not numa_nodes:
+            total_numa_nodes = -1
+        else:
+            numa_nodes = numa_nodes.splitlines()
+            total_numa_nodes = len(numa_nodes)
+            self.logger.info(numa_nodes)
+
+        force_socket = False
+
+        if int(hugepages_size) < (1024 * 1024):
+            if hugepages <= 0:
+                if self.architecture == "x86_64":
+                    arch_huge_pages = 4096
+                elif self.architecture == "i686":
+                    arch_huge_pages = 512
+                    force_socket = True
+                # set huge pagesize for x86_x32 abi target
+                elif self.architecture == "x86_x32":
+                    arch_huge_pages = 256
+                    force_socket = True
+                elif self.architecture == "ppc_64":
+                    arch_huge_pages = 512
+                elif self.architecture == "arm64":
+                    if int(hugepages_size) >= (512 * 1024):
+                        arch_huge_pages = 8
+                    else:
+                        arch_huge_pages = 2048
+                else:
+                    arch_huge_pages = 256
+            else:
+                arch_huge_pages = hugepages
+
+            if total_huge_pages != arch_huge_pages:
+                if total_numa_nodes == -1:
+                    self.set_huge_pages(arch_huge_pages)
+                else:
+                    # before all hugepage average distribution  by all socket,
+                    # but sometimes create mbuf pool on socket 0 failed when
+                    # setup testpmd, so set all huge page on first socket
+                    if force_socket:
+                        self.set_huge_pages(arch_huge_pages, numa_nodes[0])
+                        self.logger.info("force_socket on %s" % numa_nodes[0])
+                    else:
+                        # set huge pages to all numa_nodes
+                        for numa_node in numa_nodes:
+                            self.set_huge_pages(arch_huge_pages, numa_node)
+
+        self.mount_huge_pages()
+        self.hugepage_path = self.strip_hugepage_path()
+
+    def get_memory_channels(self):
+        n = self._config.memory_channels
+        if n is not None and n > 0:
+            return n
+        else:
+            return 1
+
+
+class _EalParameter(object):
+    def __init__(
+        self,
+        sut_node: SutNode,
+        fixed_prefix: bool,
+        socket: int,
+        cores: Union[str, List[int], List[str]],
+        prefix: str,
+        no_pci: bool,
+        vdevs: List[str],
+        other_eal_param: str,
+    ):
+        """
+        generate eal parameters character string;
+        :param sut_node: SUT Node;
+        :param fixed_prefix: use fixed file-prefix or not, when it is true,
+                             the file-prefix will not be added a timestamp
+        :param socket: the physical CPU socket index, -1 means no care cpu socket;
+        :param cores: set the core info, eg:
+                        cores=[0,1,2,3],
+                        cores=['0','1','2','3'],
+                        cores='default',
+                        cores='1S/4C/1T',
+                        cores='all';
+        param prefix: set file prefix string, eg:
+                        prefix='vf';
+        param no_pci: switch of disable PCI bus eg:
+                        no_pci=True;
+        param vdevs: virtual device list, eg:
+                        vdevs=['net_ring0', 'net_ring1'];
+        param other_eal_param: user defined DPDK eal parameters, eg:
+                        other_eal_param='--single-file-segments';
+        """
+        self.os = sut_node.get_os()
+        self.fixed_prefix = fixed_prefix
+        self.socket = socket
+        self.sut_node = sut_node
+        self.cores = self._validate_cores(cores)
+        self.prefix = prefix
+        self.no_pci = no_pci
+        self.vdevs = vdevs
+        self.other_eal_param = other_eal_param
+
+    _param_validate_exception_info_template = (
+        "Invalid parameter of %s about value of %s, Please reference API doc."
+    )
+
+    @staticmethod
+    def _validate_cores(cores: Union[str, List[int], List[str]]):
+        core_string_match = r"default|all|\d+S/\d+C/\d+T|$"
+        if isinstance(cores, list) and (
+            all(map(lambda _core: type(_core) == int, cores))
+            or all(map(lambda _core: type(_core) == str, cores))
+        ):
+            return cores
+        elif type(cores) == str and re.match(core_string_match, cores, re.I):
+            return cores
+        else:
+            raise ParameterInvalidException("cores", cores)
+
+    def _make_cores_param(self) -> str:
+        is_use_default_cores = (
+            self.cores == ""
+            or isinstance(self.cores, str)
+            and self.cores.lower() == "default"
+        )
+        if is_use_default_cores:
+            default_cores = "1S/2C/1T"
+            core_list = self.sut_node.get_core_list(default_cores)
+        else:
+            core_list = self._get_cores()
+
+        def _get_consecutive_cores_range(_cores: List[int]):
+            _formated_core_list = []
+            _tmp_cores_list = list(sorted(map(int, _cores)))
+            _segment = _tmp_cores_list[:1]
+            for _core_num in _tmp_cores_list[1:]:
+                if _core_num - _segment[-1] == 1:
+                    _segment.append(_core_num)
+                else:
+                    _formated_core_list.append(
+                        f"{_segment[0]}-{_segment[-1]}"
+                        if len(_segment) > 1
+                        else f"{_segment[0]}"
+                    )
+                    _index = _tmp_cores_list.index(_core_num)
+                    _formated_core_list.extend(
+                        _get_consecutive_cores_range(_tmp_cores_list[_index:])
+                    )
+                    _segment.clear()
+                    break
+            if len(_segment) > 0:
+                _formated_core_list.append(
+                    f"{_segment[0]}-{_segment[-1]}"
+                    if len(_segment) > 1
+                    else f"{_segment[0]}"
+                )
+            return _formated_core_list
+
+        return f'-l {",".join(_get_consecutive_cores_range(core_list))}'
+
+    def _make_memory_channels(self) -> str:
+        param_template = "-n {}"
+        return param_template.format(self.sut_node.get_memory_channels())
+
+    def _make_no_pci_param(self) -> str:
+        if self.no_pci is True:
+            return "--no-pci"
+        else:
+            return ""
+
+    def _make_prefix_param(self) -> str:
+        if self.prefix == "":
+            fixed_file_prefix = "dpdk" + "_" + self.sut_node.prefix_subfix
+        else:
+            fixed_file_prefix = self.prefix
+            if not self.fixed_prefix:
+                fixed_file_prefix = (
+                    fixed_file_prefix + "_" + self.sut_node.prefix_subfix
+                )
+        fixed_file_prefix = self._do_os_handle_with_prefix_param(fixed_file_prefix)
+        return fixed_file_prefix
+
+    def _make_vdevs_param(self) -> str:
+        if len(self.vdevs) == 0:
+            return ""
+        else:
+            _vdevs = ["--vdev " + vdev for vdev in self.vdevs]
+            return " ".join(_vdevs)
+
+    def _get_cores(self) -> List[int]:
+        if type(self.cores) == list:
+            return self.cores
+        elif isinstance(self.cores, str):
+            return self.sut_node.get_core_list(self.cores, socket=self.socket)
+
+    def _do_os_handle_with_prefix_param(self, file_prefix: str) -> str:
+        self.sut_node.prefix_list.append(file_prefix)
+        return "--file-prefix=" + file_prefix
+
+    def make_eal_param(self) -> str:
+        _eal_str = " ".join(
+            [
+                self._make_cores_param(),
+                self._make_memory_channels(),
+                self._make_prefix_param(),
+                self._make_no_pci_param(),
+                self._make_vdevs_param(),
+                # append user defined eal parameters
+                self.other_eal_param,
+            ]
+        )
+        return _eal_str
-- 
2.30.2


  parent reply	other threads:[~2022-08-24 16:25 UTC|newest]

Thread overview: 97+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-24 16:24 [RFC PATCH v1 00/10] dts: add hello world testcase Juraj Linkeš
2022-08-24 16:24 ` [RFC PATCH v1 01/10] dts: hello world config options Juraj Linkeš
2022-08-24 16:24 ` [RFC PATCH v1 02/10] dts: hello world cli parameters and env vars Juraj Linkeš
2022-08-24 16:24 ` [RFC PATCH v1 03/10] dts: ssh connection additions for hello world Juraj Linkeš
2022-08-24 16:24 ` [RFC PATCH v1 04/10] dts: add basic node management methods Juraj Linkeš
2022-08-24 16:24 ` Juraj Linkeš [this message]
2022-08-24 16:24 ` [RFC PATCH v1 06/10] dts: add traffic generator node Juraj Linkeš
2022-08-24 16:24 ` [RFC PATCH v1 07/10] dts: add testcase and basic test results Juraj Linkeš
2022-08-24 16:24 ` [RFC PATCH v1 08/10] dts: add test runner and statistics collector Juraj Linkeš
2022-08-24 16:24 ` [RFC PATCH v1 09/10] dts: add hello world testplan Juraj Linkeš
2022-08-24 16:24 ` [RFC PATCH v1 10/10] dts: add hello world testsuite Juraj Linkeš
2022-11-14 16:54 ` [RFC PATCH v2 00/10] dts: add hello world testcase Juraj Linkeš
2022-11-14 16:54   ` [RFC PATCH v2 01/10] dts: add node and os abstractions Juraj Linkeš
2022-11-14 16:54   ` [RFC PATCH v2 02/10] dts: add ssh command verification Juraj Linkeš
2022-11-14 16:54   ` [RFC PATCH v2 03/10] dts: add dpdk build on sut Juraj Linkeš
2022-11-16 13:15     ` Owen Hilyard
     [not found]       ` <30ad4f7d087d4932845b6ca13934b1d2@pantheon.tech>
     [not found]         ` <CAHx6DYDOFMuEm4xc65OTrtUmGBtk8Z6UtSgS2grnR_RBY5HcjQ@mail.gmail.com>
2022-11-23 12:37           ` Juraj Linkeš
2022-11-14 16:54   ` [RFC PATCH v2 04/10] dts: add dpdk execution handling Juraj Linkeš
2022-11-16 13:28     ` Owen Hilyard
     [not found]       ` <df13ee41efb64e7bb37791f21ae5bac1@pantheon.tech>
     [not found]         ` <CAHx6DYCEYxZ0Osm6fKhp3Jx8n7s=r7qVh8R41c6nCan8Or-dpA@mail.gmail.com>
2022-11-23 13:03           ` Juraj Linkeš
2022-11-28 13:05             ` Owen Hilyard
2022-11-14 16:54   ` [RFC PATCH v2 05/10] dts: add node memory setup Juraj Linkeš
2022-11-16 13:47     ` Owen Hilyard
2022-11-23 13:58       ` Juraj Linkeš
2022-11-14 16:54   ` [RFC PATCH v2 06/10] dts: add test results module Juraj Linkeš
2022-11-14 16:54   ` [RFC PATCH v2 07/10] dts: add simple stats report Juraj Linkeš
2022-11-16 13:57     ` Owen Hilyard
2022-11-14 16:54   ` [RFC PATCH v2 08/10] dts: add testsuite class Juraj Linkeš
2022-11-16 15:15     ` Owen Hilyard
2022-11-14 16:54   ` [RFC PATCH v2 09/10] dts: add hello world testplan Juraj Linkeš
2022-11-14 16:54   ` [RFC PATCH v2 10/10] dts: add hello world testsuite Juraj Linkeš
2023-01-17 15:48   ` [PATCH v3 00/10] dts: add hello world testcase Juraj Linkeš
2023-01-17 15:48     ` [PATCH v3 01/10] dts: add node and os abstractions Juraj Linkeš
2023-01-17 15:48     ` [PATCH v3 02/10] dts: add ssh command verification Juraj Linkeš
2023-01-17 15:48     ` [PATCH v3 03/10] dts: add dpdk build on sut Juraj Linkeš
2023-01-17 15:49     ` [PATCH v3 04/10] dts: add dpdk execution handling Juraj Linkeš
2023-01-17 15:49     ` [PATCH v3 05/10] dts: add node memory setup Juraj Linkeš
2023-01-17 15:49     ` [PATCH v3 06/10] dts: add test suite module Juraj Linkeš
2023-01-17 15:49     ` [PATCH v3 07/10] dts: add hello world testplan Juraj Linkeš
2023-01-17 15:49     ` [PATCH v3 08/10] dts: add hello world testsuite Juraj Linkeš
2023-01-17 15:49     ` [PATCH v3 09/10] dts: add test suite config and runner Juraj Linkeš
2023-01-17 15:49     ` [PATCH v3 10/10] dts: add test results module Juraj Linkeš
2023-01-19 16:16     ` [PATCH v3 00/10] dts: add hello world testcase Owen Hilyard
2023-02-09 16:47       ` Patrick Robb
2023-02-13 15:28     ` [PATCH v4 " Juraj Linkeš
2023-02-13 15:28       ` [PATCH v4 01/10] dts: add node and os abstractions Juraj Linkeš
2023-02-17 17:44         ` Bruce Richardson
2023-02-20 13:24           ` Juraj Linkeš
2023-02-13 15:28       ` [PATCH v4 02/10] dts: add ssh command verification Juraj Linkeš
2023-02-13 15:28       ` [PATCH v4 03/10] dts: add dpdk build on sut Juraj Linkeš
2023-02-22 16:44         ` Bruce Richardson
2023-02-13 15:28       ` [PATCH v4 04/10] dts: add dpdk execution handling Juraj Linkeš
2023-02-13 15:28       ` [PATCH v4 05/10] dts: add node memory setup Juraj Linkeš
2023-02-13 15:28       ` [PATCH v4 06/10] dts: add test suite module Juraj Linkeš
2023-02-13 15:28       ` [PATCH v4 07/10] dts: add hello world testsuite Juraj Linkeš
2023-02-13 15:28       ` [PATCH v4 08/10] dts: add test suite config and runner Juraj Linkeš
2023-02-13 15:28       ` [PATCH v4 09/10] dts: add test results module Juraj Linkeš
2023-02-13 15:28       ` [PATCH v4 10/10] doc: update DTS setup and test suite cookbook Juraj Linkeš
2023-02-17 17:26       ` [PATCH v4 00/10] dts: add hello world testcase Bruce Richardson
2023-02-20 10:13         ` Juraj Linkeš
2023-02-20 11:56           ` Bruce Richardson
2023-02-22 16:39           ` Bruce Richardson
2023-02-23  8:27             ` Juraj Linkeš
2023-02-23  9:17               ` Bruce Richardson
2023-02-23 15:28       ` [PATCH v5 " Juraj Linkeš
2023-02-23 15:28         ` [PATCH v5 01/10] dts: add node and os abstractions Juraj Linkeš
2023-02-23 15:28         ` [PATCH v5 02/10] dts: add ssh command verification Juraj Linkeš
2023-02-23 15:28         ` [PATCH v5 03/10] dts: add dpdk build on sut Juraj Linkeš
2023-02-23 15:28         ` [PATCH v5 04/10] dts: add dpdk execution handling Juraj Linkeš
2023-02-23 15:28         ` [PATCH v5 05/10] dts: add node memory setup Juraj Linkeš
2023-02-23 15:28         ` [PATCH v5 06/10] dts: add test suite module Juraj Linkeš
2023-02-23 15:28         ` [PATCH v5 07/10] dts: add hello world testsuite Juraj Linkeš
2023-02-23 15:28         ` [PATCH v5 08/10] dts: add test suite config and runner Juraj Linkeš
2023-02-23 15:28         ` [PATCH v5 09/10] dts: add test results module Juraj Linkeš
2023-02-23 15:28         ` [PATCH v5 10/10] doc: update DTS setup and test suite cookbook Juraj Linkeš
2023-03-03  8:31           ` Huang, ChenyuX
2023-02-23 16:13         ` [PATCH v5 00/10] dts: add hello world testcase Bruce Richardson
2023-02-26 19:11         ` Wathsala Wathawana Vithanage
2023-02-27  8:28           ` Juraj Linkeš
2023-02-28 15:27             ` Wathsala Wathawana Vithanage
2023-03-01  8:35               ` Juraj Linkeš
2023-03-03 10:24         ` [PATCH v6 00/10] dts: add hello world test case Juraj Linkeš
2023-03-03 10:24           ` [PATCH v6 01/10] dts: add node and os abstractions Juraj Linkeš
2023-03-03 10:24           ` [PATCH v6 02/10] dts: add ssh command verification Juraj Linkeš
2023-03-03 10:25           ` [PATCH v6 03/10] dts: add dpdk build on sut Juraj Linkeš
2023-03-20  8:30             ` David Marchand
2023-03-20 13:12               ` Juraj Linkeš
2023-03-20 13:22                 ` David Marchand
2023-03-03 10:25           ` [PATCH v6 04/10] dts: add dpdk execution handling Juraj Linkeš
2023-03-03 10:25           ` [PATCH v6 05/10] dts: add node memory setup Juraj Linkeš
2023-03-03 10:25           ` [PATCH v6 06/10] dts: add test suite module Juraj Linkeš
2023-03-03 10:25           ` [PATCH v6 07/10] dts: add hello world testsuite Juraj Linkeš
2023-03-03 10:25           ` [PATCH v6 08/10] dts: add test suite config and runner Juraj Linkeš
2023-03-03 10:25           ` [PATCH v6 09/10] dts: add test results module Juraj Linkeš
2023-03-03 10:25           ` [PATCH v6 10/10] doc: update dts setup and test suite cookbook Juraj Linkeš
2023-03-09 21:47             ` Patrick Robb
2023-03-19 15:26           ` [PATCH v6 00/10] dts: add hello world test case Thomas Monjalon

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20220824162454.394285-6-juraj.linkes@pantheon.tech \
    --to=juraj.linkes@pantheon.tech \
    --cc=Honnappa.Nagarahalli@arm.com \
    --cc=david.marchand@redhat.com \
    --cc=dev@dpdk.org \
    --cc=lijuan.tu@intel.com \
    --cc=ohilyard@iol.unh.edu \
    --cc=ronan.randles@intel.com \
    --cc=thomas@monjalon.net \
    /path/to/YOUR_REPLY

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

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