X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=resources%2Flibraries%2Fpython%2FDPDK%2FL3fwdTest.py;h=c33810348dff6e13a80d8ad7e998202a7046cc92;hb=924ab26cf80edfc9efb8116a2295478cd3f821ea;hp=6219a08e0cb302b26b553e7d1f48958328fee343;hpb=afa3def247a11985b17f310e58b6f5fae16dc306;p=csit.git diff --git a/resources/libraries/python/DPDK/L3fwdTest.py b/resources/libraries/python/DPDK/L3fwdTest.py index 6219a08e0c..c33810348d 100644 --- a/resources/libraries/python/DPDK/L3fwdTest.py +++ b/resources/libraries/python/DPDK/L3fwdTest.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016 Cisco and/or its affiliates. +# Copyright (c) 2020 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: @@ -11,93 +11,150 @@ # See the License for the specific language governing permissions and # limitations under the License. - """ This module exists to provide the l3fwd test for DPDK on topology nodes. """ -from robot.api import logger +from resources.libraries.python.Constants import Constants +from resources.libraries.python.DpdkUtil import DpdkUtil +from resources.libraries.python.ssh import exec_cmd_no_error, exec_cmd +from resources.libraries.python.topology import NodeType, Topology -from resources.libraries.python.ssh import SSH -from resources.libraries.python.constants import Constants as con -from resources.libraries.python.topology import Topology -class L3fwdTest(object): +class L3fwdTest: """Test the DPDK l3fwd performance.""" @staticmethod - def start_the_l3fwd_test(nodes_info, dut_node, dut_if1, dut_if2, - nb_cores, lcores_list, queue_nums, jumbo_frames): + def start_l3fwd( + nodes, node, if1, if2, lcores_list, nb_cores, queue_nums, + jumbo_frames): """ Execute the l3fwd on the dut_node. - :param nodes_info: All the nodes info in the topology file. - :param dut_node: Will execute the l3fwd on this node - :param dut_if1: The test link interface 1. - :param dut_if2: The test link interface 2. - :param nb_cores: The cores number for the forwarding + :param nodes: All the nodes info in the topology file. + :param node: DUT node. + :param if1: The test link interface 1. + :param if2: The test link interface 2. :param lcores_list: The lcore list string for the l3fwd routing + :param nb_cores: The cores number for the forwarding :param queue_nums: The queues number for the NIC - :param jumbo_frames: Is jumbo frames or not. Accepted: yes / no - :type nodes_info: dict - :type dut_node: dict - :type dut_if1: str - :type dut_if2: str - :type nb_cores: str + :param jumbo_frames: Indication if the jumbo frames are used (True) or + not (False). + :type nodes: dict + :type node: dict + :type if1: str + :type if2: str :type lcores_list: str + :type nb_cores: str :type queue_nums: str - :type jumbo_frames: str - :return: none + :type jumbo_frames: bool """ + if node[u"type"] == NodeType.DUT: + adj_mac0, adj_mac1, if_pci0, if_pci1 = L3fwdTest.get_adj_mac( + nodes, node, if1, if2 + ) + + list_cores = [int(item) for item in lcores_list.split(u",")] + + # prepare the port config param + nb_cores = int(nb_cores) + index = 0 + port_config = '' + for port in range(0, 2): + for queue in range(0, int(queue_nums)): + index = 0 if nb_cores == 1 else index + port_config += f"({port}, {queue}, {list_cores[index]})," + index += 1 + + if jumbo_frames: + l3fwd_args = DpdkUtil.get_l3fwd_args( + eal_corelist=f"1,{lcores_list}", + eal_driver=False, + eal_pci_whitelist0=if_pci0, + eal_pci_whitelist1=if_pci1, + eal_in_memory=True, + pmd_config=f"\\\"{port_config.rstrip(u',')}\\\"", + pmd_eth_dest_0=f"\\\"0,{adj_mac0}\\\"", + pmd_eth_dest_1=f"\\\"1,{adj_mac1}\\\"", + pmd_parse_ptype=True, + pmd_enable_jumbo=jumbo_frames, + pmd_max_pkt_len=jumbo_frames + ) + else: + l3fwd_args = DpdkUtil.get_l3fwd_args( + eal_corelist=f"1,{lcores_list}", + eal_driver=False, + eal_pci_whitelist0=if_pci0, + eal_pci_whitelist1=if_pci1, + eal_in_memory=True, + pmd_config=f"\\\"{port_config.rstrip(u',')}\\\"", + pmd_eth_dest_0=f"\\\"0,{adj_mac0}\\\"", + pmd_eth_dest_1=f"\\\"1,{adj_mac1}\\\"", + pmd_parse_ptype=True + ) + + command = f"{Constants.REMOTE_FW_DIR}/{Constants.RESOURCES_LIB_SH}"\ + f"/entry/run_l3fwd.sh \"{l3fwd_args} -P -L -p 0x3\"" + message = f"Failed to execute l3fwd test at node {node['host']}" + exec_cmd_no_error(node, command, timeout=1800, message=message) - if_key0 = dut_if1 - if_key1 = dut_if2 - if_pci0 = Topology.get_interface_pci_addr(dut_node, if_key0) - if_pci1 = Topology.get_interface_pci_addr(dut_node, if_key1) - # detect which is the port 0 + @staticmethod + def get_adj_mac(nodes, node, if1, if2): + """ + Get adjacency MAC addresses of the DUT node. + + :param nodes: All the nodes info in the topology file. + :param node: DUT node. + :param if1: The test link interface 1. + :param if2: The test link interface 2. + :type nodes: dict + :type node: dict + :type if1: str + :type if2: str + :returns: Returns MAC addresses of adjacency DUT nodes and PCI + addresses. + :rtype: str + """ + if_key0 = if1 + if_key1 = if2 + if_pci0 = Topology.get_interface_pci_addr(node, if_key0) + if_pci1 = Topology.get_interface_pci_addr(node, if_key1) + + # Detect which is the port 0. if min(if_pci0, if_pci1) != if_pci0: if_key0, if_key1 = if_key1, if_key0 - if_pci0, if_pci1 = if_pci1, if_pci0 - - adj_node0, adj_if_key0 = Topology.get_adjacent_node_and_interface( \ - nodes_info, dut_node, if_key0) - adj_node1, adj_if_key1 = Topology.get_adjacent_node_and_interface( \ - nodes_info, dut_node, if_key1) - + L3fwdTest.patch_l3fwd(node, u"patch_l3fwd_flip_routes") + + adj_node0, adj_if_key0 = Topology.get_adjacent_node_and_interface( + nodes, node, if_key0 + ) + adj_node1, adj_if_key1 = Topology.get_adjacent_node_and_interface( + nodes, node, if_key1 + ) + if_pci0 = Topology.get_interface_pci_addr(node, if_key0) + if_pci1 = Topology.get_interface_pci_addr(node, if_key1) adj_mac0 = Topology.get_interface_mac(adj_node0, adj_if_key0) adj_mac1 = Topology.get_interface_mac(adj_node1, adj_if_key1) - list_cores = lcores_list.split(',') - - # prepare the port config param - index = 0 - port_config = '' - for port in range(0, 2): - for queue in range(0, int(queue_nums)): - if int(nb_cores) == 1: - index = 0 - temp_str = '({0}, {1}, {2}),'.format(port, queue, \ - int(list_cores[index])) - else: - temp_str = '({0}, {1}, {2}),'.format(port, queue, \ - int(list_cores[index])) - - port_config += temp_str - index = index + 1 - - port_config_param = port_config.rstrip(',') - - ssh = SSH() - ssh.connect(dut_node) + return adj_mac0, adj_mac1, if_pci0, if_pci1 - cmd = 'cd {0}/dpdk-tests/dpdk_scripts/ && ./run_l3fwd.sh ' \ - '"{1}" "{2}" {3} {4} {5}'.format(con.REMOTE_FW_DIR, lcores_list, \ - port_config_param, adj_mac0, adj_mac1, jumbo_frames) - - (ret_code, _, stderr) = ssh.exec_command(cmd, timeout=600) - if ret_code != 0: - logger.error('Execute the l3fwd error: {0}'.format(stderr)) - raise Exception('Failed to execute l3fwd test at node {0}' - .format(dut_node['host'])) + @staticmethod + def patch_l3fwd(node, patch): + """ + Patch l3fwd application and recompile. + :param node: DUT node. + :param patch: Patch to apply. + :type node: dict + :type patch: str + :raises RuntimeError: Patching of l3fwd failed. + """ + command = f"{Constants.REMOTE_FW_DIR}/{Constants.RESOURCES_LIB_SH}"\ + f"/entry/patch_l3fwd.sh " \ + f"{Constants.REMOTE_FW_DIR}/{Constants.RESOURCES_LIB_SH}"\ + f"/entry/{patch}" + message = f"Failed to patch l3fwd at node {node['host']}" + ret_code, stdout, _ = exec_cmd(node, command, timeout=1800) + if ret_code != 0 and u"Skipping patch." not in stdout: + raise RuntimeError(message)