X-Git-Url: https://gerrit.fd.io/r/gitweb?p=csit.git;a=blobdiff_plain;f=resources%2Flibraries%2Fpython%2Ftopology.py;h=3c903e5c94c1ac809f1d0307e3b3ec5fb54ca88f;hp=a5c67d313c85772f4fe0978a491c8512bdb2deb4;hb=4dadc7a005ca99aa5a14ac650e9aa187cea10619;hpb=e710b52146d8c5c9db250d29c01f4f8ebdaf3261 diff --git a/resources/libraries/python/topology.py b/resources/libraries/python/topology.py index a5c67d313c..3c903e5c94 100644 --- a/resources/libraries/python/topology.py +++ b/resources/libraries/python/topology.py @@ -29,11 +29,15 @@ def load_topo_from_yaml(): :return: Nodes from loaded topology. """ - topo_path = BuiltIn().get_variable_value("${TOPOLOGY_PATH}") + try: + topo_path = BuiltIn().get_variable_value("${TOPOLOGY_PATH}") + except: + return '' with open(topo_path) as work_file: return load(work_file.read())['nodes'] + # pylint: disable=invalid-name class NodeType(object): """Defines node types used in topology dictionaries.""" @@ -46,6 +50,7 @@ class NodeType(object): class NodeSubTypeTG(object): + """Defines node sub-type TG - traffic generator.""" # T-Rex traffic generator TREX = 'TREX' # Moongen @@ -278,11 +283,12 @@ class Topology(object): :return: Interface name of the interface connected to the given link. :rtype: str """ - return Topology._get_interface_by_key_value(node, "vpp_sw_index", sw_index) + return Topology._get_interface_by_key_value(node, "vpp_sw_index", + sw_index) @staticmethod def get_interface_sw_index(node, iface_key): - """Get VPP sw_if_index for the interface. + """Get VPP sw_if_index for the interface using interface key. :param node: Node to get interface sw_if_index on. :param iface_key: Interface key from topology file, or sw_index. @@ -299,6 +305,26 @@ class Topology(object): except (KeyError, ValueError): return None + @staticmethod + def get_interface_sw_index_by_name(node, iface_name): + """Get VPP sw_if_index for the interface using interface name. + + :param node: Node to get interface sw_if_index on. + :param iface_name: Interface name. + :type node: dict + :type iface_name: str + :return: Return sw_if_index or None if not found. + :raises TypeError: If provided interface name is not a string. + """ + try: + if isinstance(iface_name, basestring): + iface_key = Topology.get_interface_by_name(node, iface_name) + return node['interfaces'][iface_key].get('vpp_sw_index') + else: + raise TypeError("Interface name must be a string.") + except (KeyError, ValueError): + return None + @staticmethod def get_interface_mtu(node, iface_key): """Get interface MTU. @@ -326,13 +352,90 @@ class Topology(object): :type node: dict :type iface_key: str :return: Interface name or None if not found. - :rtype: int + :rtype: str """ try: return node['interfaces'][iface_key].get('name') except KeyError: return None + @staticmethod + def convert_interface_reference_to_key(node, interface): + """Takes interface reference in any format + (name, link name, interface key or sw_if_index) + and converts to interface key using Topology methods. + + :param node: Node in topology. + :param interface: Name, sw_if_index, link name or key of an interface + on the node. + Valid formats are: sw_if_index, key, name. + :type node: dict + :type interface: str or int + + :return: Interface key. + :rtype: str + + :raises TypeError: If provided with invalid interface argument. + :raises RuntimeError: If the interface does not exist in topology. + """ + + if isinstance(interface, int): + key = Topology.get_interface_by_sw_index(node, interface) + if key is None: + raise RuntimeError("Interface with sw_if_index={0} does not " + "exist in topology.".format(interface)) + elif interface in Topology.get_node_interfaces(node): + key = interface + elif interface in Topology.get_links({"dut": node}): + key = Topology.get_interface_by_link_name(node, interface) + elif isinstance(interface, basestring): + key = Topology.get_interface_by_name(node, interface) + if key is None: + raise RuntimeError("Interface with key, name or link name " + "\"{0}\" does not exist in topology." + .format(interface)) + else: + raise TypeError("Type of interface argument must be integer" + " or string.") + return key + + @staticmethod + def convert_interface_reference(node, interface, wanted_format): + """Takes interface reference in any format + (name, link name, topology key or sw_if_index) and returns + its equivalent in the desired format. + + :param node: Node in topology. + :param interface: Name, sw_if_index, link name or key of an interface + on the node. + :param wanted_format: Format of return value wanted. + Valid options are: sw_if_index, key, name. + :type node: dict + :type interface: str or int + :type wanted_format: str + + :return: Interface name, interface key or sw_if_index. + :rtype: str or int + + :raises TypeError, ValueError: If provided with invalid arguments. + :raises RuntimeError: If the interface does not exist in topology. + """ + + key = Topology.convert_interface_reference_to_key(node, interface) + + conversions = { + "key": lambda x, y: y, + "name": Topology.get_interface_name, + "sw_if_index": Topology.get_interface_sw_index + } + + try: + return conversions[wanted_format](node, key) + except KeyError: + raise ValueError("Unrecognized return value wanted: {0}." + "Valid options are key, name, sw_if_index" + .format(wanted_format)) + @staticmethod def get_interface_numa_node(node, iface_key): """Get interface numa node. @@ -514,7 +617,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']) @@ -534,8 +637,8 @@ class Topology(object): :param filter_list_node2: Link filter criteria for node2. :type node1: dict :type node2: dict - :type filter_list1: list of strings - :type filter_list2: list of strings + :type filter_list_node1: list of strings + :type filter_list_node2: list of strings :return: List of strings that represent connecting link names. :rtype: list """ @@ -578,7 +681,8 @@ class Topology(object): else: return connecting_links[0] - @keyword('Get egress interfaces name on "${node1}" for link with "${node2}"') + @keyword('Get egress interfaces name on "${node1}" for link with ' + '"${node2}"') def get_egress_interfaces_name_for_nodes(self, node1, node2): """Get egress interfaces on node1 for link with node2.