fix: start testpmd and l3fwd in 3 cycles
[csit.git] / resources / libraries / python / DPDK / TestpmdTest.py
1 # Copyright (c) 2022 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                         TestpmdTest.check_testpmd(nodes[node])
92                         break
93                     except RuntimeError:
94                         TestpmdTest.start_testpmd(
95                             nodes[node], if1=if1, if2=if2,
96                             lcores_list=cpu_dp, nb_cores=dp_count_int,
97                             queue_nums=rxq_count_int,
98                             jumbo_frames=jumbo_frames,
99                             rxq_size=nic_rxq_size, txq_size=nic_txq_size
100                         )
101                 else:
102                     message = f"Failed to start testpmd at node {node}"
103                     raise RuntimeError(message)
104
105     @staticmethod
106     def start_testpmd(
107             node, if1, if2, lcores_list, nb_cores, queue_nums,
108             jumbo_frames, rxq_size=1024, txq_size=1024):
109         """
110         Execute the testpmd on the DUT node.
111
112         :param node: DUT node.
113         :param if1: The test link interface 1.
114         :param if2: The test link interface 2.
115         :param lcores_list: The DPDK run cores.
116         :param nb_cores: The cores number for the forwarding.
117         :param queue_nums: The queues number for the NIC.
118         :param jumbo_frames: Indication if the jumbo frames are used (True) or
119             not (False).
120         :param rxq_size: RXQ size. Default=1024.
121         :param txq_size: TXQ size. Default=1024.
122         :type node: dict
123         :type if1: str
124         :type if2: str
125         :type lcores_list: str
126         :type nb_cores: int
127         :type queue_nums: str
128         :type jumbo_frames: bool
129         :type rxq_size: int
130         :type txq_size: int
131         :raises RuntimeError: If the script "run_testpmd.sh" fails.
132         """
133         if node[u"type"] == NodeType.DUT:
134             if_pci0 = Topology.get_interface_pci_addr(node, if1)
135             if_pci1 = Topology.get_interface_pci_addr(node, if2)
136
137             pmd_max_pkt_len = u"9200" if jumbo_frames else u"1518"
138             testpmd_args = DpdkUtil.get_testpmd_args(
139                 eal_corelist=f"1,{lcores_list}",
140                 eal_driver=False,
141                 eal_pci_whitelist0=if_pci0,
142                 eal_pci_whitelist1=if_pci1,
143                 eal_in_memory=True,
144                 pmd_num_mbufs=32768,
145                 pmd_fwd_mode=u"io",
146                 pmd_nb_ports=u"2",
147                 pmd_portmask=u"0x3",
148                 pmd_max_pkt_len=pmd_max_pkt_len,
149                 pmd_mbuf_size=u"16384",
150                 pmd_rxd=rxq_size,
151                 pmd_txd=txq_size,
152                 pmd_rxq=queue_nums,
153                 pmd_txq=queue_nums,
154                 pmd_nb_cores=nb_cores,
155                 pmd_disable_link_check=False,
156                 pmd_auto_start=True,
157                 pmd_numa=True
158             )
159
160             command = f"{Constants.REMOTE_FW_DIR}/{Constants.RESOURCES_LIB_SH}"\
161                 f"/entry/run_testpmd.sh \"{testpmd_args}\""
162             message = f"Failed to execute testpmd at node {node['host']}"
163             exec_cmd_no_error(node, command, timeout=1800, message=message)
164
165     @staticmethod
166     def check_testpmd(node):
167         """
168         Execute the testpmd check on the DUT node.
169
170         :param node: DUT node.
171         :type node: dict
172         :raises RuntimeError: If the script "check_testpmd.sh" fails.
173         """
174         if node[u"type"] == NodeType.DUT:
175             command = f"{Constants.REMOTE_FW_DIR}/{Constants.RESOURCES_LIB_SH}"\
176                       f"/entry/check_testpmd.sh"
177             message = "Testpmd not started properly"
178             exec_cmd_no_error(node, command, timeout=1800, message=message)