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 vat.script_should_have_passed()
81 def show_runtime_counters_on_all_duts(nodes):
82 """Clear VPP runtime counters on all DUTs.
84 :param nodes: VPP nodes.
87 for node in nodes.values():
88 if node['type'] == NodeType.DUT:
89 VppCounters.vpp_show_runtime(node)
92 def vpp_show_runtime_verbose(node):
93 """Run "show runtime verbose" CLI command.
95 :param node: Node to run command on.
99 vat.execute_script("show_runtime_verbose.vat", node, json_out=False)
100 vat.script_should_have_passed()
103 def vpp_show_hardware_detail(node):
104 """Run "show hardware-interfaces detail" debug CLI command.
106 :param node: Node to run command on.
110 vat.execute_script("show_hardware_detail.vat", node, json_out=False)
111 vat.script_should_have_passed()
114 def vpp_clear_runtime(node):
115 """Run "clear runtime" CLI command.
117 :param node: Node to run command on.
121 cmd_reply = 'cli_inband_reply'
122 err_msg = "Failed to run '{cmd}' PAPI command on host {host}!".format(
123 host=node['host'], cmd=cmd)
124 args = dict(cmd='clear runtime')
125 with PapiExecutor(node) as papi_exec:
126 papi_resp = papi_exec.add(cmd, **args).execute_should_pass(err_msg)
127 data = papi_resp.reply[0]['api_reply'][cmd_reply]
128 if data['retval'] != 0:
129 raise RuntimeError("Failed to clear runtime on host {host}".
130 format(host=node['host']))
133 def clear_runtime_counters_on_all_duts(nodes):
134 """Run "clear runtime" CLI command on all DUTs.
136 :param nodes: VPP nodes.
139 for node in nodes.values():
140 if node['type'] == NodeType.DUT:
141 VppCounters.vpp_clear_runtime(node)
144 def vpp_clear_interface_counters(node):
145 """Clear interface counters on VPP node.
147 :param node: Node to clear interface counters on.
151 cmd_reply = 'cli_inband_reply'
152 err_msg = "Failed to run '{cmd}' PAPI command on host {host}!".format(
153 host=node['host'], cmd=cmd)
154 args = dict(cmd='clear interfaces')
155 with PapiExecutor(node) as papi_exec:
156 papi_resp = papi_exec.add(cmd, **args).execute_should_pass(err_msg)
157 data = papi_resp.reply[0]['api_reply'][cmd_reply]
158 if data['retval'] != 0:
159 raise RuntimeError("Failed to clear interfaces on host {host}".
160 format(host=node['host']))
163 def clear_interface_counters_on_all_duts(nodes):
164 """Clear interface counters on all DUTs.
166 :param nodes: VPP nodes.
169 for node in nodes.values():
170 if node['type'] == NodeType.DUT:
171 VppCounters.vpp_clear_interface_counters(node)
174 def vpp_clear_hardware_counters(node):
175 """Clear interface hardware counters on VPP node.
177 :param node: Node to clear hardware counters on.
181 vat.execute_script('clear_hardware.vat', node)
182 vat.script_should_have_passed()
185 def clear_hardware_counters_on_all_duts(nodes):
186 """Clear hardware counters on all DUTs.
188 :param nodes: VPP nodes.
191 for node in nodes.values():
192 if node['type'] == NodeType.DUT:
193 VppCounters.vpp_clear_hardware_counters(node)
196 def vpp_clear_errors_counters(node):
197 """Clear errors counters on VPP node.
199 :param node: Node to clear errors counters on.
203 vat.execute_script('clear_errors.vat', node)
204 vat.script_should_have_passed()
207 def clear_error_counters_on_all_duts(nodes):
208 """Clear VPP errors counters on all DUTs.
210 :param nodes: VPP nodes.
213 for node in nodes.values():
214 if node['type'] == NodeType.DUT:
215 VppCounters.vpp_clear_errors_counters(node)
217 def vpp_dump_stats_table(self, node):
218 """Dump stats table on VPP node.
220 :param node: Node to dump stats table on.
222 :returns: Stats table.
224 with VatTerminal(node) as vat:
225 vat.vat_terminal_exec_cmd('want_stats enable')
226 for _ in range(0, 12):
227 stats_table = vat.vat_terminal_exec_cmd('dump_stats_table')
228 if stats_table['interface_counters']:
229 self._stats_table = stats_table
234 def vpp_get_ipv4_interface_counter(self, node, interface):
237 :param node: Node to get interface IPv4 counter on.
238 :param interface: Interface name.
241 :returns: Interface IPv4 counter.
244 return self.vpp_get_ipv46_interface_counter(node, interface, False)
246 def vpp_get_ipv6_interface_counter(self, node, interface):
249 :param node: Node to get interface IPv6 counter on.
250 :param interface: Interface name.
253 :returns: Interface IPv6 counter.
256 return self.vpp_get_ipv46_interface_counter(node, interface, True)
258 def vpp_get_ipv46_interface_counter(self, node, interface, is_ipv6=True):
259 """Return interface IPv4/IPv6 counter.
261 :param node: Node to get interface IPv4/IPv6 counter on.
262 :param interface: Interface name.
263 :param is_ipv6: Specify IP version.
267 :returns: Interface IPv4/IPv6 counter.
270 version = 'ip6' if is_ipv6 else 'ip4'
272 if_index = topo.get_interface_sw_index(node, interface)
274 logger.trace('{i} sw_index not found.'.format(i=interface))
277 if_counters = self._stats_table.get('interface_counters')
279 logger.trace('No interface counters.')
281 for counter in if_counters:
282 if counter['vnet_counter_type'] == version:
283 data = counter['data']
284 return data[if_index]
285 logger.trace('{i} {v} counter not found.'.format(
286 i=interface, v=version))
290 def show_vpp_statistics(node):
291 """Show [error, hardware, interface] stats.
293 :param node: VPP node.
296 VppCounters.vpp_show_errors(node)
297 VppCounters.vpp_show_hardware_detail(node)
298 VppCounters.vpp_show_runtime(node)
301 def show_statistics_on_all_duts(nodes, sleeptime=5):
302 """Show VPP statistics on all DUTs.
304 :param nodes: VPP nodes.
306 :param sleeptime: Time to wait for traffic to arrive back to TG.
309 logger.trace('Waiting for statistics to be collected')
310 time.sleep(sleeptime)
311 for node in nodes.values():
312 if node['type'] == NodeType.DUT:
313 VppCounters.show_vpp_statistics(node)