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:
6 # http://www.apache.org/licenses/LICENSE-2.0
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.
14 """VPP counters utilities library."""
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
24 class VppCounters(object):
25 """VPP counters utilities."""
28 self._stats_table = None
31 def vpp_show_errors(node):
32 """Run "show errors" debug CLI command.
34 :param node: Node to run command on.
38 vat.execute_script("show_errors.vat", node, json_out=False)
39 vat.script_should_have_passed()
42 def vpp_show_errors_verbose(node):
43 """Run "show errors verbose" debug CLI command.
45 :param node: Node to run command on.
49 vat.execute_script("show_errors_verbose.vat", node, json_out=False)
50 vat.script_should_have_passed()
53 def vpp_show_errors_on_all_duts(nodes, verbose=False):
54 """Show errors on all DUTs.
56 :param nodes: VPP nodes.
57 :param verbose: If True show verbose output.
62 for node in nodes.values():
63 if node['type'] == NodeType.DUT:
65 VppCounters.vpp_show_errors_verbose(node)
67 VppCounters.vpp_show_errors(node)
70 def vpp_show_runtime(node):
71 """Run "show runtime" CLI command.
73 :param node: Node to run command on.
77 vat.execute_script("show_runtime.vat", node, json_out=False)
78 logger.info(vat.get_script_stdout())
79 vat.script_should_have_passed()
82 def show_runtime_counters_on_all_duts(nodes):
83 """Clear VPP runtime counters on all DUTs.
85 :param nodes: VPP nodes.
88 for node in nodes.values():
89 if node['type'] == NodeType.DUT:
90 VppCounters.vpp_show_runtime(node)
93 def vpp_show_runtime_verbose(node):
94 """Run "show runtime verbose" CLI command.
96 :param node: Node to run command on.
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()
105 def vpp_show_hardware_detail(node):
106 """Run "show hardware-interfaces detail" debug CLI command.
108 :param node: Node to run command on.
112 vat.execute_script("show_hardware_detail.vat", node, json_out=False)
113 vat.script_should_have_passed()
116 def vpp_clear_runtime(node):
117 """Run "clear runtime" CLI command.
119 :param node: Node to run command on.
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']))
135 def clear_runtime_counters_on_all_duts(nodes):
136 """Run "clear runtime" CLI command on all DUTs.
138 :param nodes: VPP nodes.
141 for node in nodes.values():
142 if node['type'] == NodeType.DUT:
143 VppCounters.vpp_clear_runtime(node)
146 def vpp_clear_interface_counters(node):
147 """Clear interface counters on VPP node.
149 :param node: Node to clear interface counters on.
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']))
165 def clear_interface_counters_on_all_duts(nodes):
166 """Clear interface counters on all DUTs.
168 :param nodes: VPP nodes.
171 for node in nodes.values():
172 if node['type'] == NodeType.DUT:
173 VppCounters.vpp_clear_interface_counters(node)
176 def vpp_clear_hardware_counters(node):
177 """Clear interface hardware counters on VPP node.
179 :param node: Node to clear hardware counters on.
183 vat.execute_script('clear_hardware.vat', node)
184 vat.script_should_have_passed()
187 def clear_hardware_counters_on_all_duts(nodes):
188 """Clear hardware counters on all DUTs.
190 :param nodes: VPP nodes.
193 for node in nodes.values():
194 if node['type'] == NodeType.DUT:
195 VppCounters.vpp_clear_hardware_counters(node)
198 def vpp_clear_errors_counters(node):
199 """Clear errors counters on VPP node.
201 :param node: Node to clear errors counters on.
205 vat.execute_script('clear_errors.vat', node)
206 vat.script_should_have_passed()
209 def clear_error_counters_on_all_duts(nodes):
210 """Clear VPP errors counters on all DUTs.
212 :param nodes: VPP nodes.
215 for node in nodes.values():
216 if node['type'] == NodeType.DUT:
217 VppCounters.vpp_clear_errors_counters(node)
219 def vpp_dump_stats_table(self, node):
220 """Dump stats table on VPP node.
222 :param node: Node to dump stats table on.
224 :returns: Stats table.
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
236 def vpp_get_ipv4_interface_counter(self, node, interface):
239 :param node: Node to get interface IPv4 counter on.
240 :param interface: Interface name.
243 :returns: Interface IPv4 counter.
246 return self.vpp_get_ipv46_interface_counter(node, interface, False)
248 def vpp_get_ipv6_interface_counter(self, node, interface):
251 :param node: Node to get interface IPv6 counter on.
252 :param interface: Interface name.
255 :returns: Interface IPv6 counter.
258 return self.vpp_get_ipv46_interface_counter(node, interface, True)
260 def vpp_get_ipv46_interface_counter(self, node, interface, is_ipv6=True):
261 """Return interface IPv4/IPv6 counter.
263 :param node: Node to get interface IPv4/IPv6 counter on.
264 :param interface: Interface name.
265 :param is_ipv6: Specify IP version.
269 :returns: Interface IPv4/IPv6 counter.
272 version = 'ip6' if is_ipv6 else 'ip4'
274 if_index = topo.get_interface_sw_index(node, interface)
276 logger.trace('{i} sw_index not found.'.format(i=interface))
279 if_counters = self._stats_table.get('interface_counters')
281 logger.trace('No interface counters.')
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))
292 def show_vpp_statistics(node):
293 """Show [error, hardware, interface] stats.
295 :param node: VPP node.
298 VppCounters.vpp_show_errors(node)
299 VppCounters.vpp_show_hardware_detail(node)
300 VppCounters.vpp_show_runtime(node)
303 def show_statistics_on_all_duts(nodes, sleeptime=5):
304 """Show VPP statistics on all DUTs.
306 :param nodes: VPP nodes.
308 :param sleeptime: Time to wait for traffic to arrive back to TG.
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)