1 # Copyright (c) 2019 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 util library."""
18 from robot.api import logger
20 from resources.libraries.python.Constants import Constants
21 from resources.libraries.python.DUTSetup import DUTSetup
22 from resources.libraries.python.PapiExecutor import PapiExecutor
23 from resources.libraries.python.ssh import exec_cmd, exec_cmd_no_error
24 from resources.libraries.python.topology import NodeType
25 from resources.libraries.python.VatExecutor import VatExecutor
28 class VPPUtil(object):
29 """General class for any VPP related methods/functions."""
32 def show_vpp_settings(node, *additional_cmds):
33 """Print default VPP settings. In case others are needed, can be
34 accepted as next parameters (each setting one parameter), preferably
37 :param node: VPP node.
38 :param additional_cmds: Additional commands that the vpp should print
41 :type additional_cmds: tuple
43 def_setting_tb_displayed = {
44 'IPv6 FIB': 'ip6 fib',
46 'Interface IP': 'int addr',
53 for cmd in additional_cmds:
54 def_setting_tb_displayed['Custom Setting: {}'.format(cmd)] = cmd
56 for _, cmd in def_setting_tb_displayed.items():
57 command = 'vppctl sh {cmd}'.format(cmd=cmd)
58 exec_cmd_no_error(node, command, timeout=30, sudo=True)
61 def start_vpp_service(node, retries=60):
62 """Start VPP service on the specified node.
64 :param node: VPP node.
65 :param retries: Number of times (default 60) to re-try waiting.
68 :raises RuntimeError: If VPP service fails to start.
70 DUTSetup.start_service(node, Constants.VPP_UNIT)
71 # Sleep 1 second, up to <retry> times,
72 # and verify if VPP is running.
73 for _ in range(retries):
75 command = 'vppctl show pci'
76 ret, stdout, _ = exec_cmd(node, command, timeout=30, sudo=True)
77 if not ret and 'Connection refused' not in stdout:
80 raise RuntimeError('VPP failed to start on host {name}'.
81 format(name=node['host']))
82 DUTSetup.get_service_logs(node, Constants.VPP_UNIT)
85 def start_vpp_service_on_all_duts(nodes):
86 """Start up the VPP service on all nodes.
88 :param nodes: Nodes in the topology.
91 for node in nodes.values():
92 if node['type'] == NodeType.DUT:
93 VPPUtil.start_vpp_service(node)
96 def stop_vpp_service(node):
97 """Stop VPP service on the specified node.
99 :param node: VPP node.
101 :raises RuntimeError: If VPP service fails to stop.
103 DUTSetup.stop_service(node, Constants.VPP_UNIT)
106 def stop_vpp_service_on_all_duts(nodes):
107 """Stop VPP service on all nodes.
109 :param nodes: Nodes in the topology.
112 for node in nodes.values():
113 if node['type'] == NodeType.DUT:
114 VPPUtil.stop_vpp_service(node)
117 def verify_vpp_on_dut(node):
118 """Verify that VPP is installed on DUT node.
120 :param node: DUT node.
122 :raises RuntimeError: If failed to restart VPP, get VPP version
123 or get VPP interfaces.
125 VPPUtil.vpp_show_version_verbose(node)
126 VPPUtil.vpp_show_interfaces(node)
129 def verify_vpp_on_all_duts(nodes):
130 """Verify that VPP is installed on all DUT nodes.
132 :param nodes: Nodes in the topology.
135 for node in nodes.values():
136 if node['type'] == NodeType.DUT:
137 VPPUtil.start_vpp_service(node)
138 VPPUtil.verify_vpp_on_dut(node)
141 def vpp_show_version(node, verbose=False):
142 """Run "show_version" PAPI command.
144 :param node: Node to run command on.
145 :param verbose: Show version, compile date and compile location if True
146 otherwise show only version.
151 with PapiExecutor(node) as papi_exec:
152 data = papi_exec.add('show_version').execute_should_pass().\
154 version = ('VPP version: {ver}\n'.
155 format(ver=data['version'].rstrip('\0x00')))
157 version += ('Compile date: {date}\n'
158 'Compile location: {cl}\n '.
159 format(date=data['build_date'].rstrip('\0x00'),
160 cl=data['build_directory'].rstrip('\0x00')))
164 def vpp_show_version_verbose(node):
165 """Run "show_version" API command and return verbose string of version
168 :param node: Node to run command on.
171 VPPUtil.vpp_show_version(node, verbose=True)
174 def show_vpp_version_on_all_duts(nodes):
175 """Show VPP version on all DUTs.
177 :param nodes: VPP nodes.
180 for node in nodes.values():
181 if node['type'] == NodeType.DUT:
182 VPPUtil.vpp_show_version_verbose(node)
185 def vpp_show_interfaces(node):
186 """Run "show interface" CLI command.
188 :param node: Node to run command on.
192 vat.execute_script("show_interface.vat", node, json_out=False)
195 vat.script_should_have_passed()
196 except AssertionError:
197 raise RuntimeError('Failed to get VPP interfaces on host: {name}'.
198 format(name=node['host']))
201 def vpp_show_crypto_device_mapping(node):
202 """Run "show crypto device mapping" CLI command.
204 :param node: Node to run command on.
208 vat.execute_script("show_crypto_device_mapping.vat", node,
212 def vpp_api_trace_dump(node):
213 """Run "api trace custom-dump" CLI command.
215 :param node: Node to run command on.
219 vat.execute_script("api_trace_dump.vat", node, json_out=False)
222 def vpp_api_trace_save(node):
223 """Run "api trace save" CLI command.
225 :param node: Node to run command on.
229 vat.execute_script("api_trace_save.vat", node, json_out=False)
232 def vpp_enable_traces_on_dut(node):
233 """Enable vpp packet traces on the DUT node.
235 :param node: DUT node to set up.
239 vat.execute_script("enable_dpdk_traces.vat", node, json_out=False)
240 vat.execute_script("enable_vhost_user_traces.vat", node, json_out=False)
241 vat.execute_script("enable_memif_traces.vat", node, json_out=False)
244 def vpp_enable_traces_on_all_duts(nodes):
245 """Enable vpp packet traces on all DUTs in the given topology.
247 :param nodes: Nodes in the topology.
250 for node in nodes.values():
251 if node['type'] == NodeType.DUT:
252 VPPUtil.vpp_enable_traces_on_dut(node)
255 def vpp_enable_elog_traces_on_dut(node):
256 """Enable API/CLI/Barrier traces on the DUT node.
258 :param node: DUT node to set up.
262 vat.execute_script("elog_trace_api_cli_barrier.vat", node,
266 def vpp_enable_elog_traces_on_all_duts(nodes):
267 """Enable API/CLI/Barrier traces on all DUTs in the given topology.
269 :param nodes: Nodes in the topology.
272 for node in nodes.values():
273 if node['type'] == NodeType.DUT:
274 VPPUtil.vpp_enable_elog_traces_on_dut(node)
277 def show_event_logger_on_dut(node):
278 """Show event logger on the DUT node.
280 :param node: DUT node to show traces on.
284 vat.execute_script("show_event_logger.vat", node, json_out=False)
287 def show_event_logger_on_all_duts(nodes):
288 """Show event logger on all DUTs in the given topology.
290 :param nodes: Nodes in the topology.
293 for node in nodes.values():
294 if node['type'] == NodeType.DUT:
295 VPPUtil.show_event_logger_on_dut(node)
298 def vpp_show_threads(node):
299 """Show VPP threads on node.
301 :param node: Node to run command on.
303 :returns: VPP thread data.
306 with PapiExecutor(node) as papi_exec:
307 return papi_exec.add('show_threads').execute_should_pass().\
308 verify_reply()["thread_data"]