Last bulk update of CSIT.
[csit.git] / resources / libraries / python / topology.py
index 522de37..3ced69d 100644 (file)
@@ -43,6 +43,14 @@ class NodeType(object):
     # Traffic Generator (this node has traffic generator on it)
     TG = 'TG'
 
+class NodeSubTypeTG(object):
+    #T-Rex traffic generator
+    TREX = 'TREX'
+    # Moongen
+    MOONGEN = 'MOONGEN'
+    #IxNetwork
+    IXNET = 'IXNET'
+
 DICT__nodes = load_topo_from_yaml()
 
 
@@ -345,6 +353,22 @@ class Topology(object):
 
         return None
 
+    @staticmethod
+    def get_interface_mac_by_port_key(node, port_key):
+        """Get MAC address for the interface based on port key.
+
+        :param node: Node to get interface mac on.
+        :param port_key: Dictionary key name of interface.
+        :type node: dict
+        :type port_key: str
+        :return: Return MAC or None if not found.
+        """
+        for port_name, port_data in node['interfaces'].iteritems():
+            if port_name == port_key:
+                return port_data['mac_address']
+
+        return None
+
     @staticmethod
     def get_interface_mac(node, interface):
         """Get MAC address for the interface.
@@ -365,19 +389,64 @@ class Topology(object):
         return None
 
     @staticmethod
-    def get_adjacent_interface(node, interface_name):
-        """Get interface adjacent to specified interface on local network.
-
-           :param node: Node that contains specified interface.
-           :param interface_name: Interface name.
-           :type node: dict
-           :type interface_name: str
-           :return: Return interface or None if not found.
-           :rtype: dict
+    def get_adjacent_node_and_interface_by_key(nodes_info, node, port_key):
+        """Get node and interface adjacent to specified interface
+        on local network.
+
+        :param nodes_info: Dictionary containing information on all nodes
+        in topology.
+        :param node: Node that contains specified interface.
+        :param port_key: Interface port key.
+        :type nodes_info: dict
+        :type node: dict
+        :type port_key: str
+        :return: Return (node, interface info) tuple or None if not found.
+        :rtype: (dict, dict)
+        """
+        link_name = None
+       # get link name where the interface belongs to
+        for port_name, port_data in node['interfaces'].iteritems():
+            if port_name == 'mgmt':
+                continue
+            if port_name == port_key:
+                link_name = port_data['link']
+                break
+
+        if link_name is None: 
+            return None
+
+        # find link
+        for node_data in nodes_info.values():
+            # skip self
+            if node_data['host'] == node['host']:
+                continue
+            for interface, interface_data \
+                    in node_data['interfaces'].iteritems():
+                if 'link' not in interface_data:
+                    continue
+                if interface_data['link'] == link_name:
+                    return node_data, node_data['interfaces'][interface]
+
+    @staticmethod
+    def get_adjacent_node_and_interface(nodes_info, node, interface_name):
+        """Get node and interface adjacent to specified interface
+        on local network.
+
+        :param nodes_info: Dictionary containing information on all nodes
+        in topology.
+        :param node: Node that contains specified interface.
+        :param interface_name: Interface name.
+        :type nodes_info: dict
+        :type node: dict
+        :type interface_name: str
+        :return: Return (node, interface info) tuple or None if not found.
+        :rtype: (dict, dict)
         """
         link_name = None
         # get link name where the interface belongs to
-        for _, port_data in node['interfaces'].iteritems():
+        for port_name, port_data in node['interfaces'].iteritems():
+            if port_name == 'mgmt':
+                continue
             if port_data['name'] == interface_name:
                 link_name = port_data['link']
                 break
@@ -386,7 +455,7 @@ class Topology(object):
             return None
 
         # find link
-        for _, node_data in DICT__nodes.iteritems():
+        for node_data in nodes_info.values():
             # skip self
             if node_data['host'] == node['host']:
                 continue
@@ -395,7 +464,7 @@ class Topology(object):
                 if 'link' not in interface_data:
                     continue
                 if interface_data['link'] == link_name:
-                    return node_data['interfaces'][interface]
+                    return node_data, node_data['interfaces'][interface]
 
     @staticmethod
     def get_interface_pci_addr(node, interface):
@@ -537,3 +606,44 @@ class Topology(object):
         if not interfaces:
             raise RuntimeError('No engress interface for nodes')
         return interfaces[0]
+
+    @keyword('Get link data useful in circular topology test from tg "${tgen}"'
+             ' dut1 "${dut1}" dut2 "${dut2}"')
+    def get_links_dict_from_nodes(self, tgen, dut1, dut2):
+        """Returns link combinations used in tests in circular topology.
+
+        For the time being it returns links from the Node path:
+        TG->DUT1->DUT2->TG
+        :param tg: traffic generator node data
+        :param dut1: DUT1 node data
+        :param dut2: DUT2 node data
+        :type tg: dict
+        :type dut1: dict
+        :type dut2: dict
+        :return: dictionary of possible link combinations
+        the naming convention until changed to something more general is
+        implemented is this:
+        DUT1_DUT2_LINK: link name between DUT! and DUT2
+        DUT1_TG_LINK: link name between DUT1 and TG
+        DUT2_TG_LINK: link name between DUT2 and TG
+        TG_TRAFFIC_LINKS: list of link names that generated traffic is sent
+        to and from
+        DUT1_BD_LINKS: list of link names that will be connected by the bridge
+        domain on DUT1
+        DUT2_BD_LINKS: list of link names that will be connected by the bridge
+        domain on DUT2
+        """
+        # TODO: replace with generic function.
+        dut1_dut2_link = self.get_first_active_connecting_link(dut1, dut2)
+        dut1_tg_link = self.get_first_active_connecting_link(dut1, tgen)
+        dut2_tg_link = self.get_first_active_connecting_link(dut2, tgen)
+        tg_traffic_links = [dut1_tg_link, dut2_tg_link]
+        dut1_bd_links = [dut1_dut2_link, dut1_tg_link]
+        dut2_bd_links = [dut1_dut2_link, dut2_tg_link]
+        topology_links = {'DUT1_DUT2_LINK': dut1_dut2_link,
+                          'DUT1_TG_LINK': dut1_tg_link,
+                          'DUT2_TG_LINK': dut2_tg_link,
+                          'TG_TRAFFIC_LINKS': tg_traffic_links,
+                          'DUT1_BD_LINKS': dut1_bd_links,
+                          'DUT2_BD_LINKS': dut2_bd_links}
+        return topology_links