X-Git-Url: https://gerrit.fd.io/r/gitweb?p=csit.git;a=blobdiff_plain;f=resources%2Flibraries%2Fpython%2FNodePath.py;h=dd685069147f2ecd6d448e5a21f06f4c9335edbe;hp=04e8e5ef3c3e3d50f392bba50bc5a42e9371594a;hb=76def9e0a3404b38c9e7fbd58260700207b17639;hpb=14a71b74b414df7616ccb5ada3d50ecb90d96bae diff --git a/resources/libraries/python/NodePath.py b/resources/libraries/python/NodePath.py index 04e8e5ef3c..dd68506914 100644 --- a/resources/libraries/python/NodePath.py +++ b/resources/libraries/python/NodePath.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020 Cisco and/or its affiliates. +# Copyright (c) 2022 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: @@ -13,7 +13,7 @@ """Path utilities library for nodes in the topology.""" -from resources.libraries.python.topology import Topology, NodeType +from resources.libraries.python.topology import Topology class NodePath: @@ -92,7 +92,7 @@ class NodePath: self._path = [] self._path_iter = [] - def compute_path(self, always_same_link=True): + def compute_path(self, always_same_link=True, topo_has_dut=True): """Compute path for added nodes. .. note:: First add at least two nodes to the topology. @@ -100,19 +100,26 @@ class NodePath: :param always_same_link: If True use always same link between two nodes in path. If False use different link (if available) between two nodes if one link was used before. + :param topo_has_dut: If False we want to test back to back test on TG. :type always_same_link: bool + :type topo_has_dut: bool :raises RuntimeError: If not enough nodes for path. """ nodes = self._nodes - if len(nodes) < 2: + if len(nodes) < 2 and topo_has_dut: raise RuntimeError(u"Not enough nodes to compute path") for idx in range(0, len(nodes) - 1): topo = Topology() node1 = nodes[idx] - node2 = nodes[idx + 1] n1_list = self._nodes_filter[idx] - n2_list = self._nodes_filter[idx + 1] + if topo_has_dut: + node2 = nodes[idx + 1] + n2_list = self._nodes_filter[idx + 1] + else: + node2 = node1 + n2_list = n1_list + links = topo.get_active_connecting_links( node1, node2, filter_list_node1=n1_list, filter_list_node2=n2_list @@ -139,8 +146,11 @@ class NodePath: link = l_set[0] self._links.append(link) + + use_subsequent = not topo_has_dut interface1 = topo.get_interface_by_link_name(node1, link) - interface2 = topo.get_interface_by_link_name(node2, link) + interface2 = topo.get_interface_by_link_name(node2, link, + use_subsequent) self._path.append((interface1, node1)) self._path.append((interface2, node2)) @@ -207,50 +217,93 @@ class NodePath: raise RuntimeError(u"No path for topology") return self._path[-2] - def compute_circular_topology(self, nodes, filter_list=None, nic_pfs=1): + def compute_circular_topology( + self, nodes, filter_list=None, nic_pfs=1, + always_same_link=False, topo_has_tg=True, topo_has_dut=True): """Return computed circular path. :param nodes: Nodes to append to the path. :param filter_list: Filter criteria list. :param nic_pfs: Number of PF of NIC. + :param always_same_link: If True use always same link between two nodes + in path. If False use different link (if available) + between two nodes if one link was used before. + :param topo_has_tg: If True, the topology has a TG node. If False, + the topology consists entirely of DUT nodes. + :param topo_has_dut: If True, the topology has a DUT node(s). If False, + the topology consists entirely of TG nodes. :type nodes: dict :type filter_list: list of strings - :type path_count: int + :type nic_pfs: int + :type always_same_link: bool + :type topo_has_tg: bool + :type topo_has_dut: bool :returns: Topology information dictionary. :rtype: dict + :raises RuntimeError: If unsupported combination of parameters. """ t_dict = dict() - duts = [key for key in nodes if u"DUT" in key] - t_dict[u"duts"] = duts - t_dict[u"duts_count"] = len(duts) - t_dict[u"int"] = u"pf" - - for idx in range(0, nic_pfs // 2): - self.append_node(nodes[u"TG"]) - for dut in duts: - self.append_node(nodes[dut], filter_list=filter_list) - self.append_node(nodes[u"TG"]) - self.compute_path(always_same_link=False) - - n_idx = 0 - t_idx = 1 - d_idx = 0 + if topo_has_dut: + duts = [key for key in nodes if u"DUT" in key] + t_dict[u"duts"] = duts + t_dict[u"duts_count"] = len(duts) + t_dict[u"int"] = u"pf" + + for _ in range(0, nic_pfs // 2): + if topo_has_tg: + if topo_has_dut: + self.append_node(nodes[u"TG"]) + else: + self.append_node(nodes[u"TG"], filter_list=filter_list) + if topo_has_dut: + for dut in duts: + self.append_node(nodes[dut], filter_list=filter_list) + if topo_has_tg: + if topo_has_dut: + self.append_node(nodes[u"TG"]) + else: + self.append_node(nodes[u"TG"], filter_list=filter_list) + self.compute_path(always_same_link, topo_has_dut) + + n_idx = 0 # node index + t_idx = 1 # TG interface index + d_idx = 0 # DUT interface index + prev_host = None while True: interface, node = self.next_interface() if not interface: break - if node[u"type"] == u"TG": - n_pfx = f"TG" - p_pfx = f"pf{t_idx}" - i_pfx = f"if{t_idx}" + if topo_has_tg and node.get(u"type") == u"TG": + n_pfx = f"TG" # node prefix + p_pfx = f"pf{t_idx}" # physical interface prefix + i_pfx = f"if{t_idx}" # [backwards compatible] interface prefix n_idx = 0 t_idx = t_idx + 1 - else: + elif topo_has_tg and topo_has_dut: + # Each node has 2 interfaces, starting with 1 + # Calculate prefixes appropriately for current + # path topology nomenclature: + # tg1_if1 -> dut1_if1 -> dut1_if2 -> + # [dut2_if1 -> dut2_if2 ...] -> tg1_if2 n_pfx = f"DUT{n_idx // 2 + 1}" p_pfx = f"pf{d_idx % 2 + t_idx - 1}" i_pfx = f"if{d_idx % 2 + t_idx - 1}" n_idx = n_idx + 1 d_idx = d_idx + 1 + elif not topo_has_tg and always_same_link: + this_host = node.get(u"host") + if prev_host != this_host: + # When moving to a new host in the path, + # increment the node index (n_idx) and + # reset DUT interface index (d_idx) to 1. + n_idx = n_idx + 1 + d_idx = 1 + n_pfx = f"DUT{n_idx}" + p_pfx = f"pf{d_idx}" + i_pfx = f"if{d_idx}" + d_idx = d_idx + 1 + else: + raise RuntimeError(u"Unsupported combination of paramters") t_dict[f"{n_pfx}"] = node t_dict[f"{n_pfx}_{p_pfx}"] = [interface] @@ -268,6 +321,9 @@ class NodePath: t_dict[f"{n_pfx}_pf_pci"] = [] t_dict[f"{n_pfx}_pf_pci"].append( Topology.get_interface_pci_addr(node, interface)) + if f"{n_pfx}_pf_keys" not in t_dict: + t_dict[f"{n_pfx}_pf_keys"] = [] + t_dict[f"{n_pfx}_pf_keys"].append(interface) # Backward compatibility below t_dict[f"{n_pfx.lower()}_{i_pfx}"] = interface t_dict[f"{n_pfx.lower()}_{i_pfx}_mac"] = \