ca98da2f861859181fea9751769bf5f6fe620e4d
[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         for node in nodes:
64             if u"DUT" in node:
65                 compute_resource_info = CpuUtils.get_affinity_vswitch(
66                     nodes, node, phy_cores, rx_queues=rx_queues,
67                     rxd=rxd, txd=txd
68                 )
69                 if dp_count_int > 1:
70                     BuiltIn().set_tags('MTHREAD')
71                 else:
72                     BuiltIn().set_tags('STHREAD')
73                 BuiltIn().set_tags(
74                     f"{dp_count_int}T{cpu_count_int}C"
75                 )
76
77                 cpu_dp = compute_resource_info[u"cpu_dp"]
78                 rxq_count_int = compute_resource_info[u"rxq_count_int"]
79                 if1 = topology_info[f"{node}_pf1"][0]
80                 if2 = topology_info[f"{node}_pf2"][0]
81                 TestpmdTest.start_testpmd(
82                     nodes[node], if1=if1, if2=if2, lcores_list=cpu_dp,
83                     nb_cores=dp_count_int, queue_nums=rxq_count_int,
84                     jumbo_frames=jumbo_frames, rxq_size=nic_rxq_size,
85                     txq_size=nic_txq_size
86                 )
87         for node in nodes:
88             if u"DUT" in node:
89                 for i in range(3):
90                     try:
91                         nic_model = nodes[node]["interfaces"][if1]["model"]
92                         if "Mellanox-CX7VEAT" in nic_model:
93                             break
94                         if "Mellanox-CX6DX" in nic_model:
95                             break
96                         TestpmdTest.check_testpmd(nodes[node])
97                         break
98                     except RuntimeError:
99                         TestpmdTest.start_testpmd(
100                             nodes[node], if1=if1, if2=if2,
101                             lcores_list=cpu_dp, nb_cores=dp_count_int,
102                             queue_nums=rxq_count_int,
103                             jumbo_frames=jumbo_frames,
104                             rxq_size=nic_rxq_size, txq_size=nic_txq_size
105                         )
106                 else:
107                     message = f"Failed to start testpmd at node {node}"
108                     raise RuntimeError(message)
109
110     @staticmethod
111     def start_testpmd(
112             node, if1, if2, lcores_list, nb_cores, queue_nums,
113             jumbo_frames, rxq_size=1024, txq_size=1024):
114         """
115         Execute the testpmd on the DUT node.
116
117         :param node: DUT node.
118         :param if1: The test link interface 1.
119         :param if2: The test link interface 2.
120         :param lcores_list: The DPDK run cores.
121         :param nb_cores: The cores number for the forwarding.
122         :param queue_nums: The queues number for the NIC.
123         :param jumbo_frames: Indication if the jumbo frames are used (True) or
124             not (False).
125         :param rxq_size: RXQ size. Default=1024.
126         :param txq_size: TXQ size. Default=1024.
127         :type node: dict
128         :type if1: str
129         :type if2: str
130         :type lcores_list: str
131         :type nb_cores: int
132         :type queue_nums: str
133         :type jumbo_frames: bool
134         :type rxq_size: int
135         :type txq_size: int
136         :raises RuntimeError: If the script "run_testpmd.sh" fails.
137         """
138         if node[u"type"] == NodeType.DUT:
139             if_pci0 = Topology.get_interface_pci_addr(node, if1)
140             if_pci1 = Topology.get_interface_pci_addr(node, if2)
141
142             pmd_max_pkt_len = u"9200" if jumbo_frames else u"1518"
143             testpmd_args = DpdkUtil.get_testpmd_args(
144                 eal_corelist=f"1,{lcores_list}",
145                 eal_driver=False,
146                 eal_pci_whitelist0=if_pci0,
147                 eal_pci_whitelist1=if_pci1,
148                 eal_in_memory=True,
149                 pmd_num_mbufs=32768,
150                 pmd_fwd_mode=u"io",
151                 pmd_nb_ports=u"2",
152                 pmd_portmask=u"0x3",
153                 pmd_max_pkt_len=pmd_max_pkt_len,
154                 pmd_mbuf_size=u"16384",
155                 pmd_rxd=rxq_size,
156                 pmd_txd=txq_size,
157                 pmd_rxq=queue_nums,
158                 pmd_txq=queue_nums,
159                 pmd_nb_cores=nb_cores,
160                 pmd_disable_link_check=False,
161                 pmd_auto_start=True,
162                 pmd_numa=True
163             )
164
165             command = f"{Constants.REMOTE_FW_DIR}/{Constants.RESOURCES_LIB_SH}"\
166                 f"/entry/run_testpmd.sh \"{testpmd_args}\""
167             message = f"Failed to execute testpmd at node {node['host']}"
168             exec_cmd_no_error(node, command, timeout=1800, message=message)
169
170     @staticmethod
171     def check_testpmd(node):
172         """
173         Execute the testpmd check on the DUT node.
174
175         :param node: DUT node.
176         :type node: dict
177         :raises RuntimeError: If the script "check_testpmd.sh" fails.
178         """
179         if node[u"type"] == NodeType.DUT:
180             command = f"{Constants.REMOTE_FW_DIR}/{Constants.RESOURCES_LIB_SH}"\
181                       f"/entry/check_testpmd.sh"
182             message = "Testpmd not started properly"
183             exec_cmd_no_error(node, command, timeout=1800, message=message)