fix(methodology): Update info for soak and ndrpdr
[csit.git] / resources / libraries / python / DPDK / TestpmdTest.py
1 # Copyright (c) 2023 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
5 #
6 #     http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
13
14 """
15 This module exists to start testpmd on topology nodes.
16 """
17
18 from robot.libraries.BuiltIn import BuiltIn
19 from resources.libraries.python.Constants import Constants
20 from resources.libraries.python.CpuUtils import CpuUtils
21 from resources.libraries.python.DpdkUtil import DpdkUtil
22 from resources.libraries.python.ssh import exec_cmd_no_error
23 from resources.libraries.python.topology import NodeType, Topology
24
25
26 class TestpmdTest:
27     """
28     This class start testpmd on topology nodes and check if properly started.
29     """
30
31     @staticmethod
32     def start_testpmd_on_all_duts(
33             nodes, topology_info, phy_cores, rx_queues=None, jumbo_frames=False,
34             rxd=None, txd=None, nic_rxq_size=None, nic_txq_size=None):
35         """
36         Start the testpmd with M worker threads and rxqueues N and jumbo
37         support frames on/off on all DUTs.
38
39         :param nodes: All the nodes info from the topology file.
40         :param topology_info: All the info from the topology file.
41         :param phy_cores: Number of physical cores to use.
42         :param rx_queues: Number of RX queues.
43         :param jumbo_frames: Jumbo frames on/off.
44         :param rxd: Number of RX descriptors.
45         :param txd: Number of TX descriptors.
46         :param nic_rxq_size: RX queue size.
47         :param nic_txq_size: TX queue size.
48
49         :type nodes: dict
50         :type topology_info: dict
51         :type phy_cores: int
52         :type rx_queues: int
53         :type jumbo_frames: bool
54         :type rxd: int
55         :type txd: int
56         :type nic_rxq_size: int
57         :type nic_txq_size: int
58         :raises RuntimeError: If bash return code is not 0.
59         """
60
61         cpu_count_int = dp_count_int = int(phy_cores)
62         dp_cores = cpu_count_int+1
63         compute_resource_info = CpuUtils.get_affinity_vswitch(
64             nodes, phy_cores, rx_queues=rx_queues, rxd=rxd, txd=txd
65         )
66         for node_name, node in nodes.items():
67             if node["type"] == NodeType.DUT:
68                 if dp_count_int > 1:
69                     BuiltIn().set_tags('MTHREAD')
70                 else:
71                     BuiltIn().set_tags('STHREAD')
72                 BuiltIn().set_tags(
73                     f"{dp_count_int}T{cpu_count_int}C"
74                 )
75
76                 cpu_dp = compute_resource_info[f"{node_name}_cpu_dp"]
77                 rxq_count_int = compute_resource_info["rxq_count_int"]
78                 if1 = topology_info[f"{node_name}_pf1"][0]
79                 if2 = topology_info[f"{node_name}_pf2"][0]
80                 TestpmdTest.start_testpmd(
81                     node, if1=if1, if2=if2, lcores_list=cpu_dp,
82                     nb_cores=dp_count_int, queue_nums=rxq_count_int,
83                     jumbo_frames=jumbo_frames, rxq_size=nic_rxq_size,
84                     txq_size=nic_txq_size
85                 )
86         for node in nodes:
87             if u"DUT" in node:
88                 for i in range(3):
89                     try:
90                         nic_model = nodes[node]["interfaces"][if1]["model"]
91                         if "Mellanox-CX7VEAT" in nic_model:
92                             break
93                         if "Mellanox-CX6DX" in nic_model:
94                             break
95                         TestpmdTest.check_testpmd(nodes[node])
96                         break
97                     except RuntimeError:
98                         TestpmdTest.start_testpmd(
99                             nodes[node], if1=if1, if2=if2,
100                             lcores_list=cpu_dp, nb_cores=dp_count_int,
101                             queue_nums=rxq_count_int,
102                             jumbo_frames=jumbo_frames,
103                             rxq_size=nic_rxq_size, txq_size=nic_txq_size
104                         )
105                 else:
106                     message = f"Failed to start testpmd at node {node}"
107                     raise RuntimeError(message)
108
109     @staticmethod
110     def start_testpmd(
111             node, if1, if2, lcores_list, nb_cores, queue_nums,
112             jumbo_frames, rxq_size=1024, txq_size=1024):
113         """
114         Execute the testpmd on the DUT node.
115
116         :param node: DUT node.
117         :param if1: The test link interface 1.
118         :param if2: The test link interface 2.
119         :param lcores_list: The DPDK run cores.
120         :param nb_cores: The cores number for the forwarding.
121         :param queue_nums: The queues number for the NIC.
122         :param jumbo_frames: Indication if the jumbo frames are used (True) or
123             not (False).
124         :param rxq_size: RXQ size. Default=1024.
125         :param txq_size: TXQ size. Default=1024.
126         :type node: dict
127         :type if1: str
128         :type if2: str
129         :type lcores_list: str
130         :type nb_cores: int
131         :type queue_nums: str
132         :type jumbo_frames: bool
133         :type rxq_size: int
134         :type txq_size: int
135         :raises RuntimeError: If the script "run_testpmd.sh" fails.
136         """
137         if node[u"type"] == NodeType.DUT:
138             if_pci0 = Topology.get_interface_pci_addr(node, if1)
139             if_pci1 = Topology.get_interface_pci_addr(node, if2)
140
141             pmd_max_pkt_len = u"9200" if jumbo_frames else u"1518"
142             testpmd_args = DpdkUtil.get_testpmd_args(
143                 eal_corelist=f"1,{lcores_list}",
144                 eal_driver=False,
145                 eal_pci_whitelist0=if_pci0,
146                 eal_pci_whitelist1=if_pci1,
147                 eal_in_memory=True,
148                 pmd_num_mbufs=32768,
149                 pmd_fwd_mode=u"io",
150                 pmd_nb_ports=u"2",
151                 pmd_portmask=u"0x3",
152                 pmd_max_pkt_len=pmd_max_pkt_len,
153                 pmd_mbuf_size=u"16384",
154                 pmd_rxd=rxq_size,
155                 pmd_txd=txq_size,
156                 pmd_rxq=queue_nums,
157                 pmd_txq=queue_nums,
158                 pmd_nb_cores=nb_cores,
159                 pmd_disable_link_check=False,
160                 pmd_auto_start=True,
161                 pmd_numa=True
162             )
163
164             command = f"{Constants.REMOTE_FW_DIR}/{Constants.RESOURCES_LIB_SH}"\
165                 f"/entry/run_testpmd.sh \"{testpmd_args}\""
166             message = f"Failed to execute testpmd at node {node['host']}"
167             exec_cmd_no_error(node, command, timeout=1800, message=message)
168
169     @staticmethod
170     def check_testpmd(node):
171         """
172         Execute the testpmd check on the DUT node.
173
174         :param node: DUT node.
175         :type node: dict
176         :raises RuntimeError: If the script "check_testpmd.sh" fails.
177         """
178         if node[u"type"] == NodeType.DUT:
179             command = f"{Constants.REMOTE_FW_DIR}/{Constants.RESOURCES_LIB_SH}"\
180                       f"/entry/check_testpmd.sh"
181             message = "Testpmd not started properly"
182             exec_cmd_no_error(node, command, timeout=1800, message=message)