Move methods from topology.py to more appropriate place. 99/599/18
authorMatej Klotton <mklotton@cisco.com>
Wed, 23 Mar 2016 14:01:30 +0000 (15:01 +0100)
committerGerrit Code Review <gerrit@fd.io>
Wed, 13 Apr 2016 16:08:13 +0000 (16:08 +0000)
Change-Id: I2612a9466095b3d79a4a9d938fcdbf9f93133f69
Signed-off-by: Matej Klotton <mklotton@cisco.com>
12 files changed:
resources/libraries/python/InterfaceSetup.py [deleted file]
resources/libraries/python/InterfaceUtil.py
resources/libraries/python/TGSetup.py
resources/libraries/python/VatConfigGenerator.py [deleted file]
resources/libraries/python/VatJsonUtil.py [new file with mode: 0644]
resources/libraries/python/topology.py
resources/libraries/robot/default.robot
resources/libraries/robot/vxlan.robot
tests/suites/__init__.robot
tests/suites/bridge_domain/test.robot
tests/suites/ipv4/ipv4_untagged.robot
tests/suites/l2_xconnect/l2_xconnect_untagged.robot

diff --git a/resources/libraries/python/InterfaceSetup.py b/resources/libraries/python/InterfaceSetup.py
deleted file mode 100644 (file)
index 946c8fc..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-# Copyright (c) 2016 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Interface setup library."""
-
-from ssh import SSH
-from robot.api.deco import keyword
-from resources.libraries.python.VatExecutor import VatExecutor
-
-
-class InterfaceSetup(object):
-    """Interface setup utilities."""
-
-    __UDEV_IF_RULES_FILE = '/etc/udev/rules.d/10-network.rules'
-
-    @staticmethod
-    def tg_set_interface_driver(node, pci_addr, driver):
-        """Set interface driver on the TG node.
-
-        :param node: Node to set interface driver on (must be TG node).
-        :param pci_addr: PCI address of the interface.
-        :param driver: Driver name.
-        :type node: dict
-        :type pci_addr: str
-        :type driver: str
-        """
-        old_driver = InterfaceSetup.tg_get_interface_driver(node, pci_addr)
-        if old_driver == driver:
-            return
-
-        ssh = SSH()
-        ssh.connect(node)
-
-        # Unbind from current driver
-        if old_driver is not None:
-            cmd = 'sh -c "echo {0} > /sys/bus/pci/drivers/{1}/unbind"'.format(
-                pci_addr, old_driver)
-            (ret_code, _, _) = ssh.exec_command_sudo(cmd)
-            if int(ret_code) != 0:
-                raise Exception("'{0}' failed on '{1}'".format(cmd,
-                                                               node['host']))
-
-        # Bind to the new driver
-        cmd = 'sh -c "echo {0} > /sys/bus/pci/drivers/{1}/bind"'.format(
-            pci_addr, driver)
-        (ret_code, _, _) = ssh.exec_command_sudo(cmd)
-        if int(ret_code) != 0:
-            raise Exception("'{0}' failed on '{1}'".format(cmd, node['host']))
-
-    @staticmethod
-    def tg_get_interface_driver(node, pci_addr):
-        """Get interface driver from the TG node.
-
-        :param node: Node to get interface driver on (must be TG node).
-        :param pci_addr: PCI address of the interface.
-        :type node: dict
-        :type pci_addr: str
-        :return: Interface driver or None if not found.
-        :rtype: str
-
-        .. note::
-            # lspci -vmmks 0000:00:05.0
-            Slot:   00:05.0
-            Class:  Ethernet controller
-            Vendor: Red Hat, Inc
-            Device: Virtio network device
-            SVendor:        Red Hat, Inc
-            SDevice:        Device 0001
-            PhySlot:        5
-            Driver: virtio-pci
-        """
-        ssh = SSH()
-        ssh.connect(node)
-
-        cmd = 'lspci -vmmks {0}'.format(pci_addr)
-
-        (ret_code, stdout, _) = ssh.exec_command(cmd)
-        if int(ret_code) != 0:
-            raise Exception("'{0}' failed on '{1}'".format(cmd, node['host']))
-
-        for line in stdout.splitlines():
-            if len(line) == 0:
-                continue
-            (name, value) = line.split("\t", 1)
-            if name == 'Driver:':
-                return value
-
-        return None
-
-    @staticmethod
-    def tg_set_interfaces_udev_rules(node):
-        """Set udev rules for interfaces.
-
-        Create udev rules file in /etc/udev/rules.d where are rules for each
-        interface used by TG node, based on MAC interface has specific name.
-        So after unbind and bind again to kernel driver interface has same
-        name as before. This must be called after TG has set name for each
-        port in topology dictionary.
-        udev rule example
-        SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="52:54:00:e1:8a:0f",
-        NAME="eth1"
-
-        :param node: Node to set udev rules on (must be TG node).
-        :type node: dict
-        """
-        ssh = SSH()
-        ssh.connect(node)
-
-        cmd = 'rm -f {0}'.format(InterfaceSetup.__UDEV_IF_RULES_FILE)
-        (ret_code, _, _) = ssh.exec_command_sudo(cmd)
-        if int(ret_code) != 0:
-            raise Exception("'{0}' failed on '{1}'".format(cmd, node['host']))
-
-        for if_k, if_v in node['interfaces'].items():
-            if if_k == 'mgmt':
-                continue
-            rule = 'SUBSYSTEM==\\"net\\", ACTION==\\"add\\", ATTR{address}' + \
-                '==\\"' + if_v['mac_address'] + '\\", NAME=\\"' + \
-                if_v['name'] + '\\"'
-            cmd = 'sh -c "echo \'{0}\' >> {1}"'.format(
-                rule, InterfaceSetup.__UDEV_IF_RULES_FILE)
-            (ret_code, _, _) = ssh.exec_command_sudo(cmd)
-            if int(ret_code) != 0:
-                raise Exception("'{0}' failed on '{1}'".format(cmd,
-                                                               node['host']))
-
-        cmd = '/etc/init.d/udev restart'
-        ssh.exec_command_sudo(cmd)
-
-    @staticmethod
-    def tg_set_interfaces_default_driver(node):
-        """Set interfaces default driver specified in topology yaml file.
-
-        :param node: Node to setup interfaces driver on (must be TG node).
-        :type node: dict
-        """
-        for if_k, if_v in node['interfaces'].items():
-            if if_k == 'mgmt':
-                continue
-            InterfaceSetup.tg_set_interface_driver(node, if_v['pci_address'],
-                                                   if_v['driver'])
-
-    @staticmethod
-    def create_vxlan_interface(node, vni, source_ip, destination_ip):
-        """Create VXLAN interface and return index of created interface
-
-        Executes "vxlan_add_del_tunnel src {src} dst {dst} vni {vni}" VAT
-        command on the node.
-
-        :param node: Node where to create VXLAN interface
-        :param vni: VXLAN Network Identifier
-        :param source_ip: Source IP of a VXLAN Tunnel End Point
-        :param destination_ip: Destination IP of a VXLAN Tunnel End Point
-        :type node: dict
-        :type vni: int
-        :type source_ip: str
-        :type destination_ip: str
-        :return: SW IF INDEX of created interface
-        :rtype: int
-        """
-
-        output = VatExecutor.cmd_from_template(node, "vxlan_create.vat",
-                                               src=source_ip,
-                                               dst=destination_ip,
-                                               vni=vni)
-        output = output[0]
-
-        if output["retval"] == 0:
-            return output["sw_if_index"]
-        else:
-            raise RuntimeError('Unable to create VXLAN interface on node {}'.\
-                               format(node))
index 25503c0..4631ccc 100644 (file)
 """Interface util library"""
 
 from time import time, sleep
+
 from robot.api import logger
+
+from resources.libraries.python.ssh import SSH
 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.VatJsonUtil import VatJsonUtil
+from resources.libraries.python.parsers.JsonParser import JsonParser
 
 
 class InterfaceUtil(object):
     """General utilities for managing interfaces"""
 
+    __UDEV_IF_RULES_FILE = '/etc/udev/rules.d/10-network.rules'
+
     @staticmethod
     def set_interface_state(node, interface, state):
         """Set interface state on a node.
@@ -191,3 +198,233 @@ class InterfaceUtil(object):
                     return data_if
 
         return data
+
+    @staticmethod
+    def tg_set_interface_driver(node, pci_addr, driver):
+        """Set interface driver on the TG node.
+
+        :param node: Node to set interface driver on (must be TG node).
+        :param pci_addr: PCI address of the interface.
+        :param driver: Driver name.
+        :type node: dict
+        :type pci_addr: str
+        :type driver: str
+        """
+        old_driver = InterfaceUtil.tg_get_interface_driver(node, pci_addr)
+        if old_driver == driver:
+            return
+
+        ssh = SSH()
+        ssh.connect(node)
+
+        # Unbind from current driver
+        if old_driver is not None:
+            cmd = 'sh -c "echo {0} > /sys/bus/pci/drivers/{1}/unbind"'.format(
+                pci_addr, old_driver)
+            (ret_code, _, _) = ssh.exec_command_sudo(cmd)
+            if int(ret_code) != 0:
+                raise Exception("'{0}' failed on '{1}'".format(cmd,
+                                                               node['host']))
+
+        # Bind to the new driver
+        cmd = 'sh -c "echo {0} > /sys/bus/pci/drivers/{1}/bind"'.format(
+            pci_addr, driver)
+        (ret_code, _, _) = ssh.exec_command_sudo(cmd)
+        if int(ret_code) != 0:
+            raise Exception("'{0}' failed on '{1}'".format(cmd, node['host']))
+
+    @staticmethod
+    def tg_get_interface_driver(node, pci_addr):
+        """Get interface driver from the TG node.
+
+        :param node: Node to get interface driver on (must be TG node).
+        :param pci_addr: PCI address of the interface.
+        :type node: dict
+        :type pci_addr: str
+        :return: Interface driver or None if not found.
+        :rtype: str
+
+        .. note::
+            # lspci -vmmks 0000:00:05.0
+            Slot:   00:05.0
+            Class:  Ethernet controller
+            Vendor: Red Hat, Inc
+            Device: Virtio network device
+            SVendor:        Red Hat, Inc
+            SDevice:        Device 0001
+            PhySlot:        5
+            Driver: virtio-pci
+        """
+        ssh = SSH()
+        ssh.connect(node)
+
+        cmd = 'lspci -vmmks {0}'.format(pci_addr)
+
+        (ret_code, stdout, _) = ssh.exec_command(cmd)
+        if int(ret_code) != 0:
+            raise Exception("'{0}' failed on '{1}'".format(cmd, node['host']))
+
+        for line in stdout.splitlines():
+            if len(line) == 0:
+                continue
+            (name, value) = line.split("\t", 1)
+            if name == 'Driver:':
+                return value
+
+        return None
+
+    @staticmethod
+    def tg_set_interfaces_udev_rules(node):
+        """Set udev rules for interfaces.
+
+        Create udev rules file in /etc/udev/rules.d where are rules for each
+        interface used by TG node, based on MAC interface has specific name.
+        So after unbind and bind again to kernel driver interface has same
+        name as before. This must be called after TG has set name for each
+        port in topology dictionary.
+        udev rule example
+        SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="52:54:00:e1:8a:0f",
+        NAME="eth1"
+
+        :param node: Node to set udev rules on (must be TG node).
+        :type node: dict
+        """
+        ssh = SSH()
+        ssh.connect(node)
+
+        cmd = 'rm -f {0}'.format(InterfaceUtil.__UDEV_IF_RULES_FILE)
+        (ret_code, _, _) = ssh.exec_command_sudo(cmd)
+        if int(ret_code) != 0:
+            raise Exception("'{0}' failed on '{1}'".format(cmd, node['host']))
+
+        for interface in node['interfaces'].values():
+            rule = 'SUBSYSTEM==\\"net\\", ACTION==\\"add\\", ATTR{address}' + \
+                   '==\\"' + interface['mac_address'] + '\\", NAME=\\"' + \
+                   interface['name'] + '\\"'
+            cmd = 'sh -c "echo \'{0}\' >> {1}"'.format(
+                rule, InterfaceUtil.__UDEV_IF_RULES_FILE)
+            (ret_code, _, _) = ssh.exec_command_sudo(cmd)
+            if int(ret_code) != 0:
+                raise Exception("'{0}' failed on '{1}'".format(cmd,
+                                                               node['host']))
+
+        cmd = '/etc/init.d/udev restart'
+        ssh.exec_command_sudo(cmd)
+
+    @staticmethod
+    def tg_set_interfaces_default_driver(node):
+        """Set interfaces default driver specified in topology yaml file.
+
+        :param node: Node to setup interfaces driver on (must be TG node).
+        :type node: dict
+        """
+        for interface in node['interfaces'].values():
+            InterfaceUtil.tg_set_interface_driver(node,
+                                                  interface['pci_address'],
+                                                  interface['driver'])
+
+    @staticmethod
+    def update_vpp_interface_data_on_node(node):
+        """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.
+        It does this by dumping interface list to JSON output from all
+        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
+        :type node: dict
+        """
+        vat_executor = VatExecutor()
+        vat_executor.execute_script_json_out("dump_interfaces.vat", node)
+        interface_dump_json = vat_executor.get_script_stdout()
+        VatJsonUtil.update_vpp_interface_data_from_json(node,
+                                                        interface_dump_json)
+
+    @staticmethod
+    def update_tg_interface_data_on_node(node):
+        """Update interface name for TG/linux node in DICT__nodes.
+
+        :param node: Node selected from DICT__nodes.
+        :type node: dict
+
+        .. note::
+            # for dev in `ls /sys/class/net/`;
+            > do echo "\"`cat /sys/class/net/$dev/address`\": \"$dev\""; done
+            "52:54:00:9f:82:63": "eth0"
+            "52:54:00:77:ae:a9": "eth1"
+            "52:54:00:e1:8a:0f": "eth2"
+            "00:00:00:00:00:00": "lo"
+
+        .. todo:: parse lshw -json instead
+        """
+        # First setup interface driver specified in yaml file
+        InterfaceUtil.tg_set_interfaces_default_driver(node)
+
+        # Get interface names
+        ssh = SSH()
+        ssh.connect(node)
+
+        cmd = ('for dev in `ls /sys/class/net/`; do echo "\\"`cat '
+               '/sys/class/net/$dev/address`\\": \\"$dev\\""; done;')
+
+        (ret_code, stdout, _) = ssh.exec_command(cmd)
+        if int(ret_code) != 0:
+            raise Exception('Get interface name and MAC failed')
+        tmp = "{" + stdout.rstrip().replace('\n', ',') + "}"
+        interfaces = JsonParser().parse_data(tmp)
+        for interface in node['interfaces'].values():
+            name = interfaces.get(interface['mac_address'])
+            if name is None:
+                continue
+            interface['name'] = name
+
+        # Set udev rules for interfaces
+        InterfaceUtil.tg_set_interfaces_udev_rules(node)
+
+    @staticmethod
+    def update_all_interface_data_on_all_nodes(nodes):
+        """Update interface names on all nodes in DICT__nodes.
+
+        This method updates the topology dictionary by querying interface lists
+        of all nodes mentioned in the topology dictionary.
+
+        :param nodes: Nodes in the topology.
+        :type nodes: dict
+        """
+        for node_data in nodes.values():
+            if node_data['type'] == NodeType.DUT:
+                InterfaceUtil.update_vpp_interface_data_on_node(node_data)
+            elif node_data['type'] == NodeType.TG:
+                InterfaceUtil.update_tg_interface_data_on_node(node_data)
+
+    @staticmethod
+    def create_vxlan_interface(node, vni, source_ip, destination_ip):
+        """Create VXLAN interface and return sw if index of created interface.
+
+        Executes "vxlan_add_del_tunnel src {src} dst {dst} vni {vni}" VAT
+        command on the node.
+
+        :param node: Node where to create VXLAN interface.
+        :param vni: VXLAN Network Identifier.
+        :param source_ip: Source IP of a VXLAN Tunnel End Point.
+        :param destination_ip: Destination IP of a VXLAN Tunnel End Point.
+        :type node: dict
+        :type vni: int
+        :type source_ip: str
+        :type destination_ip: str
+        :return: SW IF INDEX of created interface.
+        :rtype: int
+        """
+        output = VatExecutor.cmd_from_template(node, "vxlan_create.vat",
+                                               src=source_ip,
+                                               dst=destination_ip,
+                                               vni=vni)
+        output = output[0]
+
+        if output["retval"] == 0:
+            return output["sw_if_index"]
+        else:
+            raise RuntimeError('Unable to create VXLAN interface on node {}'
+                               .format(node))
index 3e372e9..05c8b1d 100644 (file)
@@ -14,7 +14,7 @@
 """TG Setup library."""
 
 from topology import NodeType
-from InterfaceSetup import InterfaceSetup
+from InterfaceUtil import InterfaceUtil
 
 
 class TGSetup(object):
@@ -29,4 +29,4 @@ class TGSetup(object):
         """
         for node in nodes.values():
             if node['type'] == NodeType.TG:
-                InterfaceSetup.tg_set_interfaces_default_driver(node)
+                InterfaceUtil.tg_set_interfaces_default_driver(node)
diff --git a/resources/libraries/python/VatConfigGenerator.py b/resources/libraries/python/VatConfigGenerator.py
deleted file mode 100644 (file)
index 98be9d3..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright (c) 2016 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Can be used to generate VAT scripts from VAT template files."""
-
-from robot.api import logger
-
-
-class VatConfigGenerator(object):
-    """Generates VAT configuration scripts from VAT script template files.
-    """
-    def __init__(self):
-        pass
-
-    @staticmethod
-    def generate_vat_config_file(template_file, env_var_dict, out_file):
-        """ Write VAT configuration script to out file.
-
-        Generates VAT configuration script from template using
-        dictionary containing environment variables
-        :param template_file: file that contains the VAT script template
-        :param env_var_dict: python dictionary that maps test
-        environment variables
-        """
-
-        template_data = open(template_file).read()
-        logger.trace("Loaded template file: \n '{0}'".format(template_data))
-        generated_config = template_data.format(**env_var_dict)
-        logger.trace("Generated script file: \n '{0}'".format(generated_config))
-        with open(out_file, 'w') as work_file:
-            work_file.write(generated_config)
-
-    @staticmethod
-    def generate_vat_config_string(template_file, env_var_dict):
-        """ Return wat config string generated from template.
-
-        Generates VAT configuration script from template using
-        dictionary containing environment variables
-        :param template_file: file that contains the VAT script template
-        :param env_var_dict: python dictionary that maps test
-        environment variables
-        """
-
-        template_data = open(template_file).read()
-        logger.trace("Loaded template file: \n '{0}'".format(template_data))
-        generated_config = template_data.format(**env_var_dict)
-        logger.trace("Generated script file: \n '{0}'".format(generated_config))
-        return generated_config
diff --git a/resources/libraries/python/VatJsonUtil.py b/resources/libraries/python/VatJsonUtil.py
new file mode 100644 (file)
index 0000000..36c5053
--- /dev/null
@@ -0,0 +1,102 @@
+# Copyright (c) 2016 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Utilities to work with JSON data format from VAT."""
+
+from robot.api import logger
+
+from resources.libraries.python.parsers.JsonParser import JsonParser
+
+
+class VatJsonUtil(object):
+    """Utilities to work with JSON data format from VAT."""
+
+    @staticmethod
+    def _convert_mac_to_number_list(mac_address):
+        """Convert MAC address string to list of decimal numbers.
+
+        Converts a ":" separated MAC address to decimal number list as used
+        in JSON interface dump.
+
+        :param mac_address: MAC address.
+        :type mac_address: str
+        :return: List representation of MAC address.
+        :rtype: list
+        """
+        list_mac = []
+        for num in mac_address.split(":"):
+            list_mac.append(int(num, 16))
+        return list_mac
+
+    @staticmethod
+    def get_vpp_interface_by_mac(interfaces_list, mac_address):
+        """Return interface dictionary from interface_list by MAC address.
+
+        Extracts interface dictionary from all of the interfaces in interfaces
+        list parsed from json according to mac_address of the interface.
+
+        :param interfaces_list: Interfaces parsed from JSON.
+        :param mac_address: MAC address of interface we are looking for.
+        :type interfaces_list: dict
+        :type mac_address: str
+        :return: Interface from JSON.
+        :rtype: dict
+        """
+        interface_dict = {}
+        list_mac_address = VatJsonUtil._convert_mac_to_number_list(mac_address)
+        logger.trace("MAC address {0} converted to list {1}."
+                     .format(mac_address, list_mac_address))
+        for interface in interfaces_list:
+            # TODO: create vat json integrity checking and move there
+            if "l2_address" not in interface:
+                raise KeyError(
+                    "key l2_address not found in interface dict."
+                    "Probably input list is not parsed from correct VAT "
+                    "json output.")
+            if "l2_address_length" not in interface:
+                raise KeyError(
+                    "key l2_address_length not found in interface "
+                    "dict. Probably input list is not parsed from correct "
+                    "VAT json output.")
+            mac_from_json = interface["l2_address"][:6]
+            if mac_from_json == list_mac_address:
+                if interface["l2_address_length"] != 6:
+                    raise ValueError("l2_address_length value is not 6.")
+                interface_dict = interface
+                break
+        return interface_dict
+
+    @staticmethod
+    def update_vpp_interface_data_from_json(node, interface_dump_json):
+        """Update vpp node data in node__DICT from json interface dump.
+
+        This method updates vpp interface names and sw if indexes according to
+        interface MAC addresses found in interface_dump_json.
+
+        :param node: Node dictionary.
+        :param interface_dump_json: JSON output from dump_interface_list VAT
+        command.
+        :type node: dict
+        :type interface_dump_json: str
+        """
+        interface_list = JsonParser().parse_data(interface_dump_json)
+        for ifc in node['interfaces'].values():
+            if_mac = ifc['mac_address']
+            interface_dict = VatJsonUtil.get_vpp_interface_by_mac(
+                interface_list, if_mac)
+            if not interface_dict:
+                raise Exception('Interface {0} not found by MAC {1}'
+                                .format(ifc, if_mac))
+            ifc['name'] = interface_dict["interface_name"]
+            ifc['vpp_sw_index'] = interface_dict["sw_if_index"]
+            ifc['mtu'] = interface_dict["mtu"]
index 7a27173..d04d584 100644 (file)
 
 """Defines nodes and topology structure."""
 
-from resources.libraries.python.parsers.JsonParser import JsonParser
-from resources.libraries.python.VatExecutor import VatExecutor
-from resources.libraries.python.ssh import SSH
-from resources.libraries.python.InterfaceSetup import InterfaceSetup
 from robot.api import logger
 from robot.libraries.BuiltIn import BuiltIn
 from robot.api.deco import keyword
@@ -137,8 +133,6 @@ class Topology(object):
 
         This method returns the interface names asociated with given links
         for a given node.
-        The resulting dictionary can be then used to with VatConfigGenerator
-        to generate a VAT script with proper interface names.
         :param link_names: list of names of the link that a interface is
         connected to.
         :param node: the node topology directory
@@ -168,176 +162,6 @@ class Topology(object):
 
         return self._get_interface_by_key_value(node, "vpp_sw_index", sw_index)
 
-    @staticmethod
-    def convert_mac_to_number_list(mac_address):
-        """Convert mac address string to list of decimal numbers.
-
-        Converts a : separated mac address to decimal number list as used
-        in json interface dump.
-        :param mac_address: string mac address
-        :return: list representation of mac address
-        """
-
-        list_mac = []
-        for num in mac_address.split(":"):
-            list_mac.append(int(num, 16))
-        return list_mac
-
-    def _extract_vpp_interface_by_mac(self, interfaces_list, mac_address):
-        """Return interface dictionary from interface_list by mac address.
-
-        Extracts interface dictionary from all of the interfaces in interfaces
-        list parsed from json according to mac_address of the interface
-        :param interfaces_list: dictionary of all interfaces parsed from json
-        :param mac_address: string mac address of interface we are looking for
-        :return: interface dictionary from json
-        """
-
-        interface_dict = {}
-        list_mac_address = self.convert_mac_to_number_list(mac_address)
-        logger.trace(str(list_mac_address))
-        for interface in interfaces_list:
-            # TODO: create vat json integrity checking and move there
-            if "l2_address" not in interface:
-                raise KeyError(
-                    "key l2_address not found in interface dict."
-                    "Probably input list is not parsed from correct VAT "
-                    "json output.")
-            if "l2_address_length" not in interface:
-                raise KeyError(
-                    "key l2_address_length not found in interface "
-                    "dict. Probably input list is not parsed from correct "
-                    "VAT json output.")
-            mac_from_json = interface["l2_address"][:6]
-            if mac_from_json == list_mac_address:
-                if interface["l2_address_length"] != 6:
-                    raise ValueError("l2_address_length value is not 6.")
-                interface_dict = interface
-                break
-        return interface_dict
-
-    def vpp_interface_name_from_json_by_mac(self, json_data, mac_address):
-        """Return vpp interface name string from VAT interface dump json output
-
-        Extracts the name given to an interface by VPP.
-        These interface names differ from what you would see if you
-        used the ipconfig or similar command.
-        Required json data can be obtained by calling :
-        VatExecutor.execute_script_json_out("dump_interfaces.vat", node)
-        :param json_data: string json data from sw_interface_dump VAT command
-        :param mac_address: string containing mac address of interface
-        whose vpp name we wish to discover.
-        :return: string vpp interface name
-        """
-
-        interfaces_list = JsonParser().parse_data(json_data)
-        # TODO: checking if json data is parsed correctly
-        interface_dict = self._extract_vpp_interface_by_mac(interfaces_list,
-                                                            mac_address)
-        interface_name = interface_dict["interface_name"]
-        return interface_name
-
-    def _update_node_interface_data_from_json(self, node, interface_dump_json):
-        """Update node vpp data in node__DICT from json interface dump.
-
-        This method updates vpp interface names and sw indexexs according to
-        interface mac addresses found in interface_dump_json
-        :param node: node dictionary
-        :param interface_dump_json: json output from dump_interface_list VAT
-        command
-        """
-
-        interface_list = JsonParser().parse_data(interface_dump_json)
-        for ifc in node['interfaces'].values():
-            if 'link' not in ifc:
-                continue
-            if_mac = ifc['mac_address']
-            interface_dict = self._extract_vpp_interface_by_mac(interface_list,
-                                                                if_mac)
-            if not interface_dict:
-                raise Exception('Interface {0} not found by MAC {1}'.
-                        format(ifc, if_mac))
-            ifc['name'] = interface_dict["interface_name"]
-            ifc['vpp_sw_index'] = interface_dict["sw_if_index"]
-            ifc['mtu'] = interface_dict["mtu"]
-
-    def update_vpp_interface_data_on_node(self, node):
-        """Update vpp generated interface data for a given node in DICT__nodes
-
-        Updates interface names, software index numbers and any other details
-        generated specifically by vpp that are unknown before testcase run.
-        :param node: Node selected from DICT__nodes
-        """
-
-        vat_executor = VatExecutor()
-        vat_executor.execute_script_json_out("dump_interfaces.vat", node)
-        interface_dump_json = vat_executor.get_script_stdout()
-        self._update_node_interface_data_from_json(node,
-                                                   interface_dump_json)
-
-    @staticmethod
-    def update_tg_interface_data_on_node(node):
-        """Update interface name for TG/linux node in DICT__nodes
-
-        :param node: Node selected from DICT__nodes.
-        :type node: dict
-
-        .. note::
-            # for dev in `ls /sys/class/net/`;
-            > do echo "\"`cat /sys/class/net/$dev/address`\": \"$dev\""; done
-            "52:54:00:9f:82:63": "eth0"
-            "52:54:00:77:ae:a9": "eth1"
-            "52:54:00:e1:8a:0f": "eth2"
-            "00:00:00:00:00:00": "lo"
-
-        .. todo:: parse lshw -json instead
-        """
-        # First setup interface driver specified in yaml file
-        InterfaceSetup.tg_set_interfaces_default_driver(node)
-
-        # Get interface names
-        ssh = SSH()
-        ssh.connect(node)
-
-        cmd = 'for dev in `ls /sys/class/net/`; do echo "\\"`cat ' \
-              '/sys/class/net/$dev/address`\\": \\"$dev\\""; done;'
-
-        (ret_code, stdout, _) = ssh.exec_command(cmd)
-        if int(ret_code) != 0:
-            raise Exception('Get interface name and MAC failed')
-        tmp = "{" + stdout.rstrip().replace('\n', ',') + "}"
-        interfaces = JsonParser().parse_data(tmp)
-        for if_k, if_v in node['interfaces'].items():
-            if if_k == 'mgmt':
-                continue
-            name = interfaces.get(if_v['mac_address'])
-            if name is None:
-                continue
-            if_v['name'] = name
-
-        # Set udev rules for interfaces
-        InterfaceSetup.tg_set_interfaces_udev_rules(node)
-
-    def update_all_interface_data_on_all_nodes(self, nodes):
-        """Update interface names on all nodes in DICT__nodes
-
-        :param nodes: Nodes in the topology.
-        :type nodes: dict
-
-        This method updates the topology dictionary by querying interface lists
-        of all nodes mentioned in the topology dictionary.
-        It does this by dumping interface list to json output from all devices
-        using vpp_api_test, and pairing known information from topology
-        (mac address/pci address of interface) to state from VPP.
-        For TG/linux nodes add interface name only.
-        """
-
-        for node_data in nodes.values():
-            if node_data['type'] == NodeType.DUT:
-                self.update_vpp_interface_data_on_node(node_data)
-            elif node_data['type'] == NodeType.TG:
-                self.update_tg_interface_data_on_node(node_data)
-
     @staticmethod
     def get_interface_sw_index(node, interface):
         """Get VPP sw_index for the interface.
index d085825..dae5154 100644 (file)
@@ -13,8 +13,9 @@
 
 *** Settings ***
 | Variables | resources/libraries/python/topology.py
-| Library | resources/libraries/python/DUTSetup.py
-| Library | resources/libraries/python/TGSetup.py
+| Library | resources.libraries.python.topology.Topology
+| Library | resources.libraries.python.DUTSetup
+| Library | resources.libraries.python.TGSetup
 | Library | Collections
 
 *** Keywords ***
index e855f24..1f3b141 100644 (file)
 *** Settings ***
 | Library  | Collections
 | Resource | resources/libraries/robot/default.robot
+| Resource | resources/libraries/robot/interfaces.robot
 | Resource | resources/libraries/robot/bridge_domain.robot
 | Resource | resources/libraries/robot/l2_xconnect.robot
 | Library  | resources.libraries.python.L2Util
 | Library  | resources.libraries.python.IPUtil
 | Library  | resources.libraries.python.IPv4Util
 | Library  | resources.libraries.python.IPv4Setup
-| Library  | resources.libraries.python.InterfaceSetup
-| Library  | resources.libraries.python.InterfaceUtil
-| Library  | resources.libraries.python.topology.Topology
 | Library  | resources.libraries.python.NodePath
 
 
index e025575..2016146 100644 (file)
@@ -13,9 +13,8 @@
 
 *** Settings ***
 | Resource | resources/libraries/robot/default.robot
-| Library | resources/libraries/python/SetupFramework.py
-| Library | resources.libraries.python.topology.Topology
+| Resource | resources/libraries/robot/interfaces.robot
+| Library | resources.libraries.python.SetupFramework
 | Suite Setup | Run Keywords | Setup Framework | ${nodes}
 | ...         | AND          | Setup All DUTs | ${nodes}
 | ...         | AND          | Update All Interface Data On All Nodes | ${nodes}
-
index 9695b7f..c6a4cd1 100644 (file)
@@ -16,9 +16,7 @@
 | Resource | resources/libraries/robot/interfaces.robot
 | Resource | resources/libraries/robot/bridge_domain.robot
 | Resource | resources/libraries/robot/l2_traffic.robot
-| Library | resources.libraries.python.topology.Topology
 | Library | resources.libraries.python.NodePath
-| Variables | resources/libraries/python/topology.py
 | Force Tags | HW_ENV | VM_ENV
 | Suite Setup | Setup all TGs before traffic script
 | Test Setup | Setup all DUTs before test
index 47fe34a..45ab576 100644 (file)
@@ -12,7 +12,6 @@
 # limitations under the License.
 
 *** Settings ***
-| Library | resources.libraries.python.topology.Topology
 | Library | resources.libraries.python.NodePath
 | Library | resources.libraries.python.Trace
 | Resource | resources/libraries/robot/default.robot
index cf32bfa..3370cab 100644 (file)
@@ -15,7 +15,7 @@
 | Resource | resources/libraries/robot/default.robot
 | Resource | resources/libraries/robot/l2_xconnect.robot
 | Resource | resources/libraries/robot/l2_traffic.robot
-| Library | resources.libraries.python.InterfaceUtil
+| Resource | resources/libraries/robot/interfaces.robot
 | Library | resources.libraries.python.NodePath
 | Force Tags | 3_NODE_SINGLE_LINK_TOPO | HW_ENV | VM_ENV
 | Test Setup | Setup all DUTs before test