PAPI: Fix PyLint errors
[csit.git] / resources / libraries / python / VppCounters.py
1 # Copyright (c) 2016 Cisco 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 """VPP counters utilities library."""
15
16 import time
17
18 from robot.api import logger
19 from resources.libraries.python.PapiExecutor import PapiExecutor
20 from resources.libraries.python.topology import NodeType, Topology
21 from resources.libraries.python.VatExecutor import VatExecutor, VatTerminal
22
23
24 class VppCounters(object):
25     """VPP counters utilities."""
26
27     def __init__(self):
28         self._stats_table = None
29
30     @staticmethod
31     def vpp_show_errors(node):
32         """Run "show errors" debug CLI command.
33
34         :param node: Node to run command on.
35         :type node: dict
36         """
37         vat = VatExecutor()
38         vat.execute_script("show_errors.vat", node, json_out=False)
39         vat.script_should_have_passed()
40
41     @staticmethod
42     def vpp_show_errors_verbose(node):
43         """Run "show errors verbose" debug CLI command.
44
45         :param node: Node to run command on.
46         :type node: dict
47         """
48         vat = VatExecutor()
49         vat.execute_script("show_errors_verbose.vat", node, json_out=False)
50         vat.script_should_have_passed()
51
52     @staticmethod
53     def vpp_show_errors_on_all_duts(nodes, verbose=False):
54         """Show errors on all DUTs.
55
56         :param nodes: VPP nodes.
57         :param verbose: If True show verbose output.
58         :type nodes: dict
59         :type verbose: bool
60         """
61
62         for node in nodes.values():
63             if node['type'] == NodeType.DUT:
64                 if verbose:
65                     VppCounters.vpp_show_errors_verbose(node)
66                 else:
67                     VppCounters.vpp_show_errors(node)
68
69     @staticmethod
70     def vpp_show_runtime(node):
71         """Run "show runtime" CLI command.
72
73         :param node: Node to run command on.
74         :type node: dict
75         """
76         vat = VatExecutor()
77         vat.execute_script("show_runtime.vat", node, json_out=False)
78         logger.info(vat.get_script_stdout())
79         vat.script_should_have_passed()
80
81     @staticmethod
82     def show_runtime_counters_on_all_duts(nodes):
83         """Clear VPP runtime counters on all DUTs.
84
85         :param nodes: VPP nodes.
86         :type nodes: dict
87         """
88         for node in nodes.values():
89             if node['type'] == NodeType.DUT:
90                 VppCounters.vpp_show_runtime(node)
91
92     @staticmethod
93     def vpp_show_runtime_verbose(node):
94         """Run "show runtime verbose" CLI command.
95
96         :param node: Node to run command on.
97         :type node: dict
98         """
99         vat = VatExecutor()
100         vat.execute_script("show_runtime_verbose.vat", node, json_out=False)
101         logger.info(vat.get_script_stdout())
102         vat.script_should_have_passed()
103
104     @staticmethod
105     def vpp_show_hardware_detail(node):
106         """Run "show hardware-interfaces detail" debug CLI command.
107
108         :param node: Node to run command on.
109         :type node: dict
110         """
111         vat = VatExecutor()
112         vat.execute_script("show_hardware_detail.vat", node, json_out=False)
113         vat.script_should_have_passed()
114
115     @staticmethod
116     def vpp_clear_runtime(node):
117         """Run "clear runtime" CLI command.
118
119         :param node: Node to run command on.
120         :type node: dict
121         """
122         cmd = 'cli_inband'
123         cmd_reply = 'cli_inband_reply'
124         err_msg = "Failed to run '{cmd}' PAPI command on host {host}!".format(
125             host=node['host'], cmd=cmd)
126         args = dict(cmd='clear runtime')
127         with PapiExecutor(node) as papi_exec:
128             papi_resp = papi_exec.add(cmd, **args).execute_should_pass(err_msg)
129         data = papi_resp.reply[0]['api_reply'][cmd_reply]
130         if data['retval'] != 0:
131             raise RuntimeError("Failed to clear runtime on host {host}".
132                                format(host=node['host']))
133
134     @staticmethod
135     def clear_runtime_counters_on_all_duts(nodes):
136         """Run "clear runtime" CLI command on all DUTs.
137
138         :param nodes: VPP nodes.
139         :type nodes: dict
140         """
141         for node in nodes.values():
142             if node['type'] == NodeType.DUT:
143                 VppCounters.vpp_clear_runtime(node)
144
145     @staticmethod
146     def vpp_clear_interface_counters(node):
147         """Clear interface counters on VPP node.
148
149         :param node: Node to clear interface counters on.
150         :type node: dict
151         """
152         cmd = 'cli_inband'
153         cmd_reply = 'cli_inband_reply'
154         err_msg = "Failed to run '{cmd}' PAPI command on host {host}!".format(
155             host=node['host'], cmd=cmd)
156         args = dict(cmd='clear interfaces')
157         with PapiExecutor(node) as papi_exec:
158             papi_resp = papi_exec.add(cmd, **args).execute_should_pass(err_msg)
159         data = papi_resp.reply[0]['api_reply'][cmd_reply]
160         if data['retval'] != 0:
161             raise RuntimeError("Failed to clear interfaces on host {host}".
162                                format(host=node['host']))
163
164     @staticmethod
165     def clear_interface_counters_on_all_duts(nodes):
166         """Clear interface counters on all DUTs.
167
168         :param nodes: VPP nodes.
169         :type nodes: dict
170         """
171         for node in nodes.values():
172             if node['type'] == NodeType.DUT:
173                 VppCounters.vpp_clear_interface_counters(node)
174
175     @staticmethod
176     def vpp_clear_hardware_counters(node):
177         """Clear interface hardware counters on VPP node.
178
179         :param node: Node to clear hardware counters on.
180         :type node: dict
181         """
182         vat = VatExecutor()
183         vat.execute_script('clear_hardware.vat', node)
184         vat.script_should_have_passed()
185
186     @staticmethod
187     def clear_hardware_counters_on_all_duts(nodes):
188         """Clear hardware counters on all DUTs.
189
190         :param nodes: VPP nodes.
191         :type nodes: dict
192         """
193         for node in nodes.values():
194             if node['type'] == NodeType.DUT:
195                 VppCounters.vpp_clear_hardware_counters(node)
196
197     @staticmethod
198     def vpp_clear_errors_counters(node):
199         """Clear errors counters on VPP node.
200
201         :param node: Node to clear errors counters on.
202         :type node: dict
203         """
204         vat = VatExecutor()
205         vat.execute_script('clear_errors.vat', node)
206         vat.script_should_have_passed()
207
208     @staticmethod
209     def clear_error_counters_on_all_duts(nodes):
210         """Clear VPP errors counters on all DUTs.
211
212         :param nodes: VPP nodes.
213         :type nodes: dict
214         """
215         for node in nodes.values():
216             if node['type'] == NodeType.DUT:
217                 VppCounters.vpp_clear_errors_counters(node)
218
219     def vpp_dump_stats_table(self, node):
220         """Dump stats table on VPP node.
221
222         :param node: Node to dump stats table on.
223         :type node: dict
224         :returns: Stats table.
225         """
226         with VatTerminal(node) as vat:
227             vat.vat_terminal_exec_cmd('want_stats enable')
228             for _ in range(0, 12):
229                 stats_table = vat.vat_terminal_exec_cmd('dump_stats_table')
230                 if stats_table['interface_counters']:
231                     self._stats_table = stats_table
232                     return stats_table
233                 time.sleep(1)
234             return None
235
236     def vpp_get_ipv4_interface_counter(self, node, interface):
237         """
238
239         :param node: Node to get interface IPv4 counter on.
240         :param interface: Interface name.
241         :type node: dict
242         :type interface: str
243         :returns: Interface IPv4 counter.
244         :rtype: int
245         """
246         return self.vpp_get_ipv46_interface_counter(node, interface, False)
247
248     def vpp_get_ipv6_interface_counter(self, node, interface):
249         """
250
251         :param node: Node to get interface IPv6 counter on.
252         :param interface: Interface name.
253         :type node: dict
254         :type interface: str
255         :returns: Interface IPv6 counter.
256         :rtype: int
257         """
258         return self.vpp_get_ipv46_interface_counter(node, interface, True)
259
260     def vpp_get_ipv46_interface_counter(self, node, interface, is_ipv6=True):
261         """Return interface IPv4/IPv6 counter.
262
263         :param node: Node to get interface IPv4/IPv6 counter on.
264         :param interface: Interface name.
265         :param is_ipv6: Specify IP version.
266         :type node: dict
267         :type interface: str
268         :type is_ipv6: bool
269         :returns: Interface IPv4/IPv6 counter.
270         :rtype: int
271         """
272         version = 'ip6' if is_ipv6 else 'ip4'
273         topo = Topology()
274         if_index = topo.get_interface_sw_index(node, interface)
275         if if_index is None:
276             logger.trace('{i} sw_index not found.'.format(i=interface))
277             return 0
278
279         if_counters = self._stats_table.get('interface_counters')
280         if not if_counters:
281             logger.trace('No interface counters.')
282             return 0
283         for counter in if_counters:
284             if counter['vnet_counter_type'] == version:
285                 data = counter['data']
286                 return data[if_index]
287         logger.trace('{i} {v} counter not found.'.format(
288             i=interface, v=version))
289         return 0
290
291     @staticmethod
292     def show_vpp_statistics(node):
293         """Show [error, hardware, interface] stats.
294
295         :param node: VPP node.
296         :type node: dict
297         """
298         VppCounters.vpp_show_errors(node)
299         VppCounters.vpp_show_hardware_detail(node)
300         VppCounters.vpp_show_runtime(node)
301
302     @staticmethod
303     def show_statistics_on_all_duts(nodes, sleeptime=5):
304         """Show VPP statistics on all DUTs.
305
306         :param nodes: VPP nodes.
307         :type nodes: dict
308         :param sleeptime: Time to wait for traffic to arrive back to TG.
309         :type sleeptime: int
310         """
311         logger.trace('Waiting for statistics to be collected')
312         time.sleep(sleeptime)
313         for node in nodes.values():
314             if node['type'] == NodeType.DUT:
315                 VppCounters.show_vpp_statistics(node)