From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 98EC123B for ; Wed, 20 Sep 2017 12:09:07 +0200 (CEST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Sep 2017 03:09:04 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.42,420,1500966000"; d="scan'208";a="1197117717" Received: from dpdk-test47.sh.intel.com ([10.67.118.152]) by fmsmga001.fm.intel.com with ESMTP; 20 Sep 2017 03:09:03 -0700 From: wang fei To: dts@dpdk.org Cc: wang fei Date: Wed, 20 Sep 2017 20:41:32 +0800 Message-Id: <1505911292-51156-1-git-send-email-feix.y.wang@intel.com> X-Mailer: git-send-email 2.7.4 Subject: [dts] [Patch V1] tests/TestSuite_nic_single_core_perf.py : add new test suite for nic_single_core_perf X-BeenThere: dts@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: test suite reviews and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 20 Sep 2017 10:09:08 -0000 Signed-off-by: wang fei --- tests/TestSuite_nic_single_core_perf.py | 374 ++++++++++++++++++++++++++++++++ 1 file changed, 374 insertions(+) create mode 100644 tests/TestSuite_nic_single_core_perf.py diff --git a/tests/TestSuite_nic_single_core_perf.py b/tests/TestSuite_nic_single_core_perf.py new file mode 100644 index 0000000..862335d --- /dev/null +++ b/tests/TestSuite_nic_single_core_perf.py @@ -0,0 +1,374 @@ +# BSD LICENSE +# +# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +""" +DPDK Test suite. +Test userland 10Gb PMD +""" + +import utils +import re +import time +from test_case import TestCase +from time import sleep +from settings import HEADER_SIZE +from pmd_output import PmdOutput +from etgen import IxiaPacketGenerator +from copy import deepcopy +from prettytable import PrettyTable + + +class NicSingleCorePerf(TestCase,IxiaPacketGenerator): + + def set_up_all(self): + """ + Run at the start of each test suite. + + PMD prerequisites. + """ + self.tester.extend_external_packet_generator(NicSingleCorePerf, self) + + self.frame_sizes = [64] + self.ixgbe_descriptors = [128,512,2048] + self.i40e_descriptors = [512,2048] + #number to launch testpmd for each descriptor test + self.runs = 3 + #traffic duraion in second + self.trafficDuration = 60 + self.test_cycles = [{'cores': '1S/2C/1T', 'descriptor': {},'bytes':{}, 'Mpps': {}, 'pct': {}} + ] + #list expected throughput values for 64byte packet size and diff txd/rxd values + self.expected_throughput_nnt = {64:{128: 51.303,512: 34.603,2048: 34.539}} + self.expected_throughput_fvl40g = {64:{512: 43.614,2048: 38.407}} + self.expected_throughput_fvl25g = {64:{512: 43.365,2048: 38.658}} + + self.table_header = ['Frame Size'] + for test_cycle in self.test_cycles: + self.table_header.append("txd/rxd") + self.table_header.append("Throughput") + self.table_header.append("% linerate") + self.table_header.append("Expected throughput") + + # Update config file and rebuild to get best perf on FVL + self.dut.send_expect("sed -i -e 's/CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=n/CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=y/' ./config/common_base", "#", 20) + self.dut.build_install_dpdk(self.target) + + # Based on h/w type, choose how many ports to use + self.dut_ports = self.dut.get_ports() + + self.headers_size = HEADER_SIZE['eth'] + HEADER_SIZE[ + 'ip'] + HEADER_SIZE['tcp'] + + self.ports_socket = self.dut.get_numa_id(self.dut_ports[0]) + + self.pmdout = PmdOutput(self.dut) + + pdb.set_trace() + def set_up(self): + """ + Run before each test case. + """ + pass + + def test_nic_single_core_performance(self): + """ + Run single core performance + """ + if len(self.dut_ports) >= 4 and self._get_nic_driver(self.nic) == "ixgbe": + self.single_core_performance_4ports() + elif len(self.dut_ports) >= 2 and self._get_nic_driver(self.nic) == "i40e": + self.single_core_performance_2ports() + + def single_core_performance_4ports(self): + """ + PMD Performance Benchmarking with 4 ports. + """ + all_cores_mask = utils.create_mask(self.dut.get_core_list("all")) + + # prepare traffic generator input + tgen_input = [] + + tgen_input.append((self.tester.get_local_port(self.dut_ports[0]), + self.tester.get_local_port(self.dut_ports[1]), + "test.pcap")) + tgen_input.append((self.tester.get_local_port(self.dut_ports[2]), + self.tester.get_local_port(self.dut_ports[3]), + "test.pcap")) + tgen_input.append((self.tester.get_local_port(self.dut_ports[1]), + self.tester.get_local_port(self.dut_ports[0]), + "test.pcap")) + tgen_input.append((self.tester.get_local_port(self.dut_ports[3]), + self.tester.get_local_port(self.dut_ports[2]), + "test.pcap")) + #record test results + results = {} + + # run testpmd for each core config + for test_cycle in self.test_cycles: + core_config = test_cycle['cores'] + + core_list = self.dut.get_core_list(core_config, + socket=self.ports_socket) + + if len(core_list) > 4: + queues = len(core_list) / 4 + else: + queues = 1 + + core_mask = utils.create_mask(core_list) + port_mask = utils.create_mask(self.dut.get_ports()) + + for descriptor in self.ixgbe_descriptors: + run_results = [] + for run in range(self.runs): + self.logger.info("testpmd launch #%d for Descriptor length:%d" % (run,descriptor)) + self.pmdout.start_testpmd(core_config, " --rxq=%d --txq=%d --portmask=%s --rss-ip --txrst=32 --txfreet=32 --txd=%d --rxd=%d --txqflags=0xf01" % (queues, queues, port_mask,descriptor,descriptor), socket=self.ports_socket) + command_line = self.pmdout.get_pmd_cmd() + + info = "Executing PMD using %s\n" % test_cycle['cores'] + self.logger.info(info) + + # self.dut.send_expect("set fwd mac", "testpmd> ", 100) + self.dut.send_expect("start", "testpmd> ", 100) + for frame_size in self.frame_sizes: + wirespeed = self.wirespeed(self.nic, frame_size, 4) + + # create pcap file + self.logger.info("Running with frame size %d " % frame_size) + payload_size = frame_size - self.headers_size + self.tester.scapy_append( + 'wrpcap("test.pcap", [Ether(src="52:00:00:00:00:00")/IP(src="1.2.3.4",dst="1.1.1.1")/TCP()/("X"*%d)])' % payload_size) + self.tester.scapy_execute() + + #create packet number to send + nicSpeed = self.get_nic_speed(self.nic) + pktToSend = self.packets_to_send(nicSpeed,frame_size,self.trafficDuration) + self.logger.info("Configure %s packets to send for each port" % pktToSend) + + #send the traffic + _,packets_received= self.tester.traffic_generator_send_packets(tgen_input,100,pktToSend,5,self.trafficDuration) + + throughput = packets_received/1000000.0/self.trafficDuration + run_results.append(throughput) + + self.dut.send_expect("stop", "testpmd> ") + self.dut.send_expect("quit", "# ", 30) + sleep(5) + self.logger.info("Throughput results for Descriptor :%s are :%s Mpps" % (descriptor,run_results)) + Mpps = max(run_results) + test_cycle['Mpps'][frame_size] = float("%.3f" % Mpps) + test_cycle['pct'][frame_size] = float("%.3f" % (Mpps * 100 / wirespeed)) + test_cycle['descriptor'][frame_size] = descriptor + test_cycle['bytes'][frame_size] = frame_size + + results[descriptor] = deepcopy(test_cycle) + + for descriptor in self.ixgbe_descriptors: + for frame_size in self.frame_sizes: + self.verify(results[descriptor]['Mpps'][ + frame_size] > 0, "No traffic detected") + + # Print results + table_rows = [] + self.result_table_create(self.table_header) + for descriptor in self.ixgbe_descriptors: + for frame_size in self.frame_sizes: + table_row = [results[descriptor]['bytes'][frame_size]] + table_row.append(results[descriptor]['descriptor'][frame_size]) + table_row.append(results[descriptor]['Mpps'][frame_size]) + table_row.append(results[descriptor]['pct'][frame_size]) + table_row.append(self.expected_throughput_nnt[frame_size][descriptor]) + + self.result_table_add(table_row) + table_rows.append(table_row) + + self.result_table_print() + + #export the result table into a separate .txt file in output folde + out_export = PrettyTable(self.table_header) + for row in table_rows: + out_export.add_row(row) + output_file = open("output/%s_single_core_perf.txt" % self.nic,'w') + output_file.write(str(out_export)) + output_file.close() + + #compare actual throughput and expected throughput,will raise failure is the gap lager than 1Mpps + for frame_size in self.frame_sizes: + for descriptor in self.ixgbe_descriptors: + self.verify(self.expected_throughput_nnt[frame_size][descriptor] - results[descriptor]['Mpps'][frame_size] < 1,"Unexpected Throughput,Gap exceeded 1 Mpps") + + def single_core_performance_2ports(self): + """ + PMD Performance Benchmarking with 2 ports. + """ + + all_cores_mask = utils.create_mask(self.dut.get_core_list("all")) + + # prepare traffic generator input + tgen_input = [] + tgen_input.append((self.tester.get_local_port(self.dut_ports[0]), + self.tester.get_local_port(self.dut_ports[1]), + "test.pcap")) + tgen_input.append((self.tester.get_local_port(self.dut_ports[1]), + self.tester.get_local_port(self.dut_ports[0]), + "test.pcap")) + + #record test results + results = {} + + # run testpmd for each core config + for test_cycle in self.test_cycles: + core_config = test_cycle['cores'] + + core_list = self.dut.get_core_list(core_config, + socket=self.ports_socket) + + if len(core_list) > 2: + queues = len(core_list) / 2 + else: + queues = 1 + + core_mask = utils.create_mask(core_list) + port_mask = utils.create_mask([self.dut_ports[0], self.dut_ports[1]]) + + for descriptor in self.i40e_descriptors: + run_results = [] + for run in range(self.runs): + self.logger.info("testpmd launch #%d for Descriptor length:%d" % (run,descriptor)) + self.pmdout.start_testpmd(core_config, " --rxq=%d --txq=%d --portmask=%s --rss-ip --txrst=32 --txfreet=32 --txd=%d --rxd=%d" % (queues, queues, port_mask,descriptor,descriptor), socket=self.ports_socket) + command_line = self.pmdout.get_pmd_cmd() + + info = "Executing PMD using %s\n" % test_cycle['cores'] + self.logger.info(info) + + self.dut.send_expect("start", "testpmd> ", 100) + + + for frame_size in self.frame_sizes: + wirespeed = self.wirespeed(self.nic, frame_size, 2) + + # create pcap file + self.logger.info("Running with frame size %d " % frame_size) + payload_size = frame_size - self.headers_size + self.tester.scapy_append( + 'wrpcap("test.pcap", [Ether(src="52:00:00:00:00:00")/IP(src="1.2.3.4",dst="1.1.1.1")/TCP()/("X"*%d)])' % payload_size) + self.tester.scapy_execute() + + #create packet number to send + nicSpeed = self.get_nic_speed(self.nic) + pktToSend = self.packets_to_send(nicSpeed,frame_size,self.trafficDuration) + self.logger.info("Configure %s packets to send for each port" % pktToSend) + + #send the traffic + pdb.set_trace() + _,packets_received= self.tester.traffic_generator_send_packets(tgen_input,100,pktToSend,5,self.trafficDuration) + throughput = packets_received/1000000.0/self.trafficDuration + run_results.append(throughput) + self.dut.send_expect("stop", "testpmd> ") + self.dut.send_expect("quit", "# ", 30) + sleep(5) + self.logger.info("Throughput results for Descriptor :%s are :%s Mpps" % (descriptor,run_results)) + Mpps = max(run_results) + test_cycle['Mpps'][frame_size] = float("%.3f" % Mpps) + test_cycle['pct'][frame_size] = float("%.3f" % (Mpps * 100 / wirespeed)) + test_cycle['descriptor'][frame_size] = descriptor + test_cycle['bytes'][frame_size] = frame_size + + results[descriptor] = deepcopy(test_cycle) + + for descriptor in self.i40e_descriptors: + for frame_size in self.frame_sizes: + self.verify(results[descriptor]['Mpps'][ + frame_size] > 0, "No traffic detected") + + # Print results + table_rows = [] + self.result_table_create(self.table_header) + for descriptor in self.i40e_descriptors: + for frame_size in self.frame_sizes: + table_row = [results[descriptor]['bytes'][frame_size]] + table_row.append(results[descriptor]['descriptor'][frame_size]) + table_row.append(results[descriptor]['Mpps'][frame_size]) + table_row.append(results[descriptor]['pct'][frame_size]) + if self.nic == 'fortville_spirit': + table_row.append(self.expected_throughput_fvl40g[frame_size][descriptor]) + elif self.nic == 'fortville_25g': + table_row.append(self.expected_throughput_fvl25g[frame_size][descriptor]) + self.result_table_add(table_row) + table_rows.append(table_row) + self.result_table_print() + + #export the result table into a separate .txt file in output folder + out_export = PrettyTable(self.table_header) + for row in table_rows: + out_export.add_row(row) + output_file = open("output/%s_single_core_perf.txt" % self.nic,'w') + output_file.write(str(out_export)) + output_file.close() + + #compare actual throughput and expected throughput + for frame_size in self.frame_sizes: + for descriptor in self.i40e_descriptors: + if self.nic == 'fortville_spirit': + self.verify(self.expected_throughput_fvl40g[frame_size][descriptor] - results[descriptor]['Mpps'][frame_size] < 1,"Unexpected Throughput,Gap exceeded 1Mpps") + elif self.nic == 'fortville_25g': + self.verify(self.expected_throughput_fvl25g[frame_size][descriptor] - results[descriptor]['Mpps'][frame_size] < 1,"Unexpected Throughput,Gap exceeded 1Mpps") + + def packets_to_send(self,nicSpeed=10,packetLenth=64,duration=60): + """ + Caculate and return the theoretical number of packets for specified speed for certain duration of different packet length + """ + return int(float(nicSpeed)*1000000000/8/(packetLenth+20)*duration) + + + def get_nic_speed(self,nicType): + ''' + return port link speed for NNT and FVL40G and FVL25G NIC + ''' + if nicType== 'niantic': + return 10 + elif nicType == 'fortville_spirit': + return 40 + elif nicType == 'fortville_25g': + return 25 + + + def tear_down(self): + """ + Run after each test case. + """ + pass + + def tear_down_all(self): + """ + Run after each test suite. + """ + self.dut.kill_all() -- 2.7.4