From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id 96A0B9366 for ; Thu, 22 Oct 2015 04:22:05 +0200 (CEST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga103.jf.intel.com with ESMTP; 21 Oct 2015 19:22:04 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,180,1444719600"; d="scan'208";a="816642491" Received: from fmsmsx107.amr.corp.intel.com ([10.18.124.205]) by fmsmga001.fm.intel.com with ESMTP; 21 Oct 2015 19:22:03 -0700 Received: from fmsmsx112.amr.corp.intel.com (10.18.116.6) by fmsmsx107.amr.corp.intel.com (10.18.124.205) with Microsoft SMTP Server (TLS) id 14.3.248.2; Wed, 21 Oct 2015 19:22:02 -0700 Received: from shsmsx104.ccr.corp.intel.com (10.239.110.15) by FMSMSX112.amr.corp.intel.com (10.18.116.6) with Microsoft SMTP Server (TLS) id 14.3.248.2; Wed, 21 Oct 2015 19:22:02 -0700 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.253]) by SHSMSX104.ccr.corp.intel.com ([169.254.5.194]) with mapi id 14.03.0248.002; Thu, 22 Oct 2015 10:21:43 +0800 From: "Xu, Qian Q" To: "Ding, HengX" , "dts@dpdk.org" Thread-Topic: [dts] [PATCH] L3fwd: Add RFC2544 support and able to print loss packets in linerate now. Thread-Index: AQHRDG7glvXnuoAp2UKL5oFTDIbwSp52x1QQ Date: Thu, 22 Oct 2015 02:21:42 +0000 Message-ID: <82F45D86ADE5454A95A89742C8D1410E01DF9AF1@shsmsx102.ccr.corp.intel.com> References: <1445479809-5459-1-git-send-email-hengx.ding@intel.com> In-Reply-To: <1445479809-5459-1-git-send-email-hengx.ding@intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Cc: "Ding, HengX" Subject: Re: [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:22:06 -0000 Heng, good to see your first patch!! It's better to separate daily performance test scripts and framework codes = changes. You could put all daily performance scripts to a separate branch a= nd put framework codes changes into a patch. Any objection?=20 Thanks Qian -----Original Message----- From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of Ding Heng Sent: Thursday, October 22, 2015 10:10 AM To: dts@dpdk.org Cc: Ding, HengX Subject: [dts] [PATCH] L3fwd: Add RFC2544 support and able to print loss pa= ckets in linerate now. Now l3fwd could do RFC2544 test and get zero loss rate. File etgen.py and t= ester.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 =3D {} =20 ixiaRef =3D self.tester.get_external_traffic_generator() - - ixiacfg =3D IxiaConf() - ixiaPorts =3D ixiacfg.load_ixia_config() - if ixiaRef is None or ixiaRef not in ixiaPorts: + if ixiaRef is None or ixiaRef not in ixiacfg.ixiaPorts: return =20 - self.ixiaVersion =3D ixiaPorts[ixiaRef]["Version"] - self.ports =3D ixiaPorts[ixiaRef]["Ports"] + self.ixiaVersion =3D ixiacfg.ixiaPorts[ixiaRef]["Version"] + self.ports =3D ixiacfg.ixiaPorts[ixiaRef]["Ports"] =20 self.logger.info(self.ixiaVersion) self.logger.info(self.ports) =20 - self.tclServerIP =3D ixiaPorts[ixiaRef]["IP"] + self.tclServerIP =3D ixiacfg.ixiaPorts[ixiaRef]["IP"] =20 # prepare tcl shell and ixia library self.send_expect("tclsh", "% ") @@ -476,18 +473,18 @@ class IxiaPacketGenerator(SSHConnection): =20 return {'card': int(m.group(1)), 'port': int(m.group(2))} =20 - def loss(self, portList, ratePercent): + def loss(self, portList, ratePercent, delay=3D5): """ Run loss performance test and return loss rate. """ rxPortlist, txPortlist =3D self._configure_everything(portList, ra= tePercent) - return self.get_loss_packet_rate(rxPortlist, txPortlist) + return self.get_loss_packet_rate(rxPortlist, txPortlist, delay) =20 - def get_loss_packet_rate(self, rxPortlist, txPortlist): + def get_loss_packet_rate(self, rxPortlist, txPortlist, delay=3D5): """ Get RX/TX packet statistics and calculate loss rate. """ - time.sleep(3) + time.sleep(delay) =20 self.send_expect("ixStopTransmit portList", "%", 10) time.sleep(2) @@ -507,7 +504,7 @@ class IxiaPacketGenerator(SSHConnection): revNumber +=3D self.get_frames_received() self.logger.info("rev :%f" % revNumber) =20 - return float(sendNumber - revNumber) / sendNumber + return float(sendNumber - revNumber) / sendNumber, sendNumber, rev= Number =20 def latency(self, portList, ratePercent, delay=3D5): """ @@ -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') !=3D0: + return self._stat_cget_value('framesReceived') + else: + return self._stat_cget_value('oversize') =20 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) =20 - def traffic_generator_loss(self, portList, ratePercent): + def traffic_generator_loss(self, portList, ratePercent, delay=3D60): """ 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. +# =20 """ DPDK Test suite. + + Layer-3 forwarding test script. """ =20 @@ -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. +# =20 =20 class TestL3fwd(TestCase): =20 path =3D "./examples/l3fwd/build/" =20 - test_cases_2_ports =3D {"1S/1C/1T": "%s -c %s -n %d -- -p %s -P --conf= ig '(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 =3D [(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 =3D [] - - 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 =3D { + "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 =3D { + "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 =3D { + "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 =3D { + "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 =3D [ + (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 =3D [ + (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})'") + ] =20 host_table =3D [ - "{{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}", ] =20 lpm_table =3D [ @@ -120,9 +76,9 @@ class TestL3fwd(TestCase): "{IPv4(13,101,0,0), 24, P3}", ] =20 - frame_sizes =3D [64] # 65, 128 - - methods =3D ['lpm', 'exact'] + frame_sizes =3D [64, 128, 256, 2048] + #frame_sizes =3D [64] + methods =3D ['lpm'] =20 # # @@ -147,174 +103,32 @@ class TestL3fwd(TestCase): # Test cases. # =20 - def plot_4_ports(self): - - data =3D self.l3fwd_test_results['data'] - - # Create a plot for each number of queues for frame size and mode = comparison - cores =3D '1S/1C/1T' - for queues in TestL3fwd.queues_4_ports: - ydata =3D [] - lpm_ydata =3D [] - exact_ydata =3D [] - for frame_size in TestL3fwd.frame_sizes: - for row in data: - if row[1] * 4 =3D=3D queues and row[2] =3D=3D cores an= d \ - row[0] =3D=3D frame_size: - if len(TestL3fwd.methods) =3D=3D 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]) =3D=3D 0: - self.logger.warning('No data for plotting 1S/1C/1T') - break - else: - try: - image_path =3D self.plotting.create_bars_plot( - 'test_perf_l3fwd_4ports_1S_1C_1T_%dRxQ' % queues, - 'LPM & Exact modes, 1S/1C/1T, %d Rx Queues, 4 port= s' % queues, - TestL3fwd.frame_sizes, - ydata, - ylabel=3D'% linerate', - legend=3DTestL3fwd.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 =3D TestL3fwd.frame_sizes[0] # Frame size fixed to th= e first selected - for queues in TestL3fwd.queues_4_ports: - - cores =3D [] - for row in data: - if row[2] not in cores and \ - row[1] * 4 =3D=3D queues: - cores.append(row[2]) - - ydata =3D [] - lpm_ydata =3D [] - exact_ydata =3D [] - - for core in cores: - for row in data: - if row[1] * 4 =3D=3D queues and \ - row[2] =3D=3D core and \ - row[0] =3D=3D frame_size: - if len(TestL3fwd.methods) =3D=3D 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 =3D self.plotting.create_bars_plot( - 'test_perf_l3fwd_4ports_%d_%dRxQ' % (frame_size, queue= s), - 'LPM & Exact modes, %dB, %d Rx Queues, 4 ports' % (fra= me_size, queues), - cores, - ydata, - ylabel=3D'% linerate', - legend=3DTestL3fwd.methods) - - dts.results_plot_print(image_path) - except VerifyFailure as e: - self.logger.error(str(e)) - - def plot_2_ports(self): - - data =3D self.l3fwd_test_results['data'] - - cores =3D [] - 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 =3D [] - - for core in cores: - core_ydata =3D [] - for row in data: - if row[5] =3D=3D mode and row[2] =3D=3D core: - core_ydata.append(float(row[4])) - - mode_ydata.append(core_ydata) - - image_path =3D self.plotting.create_bars_plot( - 'test_perf_l3fwd_2ports_%s' % mode, - 'L3fwd %s mode, 2 ports' % mode, - TestL3fwd.frame_sizes, - mode_ydata, - ylabel=3D'% linerate', - legend=3Dcores) - - dts.results_plot_print(image_path, 50) - - # If testing only one mode, do nothing else. - if len(TestL3fwd.methods) =3D=3D 1: - return - - # Create a plot for 1st core config for mode and frame size compar= ison - core =3D '1S/1C/1T' - - ydata =3D [] - for mode in TestL3fwd.methods: - mode_ydata =3D [] - for frame_size in TestL3fwd.frame_sizes: - for row in data: - if row[2] =3D=3D core and row[0] =3D=3D frame_size and= \ - row[5] =3D=3D mode: - mode_ydata.append(float(row[4])) - - ydata.append(mode_ydata) - - str_frame_sizes =3D [] - for frame_size in TestL3fwd.frame_sizes: - str_frame_sizes.append(str(frame_size)) - - image_path =3D self.plotting.create_bars_plot( - 'test_perf_l3fwd_2ports_1S_1C_1T', - 'L3fwd 1S/1C/1T cores, 2 ports', - TestL3fwd.frame_sizes, - ydata, - ylabel=3D'% linerate', - legend=3DTestL3fwd.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=3D.*$/CONFIG_RTE_PCI_CONFIG= =3Dy/' ./config/common_linuxapp", "# ", 5) + self.dut.send_expect( + "sed -i 's/CONFIG_RTE_PCI_EXTENDED_TAG=3D.*$/CONFIG_RTE_PCI_EX= TENDED_TAG=3D\"on\"/' ./config/common_linuxapp", "# ", 5) + self.dut.send_expect( + "sed -i 's/CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=3D.*$/CONFIG_= RTE_LIBRTE_I40E_16BYTE_RX_DESC=3Dy/' ./config/common_linuxapp", "# ", 5) + self.dut.send_expect( + "sed -i 's/CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE=3D.*$/CONFIG_R= TE_PCI_MAX_READ_REQUEST_SIZE=3D4096/' ./config/common_linuxapp", "# ", 5) + self.dut.send_expect("export RTE_TARGET=3D" + self.target, "#") + self.dut.send_expect("export RTE_SDK=3D`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 =3D self.dut.get_ports(socket=3D1) + ports =3D self.dut.get_ports(self.nic, socket=3D1) if not ports: - ports =3D self.dut.get_ports(socket=3D0) - - # Verify that enough ports are available - self.verify(len(ports) >=3D 2, "Insufficient ports for speed testi= ng") + ports =3D self.dut.get_ports(self.nic, socket=3D0) =20 # Verify that enough threads are available cores =3D self.dut.get_core_list("2S/4C/2T") @@ -322,14 +136,16 @@ class TestL3fwd(TestCase): =20 global valports valports =3D [_ for _ in ports if self.tester.get_local_port(_) != =3D -1] - self.verify(len(valports) >=3D 2, "Insufficient active ports for s= peed testing") + self.verify( + len(valports) >=3D 2, "Insufficient active ports for speed tes= ting") =20 pat =3D re.compile("P([0123])") =20 # Prepare long prefix match table, replace P(x) port pattern lpmStr =3D "static struct ipv4_l3fwd_route ipv4_l3fwd_route_array[= ] =3D {\\\n" for idx in range(len(TestL3fwd.lpm_table)): - TestL3fwd.lpm_table[idx] =3D pat.sub(self.portRepl, TestL3fwd.= lpm_table[idx]) + TestL3fwd.lpm_table[idx] =3D pat.sub( + self.portRepl, TestL3fwd.lpm_table[idx]) lpmStr =3D lpmStr + ' ' * 4 + TestL3fwd.lpm_table[idx] + ",\\\= n" lpmStr =3D lpmStr + "};" self.logger.debug(lpmStr) @@ -337,30 +153,37 @@ class TestL3fwd(TestCase): # Prepare host route table, replace P(x) port pattern exactStr =3D "static struct ipv4_l3fwd_route ipv4_l3fwd_route_arra= y[] =3D {\\\n" for idx in range(len(TestL3fwd.host_table)): - TestL3fwd.host_table[idx] =3D pat.sub(self.portRepl, TestL3fwd= .host_table[idx]) + TestL3fwd.host_table[idx] =3D pat.sub( + self.portRepl, TestL3fwd.host_table[idx]) exactStr =3D exactStr + ' ' * 4 + TestL3fwd.host_table[idx] + = ",\\\n" exactStr =3D exactStr + "};" self.logger.debug(exactStr) =20 # Compile l3fwd with LPM lookup. - self.dut.send_expect(r"sed -i '/ipv4_l3fwd_route_array\[\].*{/,/^\= }\;/c\\%s' examples/l3fwd/main.c" % lpmStr, "# ") - out =3D self.dut.build_dpdk_apps("./examples/l3fwd", "USER_FLAGS= =3D-DAPP_LOOKUP_METHOD=3D1") + self.dut.send_expect( + r"sed -i '/ipv4_l3fwd_route_array\[\].*{/,/^\}\;/c\\%s' exampl= es/l3fwd/main.c" % lpmStr, "# ") + out =3D self.dut.build_dpdk_apps( + "./examples/l3fwd", "USER_FLAGS=3D-DAPP_LOOKUP_METHOD=3D1") self.verify("Error" not in out, "compilation error 1") self.verify("No such file" not in out, "compilation error 2") =20 # Backup the LPM exe and clean up the build. - self.dut.send_expect("mv -f examples/l3fwd/build/l3fwd examples/l3= fwd/build/l3fwd_lpm", "# ") + self.dut.send_expect( + "mv -f examples/l3fwd/build/l3fwd examples/l3fwd/build/l3fwd_l= pm", "# ") out =3D self.dut.send_expect("make clean -C examples/l3fwd", "# ") =20 - # 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 =3D self.dut.build_dpdk_apps("./examples/l3fwd", "USER_FLAGS= =3D-DAPP_LOOKUP_METHOD=3D0") - - 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/l3= fwd/build/l3fwd_exact", "# ") +# # Compile l3fwd with hash/exact lookup. +# self.dut.send_expect( +# r"sed -i -e '/ipv4_l3fwd_route_array\[\].*{/,/^\}\;/c\\%s' ex= amples/l3fwd/main.c" % exactStr, "# ") +# out =3D self.dut.build_dpdk_apps( +# "./examples/l3fwd", "USER_FLAGS=3D-DAPP_LOOKUP_METHOD=3D0") +# +# 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", "# ") =20 self.l3fwd_test_results =3D {'header': [], 'data': []} @@ -374,14 +197,14 @@ class TestL3fwd(TestCase): =20 """ return [ - 'IP(src=3D"1.2.3.4",dst=3D"10.100.0.1")/UDP(sport=3D10,dport= =3D1)', - 'IP(src=3D"1.2.3.4",dst=3D"10.101.0.1")/UDP(sport=3D10,dport= =3D1)', - 'IP(src=3D"1.2.3.4",dst=3D"11.100.0.1")/UDP(sport=3D11,dport= =3D1)', - 'IP(src=3D"1.2.3.4",dst=3D"11.101.0.1")/UDP(sport=3D11,dport= =3D1)', - 'IP(src=3D"1.2.3.4",dst=3D"12.100.0.1")/UDP(sport=3D12,dport= =3D1)', - 'IP(src=3D"1.2.3.4",dst=3D"12.101.0.1")/UDP(sport=3D12,dport= =3D1)', - 'IP(src=3D"1.2.3.4",dst=3D"13.100.0.1")/UDP(sport=3D13,dport= =3D1)', - 'IP(src=3D"1.2.3.4",dst=3D"13.101.0.1")/UDP(sport=3D13,dport= =3D1)'] + 'IP(src=3D"0.0.0.0",dst=3D"11.100.0.1")', + 'IP(src=3D"0.0.0.0",dst=3D"11.101.0.1")', + 'IP(src=3D"0.0.0.0",dst=3D"10.100.0.1")', + 'IP(src=3D"0.0.0.0",dst=3D"10.101.0.1")', + 'IP(src=3D"0.0.0.0",dst=3D"13.100.0.1")', + 'IP(src=3D"0.0.0.0",dst=3D"13.101.0.1")', + 'IP(src=3D"0.0.0.0",dst=3D"12.100.0.1")', + 'IP(src=3D"0.0.0.0",dst=3D"12.101.0.1")'] =20 def repl(self, match): pid =3D match.group(1) @@ -398,6 +221,33 @@ class TestL3fwd(TestCase): =20 return '%s,%s,%s' % (str(valports[int(pid)]), qid, lcid) =20 + def RFC2544(self, portlist, delay=3D120): + """ + 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 =3D 0.0 + loss_rate =3D 100.0 + test_rate =3D 100.0 + + while (loss_rate - zero_rate) > 0.002: + self.logger.info("test rate: %f " % test_rate) + if test_rate =3D=3D 100: + lost, tx_num, rx_num =3D self.tester.traffic_generator_lo= ss(portlist, test_rate, delay) + else: + lost, _, _ =3D self.tester.traffic_generator_loss(portlist, test_rate,= delay) + if lost !=3D 0: + loss_rate =3D test_rate + test_rate =3D (test_rate + zero_rate)/2 + else: + zero_rate =3D test_rate + test_rate =3D (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 =3D command_line % (TestL3fwd.path + "l3fw= d_" + method, - core_mask, - self.dut.get_memory_chan= nels(), - dts.create_mask(valports= [:4])) + if frame_size =3D=3D 2048: + + method_command_line =3D command_line % (TestL3fwd.path + "= l3fwd_" + method, core_mask, + self.dut.get_memory_channels(), dts.create_mask(valports[= :4])) + + method_command_line +=3D " --enable-jumbo --max-pkt-len " = + "%d" % frame_size + + else: + method_command_line =3D command_line % (TestL3fwd.path + "= l3fwd_" + method, core_mask, + self.dut.get_memory_channels(), + dts.create_mask(valports[:4])) =20 dts.report(method_command_line + "\n", frame=3DTrue, annex=3DT= rue) =20 @@ -434,25 +291,48 @@ class TestL3fwd(TestCase): tgen_input =3D [] for rxPort in range(4): if rxPort % 2 =3D=3D 0: - tx_interface =3D self.tester.get_local_port(valports[r= xPort + 1]) + tx_interface =3D self.tester.get_local_port( + valports[rxPort + 1]) else: - tx_interface =3D self.tester.get_local_port(valports[r= xPort - 1]) + tx_interface =3D self.tester.get_local_port( + valports[rxPort - 1]) =20 rx_interface =3D self.tester.get_local_port(valports[rxPor= t]) - tgen_input.append((tx_interface, rx_interface, "dst%d.pcap= " % valports[rxPort])) + tgen_input.append( + (tx_interface, rx_interface, "dst%d.pcap" % valports[r= xPort])) =20 # FIX ME - bps[method], pps[method] =3D self.tester.traffic_generator_thr= oughput(tgen_input) + =09 + bps[method], pps[ + method] =3D self.tester.traffic_generator_throughput(tgen_= input) self.verify(pps[method] > 0, "No traffic detected") pps[method] /=3D 1000000.0 pct[method] =3D pps[method] * 100 / float(self.wirespeed(self.= nic, - frame_s= ize, - 4)) + frame_s= ize,4)) +# if RFC2544 =3D=3D True: +# zero_rate =3D 0.0 +# loss_rate =3D 100.0 +# test_rate =3D 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) !=3D = 0: +# stable_flag =3D 0 +# loss_rate =3D test_rate +# test_rate =3D (test_rate + zero_rate)/2 +# else: +# stable_flag =3D stable_flag + 1 +# zero_rate =3D test_rate +# test_rate =3D (test_rate + loss_rate)/2 +# =09 +# print "zero loss rate is %s" % test_rate +# =09 =20 # stop l3fwd self.dut.send_expect("^C", "#") =20 - data_row =3D [frame_size, rx_queues_per_port, cores_config] +# data_row =3D [frame_size, rx_queues_per_port, cores_config] + data_row =3D [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 =20 - def test_perf_l3fwd_4ports(self): + def test_perf_l3fwd_4ports_1S_4C_1T(self): """ L3fwd main 4 ports. """ =20 # Based on h/w type, choose how many ports to use - ports =3D self.dut.get_ports() + ports =3D self.dut.get_ports(self.nic) # Verify that enough ports are available self.verify(len(ports) >=3D 4, "Insufficient ports for speed testi= ng") =20 - header_row =3D ["Frame size", "RX Queues/NIC Port", "S/C/T"] +# header_row =3D ["Frame size", "RX Queues/NIC Port", "S/C/T"] + header_row =3D ["Frame Size(bytes)"] =20 for method in TestL3fwd.methods: - header_row.append('%s Mpps' % method) - header_row.append('% linerate') + header_row.append('Throughput(Mpps)') + header_row.append('linerate%') =20 dts.results_table_add_header(header_row) self.l3fwd_test_results['header'] =3D header_row @@ -490,13 +371,15 @@ class TestL3fwd(TestCase): for frame_size in TestL3fwd.frame_sizes: =20 # Prepare traffic flow - payload_size =3D frame_size - HEADER_SIZE['udp'] - \ + payload_size =3D frame_size - \ HEADER_SIZE['ip'] - HEADER_SIZE['eth'] =20 for _port in range(4): dmac =3D self.dut.get_mac_address(valports[_port]) - flows =3D ['Ether(dst=3D"%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])' % (v= alports[_port], string.join(flows, ','))) + flows =3D ['Ether(dst=3D"%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], strin= g.join(flows, ','))) =20 self.tester.scapy_execute() =20 @@ -506,25 +389,25 @@ class TestL3fwd(TestCase): frame=3DTrue, annex=3DTrue) =20 # Get the number of sockets of the board - number_sockets =3D self.dut.send_expect("grep \"processor\|phy= sical id\|core id\|^$\" /proc/cpuinfo | grep physical | sort -u | wc -l", "= # ") + number_sockets =3D self.dut.send_expect( + "grep \"processor\|physical id\|core id\|^$\" /proc/cpuinf= o | grep physical | sort -u | wc -l", "# ") number_sockets =3D int(number_sockets.split('\r\n')[0]) =20 # 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: =20 # Check if the board has sockets enough for the test case if number_sockets >=3D int(test_case[1].split('/')[0][0]): self.get_throughput(frame_size, *test_case) =20 - self.plot_4_ports() dts.results_table_print() =20 - def test_perf_l3fwd_2ports(self): + def no_test_perf_l3fwd_2ports_1S_4C_1T(self): """ L3fwd main 2 ports. """ =20 - header_row =3D ["Frame", "Ports", "S/C/T", "Mpps", "% linerate", "= mode"] + header_row =3D ["Frame Size(bytes)", "Throughput(Mpps)", "linerate= %"] self.l3fwd_test_results['header'] =3D header_row dts.results_table_add_header(header_row) self.l3fwd_test_results['data'] =3D [] @@ -532,24 +415,26 @@ class TestL3fwd(TestCase): for frame_size in TestL3fwd.frame_sizes: =20 # Prepare traffic flow - payload_size =3D frame_size - HEADER_SIZE['udp'] - \ + payload_size =3D frame_size - \ HEADER_SIZE['ip'] - HEADER_SIZE['eth'] =20 - flows =3D ['Ether()/%s/("X"*%d)' % (flow, payload_size) for fl= ow in self.flows()[:4]] + flows =3D ['Ether()/%s/("X"*%d)' % (flow, payload_size) + for flow in self.flows()[:4]] =20 dts.report("Flows for 2 ports, %d frame size.\n" % (frame_size= ), annex=3DTrue) dts.report("%s" % string.join(flows, '\n'), frame=3DTrue, annex=3DTrue) =20 - self.tester.scapy_append('wrpcap("test2ports.pcap", [%s])' % s= tring.join(flows, ',')) + self.tester.scapy_append( + 'wrpcap("test2ports.pcap", [%s])' % string.join(flows, ','= )) self.tester.scapy_execute() =20 # Prepare the command line global corelist pat =3D re.compile("P([0123]),([0123]),(C\{\d.\d.\d\})") coreMask =3D {} - rtCmdLines =3D dict(TestL3fwd.test_cases_2_ports) + rtCmdLines =3D dict(TestL3fwd.test_cases_2_ports_1S_4C_1T) for key in rtCmdLines.keys(): corelist =3D [] while pat.search(rtCmdLines[key]): @@ -572,8 +457,14 @@ class TestL3fwd(TestCase): dts.report(info, annex=3DTrue) =20 subtitle.append(cores) - cmdline =3D rtCmdLines[cores] % (TestL3fwd.path + "l3f= wd_" + mode, coreMask[cores], - self.dut.get_memory_cha= nnels(), dts.create_mask(valports[:2])) + if frame_size =3D=3D 2048: + cmdline =3D rtCmdLines[cores] % (TestL3fwd.path + = "l3fwd_" + mode, coreMask[cores], + self.dut.get_memory_channels(), dts.create_mask(v= alports[:2])) + + cmdline =3D cmdline + " --enable-jumbo --max-pkt-l= en " + "%d" % frame_size + else: + cmdline =3D rtCmdLines[cores] % (TestL3fwd.path + = "l3fwd_" + mode, coreMask[cores], + self.dut.get_memory_channels(), dts.create_mask(v= alports[:2])) =20 dts.report(cmdline + "\n", frame=3DTrue, annex=3DTrue) =20 @@ -584,30 +475,407 @@ class TestL3fwd(TestCase): for rxPort in range(2): # No use on rx/tx limitation if rxPort % 2 =3D=3D 0: - txIntf =3D self.tester.get_local_port(valports= [rxPort + 1]) + txIntf =3D self.tester.get_local_port( + valports[rxPort + 1]) else: - txIntf =3D self.tester.get_local_port(valports= [rxPort - 1]) + txIntf =3D self.tester.get_local_port( + valports[rxPort - 1]) =20 rxIntf =3D self.tester.get_local_port(valports[rxP= ort]) =20 tgenInput.append((txIntf, rxIntf, "test2ports.pcap= ")) =20 - _, pps =3D self.tester.traffic_generator_throughput(tg= enInput) + _, pps =3D self.tester.traffic_generator_throughput( + tgenInput) self.verify(pps > 0, "No traffic detected") pps /=3D 1000000.0 linerate =3D self.wirespeed(self.nic, frame_size, 2) pct =3D pps * 100 / linerate =20 + latencys =3D self.tester.traffic_generator_latency(tge= nInput) + print latencys + + index +=3D 1 + + # Stop l3fwd + self.dut.send_expect("^C", "#") + + data_row =3D [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 =3D ["Frame Size(bytes)", "Throughput(Mpps)", "linerate= %", + "Latency Max(ns)", "Latency Average(ns)", "Latency= Min(ns)"] + self.l3fwd_test_results['header'] =3D header_row + dts.results_table_add_header(header_row) + self.l3fwd_test_results['data'] =3D [] + + for frame_size in TestL3fwd.frame_sizes: + + # Prepare traffic flow + payload_size =3D frame_size - \ + HEADER_SIZE['ip'] - HEADER_SIZE['eth'] + + flows =3D ['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=3DTrue) + dts.report("%s" % string.join(flows, '\n'), + frame=3DTrue, annex=3DTrue) + + 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 =3D re.compile("P([0123]),([0123]),(C\{\d.\d.\d\})") + coreMask =3D {} + + rtCmdLines =3D dict(TestL3fwd.test_cases_1_ports_1S_2C_1T) + + for key in rtCmdLines.keys(): + corelist =3D [] + while pat.search(rtCmdLines[key]): + rtCmdLines[key] =3D pat.sub(self.repl, rtCmdLines[key]= ) + self.logger.info("%s\n" % str(corelist)) + coreMask[key] =3D dts.create_mask(set(corelist)) + + # measure by two different mode + for mode in TestL3fwd.methods: + + # start l3fwd + index =3D 0 + subtitle =3D [] + for cores in rtCmdLines.keys(): + + info =3D "Executing l3fwd using %s mode, 1 ports, %s a= nd %d frame size.\n" % ( + mode, cores, frame_size) + + self.logger.info(info) + dts.report(info, annex=3DTrue) + + subtitle.append(cores) + + if frame_size =3D=3D 2048: + cmdline =3D rtCmdLines[cores] % (TestL3fwd.path + = "l3fwd_" + mode, coreMask[cores], + self.dut.get_memory_channels(), dts.create_mask(v= alports[:1])) + cmdline =3D cmdline + " --enable-jumbo --max-pkt-l= en " + "%d" % frame_size + else: + cmdline =3D rtCmdLines[cores] % (TestL3fwd.path + = "l3fwd_" + mode, coreMask[cores], + self.dut.get_memory_channels(), dts.create_mask(v= alports[:1])) + + dts.report(cmdline + "\n", frame=3DTrue, annex=3DTrue) + + out =3D self.dut.send_expect(cmdline, "L3FWD:", 120) + + # Measure test + tgenInput =3D [] + for rxPort in range(1): + txIntf =3D self.tester.get_local_port(valports[rxP= ort]) + rxIntf =3D self.tester.get_local_port(valports[rxP= ort]) + + tgenInput.append((txIntf, rxIntf, "test2ports.pcap= ")) + + _, pps =3D self.tester.traffic_generator_throughput( + tgenInput) + self.verify(pps > 0, "No traffic detected") + pps /=3D 1000000.0 + linerate =3D self.wirespeed(self.nic, frame_size, 1) + pct =3D pps * 100 / linerate + + latencys =3D self.tester.traffic_generator_latency(tge= nInput) + print latencys + + index +=3D 1 + + # Stop l3fwd + self.dut.send_expect("^C", "#") + + for latency in latencys: + data_row =3D [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 =3D self.dut.get_ports(self.nic) + # Verify that enough ports are available + self.verify(len(ports) >=3D 4, "Insufficient ports for speed testi= ng") + +# header_row =3D ["Frame size", "RX Queues/NIC Port", "S/C/T"] + header_row =3D ["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'] =3D header_row + self.l3fwd_test_results['data'] =3D [] + + for frame_size in TestL3fwd.frame_sizes: + + # Prepare traffic flow + payload_size =3D frame_size - \ + HEADER_SIZE['ip'] - HEADER_SIZE['eth'] + + for _port in range(4): + =20 + dmac =3D self.dut.get_mac_address(valports[_port]) + print dmac,"\n" + flows =3D ['Ether(dst=3D"%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], strin= g.join(flows, ','))) + + self.tester.scapy_execute() + + dts.report("Flows for 4 ports, %d frame size.\n" % (frame_size= ), + annex=3DTrue) + dts.report("%s" % string.join(flows, '\n'), + frame=3DTrue, annex=3DTrue) + + # Get the number of sockets of the board + number_sockets =3D self.dut.send_expect( + "grep \"processor\|physical id\|core id\|^$\" /proc/cpuinf= o | grep physical | sort -u | wc -l", "# ") + number_sockets =3D 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 >=3D 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 =3D ["Frame Size", "Throughput(Mpps)", "linerate%", "LR= _loss_pkts(2mins)", "LR_tx_pkts(2mins)", "LR_rx_pkts(2mins)"] + self.l3fwd_test_results['header'] =3D header_row + dts.results_table_add_header(header_row) + self.l3fwd_test_results['data'] =3D [] + + for frame_size in TestL3fwd.frame_sizes: + + # Prepare traffic flow + payload_size =3D frame_size - \ + HEADER_SIZE['ip'] - HEADER_SIZE['eth'] + + flows =3D ['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=3DTrue) + dts.report("%s" % string.join(flows, '\n'), + frame=3DTrue, annex=3DTrue) + + self.tester.scapy_append( + 'wrpcap("test2ports.pcap", [%s])' % string.join(flows, ','= )) + self.tester.scapy_execute() + + # Prepare the command line + global corelist + pat =3D re.compile("P([0123]),([0123]),(C\{\d.\d.\d\})") + coreMask =3D {} + rtCmdLines =3D dict(TestL3fwd.test_cases_2_ports_1S_2C_1T) + for key in rtCmdLines.keys(): + corelist =3D [] + while pat.search(rtCmdLines[key]): + rtCmdLines[key] =3D pat.sub(self.repl, rtCmdLines[key]= ) + self.logger.info("%s\n" % str(corelist)) + coreMask[key] =3D dts.create_mask(set(corelist)) + + # measure by two different mode + for mode in TestL3fwd.methods: + + # start l3fwd + index =3D 0 + subtitle =3D [] + for cores in rtCmdLines.keys(): + + info =3D "Executing l3fwd using %s mode, 2 ports, %s a= nd %d frame size.\n" % ( + mode, cores, frame_size) + + self.logger.info(info) + dts.report(info, annex=3DTrue) + + subtitle.append(cores) + if frame_size =3D=3D 2048: + cmdline =3D rtCmdLines[cores] % (TestL3fwd.path + = "l3fwd_" + mode, coreMask[cores], + self.dut.get_memory_channels(), dts.create_mask(v= alports[:2])) + + cmdline =3D cmdline + " --enable-jumbo --max-pkt-l= en " + "%d" % frame_size + else: + cmdline =3D rtCmdLines[cores] % (TestL3fwd.path + = "l3fwd_" + mode, coreMask[cores], + self.dut.get_memory_channels(), dts.create_mask(v= alports[:2])) + + dts.report(cmdline + "\n", frame=3DTrue, annex=3DTrue) + + out =3D self.dut.send_expect(cmdline, "L3FWD:", 120) + + # Measure test + tgenInput =3D [] + for rxPort in range(2): + # No use on rx/tx limitation + if rxPort % 2 =3D=3D 0: + txIntf =3D self.tester.get_local_port( + valports[rxPort + 1]) + else: + txIntf =3D self.tester.get_local_port( + valports[rxPort - 1]) + + rxIntf =3D self.tester.get_local_port(valports[rxP= ort]) + + tgenInput.append((txIntf, rxIntf, "test2ports.pcap= ")) + + _, pps =3D self.tester.traffic_generator_throughput( + tgenInput) + self.verify(pps > 0, "No traffic detected") + pps /=3D 1000000.0 + linerate =3D self.wirespeed(self.nic, frame_size, 2) + pct =3D pps * 100 / linerate + zero_loss_rate, tx_num, rx_num =3D self.RFC2544(tgenInput) + loss_num =3D tx_num - rx_num + + latencys =3D self.tester.traffic_generator_latency(tge= nInput) + print latencys + + index +=3D 1 + + # Stop l3fwd + self.dut.send_expect("^C", "#") + + data_row =3D [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 =3D ["Frame Size(bytes)", "Throughput(Mpps)", "linerate= %", + "Latency Max(ns)", "Latency Average(ns)", "Latency= Min(ns)"] + self.l3fwd_test_results['header'] =3D header_row + dts.results_table_add_header(header_row) + self.l3fwd_test_results['data'] =3D [] + + for frame_size in TestL3fwd.frame_sizes: + + # Prepare traffic flow + payload_size =3D frame_size - \ + HEADER_SIZE['ip'] - HEADER_SIZE['eth'] + + flows =3D ['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=3DTrue) + dts.report("%s" % string.join(flows, '\n'), + frame=3DTrue, annex=3DTrue) + + 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 =3D re.compile("P([0123]),([0123]),(C\{\d.\d.\d\})") + coreMask =3D {} + + rtCmdLines =3D dict(TestL3fwd.test_cases_1_ports_1S_1C_1T) + + for key in rtCmdLines.keys(): + corelist =3D [] + while pat.search(rtCmdLines[key]): + rtCmdLines[key] =3D pat.sub(self.repl, rtCmdLines[key]= ) + self.logger.info("%s\n" % str(corelist)) + coreMask[key] =3D dts.create_mask(set(corelist)) + + # measure by two different mode + for mode in TestL3fwd.methods: + + # start l3fwd + index =3D 0 + subtitle =3D [] + for cores in rtCmdLines.keys(): + + info =3D "Executing l3fwd using %s mode, 1 ports, %s a= nd %d frame size.\n" % ( + mode, cores, frame_size) + + self.logger.info(info) + dts.report(info, annex=3DTrue) + + subtitle.append(cores) + + if frame_size =3D=3D 2048: + cmdline =3D rtCmdLines[cores] % (TestL3fwd.path + = "l3fwd_" + mode, coreMask[cores], + self.dut.get_memory_channels(), dts.create_mask(v= alports[:1])) + + cmdline =3D cmdline + " --enable-jumbo --max-pkt-l= en " + "%d" % frame_size + else: + cmdline =3D rtCmdLines[cores] % (TestL3fwd.path + = "l3fwd_" + mode, coreMask[cores], + self.dut.get_memory_channels(), dts.create_mask(v= alports[:1])) + + dts.report(cmdline + "\n", frame=3DTrue, annex=3DTrue) + + out =3D self.dut.send_expect(cmdline, "L3FWD:", 120) + + # Measure test + tgenInput =3D [] + for rxPort in range(1): + txIntf =3D self.tester.get_local_port(valports[rxP= ort]) + rxIntf =3D self.tester.get_local_port(valports[rxP= ort]) + + tgenInput.append((txIntf, rxIntf, "test2ports.pcap= ")) + + _, pps =3D self.tester.traffic_generator_throughput( + tgenInput) + self.verify(pps > 0, "No traffic detected") + pps /=3D 1000000.0 + linerate =3D self.wirespeed(self.nic, frame_size, 1) + pct =3D pps * 100 / linerate + + latencys =3D self.tester.traffic_generator_latency(tge= nInput) + print latencys + index +=3D 1 =20 # Stop l3fwd self.dut.send_expect("^C", "#") =20 - data_row =3D [frame_size, 2, cores, str(pps), str(pct)= , mode] + for latency in latencys: + data_row =3D [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) =20 - self.plot_2_ports() dts.results_table_print() =20 def ip(self, port, frag, src, proto, tos, dst, chksum, len, options, v= ersion, flags, ihl, ttl, id): --=20 1.9.3