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