diff options
Diffstat (limited to 'resources/libraries/python')
-rw-r--r-- | resources/libraries/python/Constants.py | 3 | ||||
-rw-r--r-- | resources/libraries/python/CpuUtils.py | 24 | ||||
-rw-r--r-- | resources/libraries/python/HoststackUtil.py | 60 | ||||
-rw-r--r-- | resources/libraries/python/NGINX/NGINXTools.py | 145 | ||||
-rw-r--r-- | resources/libraries/python/NGINX/__init__.py | 16 | ||||
-rw-r--r-- | resources/libraries/python/NginxConfigGenerator.py | 244 | ||||
-rw-r--r-- | resources/libraries/python/NginxUtil.py | 124 | ||||
-rw-r--r-- | resources/libraries/python/autogen/Regenerator.py | 16 | ||||
-rw-r--r-- | resources/libraries/python/autogen/Testcase.py | 9 |
9 files changed, 634 insertions, 7 deletions
diff --git a/resources/libraries/python/Constants.py b/resources/libraries/python/Constants.py index 79b94be7ff..be9fe34915 100644 --- a/resources/libraries/python/Constants.py +++ b/resources/libraries/python/Constants.py @@ -130,6 +130,9 @@ class Constants: # shell scripts location RESOURCES_LIB_SH = u"resources/libraries/bash" + # python scripts location + RESOURCES_LIB_PY = u"resources/libraries/python" + # Python API provider location RESOURCES_PAPI_PROVIDER = u"resources/tools/papi/vpp_papi_provider.py" diff --git a/resources/libraries/python/CpuUtils.py b/resources/libraries/python/CpuUtils.py index 170cbe6b2e..293d6b6913 100644 --- a/resources/libraries/python/CpuUtils.py +++ b/resources/libraries/python/CpuUtils.py @@ -255,7 +255,7 @@ class CpuUtils: cpu_list_0 = cpu_list[:cpu_list_len // CpuUtils.NR_OF_THREADS] cpu_list_1 = cpu_list[cpu_list_len // CpuUtils.NR_OF_THREADS:] cpu_range = f"{cpu_list_0[0]}{sep}{cpu_list_0[-1]}," \ - f"{cpu_list_1[0]}{sep}{cpu_list_1[-1]}" + f"{cpu_list_1[0]}{sep}{cpu_list_1[-1]}" else: cpu_range = f"{cpu_list[0]}{sep}{cpu_list[-1]}" @@ -469,3 +469,25 @@ class CpuUtils: return CpuUtils.cpu_slice_of_list_per_node( node, cpu_node=cpu_node, skip_cnt=skip_cnt, cpu_cnt=cpu_cnt, smt_used=False) + + @staticmethod + def get_cpu_idle_list(node, cpu_node, smt_used, cpu_alloc_str, sep=u","): + """ + Get idle CPU List + :param node: Node dictionary with cpuinfo. + :param cpu_node: Numa node number. + :param smt_used: True - we want to use SMT, otherwise false. + :param cpu_alloc_str: vpp used cores. + :param sep: Separator, default: ",". + :type node: dict + :type cpu_node: int + :type smt_used: bool + :type cpu_alloc_str: str + :type smt_used: bool + :type sep: str + :rtype: list + """ + cpu_list = CpuUtils.cpu_list_per_node(node, cpu_node, smt_used) + cpu_idle_list = [i for i in cpu_list + if str(i) not in cpu_alloc_str.split(sep)] + return cpu_idle_list diff --git a/resources/libraries/python/HoststackUtil.py b/resources/libraries/python/HoststackUtil.py index c307946698..e797c3c206 100644 --- a/resources/libraries/python/HoststackUtil.py +++ b/resources/libraries/python/HoststackUtil.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020 Cisco and/or its affiliates. +# Copyright (c) 2021 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: @@ -165,6 +165,39 @@ class HoststackUtil(): return stdout_log, stderr_log @staticmethod + def get_nginx_command(nginx_attributes, nginx_version, nginx_ins_dir): + """Construct the NGINX command using the specified attributes. + + :param nginx_attributes: NGINX test program attributes. + :param nginx_version: NGINX version. + :param nginx_ins_dir: NGINX install dir. + :type nginx_attributes: dict + :type nginx_version: str + :type nginx_ins_dir: str + :returns: Command line components of the NGINX command + 'env_vars' - environment variables + 'name' - program name + 'args' - command arguments. + 'path' - program path. + :rtype: dict + """ + nginx_cmd = dict() + nginx_cmd[u"env_vars"] = f"VCL_CONFIG={Constants.REMOTE_FW_DIR}/" \ + f"{Constants.RESOURCES_TPL_VCL}/" \ + f"{nginx_attributes[u'vcl_config']}" + if nginx_attributes[u"ld_preload"]: + nginx_cmd[u"env_vars"] += \ + f" LD_PRELOAD={Constants.VCL_LDPRELOAD_LIBRARY}" + if nginx_attributes[u'transparent_tls']: + nginx_cmd[u"env_vars"] += u" LDP_ENV_TLS_TRANS=1" + + nginx_cmd[u"name"] = u"nginx" + nginx_cmd[u"path"] = f"{nginx_ins_dir}nginx-{nginx_version}/sbin/" + nginx_cmd[u"args"] = f"-c {nginx_ins_dir}/" \ + f"nginx-{nginx_version}/conf/nginx.conf" + return nginx_cmd + + @staticmethod def start_hoststack_test_program(node, namespace, core_list, program): """Start the specified HostStack test program. @@ -194,9 +227,13 @@ class HoststackUtil(): env_vars = f"{program[u'env_vars']} " if u"env_vars" in program else u"" args = program[u"args"] - cmd = f"nohup {shell_cmd} \'{env_vars}taskset --cpu-list {core_list} " \ - f"{program_name} {args} >/tmp/{program_name}_stdout.log " \ - f"2>/tmp/{program_name}_stderr.log &\'" + program_path = program.get(u"path", u"") + # NGINX used `worker_cpu_affinity` in configuration file + taskset_cmd = u"" if program_name == u"nginx" else \ + f"taskset --cpu-list {core_list}" + cmd = f"nohup {shell_cmd} \'{env_vars}{taskset_cmd} " \ + f"{program_path}{program_name} {args} >/tmp/{program_name}_" \ + f"stdout.log 2>/tmp/{program_name}_stderr.log &\'" try: exec_cmd_no_error(node, cmd, sudo=True) return DUTSetup.get_pid(node, program_name)[0] @@ -350,3 +387,18 @@ class HoststackUtil(): :rtype: bool """ return server_defer_fail and client_defer_fail + + @staticmethod + def log_vpp_hoststack_data(node): + """Retrieve and log VPP HostStack data. + + :param node: DUT node. + :type node: dict + :raises RuntimeError: If node subtype is not a DUT or startup failed. + """ + + if node[u"type"] != u"DUT": + raise RuntimeError(u"Node type is not a DUT!") + + PapiSocketExecutor.run_cli_cmd(node, u"show error") + PapiSocketExecutor.run_cli_cmd(node, u"show interface") diff --git a/resources/libraries/python/NGINX/NGINXTools.py b/resources/libraries/python/NGINX/NGINXTools.py new file mode 100644 index 0000000000..9418484f15 --- /dev/null +++ b/resources/libraries/python/NGINX/NGINXTools.py @@ -0,0 +1,145 @@ +# Copyright (c) 2021 Intel and/or its affiliates. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +"""This module implements initialization and cleanup of NGINX framework.""" + +from robot.api import logger + +from resources.libraries.python.Constants import Constants +from resources.libraries.python.ssh import exec_cmd_no_error, exec_cmd +from resources.libraries.python.topology import NodeType +from resources.libraries.python.NginxUtil import NginxUtil + + +class NGINXTools: + """This class implements: + - Initialization of NGINX environment, + - Cleanup of NGINX environment. + """ + + @staticmethod + def cleanup_nginx_framework(node, nginx_ins_path): + """ + Cleanup the NGINX framework on the DUT node. + + :param node: Will cleanup the nginx on this nodes. + :param nginx_ins_path: NGINX install path. + :type node: dict + :type nginx_ins_path: str + :raises RuntimeError: If it fails to cleanup the nginx. + """ + check_path_cmd = NginxUtil.get_cmd_options(path=nginx_ins_path) + exec_cmd_no_error(node, check_path_cmd, timeout=180, + message=u"Check NGINX install path failed!") + command = f"rm -rf {nginx_ins_path}" + message = u"Cleanup the NGINX failed!" + exec_cmd_no_error(node, command, timeout=180, message=message) + + @staticmethod + def cleanup_nginx_framework_on_all_duts(nodes, nginx_ins_path): + """ + Cleanup the NGINX framework on all DUT nodes. + + :param nodes: Will cleanup the nginx on this nodes. + :param nginx_ins_path: NGINX install path. + :type nodes: dict + :type nginx_ins_path: str + :raises RuntimeError: If it fails to cleanup the nginx. + """ + for node in nodes.values(): + if node[u"type"] == NodeType.DUT: + NGINXTools.cleanup_nginx_framework(node, nginx_ins_path) + + @staticmethod + def install_original_nginx_framework(node, pkg_dir, nginx_version): + """ + Prepare the NGINX framework on the DUT node. + + :param node: Node from topology file. + :param pkg_dir: Ldp NGINX install dir. + :param nginx_version: NGINX Version. + :type node: dict + :type pkg_dir: str + :type nginx_version: str + :raises RuntimeError: If command returns nonzero return code. + """ + nginx_path = f"{pkg_dir}/nginx-{nginx_version}/sbin/nginx" + cmd_options = NginxUtil.get_cmd_options(path=nginx_path) + ret_code, _, stderr = exec_cmd(node, cmd_options, sudo=True) + if nginx_version in stderr and ret_code == 0: + logger.info(f"NGINX Version: {stderr}") + return + command = f"{Constants.REMOTE_FW_DIR}/{Constants.RESOURCES_LIB_SH}" \ + f"/entry/install_nginx.sh nginx-{nginx_version}" + message = u"Install the NGINX failed!" + exec_cmd_no_error(node, command, sudo=True, timeout=600, + message=message) + _, stderr = exec_cmd_no_error(node, cmd_options, sudo=True, + message=message) + + logger.info(f"NGINX Version: {stderr}") + + @staticmethod + def install_vsap_nginx_on_dut(node, pkg_dir): + """ + Prepare the VSAP NGINX framework on all DUT + + :param node: Node from topology file. + :param pkg_dir: Path to directory where packages are stored. + :type node: dict + :type pkg_dir: str + :raises RuntimeError: If command returns nonzero return code. + """ + command = u". /etc/lsb-release; echo \"${DISTRIB_ID}\"" + stdout, _ = exec_cmd_no_error(node, command) + + if stdout.strip() == u"Ubuntu": + logger.console(u"NGINX install on DUT... ") + exec_cmd_no_error( + node, u"apt-get purge -y 'vsap*' || true", timeout=120, + sudo=True + ) + exec_cmd_no_error( + node, f"dpkg -i --force-all {pkg_dir}vsap-nginx*.deb", + timeout=120, sudo=True, + message=u"Installation of vsap-nginx failed!" + ) + + exec_cmd_no_error(node, u"dpkg -l | grep vsap*", + sudo=True) + + logger.console(u"Completed!\n") + else: + logger.console(u"Ubuntu need!\n") + + @staticmethod + def install_nginx_framework_on_all_duts(nodes, pkg_dir, nginx_version=None): + """ + Prepare the NGINX framework on all DUTs. + + :param nodes: Nodes from topology file. + :param pkg_dir: Path to directory where packages are stored. + :param nginx_version: NGINX version. + :type nodes: dict + :type pkg_dir: str + :type nginx_version: str + """ + + for node in list(nodes.values()): + if node[u"type"] == NodeType.DUT: + if nginx_version: + NGINXTools.install_original_nginx_framework(node, pkg_dir, + nginx_version) + else: + NGINXTools.install_vsap_nginx_on_dut(node, pkg_dir) diff --git a/resources/libraries/python/NGINX/__init__.py b/resources/libraries/python/NGINX/__init__.py new file mode 100644 index 0000000000..d828cbe7cb --- /dev/null +++ b/resources/libraries/python/NGINX/__init__.py @@ -0,0 +1,16 @@ +# Copyright (c) 2021 Intel and/or its affiliates. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +__init__ file for directory resources/libraries/python/NGINX +""" diff --git a/resources/libraries/python/NginxConfigGenerator.py b/resources/libraries/python/NginxConfigGenerator.py new file mode 100644 index 0000000000..1a0f5f077a --- /dev/null +++ b/resources/libraries/python/NginxConfigGenerator.py @@ -0,0 +1,244 @@ +# Copyright (c) 2021 Intel and/or its affiliates. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Nginx Configuration File Generator library. +""" + +from resources.libraries.python.ssh import exec_cmd_no_error +from resources.libraries.python.topology import NodeType +from resources.libraries.python.NginxUtil import NginxUtil + +__all__ = [u"NginxConfigGenerator"] + + +class NginxConfigGenerator: + """NGINX Configuration File Generator.""" + + def __init__(self): + """Initialize library.""" + # VPP Node to apply configuration on + self._node = u"" + # NGINX Startup config location + self._nginx_path = u"/usr/local/nginx/" + # Serialized NGinx Configuration + self._nginx_config = u"" + # VPP Configuration + self._nodeconfig = dict() + + def set_node(self, node): + """Set DUT node. + + :param node: Node to store configuration on. + :type node: dict + :raises RuntimeError: If Node type is not DUT. + """ + if node[u"type"] != NodeType.DUT: + raise RuntimeError( + u"Startup config can only be applied to DUTnode." + ) + self._node = node + + def set_nginx_path(self, packages_dir, nginx_version): + """Set NGINX Conf Name. + + :param packages_dir: NGINX install path. + :param nginx_version: Test NGINX version. + :type packages_dir: str + :type nginx_version: str + :raises RuntimeError: If Node type is not DUT. + """ + if nginx_version: + self._nginx_path = f"{packages_dir}/nginx-{nginx_version}" + + def add_http_server_listen(self, value): + """Add Http Server listen port configuration.""" + path = [u"http", u"server", u"listen"] + self.add_config_item(self._nodeconfig, value, path) + + def add_http_server_root(self, value=u"html"): + """Add Http Server root configuration.""" + path = [u"http", u"server", u"root"] + self.add_config_item(self._nodeconfig, value, path) + + def add_http_server_index(self, value=u"index.html index.htm"): + """Add Http Server index configuration.""" + path = [u"http", u"server", u"index"] + self.add_config_item(self._nodeconfig, value, path) + + def add_config_item(self, config, value, path): + """Add NGINX configuration item. + + :param config: Startup configuration of node. + :param value: Value to insert. + :param path: Path where to insert item. + :type config: dict + :type value: str + :type path: list + """ + if len(path) == 1: + config[path[0]] = value + return + if path[0] not in config: + config[path[0]] = dict() + elif isinstance(config[path[0]], str): + config[path[0]] = dict() if config[path[0]] == u"" \ + else {config[path[0]]: u""} + self.add_config_item(config[path[0]], value, path[1:]) + + def dump_config(self, obj, level=-1): + """Dump the startup configuration in NGINX config format. + + :param obj: Python Object to print. + :param level: Nested level for indentation. + :type obj: Obj + :type level: int + :returns: nothing + """ + indent = u" " + if level >= 0: + self._nginx_config += f"{level * indent}{{\n" + if isinstance(obj, dict): + for key, val in obj.items(): + if hasattr(val, u"__iter__") and not isinstance(val, str): + self._nginx_config += f"{(level + 1) * indent}{key}\n" + self.dump_config(val, level + 1) + else: + self._nginx_config += f"{(level + 1) * indent}" \ + f"{key} {val};\n" + else: + for val in obj: + self._nginx_config += f"{(level + 1) * indent}{val};\n" + if level >= 0: + self._nginx_config += f"{level * indent}}}\n" + + def write_config(self, filename=None): + """Generate and write NGINX startup configuration to file. + + :param filename: NGINX configuration file name. + :type filename: str + """ + if filename is None: + filename = f"{self._nginx_path}/conf/nginx.conf" + self.dump_config(self._nodeconfig) + cmd = f"echo \"{self._nginx_config}\" | sudo tee {filename}" + exec_cmd_no_error( + self._node, cmd, message=u"Writing config file failed!" + ) + + def add_http_server_location(self, size): + """Add Http Server location configuration. + + :param size: File size. + :type size: int + """ + if size == 0: + files = u"return" + elif size >= 1024: + files = f"{int(size / 1024)}KB.json" + else: + files = f"{size}B.json" + key = f"{files}" + size_str = size * u"x" + value = "200 '%s'" % size_str + path = [u"http", u"server", f"location /{key}", u"return"] + self.add_config_item(self._nodeconfig, value, path) + + def add_http_access_log(self, value=u"off"): + """Add Http access_log configuration.""" + path = [u"http", u"access_log"] + self.add_config_item(self._nodeconfig, value, path) + + def add_http_include(self, value=u"mime.types"): + """Add Http include configuration.""" + path = [u"http", u"include"] + self.add_config_item(self._nodeconfig, value, path) + + def add_http_default_type(self, value=u"application/octet-stream"): + """Add Http default_type configuration.""" + path = [u"http", u"default_type"] + self.add_config_item(self._nodeconfig, value, path) + + def add_http_sendfile(self, value=u"on"): + """Add Http sendfile configuration.""" + path = [u"http", u"sendfile"] + self.add_config_item(self._nodeconfig, value, path) + + def add_http_keepalive_timeout(self, value): + """Add Http keepalive alive timeout configuration.""" + path = [u"http", u"keepalive_timeout"] + self.add_config_item(self._nodeconfig, value, path) + + def add_http_keepalive_requests(self, value): + """Add Http keepalive alive requests configuration.""" + path = [u"http", u"keepalive_requests"] + self.add_config_item(self._nodeconfig, value, path) + + def add_events_use(self, value=u"epoll"): + """Add Events use configuration.""" + path = [u"events", u"use"] + self.add_config_item(self._nodeconfig, value, path) + + def add_events_worker_connections(self, value=10240): + """Add Events worker connections configuration.""" + path = [u"events", u"worker_connections"] + self.add_config_item(self._nodeconfig, value, path) + + def add_events_accept_mutex(self, value=u"off"): + """Add Events accept mutex configuration.""" + path = [u"events", u"accept_mutex"] + self.add_config_item(self._nodeconfig, value, path) + + def add_events_multi_accept(self, value=u"off"): + """Add Events multi accept configuration.""" + path = [u"events", u"multi_accept"] + self.add_config_item(self._nodeconfig, value, path) + + def add_worker_rlimit_nofile(self, value=10240): + """Add Events worker rlimit nofile configuration.""" + path = [u"worker_rlimit_nofile"] + self.add_config_item(self._nodeconfig, value, path) + + def add_master_process(self, value=u"on"): + """Add master process configuration.""" + path = [u"master_process"] + self.add_config_item(self._nodeconfig, value, path) + + def add_daemon(self, value=u"off"): + """Add daemon configuration.""" + path = [u"daemon"] + self.add_config_item(self._nodeconfig, value, path) + + def add_worker_processes(self, value, smt_used): + """Add worker processes configuration.""" + # nginx workers : vpp used phy workers = 2:1 + if smt_used: + value = value * 4 + else: + value = value * 2 + path = [u"worker_processes"] + self.add_config_item(self._nodeconfig, value, path) + + def apply_config(self, filename=None, verify_nginx=True): + """Generate and write NGINX configuration to file and + verify configuration. + + :param filename: NGINX configuration file name. + :param verify_nginx: Verify NGINX configuration. + :type filename: str + :type verify_nginx: bool + """ + self.write_config(filename=filename) + + app_path = f"{self._nginx_path}/sbin/nginx" + if verify_nginx: + NginxUtil.nginx_config_verify(self._node, app_path) diff --git a/resources/libraries/python/NginxUtil.py b/resources/libraries/python/NginxUtil.py new file mode 100644 index 0000000000..a19ac37291 --- /dev/null +++ b/resources/libraries/python/NginxUtil.py @@ -0,0 +1,124 @@ +# Copyright (c) 2021 Intel and/or its affiliates. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""NGINX Utilities Library.""" + +from resources.libraries.python.OptionString import OptionString +from resources.libraries.python.ssh import exec_cmd_no_error +from resources.libraries.python.topology import NodeType +from resources.libraries.python.DUTSetup import DUTSetup + + +class NginxUtil: + """Utilities for NGINX.""" + + @staticmethod + def get_cmd_options(**kwargs): + """Create parameters options. + + :param kwargs: Dict of cmd parameters. + :type kwargs: dict + :returns: cmd parameters. + :rtype: OptionString + """ + cmd_options = OptionString() + nginx_path = kwargs.get(u"path", u"/usr/local/nginx") + cmd_options.add(nginx_path) + options = OptionString(prefix=u"-") + # Show Nginx Version + options.add(u"v") + # Verify Configuration + options.add(u"t") + # Send signal to a master process: stop, quit, reopen. + options.add_with_value_from_dict( + u"s", u"signal", kwargs + ) + # Set prefix path (default: /usr/local/nginx/). + options.add_with_value_from_dict( + u"p", u"prefix", kwargs + ) + # Set configuration file (default: conf/nginx.conf). + options.add_with_value_from_dict( + u"c", u"filename", kwargs + ) + # Set global directives out of configuration file + options.add_with_value_from_dict( + u"g", u"directives", kwargs + ) + cmd_options.extend(options) + return cmd_options + + @staticmethod + def nginx_cmd_stop(node, path): + """Stop NGINX cmd app on node. + :param node: Topology node. + :param path: Nginx install path. + :type node: dict + :type path: str + :returns: nothing + """ + cmd_options = NginxUtil.get_cmd_options(path=path, signal=u"stop") + + exec_cmd_no_error(node, cmd_options, sudo=True, disconnect=True, + message=u"Nginx stop failed!") + + @staticmethod + def nginx_cmd_start(node, path, filename): + """Start NGINX cmd app on node. + :param node: Topology node. + :param path: Nginx install path. + :param filename: Nginx conf name. + :type node: dict + :type path: str + :type filename: str + + :returns: nothing + """ + cmd_options = NginxUtil.get_cmd_options(path=path, + filename=filename) + + exec_cmd_no_error(node, cmd_options, sudo=True, disconnect=True, + message=u"Nginx start failed!") + + @staticmethod + def nginx_config_verify(node, path): + """Start NGINX cmd app on node. + :param node: Topology node. + :param path: Nginx install path. + :type node: dict + :type path: str + :returns: nothing + """ + cmd_options = NginxUtil.get_cmd_options(path=path) + exec_cmd_no_error(node, cmd_options, sudo=True, disconnect=True, + message=u"Nginx Config failed!") + + @staticmethod + def taskset_nginx_pid_to_idle_cores(node, cpu_idle_list): + """Set idle cpus to NGINX pid on node. + + :param node: Topology node. + :param cpu_idle_list: Idle Cpus. + :type node: dict + :type cpu_idle_list: list + :returns: nothing + """ + if node[u"type"] != NodeType.DUT: + raise RuntimeError(u'Node type is not a DUT!') + pids = DUTSetup.get_pid(node, u"nginx") + for index, pid in enumerate(pids): + cmd = f"taskset -pc {cpu_idle_list[index]} {pid}" + exec_cmd_no_error( + node, cmd, sudo=True, timeout=180, + message=u"taskset cores to nginx pid failed!" + ) diff --git a/resources/libraries/python/autogen/Regenerator.py b/resources/libraries/python/autogen/Regenerator.py index e670b692de..fd0d8cfee0 100644 --- a/resources/libraries/python/autogen/Regenerator.py +++ b/resources/libraries/python/autogen/Regenerator.py @@ -85,7 +85,7 @@ def get_iface_and_suite_ids(filename): # It was something like "2n1l", we need one more split. dash_split = dash_split[1].split(u"-", 1) nic_code = dash_split[0] - suite_id = dash_split[1].split(u".", 1)[0] + suite_id = dash_split[1].split(u".robot", 1)[0] suite_tag = suite_id.rsplit(u"-", 1)[0] for prefix in Constants.FORBIDDEN_SUITE_PREFIX_LIST: if suite_tag.startswith(prefix): @@ -553,6 +553,17 @@ class Regenerator: {u"frame_size": u"IMIX_v4_1", u"phy_cores": 4} ] + http_kwargs_list = [ + {u"frame_size": 0, u"phy_cores": 1}, + {u"frame_size": 0, u"phy_cores": 2}, + {u"frame_size": 64, u"phy_cores": 1}, + {u"frame_size": 64, u"phy_cores": 2}, + {u"frame_size": 1024, u"phy_cores": 1}, + {u"frame_size": 1024, u"phy_cores": 2}, + {u"frame_size": 2048, u"phy_cores": 1}, + {u"frame_size": 2048, u"phy_cores": 2} + ] + for in_filename in glob(pattern): if not self.quiet: print( @@ -583,6 +594,9 @@ class Regenerator: ) elif in_filename.endswith(u"-reconf.robot"): write_reconf_files(in_filename, in_prolog, default_kwargs_list) + elif in_filename.endswith(u"-rps.robot") \ + or in_filename.endswith(u"-cps.robot"): + write_tcp_files(in_filename, in_prolog, http_kwargs_list) elif in_filename.endswith(u"-bps.robot"): hoststack_kwargs_list = \ hs_quic_kwargs_list if u"quic" in in_filename \ diff --git a/resources/libraries/python/autogen/Testcase.py b/resources/libraries/python/autogen/Testcase.py index 173c5919af..643d32a3cb 100644 --- a/resources/libraries/python/autogen/Testcase.py +++ b/resources/libraries/python/autogen/Testcase.py @@ -100,7 +100,14 @@ class Testcase: # TODO: Choose a better frame size identifier for streamed protocols # (TCP, QUIC, SCTP, ...) where DUT (not TG) decides frame size. if u"tcphttp" in suite_id: - template_string = f''' + if u"rps" or u"cps" in suite_id: + template_string = f''' +| ${{frame_str}}-${{cores_str}}c-{suite_id} +| | [Tags] | ${{frame_str}} | ${{cores_str}}C +| | frame_size=${{frame_num}} | phy_cores=${{cores_num}} +''' + else: + template_string = f''' | IMIX-${{cores_str}}c-{suite_id} | | [Tags] | ${{cores_str}}C | | phy_cores=${{cores_num}} |