+
+ def get_links_dict_from_nodes(self, tgen, dut1, dut2):
+ """Return link combinations used in tests in circular topology.
+
+ For the time being it returns links from the Node path:
+ TG->DUT1->DUT2->TG
+ 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
+
+ :param tgen: Traffic generator node data.
+ :param dut1: DUT1 node data.
+ :param dut2: DUT2 node data.
+ :type tgen: dict
+ :type dut1: dict
+ :type dut2: dict
+ :returns: Dictionary of possible link combinations.
+ :rtype: dict
+ """
+ # 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 = {
+ u"DUT1_DUT2_LINK": dut1_dut2_link,
+ u"DUT1_TG_LINK": dut1_tg_link,
+ u"DUT2_TG_LINK": dut2_tg_link,
+ u"TG_TRAFFIC_LINKS": tg_traffic_links,
+ u"DUT1_BD_LINKS": dut1_bd_links,
+ u"DUT2_BD_LINKS": dut2_bd_links
+ }
+ return topology_links
+
+ @staticmethod
+ def is_tg_node(node):
+ """Find out whether the node is TG.
+
+ :param node: Node to examine.
+ :type node: dict
+ :returns: True if node is type of TG, otherwise False.
+ :rtype: bool
+ """
+ return node[u"type"] == NodeType.TG
+
+ @staticmethod
+ def get_node_hostname(node):
+ """Return host (hostname/ip address) of the node.
+
+ :param node: Node created from topology.
+ :type node: dict
+ :returns: Hostname or IP address.
+ :rtype: str
+ """
+ return node[u"host"]
+
+ @staticmethod
+ def get_node_arch(node):
+ """Return arch of the node.
+ Default to x86_64 if no arch present
+
+ :param node: Node created from topology.
+ :type node: dict
+ :returns: Node architecture
+ :rtype: str
+ """
+ try:
+ return node[u"arch"]
+ except KeyError:
+ node[u"arch"] = u"x86_64"
+ return u"x86_64"
+
+ @staticmethod
+ def get_cryptodev(node):
+ """Return Crytodev configuration of the node.
+
+ :param node: Node created from topology.
+ :type node: dict
+ :returns: Cryptodev configuration string.
+ :rtype: str
+ """
+ try:
+ return node[u"cryptodev"]
+ except KeyError:
+ return None
+
+ def get_bus(node):
+ """Return bus configuration of the node.
+
+ :param node: Node created from topology.
+ :type node: dict
+ :returns: bus configuration string.
+ :rtype: str
+ """
+ try:
+ return node[u"bus"]
+ except KeyError:
+ return None
+
+ @staticmethod
+ def get_uio_driver(node):
+ """Return uio-driver configuration of the node.
+
+ :param node: Node created from topology.
+ :type node: dict
+ :returns: uio-driver configuration string.
+ :rtype: str
+ """
+ try:
+ return node[u"uio_driver"]
+ except KeyError:
+ return None
+
+ @staticmethod
+ def set_interface_numa_node(node, iface_key, numa_node_id):
+ """Set interface numa_node location.
+
+ :param node: Node to set numa_node on.
+ :param iface_key: Interface key from topology file.
+ :param numa_node_id: Num_node ID.
+ :type node: dict
+ :type iface_key: str
+ :type numa_node_id: int
+ :returns: Return iface_key or None if not found.
+ """
+ try:
+ node[u"interfaces"][iface_key][u"numa_node"] = numa_node_id
+ return iface_key
+ except KeyError:
+ return None
+
+ @staticmethod
+ def add_new_socket(node, socket_type, socket_id, socket_path):
+ """Add socket file of specific SocketType and ID to node.
+
+ :param node: Node to add socket on.
+ :param socket_type: Socket type.
+ :param socket_id: Socket id, currently equals to unique node key.
+ :param socket_path: Socket absolute path.
+ :type node: dict
+ :type socket_type: SocketType
+ :type socket_id: str
+ :type socket_path: str
+ """
+ path = [u"sockets", socket_type, socket_id]
+ Topology.add_node_item(node, socket_path, path)
+
+ @staticmethod
+ def del_node_socket_id(node, socket_type, socket_id):
+ """Delete socket of specific SocketType and ID from node.
+
+ :param node: Node to delete socket from.
+ :param socket_type: Socket type.
+ :param socket_id: Socket id, currently equals to unique node key.
+ :type node: dict
+ :type socket_type: SocketType
+ :type socket_id: str
+ """
+ node[u"sockets"][socket_type].pop(socket_id)
+
+ @staticmethod
+ def get_node_sockets(node, socket_type=None):
+ """Get node socket files.
+
+ :param node: Node to get sockets from.
+ :param socket_type: Socket type or None for all sockets.
+ :type node: dict
+ :type socket_type: SocketType
+ :returns: Node sockets or None if not found.
+ :rtype: dict
+ """
+ try:
+ if socket_type:
+ return node[u"sockets"][socket_type]
+ return node[u"sockets"]
+ except KeyError:
+ return None
+
+ @staticmethod
+ def clean_sockets_on_all_nodes(nodes):
+ """Remove temporary socket files from topology file.
+
+ :param nodes: SUT nodes.
+ :type node: dict
+ """
+ for node in nodes.values():
+ if u"sockets" in list(node.keys()):
+ # Containers are disconnected and destroyed already.
+ node.pop(u"sockets")