aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--resources/libraries/python/InterfaceUtil.py48
-rw-r--r--resources/libraries/python/Memif.py157
-rw-r--r--resources/libraries/python/Tap.py72
-rw-r--r--resources/libraries/python/VhostUser.py24
-rw-r--r--resources/libraries/python/topology.py152
-rw-r--r--resources/libraries/robot/performance/performance_setup.robot5
-rw-r--r--resources/libraries/robot/shared/default.robot3
-rw-r--r--tests/vpp/func/vm_vhost/l2bd/eth2p-dot1q-l2bdbasemaclrn-eth-2vhost-1vm-func.robot6
-rw-r--r--tests/vpp/func/vm_vhost/l2bd/eth2p-eth-l2bdbasemaclrn-eth-2vhost-1vm-func.robot9
-rw-r--r--tests/vpp/func/vm_vhost/l2bd/eth2p-eth-l2bdbasemacstc-eth-2vhost-1vm-func.robot9
10 files changed, 407 insertions, 78 deletions
diff --git a/resources/libraries/python/InterfaceUtil.py b/resources/libraries/python/InterfaceUtil.py
index a68b921146..503715c6dd 100644
--- a/resources/libraries/python/InterfaceUtil.py
+++ b/resources/libraries/python/InterfaceUtil.py
@@ -655,10 +655,14 @@ class InterfaceUtil(object):
sw_if_index=sw_if_index,
vlan=vlan)
if output[0]["retval"] == 0:
- sw_subif_index = output[0]["sw_if_index"]
+ sw_subif_idx = output[0]["sw_if_index"]
logger.trace('VLAN subinterface with sw_if_index {} and VLAN ID {} '
- 'created on node {}'.format(sw_subif_index,
+ 'created on node {}'.format(sw_subif_idx,
vlan, node['host']))
+ if_key = Topology.add_new_port(node, "vlan_subif")
+ Topology.update_interface_sw_if_index(node, if_key, sw_subif_idx)
+ ifc_name = InterfaceUtil.vpp_get_interface_name(node, sw_subif_idx)
+ Topology.update_interface_name(node, if_key, ifc_name)
else:
raise RuntimeError('Unable to create VLAN subinterface on node {}'
.format(node['host']))
@@ -666,7 +670,7 @@ class InterfaceUtil(object):
with VatTerminal(node, False) as vat:
vat.vat_terminal_exec_cmd('exec show interfaces')
- return '{}.{}'.format(interface, vlan), sw_subif_index
+ return '{}.{}'.format(interface, vlan), sw_subif_idx
@staticmethod
def create_vxlan_interface(node, vni, source_ip, destination_ip):
@@ -695,9 +699,14 @@ class InterfaceUtil(object):
output = output[0]
if output["retval"] == 0:
- return output["sw_if_index"]
+ sw_if_idx = output["sw_if_index"]
+ if_key = Topology.add_new_port(node, "vxlan_tunnel")
+ Topology.update_interface_sw_if_index(node, if_key, sw_if_idx)
+ ifc_name = InterfaceUtil.vpp_get_interface_name(node, sw_if_idx)
+ Topology.update_interface_name(node, if_key, ifc_name)
+ return sw_if_idx
else:
- raise RuntimeError('Unable to create VXLAN interface on node {0}'
+ raise RuntimeError("Unable to create VXLAN interface on node {0}"
.format(node))
@staticmethod
@@ -823,9 +832,13 @@ class InterfaceUtil(object):
type_subif=type_subif)
if output[0]["retval"] == 0:
- sw_subif_index = output[0]["sw_if_index"]
+ sw_subif_idx = output[0]["sw_if_index"]
logger.trace('Created subinterface with index {}'
- .format(sw_subif_index))
+ .format(sw_subif_idx))
+ if_key = Topology.add_new_port(node, "subinterface")
+ Topology.update_interface_sw_if_index(node, if_key, sw_subif_idx)
+ ifc_name = InterfaceUtil.vpp_get_interface_name(node, sw_subif_idx)
+ Topology.update_interface_name(node, if_key, ifc_name)
else:
raise RuntimeError('Unable to create sub-interface on node {}'
.format(node['host']))
@@ -834,7 +847,7 @@ class InterfaceUtil(object):
vat.vat_terminal_exec_cmd('exec show interfaces')
name = '{}.{}'.format(interface, sub_id)
- return name, sw_subif_index
+ return name, sw_subif_idx
@staticmethod
def create_gre_tunnel_interface(node, source_ip, destination_ip):
@@ -856,14 +869,19 @@ class InterfaceUtil(object):
output = output[0]
if output["retval"] == 0:
- sw_if_index = output["sw_if_index"]
+ sw_if_idx = output["sw_if_index"]
vat_executor = VatExecutor()
vat_executor.execute_script_json_out("dump_interfaces.vat", node)
interface_dump_json = vat_executor.get_script_stdout()
name = VatJsonUtil.get_interface_name_from_json(
- interface_dump_json, sw_if_index)
- return name, sw_if_index
+ interface_dump_json, sw_if_idx)
+
+ if_key = Topology.add_new_port(node, "gre_tunnel")
+ Topology.update_interface_sw_if_index(node, if_key, sw_if_idx)
+ Topology.update_interface_name(node, if_key, name)
+
+ return name, sw_if_idx
else:
raise RuntimeError('Unable to create GRE tunnel on node {}.'
.format(node))
@@ -881,7 +899,12 @@ class InterfaceUtil(object):
"""
out = VatExecutor.cmd_from_template(node, "create_loopback.vat")
if out[0].get('retval') == 0:
- return out[0].get('sw_if_index')
+ sw_if_idx = out[0].get('sw_if_index')
+ if_key = Topology.add_new_port(node, "loopback")
+ Topology.update_interface_sw_if_index(node, if_key, sw_if_idx)
+ ifc_name = InterfaceUtil.vpp_get_interface_name(node, sw_if_idx)
+ Topology.update_interface_name(node, if_key, ifc_name)
+ return sw_if_idx
else:
raise RuntimeError('Create loopback failed on node "{}"'
.format(node['host']))
@@ -1067,7 +1090,6 @@ class InterfaceUtil(object):
raise RuntimeError('Unable to assign interface to FIB node {}.'
.format(node))
-
@staticmethod
def set_linux_interface_mac(node, interface, mac, namespace=None):
"""Set MAC address for interface in linux.
diff --git a/resources/libraries/python/Memif.py b/resources/libraries/python/Memif.py
index 09fa2a8c3e..e3cea939ec 100644
--- a/resources/libraries/python/Memif.py
+++ b/resources/libraries/python/Memif.py
@@ -15,6 +15,7 @@
from resources.libraries.python.ssh import SSH
from resources.libraries.python.VatExecutor import VatExecutor, VatTerminal
+from resources.libraries.python.topology import Topology
class Memif(object):
@@ -24,7 +25,7 @@ class Memif(object):
pass
@staticmethod
- def create_memif_interface(node, socket, mid, role="master"):
+ def create_memif_interface(node, socket, mid, role='master'):
"""Create Memif interface on the given node.
:param node: Given node to create Memif interface on.
@@ -46,13 +47,25 @@ class Memif(object):
socket=socket, id=mid, role=role)
if 'sw_if_index' in vat.vat_stdout:
try:
- return int(vat.vat_stdout.split()[4])
+ sw_if_idx = int(vat.vat_stdout.split()[4])
+ if_key = Topology.add_new_port(node, 'memif')
+ Topology.update_interface_sw_if_index(
+ node, if_key, sw_if_idx)
+ ifc_name = Memif.vpp_get_memif_interface_name(
+ node, sw_if_idx)
+ Topology.update_interface_name(node, if_key, ifc_name)
+ ifc_mac = Memif.vpp_get_memif_interface_mac(node, sw_if_idx)
+ Topology.update_interface_mac_address(node, if_key, ifc_mac)
+ Topology.update_interface_memif_socket(node, if_key, socket)
+ Topology.update_interface_memif_id(node, if_key, mid)
+ Topology.update_interface_memif_role(node, if_key, role)
+ return sw_if_idx
except KeyError:
raise ValueError('Create Memif interface failed on node '
- '{}"'.format(node['host']))
+ '{}'.format(node['host']))
else:
raise ValueError('Create Memif interface failed on node '
- '{}"'.format(node['host']))
+ '{}'.format(node['host']))
@staticmethod
def show_memif(node):
@@ -78,3 +91,139 @@ class Memif(object):
for sock in socks:
ssh.exec_command_sudo('rm -f {}'.format(sock))
+
+ @staticmethod
+ def parse_memif_dump_data(memif_data):
+ """Convert Memif data to dictionary.
+
+ :param memif_data: Dump of Memif interfaces data.
+ :type memif_data: str
+ :returns: Memif interfaces data in dictionary.
+ :rtype: dict
+ :raises RuntimeError: If there is no memif interface name found in
+ provided data.
+ """
+ memif_name = None
+ memif_dict = dict()
+ memif_data = str(memif_data)
+ values = dict()
+
+ clutter = ['vat#']
+ for garbage in clutter:
+ memif_data = memif_data.replace(garbage, '')
+
+ for line in memif_data.splitlines():
+ if line.startswith('Sending') or len(line) == 0:
+ continue
+ elif line.startswith('memif'):
+ if memif_name:
+ memif_dict[memif_name] = values
+ line_split = line.split(':', 1)
+ memif_name = str(line_split[0])
+ values = dict()
+ line = line_split[1]
+ line_split = line.split()
+ for i in range(0, len(line_split), 2):
+ key = str(line_split[i])
+ try:
+ value = line_split[i+1]
+ except IndexError:
+ value = None
+ values[key] = value
+ if memif_name:
+ memif_dict[memif_name] = values
+ else:
+ raise RuntimeError('No memif interface name found')
+
+ return memif_dict
+
+ @staticmethod
+ def vpp_get_memif_interface_name(node, sw_if_idx):
+ """Get Memif interface name from Memif interfaces dump.
+
+ :param node: DUT node.
+ :param sw_if_idx: DUT node.
+ :type node: dict
+ :type sw_if_idx: int
+ :returns: Memif interface name.
+ :rtype: str
+ """
+ with VatTerminal(node, json_param=False) as vat:
+ vat.vat_terminal_exec_cmd_from_template('memif_dump.vat')
+ memif_data = Memif.parse_memif_dump_data(vat.vat_stdout)
+ for item in memif_data:
+ if memif_data[item]['sw_if_index'] == str(sw_if_idx):
+ return item
+ return None
+
+ @staticmethod
+ def vpp_get_memif_interface_mac(node, sw_if_idx):
+ """Get Memif interface MAC address from Memif interfaces dump.
+
+ :param node: DUT node.
+ :param sw_if_idx: DUT node.
+ :type node: dict
+ :type sw_if_idx: int
+ :returns: Memif interface MAC address.
+ :rtype: str
+ """
+ with VatTerminal(node, json_param=False) as vat:
+ vat.vat_terminal_exec_cmd_from_template('memif_dump.vat')
+ memif_data = Memif.parse_memif_dump_data(vat.vat_stdout)
+ for item in memif_data:
+ if memif_data[item]['sw_if_index'] == str(sw_if_idx):
+ return memif_data[item].get('mac', None)
+
+ @staticmethod
+ def vpp_get_memif_interface_socket(node, sw_if_idx):
+ """Get Memif interface socket path from Memif interfaces dump.
+
+ :param node: DUT node.
+ :param sw_if_idx: DUT node.
+ :type node: dict
+ :type sw_if_idx: int
+ :returns: Memif interface socket path.
+ :rtype: str
+ """
+ with VatTerminal(node, json_param=False) as vat:
+ vat.vat_terminal_exec_cmd_from_template('memif_dump.vat')
+ memif_data = Memif.parse_memif_dump_data(vat.vat_stdout)
+ for item in memif_data:
+ if memif_data[item]['sw_if_index'] == str(sw_if_idx):
+ return memif_data[item].get('socket', None)
+
+ @staticmethod
+ def vpp_get_memif_interface_id(node, sw_if_idx):
+ """Get Memif interface ID from Memif interfaces dump.
+
+ :param node: DUT node.
+ :param sw_if_idx: DUT node.
+ :type node: dict
+ :type sw_if_idx: int
+ :returns: Memif interface ID.
+ :rtype: int
+ """
+ with VatTerminal(node, json_param=False) as vat:
+ vat.vat_terminal_exec_cmd_from_template('memif_dump.vat')
+ memif_data = Memif.parse_memif_dump_data(vat.vat_stdout)
+ for item in memif_data:
+ if memif_data[item]['sw_if_index'] == str(sw_if_idx):
+ return int(memif_data[item].get('id', None))
+
+ @staticmethod
+ def vpp_get_memif_interface_role(node, sw_if_idx):
+ """Get Memif interface role from Memif interfaces dump.
+
+ :param node: DUT node.
+ :param sw_if_idx: DUT node.
+ :type node: dict
+ :type sw_if_idx: int
+ :returns: Memif interface role.
+ :rtype: int
+ """
+ with VatTerminal(node, json_param=False) as vat:
+ vat.vat_terminal_exec_cmd_from_template('memif_dump.vat')
+ memif_data = Memif.parse_memif_dump_data(vat.vat_stdout)
+ for item in memif_data:
+ if memif_data[item]['sw_if_index'] == str(sw_if_idx):
+ return memif_data[item].get('role', None)
diff --git a/resources/libraries/python/Tap.py b/resources/libraries/python/Tap.py
index 6c346860de..cf0ae215ed 100644
--- a/resources/libraries/python/Tap.py
+++ b/resources/libraries/python/Tap.py
@@ -15,6 +15,7 @@
from resources.libraries.python.VatExecutor import VatTerminal
from resources.libraries.python.InterfaceUtil import InterfaceUtil
+from resources.libraries.python.topology import Topology
class Tap(object):
@@ -30,7 +31,7 @@ class Tap(object):
:type node: dict
:type tap_name: str
:type mac: str
- :return: Returns a interface index.
+ :returns: Returns a interface index.
:rtype: int
"""
command = 'connect'
@@ -42,7 +43,17 @@ class Tap(object):
resp = vat.vat_terminal_exec_cmd_from_template('tap.vat',
tap_command=command,
tap_arguments=args)
- return resp[0]['sw_if_index']
+ sw_if_idx = resp[0]['sw_if_index']
+ if_key = Topology.add_new_port(node, 'tap')
+ Topology.update_interface_sw_if_index(node, if_key, sw_if_idx)
+ ifc_name = Tap.vpp_get_tap_interface_name(node, sw_if_idx)
+ Topology.update_interface_name(node, if_key, ifc_name)
+ if mac is None:
+ mac = Tap.vpp_get_tap_interface_mac(node, sw_if_idx)
+ Topology.update_interface_mac_address(node, if_key, mac)
+ Topology.update_interface_tap_dev_name(node, if_key, tap_name)
+
+ return sw_if_idx
@staticmethod
def modify_tap_interface(node, if_index, tap_name, mac=None):
@@ -69,6 +80,11 @@ class Tap(object):
resp = vat.vat_terminal_exec_cmd_from_template('tap.vat',
tap_command=command,
tap_arguments=args)
+ if_key = Topology.get_interface_by_sw_index(node, if_index)
+ Topology.update_interface_tap_dev_name(node, if_key, tap_name)
+ if mac:
+ Topology.update_interface_mac_address(node, if_key, mac)
+
return resp[0]['sw_if_index']
@staticmethod
@@ -90,6 +106,8 @@ class Tap(object):
if int(resp[0]['retval']) != 0:
raise RuntimeError(
'Could not remove tap interface: {}'.format(resp))
+ if_key = Topology.get_interface_sw_index(node, if_index)
+ Topology.remove_port(node, if_key)
@staticmethod
def check_tap_present(node, tap_name):
@@ -105,3 +123,53 @@ class Tap(object):
if len(tap_if) == 0:
raise RuntimeError(
'Tap interface :{} does not exist'.format(tap_name))
+
+ @staticmethod
+ def vpp_get_tap_interface_name(node, sw_if_idx):
+ """Get VPP tap interface name from hardware interfaces dump.
+
+ :param node: DUT node.
+ :param sw_if_idx: DUT node.
+ :type node: dict
+ :type sw_if_idx: int
+ :returns: VPP tap interface name.
+ :rtype: str
+ """
+ with VatTerminal(node, json_param=False) as vat:
+ response = vat.vat_terminal_exec_cmd_from_template(
+ 'show_hardware_detail.vat')
+
+ for line in str(response[0]).splitlines():
+ if line.startswith('tap-'):
+ line_split = line.split()
+ if line_split[1] == sw_if_idx:
+ return line_split[0]
+
+ return None
+
+ @staticmethod
+ def vpp_get_tap_interface_mac(node, sw_if_idx):
+ """Get tap interface MAC address from hardware interfaces dump.
+
+ :param node: DUT node.
+ :param sw_if_idx: DUT node.
+ :type node: dict
+ :type sw_if_idx: int
+ :returns: Tap interface MAC address.
+ :rtype: str
+ """
+ with VatTerminal(node, json_param=False) as vat:
+ response = vat.vat_terminal_exec_cmd_from_template(
+ 'show_hardware_detail.vat')
+
+ tap_if_match = False
+ for line in str(response[0]).splitlines():
+ if tap_if_match:
+ line_split = line.split()
+ return line_split[-1]
+ if line.startswith('tap-'):
+ line_split = line.split()
+ if line_split[1] == sw_if_idx:
+ tap_if_match = True
+
+ return None
diff --git a/resources/libraries/python/VhostUser.py b/resources/libraries/python/VhostUser.py
index 680d4ae300..2e0ed1eada 100644
--- a/resources/libraries/python/VhostUser.py
+++ b/resources/libraries/python/VhostUser.py
@@ -14,7 +14,8 @@
"""Vhost-user interfaces library."""
from resources.libraries.python.VatExecutor import VatExecutor, VatTerminal
-from resources.libraries.python.topology import NodeType
+from resources.libraries.python.topology import NodeType, Topology
+from resources.libraries.python.InterfaceUtil import InterfaceUtil
class VhostUser(object):
@@ -28,13 +29,22 @@ class VhostUser(object):
:param socket: Vhost-user interface socket path.
:type node: dict
:type socket: str
- :return: SW interface index.
+ :returns: SW interface index.
:rtype: int
+ :raises RuntimeError: If Vhost-user interface creation failed.
"""
- out = VatExecutor.cmd_from_template(node, "create_vhost_user_if.vat",
+ out = VatExecutor.cmd_from_template(node, 'create_vhost_user_if.vat',
sock=socket)
if out[0].get('retval') == 0:
- return out[0].get('sw_if_index')
+ sw_if_idx = int(out[0].get('sw_if_index'))
+ if_key = Topology.add_new_port(node, 'vhost')
+ Topology.update_interface_sw_if_index(node, if_key, sw_if_idx)
+ ifc_name = InterfaceUtil.vpp_get_interface_name(node, sw_if_idx)
+ Topology.update_interface_name(node, if_key, ifc_name)
+ ifc_mac = InterfaceUtil.vpp_get_interface_mac(node, sw_if_idx)
+ Topology.update_interface_mac_address(node, if_key, ifc_mac)
+ Topology.update_interface_vhost_socket(node, if_key, socket)
+ return sw_if_idx
else:
raise RuntimeError('Create Vhost-user interface failed on node '
'"{}"'.format(node['host']))
@@ -47,7 +57,7 @@ class VhostUser(object):
:param socket: Vhost-user interface socket path.
:type node: dict
:type socket: str
- :return: Interface name or None if not found.
+ :returns: Interface name or None if not found.
:rtype: str
"""
for interface in node['interfaces'].values():
@@ -64,7 +74,7 @@ class VhostUser(object):
:param sw_if_index: Idx of the specific interface.
:type node: dict
:type sw_if_index: str
- :return: l2_address of the given interface.
+ :returns: l2_address of the given interface.
:rtype: str
"""
@@ -83,7 +93,7 @@ class VhostUser(object):
:param node: VPP node to get interface data from.
:type node: dict
- :return: nothing
+ :returns: nothing
"""
vat = VatExecutor()
vat.execute_script("show_vhost.vat", node, json_out=False)
diff --git a/resources/libraries/python/topology.py b/resources/libraries/python/topology.py
index 791b07053c..4ff68ec43d 100644
--- a/resources/libraries/python/topology.py
+++ b/resources/libraries/python/topology.py
@@ -87,7 +87,7 @@ class Topology(object):
:param ptype: Port type, used as key prefix.
:type node: dict
:type ptype: str
- :return: Port key or None
+ :returns: Port key or None
:rtype: string or None
"""
max_ports = 1000000
@@ -100,6 +100,21 @@ class Topology(object):
return iface
@staticmethod
+ def remove_port(node, iface_key):
+ """Remove required port from active topology.
+
+ :param node: Node to remove port on.
+ :param: iface_key: Topology key of the interface.
+ :type node: dict
+ :type iface_key: str
+ :returns: Nothing
+ """
+ try:
+ node['interfaces'].pop(iface_key)
+ except KeyError:
+ pass
+
+ @staticmethod
def remove_all_ports(node, ptype):
"""Remove all ports with ptype as prefix.
@@ -107,13 +122,29 @@ class Topology(object):
:param: ptype: Port type, used as key prefix.
:type node: dict
:type ptype: str
- :return: Nothing
+ :returns: Nothing
"""
for if_key in list(node['interfaces']):
if if_key.startswith(str(ptype)):
node['interfaces'].pop(if_key)
@staticmethod
+ def remove_all_added_ports_on_all_duts_from_topology(nodes):
+ """Remove all added ports on all DUT nodes in the topology.
+
+ :param nodes: Nodes in the topology.
+ :type nodes: dict
+ :returns: Nothing
+ """
+ port_types = ('subinterface', 'vlan_subif', 'memif', 'tap', 'vhost',
+ 'loopback', 'gre_tunnel', 'vxlan_tunnel')
+
+ for node_data in nodes.values():
+ if node_data['type'] == NodeType.DUT:
+ for ptype in port_types:
+ Topology.remove_all_ports(node_data, ptype)
+
+ @staticmethod
def update_interface_sw_if_index(node, iface_key, sw_if_index):
"""Update sw_if_index on the interface from the node.
@@ -166,6 +197,59 @@ class Topology(object):
node['interfaces'][iface_key]['vhost_socket'] = str(vhost_socket)
@staticmethod
+ def update_interface_memif_socket(node, iface_key, memif_socket):
+ """Update memif socket name on the interface from the node.
+
+ :param node: Node to update socket name on.
+ :param iface_key: Topology key of the interface.
+ :param memif_socket: Path to named socket on node.
+ :type node: dict
+ :type iface_key: str
+ :type memif_socket: str
+ """
+ node['interfaces'][iface_key]['memif_socket'] = str(memif_socket)
+
+ @staticmethod
+ def update_interface_memif_id(node, iface_key, memif_id):
+ """Update memif ID on the interface from the node.
+
+ :param node: Node to update memif ID on.
+ :param iface_key: Topology key of the interface.
+ :param memif_id: Memif interface ID.
+ :type node: dict
+ :type iface_key: str
+ :type memif_id: str
+ """
+ node['interfaces'][iface_key]['memif_id'] = str(memif_id)
+
+ @staticmethod
+ def update_interface_memif_role(node, iface_key, memif_role):
+ """Update memif role on the interface from the node.
+
+ :param node: Node to update memif role on.
+ :param iface_key: Topology key of the interface.
+ :param memif_role: Memif role.
+ :type node: dict
+ :type iface_key: str
+ :type memif_role: str
+ """
+ node['interfaces'][iface_key]['memif_role'] = str(memif_role)
+
+ @staticmethod
+ def update_interface_tap_dev_name(node, iface_key, dev_name):
+ """Update device name on the tap interface from the node.
+
+ :param node: Node to update tap device name on.
+ :param iface_key: Topology key of the interface.
+ :param dev_name: Device name of the tap interface.
+ :type node: dict
+ :type iface_key: str
+ :type dev_name: str
+ :returns: Nothing
+ """
+ node['interfaces'][iface_key]['dev_name'] = str(dev_name)
+
+ @staticmethod
def get_node_by_hostname(nodes, hostname):
"""Get node from nodes of the topology by hostname.
@@ -173,7 +257,7 @@ class Topology(object):
:param hostname: Host name.
:type nodes: dict
:type hostname: str
- :return: Node dictionary or None if not found.
+ :returns: Node dictionary or None if not found.
"""
for node in nodes.values():
if node['host'] == hostname:
@@ -187,7 +271,7 @@ class Topology(object):
:param nodes: Nodes of the test topology.
:type nodes: dict
- :return: Links in the topology.
+ :returns: Links in the topology.
:rtype: list
"""
links = []
@@ -212,7 +296,7 @@ class Topology(object):
:type node: dict
:type key: string
:type value: string
- :return: Interface key from topology file
+ :returns: Interface key from topology file
:rtype: string
"""
interfaces = node['interfaces']
@@ -236,7 +320,7 @@ class Topology(object):
:param iface_name: Interface name (string form).
:type node: dict
:type iface_name: string
- :return: Interface key.
+ :returns: Interface key.
:rtype: str
"""
return Topology._get_interface_by_key_value(node, "name", iface_name)
@@ -252,7 +336,7 @@ class Topology(object):
:param link_name: Name of the link that a interface is connected to.
:type node: dict
:type link_name: string
- :return: Interface key of the interface connected to the given link.
+ :returns: Interface key of the interface connected to the given link.
:rtype: str
"""
return Topology._get_interface_by_key_value(node, "link", link_name)
@@ -268,7 +352,7 @@ class Topology(object):
connected to.
:type node: dict
:type link_names: list
- :return: Dictionary of interface names that are connected to the given
+ :returns: Dictionary of interface names that are connected to the given
links.
:rtype: dict
"""
@@ -294,7 +378,7 @@ class Topology(object):
:param sw_index: Sw_index of the link that a interface is connected to.
:type node: dict
:type sw_index: int
- :return: Interface name of the interface connected to the given link.
+ :returns: Interface name of the interface connected to the given link.
:rtype: str
"""
return Topology._get_interface_by_key_value(node, "vpp_sw_index",
@@ -308,7 +392,7 @@ class Topology(object):
:param iface_key: Interface key from topology file, or sw_index.
:type node: dict
:type iface_key: str/int
- :return: Return sw_if_index or None if not found.
+ :returns: Return sw_if_index or None if not found.
"""
try:
if isinstance(iface_key, basestring):
@@ -327,7 +411,7 @@ class Topology(object):
:param iface_name: Interface name.
:type node: dict
:type iface_name: str
- :return: Return sw_if_index or None if not found.
+ :returns: Return sw_if_index or None if not found.
:raises TypeError: If provided interface name is not a string.
"""
try:
@@ -348,7 +432,7 @@ class Topology(object):
:param iface_key: Interface key from topology file.
:type node: dict
:type iface_key: str
- :return: MTU or None if not found.
+ :returns: MTU or None if not found.
:rtype: int
"""
try:
@@ -365,7 +449,7 @@ class Topology(object):
:param iface_key: Interface key from topology file.
:type node: dict
:type iface_key: str
- :return: Interface name or None if not found.
+ :returns: Interface name or None if not found.
:rtype: str
"""
try:
@@ -386,7 +470,7 @@ class Topology(object):
:type node: dict
:type interface: str or int
- :return: Interface key.
+ :returns: Interface key.
:rtype: str
:raises TypeError: If provided with invalid interface argument.
@@ -428,7 +512,7 @@ class Topology(object):
:type interface: str or int
:type wanted_format: str
- :return: Interface name, interface key or sw_if_index.
+ :returns: Interface name, interface key or sw_if_index.
:rtype: str or int
:raises TypeError, ValueError: If provided with invalid arguments.
@@ -460,7 +544,7 @@ class Topology(object):
:param iface_key: Interface key from topology file.
:type node: dict
:type iface_key: str
- :return: numa node id, None if not available.
+ :returns: numa node id, None if not available.
:rtype: int
"""
try:
@@ -508,7 +592,7 @@ class Topology(object):
:param iface_key: Interface key from topology file.
:type node: dict
:type iface_key: str
- :return: Return MAC or None if not found.
+ :returns: Return MAC or None if not found.
"""
try:
return node['interfaces'][iface_key].get('mac_address')
@@ -527,7 +611,7 @@ class Topology(object):
:type nodes_info: dict
:type node: dict
:type iface_key: str
- :return: Return (node, interface_key) tuple or None if not found.
+ :returns: Return (node, interface_key) tuple or None if not found.
:rtype: (dict, str)
"""
link_name = None
@@ -562,7 +646,7 @@ class Topology(object):
:param iface_key: Interface key from topology file.
:type node: dict
:type iface_key: str
- :return: Return PCI address or None if not found.
+ :returns: Return PCI address or None if not found.
"""
try:
return node['interfaces'][iface_key].get('pci_address')
@@ -577,7 +661,7 @@ class Topology(object):
:param iface_key: Interface key from topology file.
:type node: dict
:type iface_key: str
- :return: Return interface driver or None if not found.
+ :returns: Return interface driver or None if not found.
"""
try:
return node['interfaces'][iface_key].get('driver')
@@ -590,7 +674,7 @@ class Topology(object):
:param node: Node to get list of interfaces from.
:type node: dict
- :return: Return list of keys of all interfaces.
+ :returns: Return list of keys of all interfaces.
:rtype: list
"""
return node['interfaces'].keys()
@@ -603,7 +687,7 @@ class Topology(object):
:param link_name: Link name.
:type node: dict
:type link_name: str
- :return: MAC address string.
+ :returns: MAC address string.
:rtype: str
"""
for port in node['interfaces'].values():
@@ -619,7 +703,7 @@ class Topology(object):
:param filter_list: Link filter criteria.
:type node: dict
:type filter_list: list of strings
- :return: List of strings that represent link names occupied by the node.
+ :returns: List of strings representing link names occupied by the node.
:rtype: list
"""
interfaces = node['interfaces']
@@ -631,7 +715,7 @@ class Topology(object):
if filt == interface['model']:
link_names.append(interface['link'])
elif (filter_list is not None) and ('model' not in interface):
- logger.trace("Cannot apply filter on interface: {}"
+ logger.trace('Cannot apply filter on interface: {}'
.format(str(interface)))
else:
link_names.append(interface['link'])
@@ -653,7 +737,7 @@ class Topology(object):
:type node2: dict
:type filter_list_node1: list of strings
:type filter_list_node2: list of strings
- :return: List of strings that represent connecting link names.
+ :returns: List of strings that represent connecting link names.
:rtype: list
"""
@@ -685,7 +769,7 @@ class Topology(object):
:param node2: Connected node.
:type node1: dict
:type node2: dict
- :return: Name of link connecting the two nodes together.
+ :returns: Name of link connecting the two nodes together.
:rtype: str
:raises: RuntimeError
"""
@@ -704,7 +788,7 @@ class Topology(object):
:param node2: Second node.
:type node1: dict
:type node2: dict
- :return: Egress interfaces.
+ :returns: Egress interfaces.
:rtype: list
"""
interfaces = []
@@ -732,7 +816,7 @@ class Topology(object):
:param node2: Second node.
:type node1: dict
:type node2: dict
- :return: Egress interface name.
+ :returns: Egress interface name.
:rtype: str
"""
interfaces = self.get_egress_interfaces_name_for_nodes(node1, node2)
@@ -765,7 +849,7 @@ class Topology(object):
:type tgen: dict
:type dut1: dict
:type dut2: dict
- :return: Dictionary of possible link combinations.
+ :returns: Dictionary of possible link combinations.
:rtype: dict
"""
# TODO: replace with generic function.
@@ -789,7 +873,7 @@ class Topology(object):
:param node: Node to examine.
:type node: dict
- :return: True if node is type of TG, otherwise False.
+ :returns: True if node is type of TG, otherwise False.
:rtype: bool
"""
return node['type'] == NodeType.TG
@@ -800,7 +884,7 @@ class Topology(object):
:param node: Node created from topology.
:type node: dict
- :return: Hostname or IP address.
+ :returns: Hostname or IP address.
:rtype: str
"""
return node['host']
@@ -811,7 +895,7 @@ class Topology(object):
:param node: Node created from topology.
:type node: dict
- :return: Cryptodev configuration string.
+ :returns: Cryptodev configuration string.
:rtype: str
"""
try:
@@ -825,7 +909,7 @@ class Topology(object):
:param node: Node created from topology.
:type node: dict
- :return: uio-driver configuration string.
+ :returns: uio-driver configuration string.
:rtype: str
"""
try:
@@ -841,7 +925,7 @@ class Topology(object):
:param iface_key: Interface key from topology file.
:type node: dict
:type iface_key: str
- :return: Return iface_key or None if not found.
+ :returns: Return iface_key or None if not found.
"""
try:
node['interfaces'][iface_key]['numa_node'] = numa_node_id
diff --git a/resources/libraries/robot/performance/performance_setup.robot b/resources/libraries/robot/performance/performance_setup.robot
index 434a555dcd..492815b9b6 100644
--- a/resources/libraries/robot/performance/performance_setup.robot
+++ b/resources/libraries/robot/performance/performance_setup.robot
@@ -437,6 +437,7 @@
| | ...
| | [Arguments] | ${rate} | ${framesize} | ${topology_type}
| | ...
+| | Remove All Added Ports On All DUTs From Topology | ${nodes}
| | Show VAT History On All DUTs | ${nodes}
| | Show statistics on all DUTs | ${nodes}
| | Run Keyword If Test Failed
@@ -446,12 +447,14 @@
| Tear down performance ndrchk test
| | [Documentation] | Common test teardown for ndrchk performance tests.
| | ...
+| | Remove All Added Ports On All DUTs From Topology | ${nodes}
| | Show VAT History On All DUTs | ${nodes}
| | Show statistics on all DUTs | ${nodes}
| Tear down performance pdrchk test
| | [Documentation] | Common test teardown for pdrchk performance tests.
| | ...
+| | Remove All Added Ports On All DUTs From Topology | ${nodes}
| | Show VAT History On All DUTs | ${nodes}
| | Show statistics on all DUTs | ${nodes}
@@ -478,6 +481,7 @@
| | ... | ${dut1_node}=${None} | ${dut1_vm_refs}=${None}
| | ... | ${dut2_node}=${None} | ${dut2_vm_refs}=${None}
| | ...
+| | Remove All Added Ports On All DUTs From Topology | ${nodes}
| | Show VAT History On All DUTs | ${nodes}
| | Show VPP vhost on all DUTs | ${nodes}
| | Show statistics on all DUTs | ${nodes}
@@ -512,6 +516,7 @@
| | ... | ${dut1_node}=${None} | ${dut1_vm_refs}=${None}
| | ... | ${dut2_node}=${None} | ${dut2_vm_refs}=${None}
| | ...
+| | Remove All Added Ports On All DUTs From Topology | ${nodes}
| | Show VAT History On All DUTs | ${nodes}
| | Show VPP vhost on all DUTs | ${nodes}
| | Show statistics on all DUTs | ${nodes}
diff --git a/resources/libraries/robot/shared/default.robot b/resources/libraries/robot/shared/default.robot
index fa291bf1aa..555919f9c8 100644
--- a/resources/libraries/robot/shared/default.robot
+++ b/resources/libraries/robot/shared/default.robot
@@ -312,6 +312,7 @@
| Tear down functional test
| | [Documentation] | Common test teardown for functional tests.
| | ...
+| | Remove All Added Ports On All DUTs From Topology | ${nodes}
| | Show Packet Trace on All DUTs | ${nodes}
| | Show VAT History On All DUTs | ${nodes}
| | Vpp Show Errors On All DUTs | ${nodes}
@@ -320,6 +321,7 @@
| Tear down LISP functional test
| | [Documentation] | Common test teardown for functional tests with LISP.
| | ...
+| | Remove All Added Ports On All DUTs From Topology | ${nodes}
| | Show Packet Trace on All DUTs | ${nodes}
| | Show VAT History On All DUTs | ${nodes}
| | Show Vpp Settings | ${nodes['DUT1']}
@@ -340,6 +342,7 @@
| | ...
| | [Arguments] | ${vm_node}
| | ...
+| | Remove All Added Ports On All DUTs From Topology | ${nodes}
| | Show Packet Trace on All DUTs | ${nodes}
| | Show VAT History On All DUTs | ${nodes}
| | Show Vpp Settings | ${nodes['DUT1']}
diff --git a/tests/vpp/func/vm_vhost/l2bd/eth2p-dot1q-l2bdbasemaclrn-eth-2vhost-1vm-func.robot b/tests/vpp/func/vm_vhost/l2bd/eth2p-dot1q-l2bdbasemaclrn-eth-2vhost-1vm-func.robot
index 7eb7d3e857..4eaaefd4fa 100644
--- a/tests/vpp/func/vm_vhost/l2bd/eth2p-dot1q-l2bdbasemaclrn-eth-2vhost-1vm-func.robot
+++ b/tests/vpp/func/vm_vhost/l2bd/eth2p-dot1q-l2bdbasemaclrn-eth-2vhost-1vm-func.robot
@@ -22,10 +22,8 @@
| Library | resources.libraries.python.Trace
| Force Tags | 3_NODE_DOUBLE_LINK_TOPO | HW_ENV | VM_ENV | VPP_VM_ENV
| Test Setup | Set up functional test
-| Test Teardown | Run Keywords | Show Packet Trace on All DUTs | ${nodes}
-| ... | AND | Show vpp trace dump on all DUTs
-| ... | AND | Stop and clear QEMU | ${dut_node} | ${vm_node}
-| ... | AND | Verify VPP PID in Teardown
+| Test Teardown | Run Keywords | Tear down functional test
+| ... | AND | Stop and clear QEMU | ${dut_node} | ${vm_node}
| Documentation | *L2 bridge domain with VLAN tag over VM test cases*
| ...
| ... | *[Top] Network Topologies:* TG=DUT 2-node circular topology
diff --git a/tests/vpp/func/vm_vhost/l2bd/eth2p-eth-l2bdbasemaclrn-eth-2vhost-1vm-func.robot b/tests/vpp/func/vm_vhost/l2bd/eth2p-eth-l2bdbasemaclrn-eth-2vhost-1vm-func.robot
index 678e268235..e7af3f0338 100644
--- a/tests/vpp/func/vm_vhost/l2bd/eth2p-eth-l2bdbasemaclrn-eth-2vhost-1vm-func.robot
+++ b/tests/vpp/func/vm_vhost/l2bd/eth2p-eth-l2bdbasemaclrn-eth-2vhost-1vm-func.robot
@@ -19,7 +19,8 @@
| Library | resources.libraries.python.Trace
| Force Tags | 3_NODE_DOUBLE_LINK_TOPO | HW_ENV | VM_ENV | VPP_VM_ENV
| Test Setup | Set up functional test
-| Test Teardown | Tear down functional test
+| Test Teardown | Run Keywords | Tear down functional test
+| ... | AND | Stop and clear QEMU | ${dut_node} | ${vm_node}
| Documentation | *L2 bridge-domain test cases*
| ...
| ... | *[Top] Network Topologies:* TG=DUT=VM 3-node topology with VM
@@ -52,9 +53,6 @@
| | ... | switched thru DUT1 and VM in both directions and are correct on
| | ... | receive. [Ref]
| | ...
-| | [Teardown] | Run Keywords | Stop and clear QEMU | ${dut_node} | ${vm_node}
-| | ... | AND | Tear down functional test
-| | ...
| | Given Configure path in 2-node circular topology
| | ... | ${nodes['TG']} | ${nodes['DUT1']} | ${nodes['TG']}
| | And Set interfaces in 2-node circular topology up
@@ -85,9 +83,6 @@
| | ... | switched thru DUT1 and VM in both directions and are correct on
| | ... | receive. [Ref]
| | ...
-| | [Teardown] | Run Keywords | Stop and clear QEMU | ${dut_node} | ${vm_node}
-| | ... | AND | Tear down functional test
-| | ...
| | Given Configure path in 2-node circular topology
| | ... | ${nodes['TG']} | ${nodes['DUT1']} | ${nodes['TG']}
| | And Set interfaces in 2-node circular topology up
diff --git a/tests/vpp/func/vm_vhost/l2bd/eth2p-eth-l2bdbasemacstc-eth-2vhost-1vm-func.robot b/tests/vpp/func/vm_vhost/l2bd/eth2p-eth-l2bdbasemacstc-eth-2vhost-1vm-func.robot
index 22ec61d395..18ad1b77c3 100644
--- a/tests/vpp/func/vm_vhost/l2bd/eth2p-eth-l2bdbasemacstc-eth-2vhost-1vm-func.robot
+++ b/tests/vpp/func/vm_vhost/l2bd/eth2p-eth-l2bdbasemacstc-eth-2vhost-1vm-func.robot
@@ -19,7 +19,8 @@
| Library | resources.libraries.python.Trace
| Force Tags | 3_NODE_DOUBLE_LINK_TOPO | HW_ENV | VM_ENV | VPP_VM_ENV
| Test Setup | Set up functional test
-| Test Teardown | Tear down functional test
+| Test Teardown | Run Keywords | Tear down functional test
+| ... | AND | Stop and clear QEMU | ${dut_node} | ${vm_node}
| Documentation | *L2 bridge-domain test cases*
| ...
| ... | *[Top] Network Topologies:* TG=DUT=VM 3-node topology with VM
@@ -52,9 +53,6 @@
| | ... | switched thru DUT1 and VM in both directions and are correct on
| | ... | receive. [Ref]
| | ...
-| | [Teardown] | Run Keywords | Stop and clear QEMU | ${dut_node} | ${vm_node}
-| | ... | AND | Tear down functional test
-| | ...
| | Given Configure path in 2-node circular topology
| | ... | ${nodes['TG']} | ${nodes['DUT1']} | ${nodes['TG']}
| | And Set interfaces in 2-node circular topology up
@@ -105,9 +103,6 @@
| | ... | switched thru DUT1 and VM in both directions and are correct on
| | ... | receive. [Ref]
| | ...
-| | [Teardown] | Run Keywords | Stop and clear QEMU | ${dut_node} | ${vm_node}
-| | ... | AND | Tear down functional test
-| | ...
| | Given Configure path in 2-node circular topology
| | ... | ${nodes['TG']} | ${nodes['DUT1']} | ${nodes['TG']}
| | And Set interfaces in 2-node circular topology up