Revert "fix(IPsecUtil): Delete keywords no longer used"
[csit.git] / resources / tools / ab / ABTools.py
1 # Copyright (c) 2023 Intel and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
5 #
6 #     http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
13
14 """ab implementation into CSIT framework."""
15
16 from re import search
17 from resources.libraries.python.Constants import Constants
18 from resources.libraries.python.model.ExportResult import (
19     export_hoststack_results
20 )
21 from resources.libraries.python.OptionString import OptionString
22 from resources.libraries.python.ssh import exec_cmd_no_error
23 from resources.libraries.python.topology import NodeType
24
25
26 class ABTools:
27     """This class implements:
28     - Get ab command.
29     - Check ab version.
30     """
31
32     @staticmethod
33     def get_cmd_options(**kwargs):
34         """Create  parameters options.
35
36         :param kwargs: Dict of cmd parameters.
37         :type kwargs: dict
38         :returns: Cmd parameters.
39         :rtype: OptionString
40         """
41         cmd = OptionString()
42         cmd.add("python3")
43         dirname = f"{Constants.REMOTE_FW_DIR}/resources/tools/ab"
44         cmd.add(f"{dirname}/ABFork.py")
45         cmd_options = OptionString(prefix="-")
46         # Number of requests to perform.
47         cmd_options.add_with_value_from_dict("r", "requests", kwargs)
48         # Server port number to use.
49         cmd_options.add_with_value_from_dict("p", "port", kwargs)
50         # Number of clients being processed at the same time.
51         cmd_options.add_with_value_from_dict("c", "clients", kwargs)
52         # Filename to be requested from the servers.
53         cmd_options.add_with_value_from_dict("f", "files", kwargs)
54         # Server ip address.
55         cmd_options.add_with_value_from_dict("i", "ip", kwargs)
56         # tg ip address.
57         cmd_options.add_with_value_from_dict("g", "tip", kwargs)
58         # Specify SSL/TLS cipher suite.
59         cmd_options.add_with_value_from_dict("z", "cipher", kwargs, default=0)
60         # Specify SSL/TLS protocol.
61         cmd_options.add_with_value_from_dict("t", "protocol", kwargs,
62                                              default=0)
63         # Mode: RPS or CPS.
64         cmd_options.add_with_value_from_dict("m", "mode", kwargs)
65         return cmd.extend(cmd_options)
66
67     @staticmethod
68     def check_ab(tg_node):
69         """Check if ab is installed on the TG node.
70
71         :param tg_node: Topology node.
72         :type tg_node: dict
73         :raises: RuntimeError if the given node is not a TG node or if the
74             command is not available.
75         """
76
77         if tg_node["type"] != NodeType.TG:
78             raise RuntimeError("Node type is not a TG!")
79
80         cmd = "command -v ab"
81         message = "ab not installed on TG node!"
82         exec_cmd_no_error(tg_node, cmd, message=message)
83
84     @staticmethod
85     def get_ab_type(node):
86         """Log and return the installed traffic generator type.
87
88         :param node: Node from topology file.
89         :type node: dict
90         :returns: Traffic generator type string.
91         :rtype: str
92         """
93         return "AB"
94
95     @staticmethod
96     def get_ab_version(node):
97         """Log and return the installed traffic generator version.
98
99         :param node: Node from topology file.
100         :type node: dict
101         :returns: Traffic generator version string.
102         :rtype: str
103         """
104         command = f"ab -V | head -1 | cut -d',' -f2"
105         message = "Get AB version failed!"
106         stdout, _ = exec_cmd_no_error(node, command, message=message)
107         return stdout.strip()
108
109     @staticmethod
110     def run_ab(tg_node, ip_addr, tg_addr, tls_tcp, cipher, files_num, rps_cps,
111                r_total, c_total, port, protocol="TLS1.3"):
112         """ Run ab test.
113
114         :param tg_node: Topology node.
115         :param ip_addr: Sut ip address.
116         :param tg_addr: Tg ip address.
117         :param tls_tcp: TLS or TCP.
118         :param cipher: Specify SSL/TLS cipher suite.
119         :param files_num: Filename to be requested from the servers.
120         The file is named after the file size.
121         :param rps_cps: RPS or CPS.
122         :param r_total: Requests total.
123         :param r_total: Clients total.
124         :param port: Server listen port.
125         :param protocol: TLS Protocol.
126         :type tg_node: dict
127         :type ip_addr: str
128         :type tg_addr: str
129         :type tls_tcp: str
130         :type cipher: str
131         :type files_num: int
132         :type rps_cps: str
133         :type r_total: int
134         :type c_total: int
135         :type port: int
136         :type protocol: str
137         :returns: Message with measured data.
138         :rtype: str
139         :raises: RuntimeError if node type is not a TG.
140         """
141         if files_num == 0:
142             files = "return"
143         elif files_num >= 1024:
144             files = f"{int(files_num / 1024)}KB.json"
145         else:
146             files = f"{files_num}B.json"
147
148         cmd = ABTools.get_cmd_options(
149             requests=r_total,
150             clients=c_total,
151             ip=ip_addr,
152             tip=tg_addr,
153             files=files,
154             cipher=cipher,
155             protocol=protocol,
156             port=port,
157             mode=rps_cps,
158         )
159         stdout, _ = exec_cmd_no_error(
160             tg_node, cmd, timeout=180, sudo=True, message="ab runtime error!"
161         )
162
163         rate_unit = rps_cps
164         rate = None
165         bandwidth = None
166         latency = None
167         completed_requests = None
168         failed_requests = None
169         for line in stdout.splitlines():
170             if f"Connection {rps_cps} rate:" in line:
171                 rate = float(search(r":\s*(\d+\.?\d+)", line).group(1))
172             elif "Transfer Rate:" in line:
173                 bandwidth = \
174                     float(search(r":\s*(\d+\.?\d+)", line).group(1)) * 8000
175             elif "Latency:" in line:
176                 latency = float(search(r":\s*(\d+\.?\d+)", line).group(1))
177             elif "Completed requests:" in line:
178                 completed_requests = int(search(r":\s*(\d+)", line).group(1))
179             elif "Failed requests" in line:
180                 failed_requests = int(search(r":\s*(\d+)", line).group(1))
181
182         export_hoststack_results(
183             bandwidth, rate, rate_unit, latency, failed_requests,
184             completed_requests
185         )
186
187         return stdout