Add Honeycomb interface management tests (ipv4, ipv6, ethernet, routing)
[csit.git] / resources / libraries / python / InterfaceUtil.py
index 6526fe8..ec2ef69 100644 (file)
@@ -18,6 +18,7 @@ from time import time, sleep
 from robot.api import logger
 
 from resources.libraries.python.ssh import SSH
 from robot.api import logger
 
 from resources.libraries.python.ssh import SSH
+from resources.libraries.python.IPUtil import convert_ipv4_netmask_prefix
 from resources.libraries.python.ssh import exec_cmd_no_error
 from resources.libraries.python.topology import NodeType, Topology
 from resources.libraries.python.VatExecutor import VatExecutor, VatTerminal
 from resources.libraries.python.ssh import exec_cmd_no_error
 from resources.libraries.python.topology import NodeType, Topology
 from resources.libraries.python.VatExecutor import VatExecutor, VatTerminal
@@ -36,9 +37,9 @@ class InterfaceUtil(object):
 
         Function can be used for DUTs as well as for TGs.
 
 
         Function can be used for DUTs as well as for TGs.
 
-        :param node: node where the interface is
-        :param interface: interface name or sw_if_index
-        :param state: one of 'up' or 'down'
+        :param node: Node where the interface is.
+        :param interface: Interface name or sw_if_index.
+        :param state: One of 'up' or 'down'.
         :type node: dict
         :type interface: str or int
         :type state: str
         :type node: dict
         :type interface: str or int
         :type state: str
@@ -73,9 +74,9 @@ class InterfaceUtil(object):
 
         Function can be used only for TGs.
 
 
         Function can be used only for TGs.
 
-        :param node: node where the interface is
-        :param interface: interface name
-        :param mtu: MTU to set
+        :param node: Node where the interface is.
+        :param interface: Interface name.
+        :param mtu: MTU to set.
         :type node: dict
         :type interface: str
         :type mtu: int
         :type node: dict
         :type interface: str
         :type mtu: int
@@ -97,7 +98,7 @@ class InterfaceUtil(object):
 
         Function can be used only for TGs.
 
 
         Function can be used only for TGs.
 
-        :param node: node where to set default MTU
+        :param node: Node where to set default MTU.
         :type node: dict
         :return: nothing
         """
         :type node: dict
         :return: nothing
         """
@@ -109,7 +110,7 @@ class InterfaceUtil(object):
         """Wait until all interfaces with admin-up are in link-up state.
 
         :param node: Node to wait on.
         """Wait until all interfaces with admin-up are in link-up state.
 
         :param node: Node to wait on.
-        :param timeout: Waiting timeout in seconds (optional, default 10s)
+        :param timeout: Waiting timeout in seconds (optional, default 10s).
         :type node: dict
         :type timeout: int
         :raises: RuntimeError if the timeout period value has elapsed.
         :type node: dict
         :type timeout: int
         :raises: RuntimeError if the timeout period value has elapsed.
@@ -172,6 +173,7 @@ class InterfaceUtil(object):
         """Get all interface data from a VPP node. If a name or
         sw_interface_index is provided, return only data for the matching
         interface.
         """Get all interface data from a VPP node. If a name or
         sw_interface_index is provided, return only data for the matching
         interface.
+
         :param node: VPP node to get interface data from.
         :param interface: Numeric index or name string of a specific interface.
         :type node: dict
         :param node: VPP node to get interface data from.
         :param interface: Numeric index or name string of a specific interface.
         :type node: dict
@@ -199,6 +201,36 @@ class InterfaceUtil(object):
 
         return data
 
 
         return data
 
+    @staticmethod
+    def vpp_get_interface_ip_addresses(node, interface, ip_version):
+        """Get list of IP addresses from an interface on a VPP node.
+
+         :param node: VPP node to get data from.
+         :param interface: Name of an interface on the VPP node.
+         :param ip_version: IP protocol version (ipv4 or ipv6).
+         :type node: dict
+         :type interface: str
+         :type ip_version: str
+         :return: List of dictionaries, each containing IP address, subnet
+         prefix length and also the subnet mask for ipv4 addresses.
+         Note: A single interface may have multiple IP addresses assigned.
+         :rtype: list
+        """
+        sw_if_index = Topology.get_interface_sw_index(node, interface)
+
+        with VatTerminal(node) as vat:
+            response = vat.vat_terminal_exec_cmd_from_template(
+                "ip_address_dump.vat", ip_version=ip_version,
+                sw_if_index=sw_if_index)
+
+        data = response[0]
+
+        if ip_version == "ipv4":
+            for item in data:
+                item["netmask"] = convert_ipv4_netmask_prefix(
+                    item["prefix_length"])
+        return data
+
     @staticmethod
     def tg_set_interface_driver(node, pci_addr, driver):
         """Set interface driver on the TG node.
     @staticmethod
     def tg_set_interface_driver(node, pci_addr, driver):
         """Set interface driver on the TG node.
@@ -325,7 +357,7 @@ class InterfaceUtil(object):
 
     @staticmethod
     def update_vpp_interface_data_on_node(node):
 
     @staticmethod
     def update_vpp_interface_data_on_node(node):
-        """Update vpp generated interface data for a given node in DICT__nodes
+        """Update vpp generated interface data for a given node in DICT__nodes.
 
         Updates interface names, software if index numbers and any other details
         generated specifically by vpp that are unknown before testcase run.
 
         Updates interface names, software if index numbers and any other details
         generated specifically by vpp that are unknown before testcase run.
@@ -333,7 +365,7 @@ class InterfaceUtil(object):
         devices using vpp_api_test, and pairing known information from topology
         (mac address/pci address of interface) to state from VPP.
 
         devices using vpp_api_test, and pairing known information from topology
         (mac address/pci address of interface) to state from VPP.
 
-        :param node: Node selected from DICT__nodes
+        :param node: Node selected from DICT__nodes.
         :type node: dict
         """
         vat_executor = VatExecutor()
         :type node: dict
         """
         vat_executor = VatExecutor()
@@ -460,3 +492,65 @@ class InterfaceUtil(object):
         else:
             raise RuntimeError('Unable to create VXLAN interface on node {}'
                                .format(node))
         else:
             raise RuntimeError('Unable to create VXLAN interface on node {}'
                                .format(node))
+
+    @staticmethod
+    def create_subinterface(node, interface, sub_id, outer_vlan_id,
+                            inner_vlan_id, type_subif):
+        """Create sub-interface on node.
+
+        :param node: Node to add sub-interface.
+        :param interface: Interface name on which create sub-interface.
+        :param sub_id: ID of the sub-interface to be created.
+        :param outer_vlan_id: Outer VLAN ID.
+        :param inner_vlan_id: Inner VLAN ID.
+        :param type_subif: Type of sub-interface.
+        :type node: dict
+        :type interface: str or int
+        :type sub_id: int
+        :type outer_vlan_id: int
+        :type inner_vlan_id: int
+        :type type_subif: str
+        :return: name and index of created sub-interface
+        :rtype: tuple
+        """
+
+        if isinstance(interface, basestring):
+            sw_if_index = Topology.get_interface_sw_index(node, interface)
+        else:
+            sw_if_index = interface
+
+        output = VatExecutor.cmd_from_template(node, "create_sub_interface.vat",
+                                               sw_if_index=sw_if_index,
+                                               sub_id=sub_id,
+                                               outer_vlan_id=outer_vlan_id,
+                                               inner_vlan_id=inner_vlan_id,
+                                               type_subif=type_subif)
+
+        if output[0]["retval"] == 0:
+            sw_subif_index = output[0]["sw_if_index"]
+            logger.trace('Created subinterface with index {}'
+                         .format(sw_subif_index))
+        else:
+            raise RuntimeError('Unable to create subinterface on node {}'
+                               .format(node['host']))
+
+        with VatTerminal(node) as vat:
+            vat.vat_terminal_exec_cmd('exec show interfaces')
+
+        return '{}.{}'.format(interface, sub_id), sw_subif_index
+
+    @staticmethod
+    def vpp_create_loopback(node):
+        """Create loopback interface on VPP node.
+
+        :param node: Node to create loopback interface on.
+        :type node: dict
+        :return: SW interface index.
+        :rtype: int
+        """
+        out = VatExecutor.cmd_from_template(node, "create_loopback.vat")
+        if out[0].get('retval') == 0:
+            return out[0].get('sw_if_index')
+        else:
+            raise RuntimeError('Create loopback failed on node "{}"'
+                               .format(node['host']))