diff options
Diffstat (limited to 'resources/tools/ab/ABTools.py')
-rw-r--r-- | resources/tools/ab/ABTools.py | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/resources/tools/ab/ABTools.py b/resources/tools/ab/ABTools.py new file mode 100644 index 0000000000..b929b49fdd --- /dev/null +++ b/resources/tools/ab/ABTools.py @@ -0,0 +1,187 @@ +# Copyright (c) 2023 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. + +"""ab implementation into CSIT framework.""" + +from re import search +from resources.libraries.python.Constants import Constants +from resources.libraries.python.model.ExportResult import ( + export_hoststack_results +) +from resources.libraries.python.OptionString import OptionString +from resources.libraries.python.ssh import exec_cmd_no_error +from resources.libraries.python.topology import NodeType + + +class ABTools: + """This class implements: + - Get ab command. + - Check ab version. + """ + + @staticmethod + def get_cmd_options(**kwargs): + """Create parameters options. + + :param kwargs: Dict of cmd parameters. + :type kwargs: dict + :returns: Cmd parameters. + :rtype: OptionString + """ + cmd = OptionString() + cmd.add("python3") + dirname = f"{Constants.REMOTE_FW_DIR}/resources/tools/ab" + cmd.add(f"{dirname}/ABFork.py") + cmd_options = OptionString(prefix="-") + # Number of requests to perform. + cmd_options.add_with_value_from_dict("r", "requests", kwargs) + # Server port number to use. + cmd_options.add_with_value_from_dict("p", "port", kwargs) + # Number of clients being processed at the same time. + cmd_options.add_with_value_from_dict("c", "clients", kwargs) + # Filename to be requested from the servers. + cmd_options.add_with_value_from_dict("f", "files", kwargs) + # Server ip address. + cmd_options.add_with_value_from_dict("i", "ip", kwargs) + # tg ip address. + cmd_options.add_with_value_from_dict("g", "tip", kwargs) + # Specify SSL/TLS cipher suite. + cmd_options.add_with_value_from_dict("z", "cipher", kwargs, default=0) + # Specify SSL/TLS protocol. + cmd_options.add_with_value_from_dict("t", "protocol", kwargs, + default=0) + # Mode: RPS or CPS. + cmd_options.add_with_value_from_dict("m", "mode", kwargs) + return cmd.extend(cmd_options) + + @staticmethod + def check_ab(tg_node): + """Check if ab is installed on the TG node. + + :param tg_node: Topology node. + :type tg_node: dict + :raises: RuntimeError if the given node is not a TG node or if the + command is not available. + """ + + if tg_node["type"] != NodeType.TG: + raise RuntimeError("Node type is not a TG!") + + cmd = "command -v ab" + message = "ab not installed on TG node!" + exec_cmd_no_error(tg_node, cmd, message=message) + + @staticmethod + def get_ab_type(node): + """Log and return the installed traffic generator type. + + :param node: Node from topology file. + :type node: dict + :returns: Traffic generator type string. + :rtype: str + """ + return "AB" + + @staticmethod + def get_ab_version(node): + """Log and return the installed traffic generator version. + + :param node: Node from topology file. + :type node: dict + :returns: Traffic generator version string. + :rtype: str + """ + command = f"ab -V | head -1 | cut -d',' -f2" + message = "Get AB version failed!" + stdout, _ = exec_cmd_no_error(node, command, message=message) + return stdout.strip() + + @staticmethod + def run_ab(tg_node, ip_addr, tg_addr, tls_tcp, cipher, files_num, rps_cps, + r_total, c_total, port, protocol="TLS1.3"): + """ Run ab test. + + :param tg_node: Topology node. + :param ip_addr: Sut ip address. + :param tg_addr: Tg ip address. + :param tls_tcp: TLS or TCP. + :param cipher: Specify SSL/TLS cipher suite. + :param files_num: Filename to be requested from the servers. + The file is named after the file size. + :param rps_cps: RPS or CPS. + :param r_total: Requests total. + :param r_total: Clients total. + :param port: Server listen port. + :param protocol: TLS Protocol. + :type tg_node: dict + :type ip_addr: str + :type tg_addr: str + :type tls_tcp: str + :type cipher: str + :type files_num: int + :type rps_cps: str + :type r_total: int + :type c_total: int + :type port: int + :type protocol: str + :returns: Message with measured data. + :rtype: str + :raises: RuntimeError if node type is not a TG. + """ + if files_num == 0: + files = "return" + elif files_num >= 1024: + files = f"{int(files_num / 1024)}KB.json" + else: + files = f"{files_num}B.json" + + cmd = ABTools.get_cmd_options( + requests=r_total, + clients=c_total, + ip=ip_addr, + tip=tg_addr, + files=files, + cipher=cipher, + protocol=protocol, + port=port, + mode=rps_cps, + ) + stdout, _ = exec_cmd_no_error( + tg_node, cmd, timeout=180, sudo=True, message="ab runtime error!" + ) + + rate_unit = rps_cps + rate = None + bandwidth = None + latency = None + completed_requests = None + failed_requests = None + for line in stdout.splitlines(): + if f"Connection {rps_cps} rate:" in line: + rate = float(search(r":\s*(\d+\.?\d+)", line).group(1)) + elif "Transfer Rate:" in line: + bandwidth = \ + float(search(r":\s*(\d+\.?\d+)", line).group(1)) * 8000 + elif "Latency:" in line: + latency = float(search(r":\s*(\d+\.?\d+)", line).group(1)) + elif "Completed requests:" in line: + completed_requests = int(search(r":\s*(\d+)", line).group(1)) + elif "Failed requests" in line: + failed_requests = int(search(r":\s*(\d+)", line).group(1)) + + export_hoststack_results( + bandwidth, rate, rate_unit, latency, failed_requests, + completed_requests + ) + + return stdout |