From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id F13C01B1DF for ; Thu, 21 Dec 2017 03:16:41 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Dec 2017 18:16:40 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.45,434,1508828400"; d="scan'208";a="4542534" Received: from dpdk-test47.sh.intel.com ([10.67.118.152]) by orsmga006.jf.intel.com with ESMTP; 20 Dec 2017 18:16:39 -0800 From: wang fei To: dts@dpdk.org Cc: wang fei Date: Thu, 21 Dec 2017 12:47:11 +0800 Message-Id: <1513831631-61940-1-git-send-email-feix.y.wang@intel.com> X-Mailer: git-send-email 2.7.4 Subject: [dts] [PATCH V1] for next branch: tests/TestSuite_nic_single_core_perf.py: add nic_single_core_perf test suite that tests with TREX 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: Thu, 21 Dec 2017 02:16:42 -0000 Signed-off-by: wang fei --- tests/TestSuite_nic_single_core_perf.py | 358 ++++++++++++++++++++++++++++++++ 1 file changed, 358 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..0ef51e8 --- /dev/null +++ b/tests/TestSuite_nic_single_core_perf.py @@ -0,0 +1,358 @@ +# 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 copy import deepcopy +from prettytable import PrettyTable + +class TestNicSingleCorePerf(TestCase): + + def set_up_all(self): + """ + Run at the start of each test suite. + PMD prerequisites. + """ + + 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 = 1 + + # 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("Ixia 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) + + def set_up(self): + """ + Run before each test case. + """ + pass + + def test_nic_single_core_perf(self): + """ + Run single core performance + """ + if len(self.dut_ports) >= 4 and self._get_nic_driver(self.nic) == "ixgbe": + self.nic_single_core_perf_4ports() + + elif len(self.dut_ports) >= 2 and self._get_nic_driver(self.nic) == "i40e": + self.nic_single_core_perf_2ports() + + def nic_single_core_perf_4ports(self): + """ + PMD Performance Benchmarking with 4 ports. + """ + # traffic option + options = { + 'rate' : '100%', + 'ip': {'action': 'inc', 'mask' : '255.255.255.0', 'step': '0.0.0.1'} + } + + # 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.rst_report(info, annex=True) + self.logger.info(info) + #self.rst_report(command_line + "\n\n", frame=True, annex=True) + + 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() + + txport0 = self.tester.get_local_port(self.dut.get_ports()[0]) + txport1 = self.tester.get_local_port(self.dut.get_ports()[1]) + txport2 = self.tester.get_local_port(self.dut.get_ports()[2]) + txport3 = self.tester.get_local_port(self.dut.get_ports()[3]) + stream_id0 = self.tester.pktgen.add_stream(txport0, txport1, r'/root/test.pcap') + stream_id1 = self.tester.pktgen.add_stream(txport1, txport0, r'/root/test.pcap') + stream_id2 = self.tester.pktgen.add_stream(txport2, txport3, r'/root/test.pcap') + stream_id3 = self.tester.pktgen.add_stream(txport3, txport2, r'/root/test.pcap') + self.tester.pktgen.config_stream(stream_id0, options) + self.tester.pktgen.config_stream(stream_id1, options) + self.tester.pktgen.config_stream(stream_id2, options) + self.tester.pktgen.config_stream(stream_id3, options) + + # send the traffic + _, packets_received = self.tester.pktgen.measure_throughput(stream_ids=[stream_id0, stream_id1, stream_id2, stream_id3], delay=self.trafficDuration) + + throughput = packets_received / 1000000.0 + 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 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,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 nic_single_core_perf_2ports(self): + """ + PMD Performance Benchmarking with 2 ports. + """ + pci0 = self.dut.ports_info[0]['pci'] + pci1 = self.dut.ports_info[1]['pci'] + eal = "-w %s -w %s" % (pci0, pci1) + + # traffic option + options = { + 'rate' : '100%', + #'ip': {'action': 'inc', 'mask' : '255.255.255.0', 'step': '0.0.0.1'} + } + + # 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 --txd=%d --rxd=%d" % (queues, queues, port_mask, descriptor, descriptor), eal, 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.rst_report(info, annex=True) + #self.rst_report(command_line + "\n\n", frame=True, annex=True) + + 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() + + txport0 = self.tester.get_local_port(self.dut.get_ports()[0]) + txport1 = self.tester.get_local_port(self.dut.get_ports()[1]) + stream_id0 = self.tester.pktgen.add_stream(txport0, txport1, r'/root/test.pcap') + stream_id1 = self.tester.pktgen.add_stream(txport1, txport0, r'/root/test.pcap') + self.tester.pktgen.config_stream(stream_id0, options) + self.tester.pktgen.config_stream(stream_id1, options) + + # send the traffic + _, packets_received = self.tester.pktgen.measure_throughput(stream_ids=[stream_id0, stream_id1], delay=self.trafficDuration) + + throughput = packets_received / 1000000.0 + 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 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