From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 5549E9366 for ; Thu, 22 Oct 2015 04:10:22 +0200 (CEST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga102.fm.intel.com with ESMTP; 21 Oct 2015 19:10:16 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,180,1444719600"; d="scan'208";a="799774184" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by orsmga001.jf.intel.com with ESMTP; 21 Oct 2015 19:10:15 -0700 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shvmail01.sh.intel.com with ESMTP id t9M2AEGx009999; Thu, 22 Oct 2015 10:10:14 +0800 Received: from shecgisg004.sh.intel.com (localhost [127.0.0.1]) by shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id t9M2AAfC005497; Thu, 22 Oct 2015 10:10:13 +0800 Received: (from hengdinx@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id t9M2AACg005493; Thu, 22 Oct 2015 10:10:10 +0800 From: Ding Heng To: dts@dpdk.org Date: Thu, 22 Oct 2015 10:10:09 +0800 Message-Id: <1445479809-5459-1-git-send-email-hengx.ding@intel.com> X-Mailer: git-send-email 1.7.4.1 Cc: Ding Heng Subject: [dts] [PATCH] L3fwd: Add RFC2544 support and able to print loss packets in linerate now. 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, 22 Oct 2015 02:10:23 -0000 Now l3fwd could do RFC2544 test and get zero loss rate. File etgen.py and tester.py has been made some changes to met this function. Signed-off-by: Ding Heng diff --git a/framework/etgen.py b/framework/etgen.py index 508439b..ee58dfd 100644 --- a/framework/etgen.py +++ b/framework/etgen.py @@ -33,7 +33,7 @@ import re import string import time import dts -from config import IxiaConf +import ixiacfg from ssh_connection import SSHConnection from settings import SCAPY2IXIA from logger import getLogger @@ -147,19 +147,16 @@ class IxiaPacketGenerator(SSHConnection): self.conRelation = {} ixiaRef = self.tester.get_external_traffic_generator() - - ixiacfg = IxiaConf() - ixiaPorts = ixiacfg.load_ixia_config() - if ixiaRef is None or ixiaRef not in ixiaPorts: + if ixiaRef is None or ixiaRef not in ixiacfg.ixiaPorts: return - self.ixiaVersion = ixiaPorts[ixiaRef]["Version"] - self.ports = ixiaPorts[ixiaRef]["Ports"] + self.ixiaVersion = ixiacfg.ixiaPorts[ixiaRef]["Version"] + self.ports = ixiacfg.ixiaPorts[ixiaRef]["Ports"] self.logger.info(self.ixiaVersion) self.logger.info(self.ports) - self.tclServerIP = ixiaPorts[ixiaRef]["IP"] + self.tclServerIP = ixiacfg.ixiaPorts[ixiaRef]["IP"] # prepare tcl shell and ixia library self.send_expect("tclsh", "% ") @@ -476,18 +473,18 @@ class IxiaPacketGenerator(SSHConnection): return {'card': int(m.group(1)), 'port': int(m.group(2))} - def loss(self, portList, ratePercent): + def loss(self, portList, ratePercent, delay=5): """ Run loss performance test and return loss rate. """ rxPortlist, txPortlist = self._configure_everything(portList, ratePercent) - return self.get_loss_packet_rate(rxPortlist, txPortlist) + return self.get_loss_packet_rate(rxPortlist, txPortlist, delay) - def get_loss_packet_rate(self, rxPortlist, txPortlist): + def get_loss_packet_rate(self, rxPortlist, txPortlist, delay=5): """ Get RX/TX packet statistics and calculate loss rate. """ - time.sleep(3) + time.sleep(delay) self.send_expect("ixStopTransmit portList", "%", 10) time.sleep(2) @@ -507,7 +504,7 @@ class IxiaPacketGenerator(SSHConnection): revNumber += self.get_frames_received() self.logger.info("rev :%f" % revNumber) - return float(sendNumber - revNumber) / sendNumber + return float(sendNumber - revNumber) / sendNumber, sendNumber, revNumber def latency(self, portList, ratePercent, delay=5): """ @@ -801,7 +798,10 @@ class IxiaPacketGenerator(SSHConnection): Returns the number of packets captured by IXIA on a previously set port. Call self.stat_get_stat_all_stats(port) before. """ - return self._stat_cget_value('framesReceived') + if self._stat_cget_value('framesReceived') !=0: + return self._stat_cget_value('framesReceived') + else: + return self._stat_cget_value('oversize') def get_flow_control_frames(self): """ diff --git a/framework/tester.py b/framework/tester.py index de0bc24..665cdf3 100644 --- a/framework/tester.py +++ b/framework/tester.py @@ -424,12 +424,12 @@ class Tester(Crb): return None return self.packet_gen.throughput(portList, rate_percent) - def traffic_generator_loss(self, portList, ratePercent): + def traffic_generator_loss(self, portList, ratePercent, delay=60): """ Run loss performance test on specified ports. """ if self.check_port_list(portList, 'ixia'): - return self.ixia_packet_gen.loss(portList, ratePercent) + return self.ixia_packet_gen.loss(portList, ratePercent, delay) elif not self.check_port_list(portList): self.logger.warning("exception by mixed port types") return None diff --git a/tests/TestSuite_l3fwd.py b/tests/TestSuite_l3fwd.py index 65fa6f7..9c1955d 100644 --- a/tests/TestSuite_l3fwd.py +++ b/tests/TestSuite_l3fwd.py @@ -1,36 +1,9 @@ -# 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. + + Layer-3 forwarding test script. """ @@ -41,72 +14,55 @@ from plotting import Plotting from test_case import TestCase from exception import VerifyFailure from settings import HEADER_SIZE +from etgen import IxiaPacketGenerator + +import time + +# +# +# Test class. +# class TestL3fwd(TestCase): path = "./examples/l3fwd/build/" - test_cases_2_ports = {"1S/1C/1T": "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}), (P1,0,C{1.1.0})'", - "1S/1C/2T": "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}), (P1,0,C{1.1.1})'", - "1S/2C/1T": "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}), (P1,0,C{1.2.0})'" - } - - test_cases_4_ports = [(1, "1S/1C/1T", - "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P1,0,C{1.1.0}),(P2,0,C{1.1.0}),(P3,0,C{1.1.0})'"), - (1, "1S/1C/2T", - "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P1,0,C{1.1.0}),(P2,0,C{1.1.1}),(P3,0,C{1.1.1})'"), - (1, "1S/2C/1T", - "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P1,0,C{1.1.0}),(P2,0,C{1.2.0}),(P3,0,C{1.2.0})'"), - (1, "1S/2C/2T", - "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P1,0,C{1.1.1}),(P2,0,C{1.2.0}),(P3,0,C{1.2.1})'"), - (1, "1S/4C/1T", - "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P1,0,C{1.2.0}),(P2,0,C{1.3.0}),(P3,0,C{1.4.0})'"), - (1, "2S/1C/1T", - "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{0.1.0}),(P1,0,C{0.1.0}),(P2,0,C{1.1.0}),(P3,0,C{1.1.0})'"), - (1, "2S/1C/2T", - "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{0.1.0}),(P1,0,C{0.1.1}),(P2,0,C{1.1.0}),(P3,0,C{1.1.1})'"), - (1, "2S/2C/1T", - "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{0.1.0}),(P1,0,C{0.2.0}),(P2,0,C{1.1.0}),(P3,0,C{1.2.0})'"), - (2, "1S/1C/1T", - "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P0,1,C{1.1.0}),(P1,0,C{1.1.0}),(P1,1,C{1.1.0}),(P2,0,C{1.1.0}),(P2,1,C{1.1.0}),(P3,0,C{1.1.0}),(P3,1,C{1.1.0})'"), - (2, "1S/1C/2T", - "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P0,1,C{1.1.0}),(P1,0,C{1.1.0}),(P1,1,C{1.1.0}),(P2,0,C{1.1.1}),(P2,1,C{1.1.1}),(P3,0,C{1.1.1}),(P3,1,C{1.1.1})'"), - (2, "1S/2C/1T", - "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P0,1,C{1.1.0}),(P1,0,C{1.1.0}),(P1,1,C{1.1.0}),(P2,0,C{1.2.0}),(P2,1,C{1.2.0}),(P3,0,C{1.2.0}),(P3,1,C{1.2.0})'"), - (2, "1S/2C/2T", - "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P0,1,C{1.1.0}),(P1,0,C{1.1.1}),(P1,1,C{1.1.1}),(P2,0,C{1.2.0}),(P2,1,C{1.2.0}),(P3,0,C{1.2.1}),(P3,1,C{1.2.1})'"), - (2, "1S/4C/1T", - "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P0,1,C{1.1.0}),(P1,0,C{1.2.0}),(P1,1,C{1.2.0}),(P2,0,C{1.3.0}),(P2,1,C{1.3.0}),(P3,0,C{1.4.0}),(P3,1,C{1.4.0})'"), - (2, "1S/4C/2T", - "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P0,1,C{1.1.1}),(P1,0,C{1.2.0}),(P1,1,C{1.2.1}),(P2,0,C{1.3.0}),(P2,1,C{1.3.1}),(P3,0,C{1.4.0}),(P3,1,C{1.4.1})'"), - (2, "2S/1C/1T", - "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{0.1.0}),(P0,1,C{0.1.0}),(P1,0,C{0.1.0}),(P1,1,C{0.1.0}),(P2,0,C{1.1.0}),(P2,1,C{1.1.0}),(P3,0,C{1.1.0}),(P3,1,C{1.1.0})'"), - (2, "2S/1C/2T", - "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{0.1.0}),(P0,1,C{0.1.0}),(P1,0,C{0.1.1}),(P1,1,C{0.1.1}),(P2,0,C{1.1.0}),(P2,1,C{1.1.0}),(P3,0,C{1.1.1}),(P3,1,C{1.1.1})'"), - (2, "2S/2C/1T", - "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{0.1.0}),(P0,1,C{0.1.0}),(P1,0,C{0.2.0}),(P1,1,C{0.2.0}),(P2,0,C{1.1.0}),(P2,1,C{1.1.0}),(P3,0,C{1.2.0}),(P3,1,C{1.2.0})'"), - (2, "2S/2C/2T", - "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{0.1.0}),(P0,1,C{0.1.1}),(P1,0,C{0.2.0}),(P1,1,C{0.2.1}),(P2,0,C{1.1.0}),(P2,1,C{1.1.1}),(P3,0,C{1.2.0}),(P3,1,C{1.2.1})'"), - (2, "2S/4C/1T", - "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{0.1.0}),(P0,1,C{0.2.0}),(P1,0,C{0.3.0}),(P1,1,C{0.4.0}),(P2,0,C{1.1.0}),(P2,1,C{1.2.0}),(P3,0,C{1.3.0}),(P3,1,C{1.4.0})'") - ] - - queues_4_ports = [] - - for case in test_cases_4_ports: - if case[0] * 4 not in queues_4_ports: - queues_4_ports.append(case[0] * 4) + test_cases_1_ports_1S_2C_1T = { + "1S/2C/1T": "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}), (P0,1,C{1.2.0})'" + } + + test_cases_1_ports_1S_1C_1T = { + "1S/1C/1T": "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0})'" + } + + test_cases_2_ports_1S_4C_1T = { + "1S/4C/1T": "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}), (P0,1,C{1.2.0}),(P1,0,C{1.3.0}),(P1,1,C{1.4.0})'" + } + + test_cases_2_ports_1S_2C_1T = { + "1S/2C/1T": "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}), (P1,0,C{1.2.0})'" + } + + test_cases_4_ports_1S_4C_1T = [ + (4, "1S/4C/1T", + "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P1,0,C{1.2.0}),(P2,0,C{1.3.0}),(P3,0,C{1.4.0})'") + ] + + test_cases_4_ports_1S_1C_1T = [ + (1, "1S/1C/1T", + "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P1,0,C{1.1.0}),(P2,0,C{1.1.0}),(P3,0,C{1.1.0})'") + ] host_table = [ - "{{IPv4(10,100,0,1), IPv4(1,2,3,4), 1, 10, IPPROTO_UDP}, P0}", - "{{IPv4(10,101,0,1), IPv4(1,2,3,4), 1, 10, IPPROTO_UDP}, P0}", - "{{IPv4(11,100,0,1), IPv4(1,2,3,4), 1, 11, IPPROTO_UDP}, P1}", - "{{IPv4(11,101,0,1), IPv4(1,2,3,4), 1, 11, IPPROTO_UDP}, P1}", - "{{IPv4(12,100,0,1), IPv4(1,2,3,4), 1, 12, IPPROTO_UDP}, P2}", - "{{IPv4(12,101,0,1), IPv4(1,2,3,4), 1, 12, IPPROTO_UDP}, P2}", - "{{IPv4(13,100,0,1), IPv4(1,2,3,4), 1, 13, IPPROTO_UDP}, P3}", - "{{IPv4(13,101,0,1), IPv4(1,2,3,4), 1, 13, IPPROTO_UDP}, P3}", + "{{IPv4(10,100,0,1), IPv4(0,0,0,0), 1, 10, IPPROTO_UDP}, P0}", + "{{IPv4(10,101,0,1), IPv4(0,0,0,0), 1, 10, IPPROTO_UDP}, P0}", + "{{IPv4(11,100,0,1), IPv4(0,0,0,0), 1, 11, IPPROTO_UDP}, P1}", + "{{IPv4(11,101,0,1), IPv4(0,0,0,0), 1, 11, IPPROTO_UDP}, P1}", + "{{IPv4(12,100,0,1), IPv4(0,0,0,0), 1, 12, IPPROTO_UDP}, P2}", + "{{IPv4(12,101,0,1), IPv4(0,0,0,0), 1, 12, IPPROTO_UDP}, P2}", + "{{IPv4(13,100,0,1), IPv4(0,0,0,0), 1, 13, IPPROTO_UDP}, P3}", + "{{IPv4(13,101,0,1), IPv4(0,0,0,0), 1, 13, IPPROTO_UDP}, P3}", ] lpm_table = [ @@ -120,9 +76,9 @@ class TestL3fwd(TestCase): "{IPv4(13,101,0,0), 24, P3}", ] - frame_sizes = [64] # 65, 128 - - methods = ['lpm', 'exact'] + frame_sizes = [64, 128, 256, 2048] + #frame_sizes = [64] + methods = ['lpm'] # # @@ -147,174 +103,32 @@ class TestL3fwd(TestCase): # Test cases. # - def plot_4_ports(self): - - data = self.l3fwd_test_results['data'] - - # Create a plot for each number of queues for frame size and mode comparison - cores = '1S/1C/1T' - for queues in TestL3fwd.queues_4_ports: - ydata = [] - lpm_ydata = [] - exact_ydata = [] - for frame_size in TestL3fwd.frame_sizes: - for row in data: - if row[1] * 4 == queues and row[2] == cores and \ - row[0] == frame_size: - if len(TestL3fwd.methods) == 2: - lpm_ydata.append(row[4]) - exact_ydata.append(row[6]) - else: - if 'lpm' in TestL3fwd.methods: - lpm_ydata.append(row[4]) - if 'exact' in TestL3fwd.methods: - exact_ydata.append(row[4]) - - if 'lpm' in TestL3fwd.methods: - ydata.append(lpm_ydata) - if 'exact' in TestL3fwd.methods: - ydata.append(exact_ydata) - - if len(ydata[0]) == 0: - self.logger.warning('No data for plotting 1S/1C/1T') - break - else: - try: - image_path = self.plotting.create_bars_plot( - 'test_perf_l3fwd_4ports_1S_1C_1T_%dRxQ' % queues, - 'LPM & Exact modes, 1S/1C/1T, %d Rx Queues, 4 ports' % queues, - TestL3fwd.frame_sizes, - ydata, - ylabel='% linerate', - legend=TestL3fwd.methods) - - dts.results_plot_print(image_path, 50) - except VerifyFailure as e: - self.logger.error(str(e)) - - # Create a plot for each number of queues for core config and mode comparison - frame_size = TestL3fwd.frame_sizes[0] # Frame size fixed to the first selected - for queues in TestL3fwd.queues_4_ports: - - cores = [] - for row in data: - if row[2] not in cores and \ - row[1] * 4 == queues: - cores.append(row[2]) - - ydata = [] - lpm_ydata = [] - exact_ydata = [] - - for core in cores: - for row in data: - if row[1] * 4 == queues and \ - row[2] == core and \ - row[0] == frame_size: - if len(TestL3fwd.methods) == 2: - lpm_ydata.append(row[4]) - exact_ydata.append(row[6]) - else: - if 'lpm' in TestL3fwd.methods: - lpm_ydata.append(row[4]) - if 'exact' in TestL3fwd.methods: - exact_ydata.append(row[4]) - - if 'lpm' in TestL3fwd.methods: - ydata.append(lpm_ydata) - if 'exact' in TestL3fwd.methods: - ydata.append(exact_ydata) - - try: - image_path = self.plotting.create_bars_plot( - 'test_perf_l3fwd_4ports_%d_%dRxQ' % (frame_size, queues), - 'LPM & Exact modes, %dB, %d Rx Queues, 4 ports' % (frame_size, queues), - cores, - ydata, - ylabel='% linerate', - legend=TestL3fwd.methods) - - dts.results_plot_print(image_path) - except VerifyFailure as e: - self.logger.error(str(e)) - - def plot_2_ports(self): - - data = self.l3fwd_test_results['data'] - - cores = [] - for row in data: - if row[2] not in cores: - cores.append(row[2]) - - # Create a plot for each mode for frame size and cores comparison - for mode in TestL3fwd.methods: - mode_ydata = [] - - for core in cores: - core_ydata = [] - for row in data: - if row[5] == mode and row[2] == core: - core_ydata.append(float(row[4])) - - mode_ydata.append(core_ydata) - - image_path = self.plotting.create_bars_plot( - 'test_perf_l3fwd_2ports_%s' % mode, - 'L3fwd %s mode, 2 ports' % mode, - TestL3fwd.frame_sizes, - mode_ydata, - ylabel='% linerate', - legend=cores) - - dts.results_plot_print(image_path, 50) - - # If testing only one mode, do nothing else. - if len(TestL3fwd.methods) == 1: - return - - # Create a plot for 1st core config for mode and frame size comparison - core = '1S/1C/1T' - - ydata = [] - for mode in TestL3fwd.methods: - mode_ydata = [] - for frame_size in TestL3fwd.frame_sizes: - for row in data: - if row[2] == core and row[0] == frame_size and \ - row[5] == mode: - mode_ydata.append(float(row[4])) - - ydata.append(mode_ydata) - - str_frame_sizes = [] - for frame_size in TestL3fwd.frame_sizes: - str_frame_sizes.append(str(frame_size)) - - image_path = self.plotting.create_bars_plot( - 'test_perf_l3fwd_2ports_1S_1C_1T', - 'L3fwd 1S/1C/1T cores, 2 ports', - TestL3fwd.frame_sizes, - ydata, - ylabel='% linerate', - legend=TestL3fwd.methods) - - dts.results_plot_print(image_path) - def set_up_all(self): """ Run at the start of each test suite. - - L3fwd Prerequisites """ + + self.dut.unbind_interfaces_linux() + self.dut.send_expect( + "sed -i 's/CONFIG_RTE_PCI_CONFIG=.*$/CONFIG_RTE_PCI_CONFIG=y/' ./config/common_linuxapp", "# ", 5) + self.dut.send_expect( + "sed -i 's/CONFIG_RTE_PCI_EXTENDED_TAG=.*$/CONFIG_RTE_PCI_EXTENDED_TAG=\"on\"/' ./config/common_linuxapp", "# ", 5) + self.dut.send_expect( + "sed -i 's/CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=.*$/CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=y/' ./config/common_linuxapp", "# ", 5) + self.dut.send_expect( + "sed -i 's/CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE=.*$/CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE=4096/' ./config/common_linuxapp", "# ", 5) + self.dut.send_expect("export RTE_TARGET=" + self.target, "#") + self.dut.send_expect("export RTE_SDK=`pwd`", "#") + self.dut.send_expect("rm -rf %s" % self.target, "# ", 5) + self.dut.build_install_dpdk(self.target) + time.sleep(10) + self.dut.bind_interfaces_linux() + # Based on h/w type, choose how many ports to use - ports = self.dut.get_ports(socket=1) + ports = self.dut.get_ports(self.nic, socket=1) if not ports: - ports = self.dut.get_ports(socket=0) - - # Verify that enough ports are available - self.verify(len(ports) >= 2, "Insufficient ports for speed testing") + ports = self.dut.get_ports(self.nic, socket=0) # Verify that enough threads are available cores = self.dut.get_core_list("2S/4C/2T") @@ -322,14 +136,16 @@ class TestL3fwd(TestCase): global valports valports = [_ for _ in ports if self.tester.get_local_port(_) != -1] - self.verify(len(valports) >= 2, "Insufficient active ports for speed testing") + self.verify( + len(valports) >= 2, "Insufficient active ports for speed testing") pat = re.compile("P([0123])") # Prepare long prefix match table, replace P(x) port pattern lpmStr = "static struct ipv4_l3fwd_route ipv4_l3fwd_route_array[] = {\\\n" for idx in range(len(TestL3fwd.lpm_table)): - TestL3fwd.lpm_table[idx] = pat.sub(self.portRepl, TestL3fwd.lpm_table[idx]) + TestL3fwd.lpm_table[idx] = pat.sub( + self.portRepl, TestL3fwd.lpm_table[idx]) lpmStr = lpmStr + ' ' * 4 + TestL3fwd.lpm_table[idx] + ",\\\n" lpmStr = lpmStr + "};" self.logger.debug(lpmStr) @@ -337,30 +153,37 @@ class TestL3fwd(TestCase): # Prepare host route table, replace P(x) port pattern exactStr = "static struct ipv4_l3fwd_route ipv4_l3fwd_route_array[] = {\\\n" for idx in range(len(TestL3fwd.host_table)): - TestL3fwd.host_table[idx] = pat.sub(self.portRepl, TestL3fwd.host_table[idx]) + TestL3fwd.host_table[idx] = pat.sub( + self.portRepl, TestL3fwd.host_table[idx]) exactStr = exactStr + ' ' * 4 + TestL3fwd.host_table[idx] + ",\\\n" exactStr = exactStr + "};" self.logger.debug(exactStr) # Compile l3fwd with LPM lookup. - self.dut.send_expect(r"sed -i '/ipv4_l3fwd_route_array\[\].*{/,/^\}\;/c\\%s' examples/l3fwd/main.c" % lpmStr, "# ") - out = self.dut.build_dpdk_apps("./examples/l3fwd", "USER_FLAGS=-DAPP_LOOKUP_METHOD=1") + self.dut.send_expect( + r"sed -i '/ipv4_l3fwd_route_array\[\].*{/,/^\}\;/c\\%s' examples/l3fwd/main.c" % lpmStr, "# ") + out = self.dut.build_dpdk_apps( + "./examples/l3fwd", "USER_FLAGS=-DAPP_LOOKUP_METHOD=1") self.verify("Error" not in out, "compilation error 1") self.verify("No such file" not in out, "compilation error 2") # Backup the LPM exe and clean up the build. - self.dut.send_expect("mv -f examples/l3fwd/build/l3fwd examples/l3fwd/build/l3fwd_lpm", "# ") + self.dut.send_expect( + "mv -f examples/l3fwd/build/l3fwd examples/l3fwd/build/l3fwd_lpm", "# ") out = self.dut.send_expect("make clean -C examples/l3fwd", "# ") - # Compile l3fwd with hash/exact lookup. - self.dut.send_expect(r"sed -i -e '/ipv4_l3fwd_route_array\[\].*{/,/^\}\;/c\\%s' examples/l3fwd/main.c" % exactStr, "# ") - out = self.dut.build_dpdk_apps("./examples/l3fwd", "USER_FLAGS=-DAPP_LOOKUP_METHOD=0") - - self.verify("Error" not in out, "compilation error 1") - self.verify("No such file" not in out, "compilation error 2") - - # Backup the Hash/Exact exe. - self.dut.send_expect("mv -f examples/l3fwd/build/l3fwd examples/l3fwd/build/l3fwd_exact", "# ") +# # Compile l3fwd with hash/exact lookup. +# self.dut.send_expect( +# r"sed -i -e '/ipv4_l3fwd_route_array\[\].*{/,/^\}\;/c\\%s' examples/l3fwd/main.c" % exactStr, "# ") +# out = self.dut.build_dpdk_apps( +# "./examples/l3fwd", "USER_FLAGS=-DAPP_LOOKUP_METHOD=0") +# +# self.verify("Error" not in out, "compilation error 1") +# self.verify("No such file" not in out, "compilation error 2") +# +# # Backup the Hash/Exact exe. +# self.dut.send_expect( +# "mv -f examples/l3fwd/build/l3fwd examples/l3fwd/build/l3fwd_exact", "# ") self.l3fwd_test_results = {'header': [], 'data': []} @@ -374,14 +197,14 @@ class TestL3fwd(TestCase): """ return [ - 'IP(src="1.2.3.4",dst="10.100.0.1")/UDP(sport=10,dport=1)', - 'IP(src="1.2.3.4",dst="10.101.0.1")/UDP(sport=10,dport=1)', - 'IP(src="1.2.3.4",dst="11.100.0.1")/UDP(sport=11,dport=1)', - 'IP(src="1.2.3.4",dst="11.101.0.1")/UDP(sport=11,dport=1)', - 'IP(src="1.2.3.4",dst="12.100.0.1")/UDP(sport=12,dport=1)', - 'IP(src="1.2.3.4",dst="12.101.0.1")/UDP(sport=12,dport=1)', - 'IP(src="1.2.3.4",dst="13.100.0.1")/UDP(sport=13,dport=1)', - 'IP(src="1.2.3.4",dst="13.101.0.1")/UDP(sport=13,dport=1)'] + 'IP(src="0.0.0.0",dst="11.100.0.1")', + 'IP(src="0.0.0.0",dst="11.101.0.1")', + 'IP(src="0.0.0.0",dst="10.100.0.1")', + 'IP(src="0.0.0.0",dst="10.101.0.1")', + 'IP(src="0.0.0.0",dst="13.100.0.1")', + 'IP(src="0.0.0.0",dst="13.101.0.1")', + 'IP(src="0.0.0.0",dst="12.100.0.1")', + 'IP(src="0.0.0.0",dst="12.101.0.1")'] def repl(self, match): pid = match.group(1) @@ -398,6 +221,33 @@ class TestL3fwd(TestCase): return '%s,%s,%s' % (str(valports[int(pid)]), qid, lcid) + def RFC2544(self, portlist, delay=120): + """ + zero_rate: dpdk will not lost packet in this line rate. + loss_rate: dpdk will loss packet in this line rate. + test_rate: the line rate we are going to test. + """ + zero_rate = 0.0 + loss_rate = 100.0 + test_rate = 100.0 + + while (loss_rate - zero_rate) > 0.002: + self.logger.info("test rate: %f " % test_rate) + if test_rate == 100: + lost, tx_num, rx_num = self.tester.traffic_generator_loss(portlist, test_rate, delay) + else: + lost, _, _ = self.tester.traffic_generator_loss(portlist, test_rate, delay) + if lost != 0: + loss_rate = test_rate + test_rate = (test_rate + zero_rate)/2 + else: + zero_rate = test_rate + test_rate = (test_rate + loss_rate)/2 + + self.logger.info("zero loss rate is %s" % test_rate) + return test_rate, tx_num, rx_num + + def get_throughput(self, frame_size, rx_queues_per_port, cores_config, command_line): """ Get the throughput for a test case from test_cases_4_ports. @@ -421,10 +271,17 @@ class TestL3fwd(TestCase): # First, measure by two different methods for method in TestL3fwd.methods: # start l3fwd - method_command_line = command_line % (TestL3fwd.path + "l3fwd_" + method, - core_mask, - self.dut.get_memory_channels(), - dts.create_mask(valports[:4])) + if frame_size == 2048: + + method_command_line = command_line % (TestL3fwd.path + "l3fwd_" + method, core_mask, + self.dut.get_memory_channels(), dts.create_mask(valports[:4])) + + method_command_line += " --enable-jumbo --max-pkt-len " + "%d" % frame_size + + else: + method_command_line = command_line % (TestL3fwd.path + "l3fwd_" + method, core_mask, + self.dut.get_memory_channels(), + dts.create_mask(valports[:4])) dts.report(method_command_line + "\n", frame=True, annex=True) @@ -434,25 +291,48 @@ class TestL3fwd(TestCase): tgen_input = [] for rxPort in range(4): if rxPort % 2 == 0: - tx_interface = self.tester.get_local_port(valports[rxPort + 1]) + tx_interface = self.tester.get_local_port( + valports[rxPort + 1]) else: - tx_interface = self.tester.get_local_port(valports[rxPort - 1]) + tx_interface = self.tester.get_local_port( + valports[rxPort - 1]) rx_interface = self.tester.get_local_port(valports[rxPort]) - tgen_input.append((tx_interface, rx_interface, "dst%d.pcap" % valports[rxPort])) + tgen_input.append( + (tx_interface, rx_interface, "dst%d.pcap" % valports[rxPort])) # FIX ME - bps[method], pps[method] = self.tester.traffic_generator_throughput(tgen_input) + + bps[method], pps[ + method] = self.tester.traffic_generator_throughput(tgen_input) self.verify(pps[method] > 0, "No traffic detected") pps[method] /= 1000000.0 pct[method] = pps[method] * 100 / float(self.wirespeed(self.nic, - frame_size, - 4)) + frame_size,4)) +# if RFC2544 == True: +# zero_rate = 0.0 +# loss_rate = 100.0 +# test_rate = 100.0 +# +# while (loss_rate - zero_rate) > 0.002: +# print "test_rate is %s!!!!!!!!!!!!!!" % test_rate +# if self.tester.traffic_generator_loss(tgen_input, test_rate, 60) != 0: +# stable_flag = 0 +# loss_rate = test_rate +# test_rate = (test_rate + zero_rate)/2 +# else: +# stable_flag = stable_flag + 1 +# zero_rate = test_rate +# test_rate = (test_rate + loss_rate)/2 +# +# print "zero loss rate is %s" % test_rate +# # stop l3fwd self.dut.send_expect("^C", "#") - data_row = [frame_size, rx_queues_per_port, cores_config] +# data_row = [frame_size, rx_queues_per_port, cores_config] + data_row = [frame_size] for method in TestL3fwd.methods: data_row.append(pps[method]) data_row.append(pct[method]) @@ -467,21 +347,22 @@ class TestL3fwd(TestCase): """ pass - def test_perf_l3fwd_4ports(self): + def test_perf_l3fwd_4ports_1S_4C_1T(self): """ L3fwd main 4 ports. """ # Based on h/w type, choose how many ports to use - ports = self.dut.get_ports() + ports = self.dut.get_ports(self.nic) # Verify that enough ports are available self.verify(len(ports) >= 4, "Insufficient ports for speed testing") - header_row = ["Frame size", "RX Queues/NIC Port", "S/C/T"] +# header_row = ["Frame size", "RX Queues/NIC Port", "S/C/T"] + header_row = ["Frame Size(bytes)"] for method in TestL3fwd.methods: - header_row.append('%s Mpps' % method) - header_row.append('% linerate') + header_row.append('Throughput(Mpps)') + header_row.append('linerate%') dts.results_table_add_header(header_row) self.l3fwd_test_results['header'] = header_row @@ -490,13 +371,15 @@ class TestL3fwd(TestCase): for frame_size in TestL3fwd.frame_sizes: # Prepare traffic flow - payload_size = frame_size - HEADER_SIZE['udp'] - \ + payload_size = frame_size - \ HEADER_SIZE['ip'] - HEADER_SIZE['eth'] for _port in range(4): dmac = self.dut.get_mac_address(valports[_port]) - flows = ['Ether(dst="%s")/%s/("X"*%d)' % (dmac, flow, payload_size) for flow in self.flows()[_port * 2:(_port + 1) * 2]] - self.tester.scapy_append('wrpcap("dst%d.pcap", [%s])' % (valports[_port], string.join(flows, ','))) + flows = ['Ether(dst="%s")/%s/("X"*%d)' % (dmac, flow, payload_size) + for flow in self.flows()[_port * 2:(_port + 1) * 2]] + self.tester.scapy_append( + 'wrpcap("dst%d.pcap", [%s])' % (valports[_port], string.join(flows, ','))) self.tester.scapy_execute() @@ -506,25 +389,25 @@ class TestL3fwd(TestCase): frame=True, annex=True) # Get the number of sockets of the board - number_sockets = self.dut.send_expect("grep \"processor\|physical id\|core id\|^$\" /proc/cpuinfo | grep physical | sort -u | wc -l", "# ") + number_sockets = self.dut.send_expect( + "grep \"processor\|physical id\|core id\|^$\" /proc/cpuinfo | grep physical | sort -u | wc -l", "# ") number_sockets = int(number_sockets.split('\r\n')[0]) # Run case by case - for test_case in TestL3fwd.test_cases_4_ports: + for test_case in TestL3fwd.test_cases_4_ports_1S_4C_1T: # Check if the board has sockets enough for the test case if number_sockets >= int(test_case[1].split('/')[0][0]): self.get_throughput(frame_size, *test_case) - self.plot_4_ports() dts.results_table_print() - def test_perf_l3fwd_2ports(self): + def no_test_perf_l3fwd_2ports_1S_4C_1T(self): """ L3fwd main 2 ports. """ - header_row = ["Frame", "Ports", "S/C/T", "Mpps", "% linerate", "mode"] + header_row = ["Frame Size(bytes)", "Throughput(Mpps)", "linerate%"] self.l3fwd_test_results['header'] = header_row dts.results_table_add_header(header_row) self.l3fwd_test_results['data'] = [] @@ -532,24 +415,26 @@ class TestL3fwd(TestCase): for frame_size in TestL3fwd.frame_sizes: # Prepare traffic flow - payload_size = frame_size - HEADER_SIZE['udp'] - \ + payload_size = frame_size - \ HEADER_SIZE['ip'] - HEADER_SIZE['eth'] - flows = ['Ether()/%s/("X"*%d)' % (flow, payload_size) for flow in self.flows()[:4]] + flows = ['Ether()/%s/("X"*%d)' % (flow, payload_size) + for flow in self.flows()[:4]] dts.report("Flows for 2 ports, %d frame size.\n" % (frame_size), annex=True) dts.report("%s" % string.join(flows, '\n'), frame=True, annex=True) - self.tester.scapy_append('wrpcap("test2ports.pcap", [%s])' % string.join(flows, ',')) + self.tester.scapy_append( + 'wrpcap("test2ports.pcap", [%s])' % string.join(flows, ',')) self.tester.scapy_execute() # Prepare the command line global corelist pat = re.compile("P([0123]),([0123]),(C\{\d.\d.\d\})") coreMask = {} - rtCmdLines = dict(TestL3fwd.test_cases_2_ports) + rtCmdLines = dict(TestL3fwd.test_cases_2_ports_1S_4C_1T) for key in rtCmdLines.keys(): corelist = [] while pat.search(rtCmdLines[key]): @@ -572,8 +457,14 @@ class TestL3fwd(TestCase): dts.report(info, annex=True) subtitle.append(cores) - cmdline = rtCmdLines[cores] % (TestL3fwd.path + "l3fwd_" + mode, coreMask[cores], - self.dut.get_memory_channels(), dts.create_mask(valports[:2])) + if frame_size == 2048: + cmdline = rtCmdLines[cores] % (TestL3fwd.path + "l3fwd_" + mode, coreMask[cores], + self.dut.get_memory_channels(), dts.create_mask(valports[:2])) + + cmdline = cmdline + " --enable-jumbo --max-pkt-len " + "%d" % frame_size + else: + cmdline = rtCmdLines[cores] % (TestL3fwd.path + "l3fwd_" + mode, coreMask[cores], + self.dut.get_memory_channels(), dts.create_mask(valports[:2])) dts.report(cmdline + "\n", frame=True, annex=True) @@ -584,30 +475,407 @@ class TestL3fwd(TestCase): for rxPort in range(2): # No use on rx/tx limitation if rxPort % 2 == 0: - txIntf = self.tester.get_local_port(valports[rxPort + 1]) + txIntf = self.tester.get_local_port( + valports[rxPort + 1]) else: - txIntf = self.tester.get_local_port(valports[rxPort - 1]) + txIntf = self.tester.get_local_port( + valports[rxPort - 1]) rxIntf = self.tester.get_local_port(valports[rxPort]) tgenInput.append((txIntf, rxIntf, "test2ports.pcap")) - _, pps = self.tester.traffic_generator_throughput(tgenInput) + _, pps = self.tester.traffic_generator_throughput( + tgenInput) self.verify(pps > 0, "No traffic detected") pps /= 1000000.0 linerate = self.wirespeed(self.nic, frame_size, 2) pct = pps * 100 / linerate + latencys = self.tester.traffic_generator_latency(tgenInput) + print latencys + + index += 1 + + # Stop l3fwd + self.dut.send_expect("^C", "#") + + data_row = [frame_size, str(pps), str(pct)] + dts.results_table_add_row(data_row) + + self.l3fwd_test_results['data'].append(data_row) + + dts.results_table_print() + + def no_test_perf_l3fwd_1ports_1S_2C_1T(self): + """ + L3fwd main 1 ports. + """ + + header_row = ["Frame Size(bytes)", "Throughput(Mpps)", "linerate%", + "Latency Max(ns)", "Latency Average(ns)", "Latency Min(ns)"] + self.l3fwd_test_results['header'] = header_row + dts.results_table_add_header(header_row) + self.l3fwd_test_results['data'] = [] + + for frame_size in TestL3fwd.frame_sizes: + + # Prepare traffic flow + payload_size = frame_size - \ + HEADER_SIZE['ip'] - HEADER_SIZE['eth'] + + flows = ['Ether()/%s/("X"*%d)' % (flow, payload_size) + for flow in self.flows()[:1]] + + dts.report("Flows for 1 ports, %d frame size.\n" % (frame_size), + annex=True) + dts.report("%s" % string.join(flows, '\n'), + frame=True, annex=True) + + self.tester.scapy_append( + 'wrpcap("test2ports.pcap", [%s])' % string.join(flows, ',')) + self.tester.scapy_execute() + + # Prepare the command line + global corelist + global corelist_jumboframe + pat = re.compile("P([0123]),([0123]),(C\{\d.\d.\d\})") + coreMask = {} + + rtCmdLines = dict(TestL3fwd.test_cases_1_ports_1S_2C_1T) + + for key in rtCmdLines.keys(): + corelist = [] + while pat.search(rtCmdLines[key]): + rtCmdLines[key] = pat.sub(self.repl, rtCmdLines[key]) + self.logger.info("%s\n" % str(corelist)) + coreMask[key] = dts.create_mask(set(corelist)) + + # measure by two different mode + for mode in TestL3fwd.methods: + + # start l3fwd + index = 0 + subtitle = [] + for cores in rtCmdLines.keys(): + + info = "Executing l3fwd using %s mode, 1 ports, %s and %d frame size.\n" % ( + mode, cores, frame_size) + + self.logger.info(info) + dts.report(info, annex=True) + + subtitle.append(cores) + + if frame_size == 2048: + cmdline = rtCmdLines[cores] % (TestL3fwd.path + "l3fwd_" + mode, coreMask[cores], + self.dut.get_memory_channels(), dts.create_mask(valports[:1])) + cmdline = cmdline + " --enable-jumbo --max-pkt-len " + "%d" % frame_size + else: + cmdline = rtCmdLines[cores] % (TestL3fwd.path + "l3fwd_" + mode, coreMask[cores], + self.dut.get_memory_channels(), dts.create_mask(valports[:1])) + + dts.report(cmdline + "\n", frame=True, annex=True) + + out = self.dut.send_expect(cmdline, "L3FWD:", 120) + + # Measure test + tgenInput = [] + for rxPort in range(1): + txIntf = self.tester.get_local_port(valports[rxPort]) + rxIntf = self.tester.get_local_port(valports[rxPort]) + + tgenInput.append((txIntf, rxIntf, "test2ports.pcap")) + + _, pps = self.tester.traffic_generator_throughput( + tgenInput) + self.verify(pps > 0, "No traffic detected") + pps /= 1000000.0 + linerate = self.wirespeed(self.nic, frame_size, 1) + pct = pps * 100 / linerate + + latencys = self.tester.traffic_generator_latency(tgenInput) + print latencys + + index += 1 + + # Stop l3fwd + self.dut.send_expect("^C", "#") + + for latency in latencys: + data_row = [frame_size, str(pps), str(pct), str( + latency['max']), str(latency['average']), str(latency['min'])] + dts.results_table_add_row(data_row) + self.l3fwd_test_results['data'].append(data_row) + + dts.results_table_print() + + def test_perf_l3fwd_4ports_1S_1C_1T(self): + """ + L3fwd main 4 ports. + """ + + # Based on h/w type, choose how many ports to use + ports = self.dut.get_ports(self.nic) + # Verify that enough ports are available + self.verify(len(ports) >= 4, "Insufficient ports for speed testing") + +# header_row = ["Frame size", "RX Queues/NIC Port", "S/C/T"] + header_row = ["Frame Size(bytes)"] + + for method in TestL3fwd.methods: + header_row.append('Throughput(Mpps)') + header_row.append('linerate%') + + dts.results_table_add_header(header_row) + self.l3fwd_test_results['header'] = header_row + self.l3fwd_test_results['data'] = [] + + for frame_size in TestL3fwd.frame_sizes: + + # Prepare traffic flow + payload_size = frame_size - \ + HEADER_SIZE['ip'] - HEADER_SIZE['eth'] + + for _port in range(4): + + dmac = self.dut.get_mac_address(valports[_port]) + print dmac,"\n" + flows = ['Ether(dst="%s")/%s/("X"*%d)' % (dmac, flow, payload_size) + for flow in self.flows()[_port * 2:(_port + 1) * 2]] + self.tester.scapy_append( + 'wrpcap("dst%d.pcap", [%s])' % (valports[_port], string.join(flows, ','))) + + self.tester.scapy_execute() + + dts.report("Flows for 4 ports, %d frame size.\n" % (frame_size), + annex=True) + dts.report("%s" % string.join(flows, '\n'), + frame=True, annex=True) + + # Get the number of sockets of the board + number_sockets = self.dut.send_expect( + "grep \"processor\|physical id\|core id\|^$\" /proc/cpuinfo | grep physical | sort -u | wc -l", "# ") + number_sockets = int(number_sockets.split('\r\n')[0]) + + # Run case by case + for test_case in TestL3fwd.test_cases_4_ports_1S_1C_1T: + + # Check if the board has sockets enough for the test case + if number_sockets >= int(test_case[1].split('/')[0][0]): + self.get_throughput(frame_size, *test_case) + + dts.results_table_print() + + def test_perf_l3fwd_2ports_1S_2C_1T(self): + """ + L3fwd main 2 ports. + """ + + header_row = ["Frame Size", "Throughput(Mpps)", "linerate%", "LR_loss_pkts(2mins)", "LR_tx_pkts(2mins)", "LR_rx_pkts(2mins)"] + self.l3fwd_test_results['header'] = header_row + dts.results_table_add_header(header_row) + self.l3fwd_test_results['data'] = [] + + for frame_size in TestL3fwd.frame_sizes: + + # Prepare traffic flow + payload_size = frame_size - \ + HEADER_SIZE['ip'] - HEADER_SIZE['eth'] + + flows = ['Ether()/%s/("X"*%d)' % (flow, payload_size) + for flow in self.flows()[:4]] + + dts.report("Flows for 2 ports, %d frame size.\n" % (frame_size), + annex=True) + dts.report("%s" % string.join(flows, '\n'), + frame=True, annex=True) + + self.tester.scapy_append( + 'wrpcap("test2ports.pcap", [%s])' % string.join(flows, ',')) + self.tester.scapy_execute() + + # Prepare the command line + global corelist + pat = re.compile("P([0123]),([0123]),(C\{\d.\d.\d\})") + coreMask = {} + rtCmdLines = dict(TestL3fwd.test_cases_2_ports_1S_2C_1T) + for key in rtCmdLines.keys(): + corelist = [] + while pat.search(rtCmdLines[key]): + rtCmdLines[key] = pat.sub(self.repl, rtCmdLines[key]) + self.logger.info("%s\n" % str(corelist)) + coreMask[key] = dts.create_mask(set(corelist)) + + # measure by two different mode + for mode in TestL3fwd.methods: + + # start l3fwd + index = 0 + subtitle = [] + for cores in rtCmdLines.keys(): + + info = "Executing l3fwd using %s mode, 2 ports, %s and %d frame size.\n" % ( + mode, cores, frame_size) + + self.logger.info(info) + dts.report(info, annex=True) + + subtitle.append(cores) + if frame_size == 2048: + cmdline = rtCmdLines[cores] % (TestL3fwd.path + "l3fwd_" + mode, coreMask[cores], + self.dut.get_memory_channels(), dts.create_mask(valports[:2])) + + cmdline = cmdline + " --enable-jumbo --max-pkt-len " + "%d" % frame_size + else: + cmdline = rtCmdLines[cores] % (TestL3fwd.path + "l3fwd_" + mode, coreMask[cores], + self.dut.get_memory_channels(), dts.create_mask(valports[:2])) + + dts.report(cmdline + "\n", frame=True, annex=True) + + out = self.dut.send_expect(cmdline, "L3FWD:", 120) + + # Measure test + tgenInput = [] + for rxPort in range(2): + # No use on rx/tx limitation + if rxPort % 2 == 0: + txIntf = self.tester.get_local_port( + valports[rxPort + 1]) + else: + txIntf = self.tester.get_local_port( + valports[rxPort - 1]) + + rxIntf = self.tester.get_local_port(valports[rxPort]) + + tgenInput.append((txIntf, rxIntf, "test2ports.pcap")) + + _, pps = self.tester.traffic_generator_throughput( + tgenInput) + self.verify(pps > 0, "No traffic detected") + pps /= 1000000.0 + linerate = self.wirespeed(self.nic, frame_size, 2) + pct = pps * 100 / linerate + zero_loss_rate, tx_num, rx_num = self.RFC2544(tgenInput) + loss_num = tx_num - rx_num + + latencys = self.tester.traffic_generator_latency(tgenInput) + print latencys + + index += 1 + + # Stop l3fwd + self.dut.send_expect("^C", "#") + + data_row = [frame_size, str(pps), str(pct), str(loss_num), str(tx_num), str(rx_num)] + dts.results_table_add_row(data_row) + + self.l3fwd_test_results['data'].append(data_row) + + dts.results_table_print() + + def test_perf_l3fwd_1ports_1S_1C_1T(self): + """ + L3fwd main 1 ports. + """ + + header_row = ["Frame Size(bytes)", "Throughput(Mpps)", "linerate%", + "Latency Max(ns)", "Latency Average(ns)", "Latency Min(ns)"] + self.l3fwd_test_results['header'] = header_row + dts.results_table_add_header(header_row) + self.l3fwd_test_results['data'] = [] + + for frame_size in TestL3fwd.frame_sizes: + + # Prepare traffic flow + payload_size = frame_size - \ + HEADER_SIZE['ip'] - HEADER_SIZE['eth'] + + flows = ['Ether()/%s/("X"*%d)' % (flow, payload_size) + for flow in self.flows()[:1]] + + dts.report("Flows for 1 ports, %d frame size.\n" % (frame_size), + annex=True) + dts.report("%s" % string.join(flows, '\n'), + frame=True, annex=True) + + self.tester.scapy_append( + 'wrpcap("test2ports.pcap", [%s])' % string.join(flows, ',')) + self.tester.scapy_execute() + + # Prepare the command line + global corelist + global corelist_jumboframe + pat = re.compile("P([0123]),([0123]),(C\{\d.\d.\d\})") + coreMask = {} + + rtCmdLines = dict(TestL3fwd.test_cases_1_ports_1S_1C_1T) + + for key in rtCmdLines.keys(): + corelist = [] + while pat.search(rtCmdLines[key]): + rtCmdLines[key] = pat.sub(self.repl, rtCmdLines[key]) + self.logger.info("%s\n" % str(corelist)) + coreMask[key] = dts.create_mask(set(corelist)) + + # measure by two different mode + for mode in TestL3fwd.methods: + + # start l3fwd + index = 0 + subtitle = [] + for cores in rtCmdLines.keys(): + + info = "Executing l3fwd using %s mode, 1 ports, %s and %d frame size.\n" % ( + mode, cores, frame_size) + + self.logger.info(info) + dts.report(info, annex=True) + + subtitle.append(cores) + + if frame_size == 2048: + cmdline = rtCmdLines[cores] % (TestL3fwd.path + "l3fwd_" + mode, coreMask[cores], + self.dut.get_memory_channels(), dts.create_mask(valports[:1])) + + cmdline = cmdline + " --enable-jumbo --max-pkt-len " + "%d" % frame_size + else: + cmdline = rtCmdLines[cores] % (TestL3fwd.path + "l3fwd_" + mode, coreMask[cores], + self.dut.get_memory_channels(), dts.create_mask(valports[:1])) + + dts.report(cmdline + "\n", frame=True, annex=True) + + out = self.dut.send_expect(cmdline, "L3FWD:", 120) + + # Measure test + tgenInput = [] + for rxPort in range(1): + txIntf = self.tester.get_local_port(valports[rxPort]) + rxIntf = self.tester.get_local_port(valports[rxPort]) + + tgenInput.append((txIntf, rxIntf, "test2ports.pcap")) + + _, pps = self.tester.traffic_generator_throughput( + tgenInput) + self.verify(pps > 0, "No traffic detected") + pps /= 1000000.0 + linerate = self.wirespeed(self.nic, frame_size, 1) + pct = pps * 100 / linerate + + latencys = self.tester.traffic_generator_latency(tgenInput) + print latencys + index += 1 # Stop l3fwd self.dut.send_expect("^C", "#") - data_row = [frame_size, 2, cores, str(pps), str(pct), mode] + for latency in latencys: + data_row = [frame_size, str(pps), str(pct), str( + latency['max']), str(latency['average']), str(latency['min'])] dts.results_table_add_row(data_row) self.l3fwd_test_results['data'].append(data_row) - self.plot_2_ports() dts.results_table_print() def ip(self, port, frag, src, proto, tos, dst, chksum, len, options, version, flags, ihl, ttl, id): -- 1.9.3