fix(uti): Add TG type export
[csit.git] / resources / tools / ab / ABTools.py
1 # Copyright (c) 2022 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 robot.api import logger
17 from resources.libraries.python.topology import NodeType
18 from resources.libraries.python.Constants import Constants
19 from resources.libraries.python.ssh import exec_cmd_no_error
20 from resources.libraries.python.OptionString import OptionString
21
22
23 class ABTools:
24     """This class implements:
25     - Get ab command.
26     - Check ab version.
27     """
28
29     @staticmethod
30     def get_cmd_options(**kwargs):
31         """Create  parameters options.
32
33         :param kwargs: Dict of cmd parameters.
34         :type kwargs: dict
35         :returns: Cmd parameters.
36         :rtype: OptionString
37         """
38         cmd = OptionString()
39         cmd.add(u"python3")
40         dirname = f"{Constants.REMOTE_FW_DIR}/resources/tools/ab"
41         cmd.add(f"{dirname}/ABFork.py")
42         cmd_options = OptionString(prefix=u"-")
43         # Number of requests to perform.
44         cmd_options.add_with_value_from_dict(u"r", u"requests", kwargs)
45         # Server port number to use.
46         cmd_options.add_with_value_from_dict(u"p", u"port", kwargs)
47         # Number of clients being processed at the same time.
48         cmd_options.add_with_value_from_dict(u"c", u"clients", kwargs)
49         # Filename to be requested from the servers.
50         cmd_options.add_with_value_from_dict(u"f", u"files", kwargs)
51         # Server ip address.
52         cmd_options.add_with_value_from_dict(u"i", u"ip", kwargs)
53         # tg ip address.
54         cmd_options.add_with_value_from_dict(u"g", u"tip", kwargs)
55         # Specify SSL/TLS cipher suite.
56         cmd_options.add_with_value_from_dict(u"z", u"cipher", kwargs, default=0)
57         # Specify SSL/TLS protocol.
58         cmd_options.add_with_value_from_dict(u"t", u"protocol", kwargs,
59                                              default=0)
60         # Mode: RPS or CPS.
61         cmd_options.add_with_value_from_dict(u"m", u"mode", kwargs)
62         return cmd.extend(cmd_options)
63
64     @staticmethod
65     def check_ab(tg_node):
66         """Check if ab is installed on the TG node.
67
68         :param tg_node: Topology node.
69         :type tg_node: dict
70         :raises: RuntimeError if the given node is not a TG node or if the
71             command is not available.
72         """
73
74         if tg_node[u"type"] != NodeType.TG:
75             raise RuntimeError(u"Node type is not a TG!")
76
77         cmd = u"command -v ab"
78         message = u"ab not installed on TG node!"
79         exec_cmd_no_error(tg_node, cmd, message=message)
80
81     @staticmethod
82     def get_ab_type(node):
83         """Log and return the installed traffic generator type.
84
85         :param node: Node from topology file.
86         :type node: dict
87         :returns: Traffic generator type string.
88         :rtype: str
89         """
90         return "AB"
91
92     @staticmethod
93     def get_ab_version(node):
94         """Log and return the installed traffic generator version.
95
96         :param node: Node from topology file.
97         :type node: dict
98         :returns: Traffic generator version string.
99         :rtype: str
100         """
101         command = f"ab -V | head -1 | cut -d',' -f2"
102         message = u"Get AB version failed!"
103         stdout, _ = exec_cmd_no_error(node, command, message=message)
104         return stdout.strip()
105
106     @staticmethod
107     def run_ab(tg_node, ip_addr, tg_addr, tls_tcp, cipher, files_num, rps_cps,
108                r_total, c_total, port, protocol=u"TLS1.3"):
109         """ Run ab test.
110
111         :param tg_node: Topology node.
112         :param ip_addr: Sut ip address.
113         :param tg_addr: Tg ip address.
114         :param tls_tcp: TLS or TCP.
115         :param cipher: Specify SSL/TLS cipher suite.
116         :param files_num: Filename to be requested from the servers.
117         The file is named after the file size.
118         :param rps_cps: RPS or CPS.
119         :param r_total: Requests total.
120         :param r_total: Clients total.
121         :param port: Server listen port.
122         :param protocol: TLS Protocol.
123         :type tg_node: dict
124         :type ip_addr: str
125         :type tg_addr: str
126         :type tls_tcp: str
127         :type cipher: str
128         :type files_num: int
129         :type rps_cps: str
130         :type r_total: int
131         :type c_total: int
132         :type port: int
133         :type protocol: str
134         :returns: Message with measured data.
135         :rtype: str
136         :raises: RuntimeError if node type is not a TG.
137         """
138         if files_num == 0:
139             files = u"return"
140         elif files_num >= 1024:
141             files = f"{int(files_num / 1024)}KB.json"
142         else:
143             files = f"{files_num}B.json"
144
145         cmd = ABTools.get_cmd_options(
146             requests=r_total,
147             clients=c_total,
148             ip=ip_addr,
149             tip=tg_addr,
150             files=files,
151             cipher=cipher,
152             protocol=protocol,
153             port=port,
154             mode=rps_cps,
155         )
156         stdout, _ = exec_cmd_no_error(tg_node, cmd, timeout=180, sudo=True,
157                                       message=u"ab runtime error!")
158         log_msg = ABTools._parse_ab_output(stdout, rps_cps, tls_tcp)
159
160         logger.info(log_msg)
161
162         return log_msg
163
164     @staticmethod
165     def _parse_ab_output(msg, rps_cps, tls_tcp):
166         """Parse the ab stdout with the results.
167
168         :param msg: Ab Stdout.
169         :param rps_cps: RPS or CPS.
170         :param tls_tcp: TLS or TCP.
171         :type msg: str
172         :type rps_cps: str
173         :type tls_tcp: str
174         :return: Message with measured data.
175         :rtype: str
176         """
177
178         msg_lst = msg.splitlines(keepends=False)
179
180         total_cps = u""
181         latency = u""
182         processing = u""
183         complete_req = u""
184         failed_req = u""
185         total_bytes = u""
186         rate = u""
187
188         if tls_tcp == u"tls":
189             log_msg = u"\nMeasured HTTPS values:\n"
190         else:
191             log_msg = u"\nMeasured HTTP values:\n"
192
193         for line in msg_lst:
194             if f"Connection {rps_cps} rate:" in line:
195                 # rps (cps)
196                 total_cps = line + u"\n"
197             elif u"Transfer Rate:" in line:
198                 # Rate
199                 rate = line + u"\n"
200             elif u"Latency:" in line:
201                 # Latency
202                 latency = line + u"\n"
203             elif u"Total data transferred" in line:
204                 total_bytes = line + u"\n"
205             elif u"Completed requests" in line:
206                 complete_req = line + u"\n"
207             elif u"Failed requests" in line:
208                 failed_req = line + u"\n"
209
210         log_msg += rate
211         log_msg += latency
212         log_msg += processing
213         log_msg += complete_req
214         log_msg += failed_req
215         log_msg += total_bytes
216         log_msg += total_cps
217
218         return log_msg