From: "Liu, Yong" <yong.liu@intel.com>
To: "Ding, HengX" <hengx.ding@intel.com>, "dts@dpdk.org" <dts@dpdk.org>
Cc: "Ding, HengX" <hengx.ding@intel.com>
Subject: Re: [dts] [PATCH] L3fwd: Add RFC2544 support and able to print loss packets in linerate now.
Date: Thu, 22 Oct 2015 03:16:53 +0000 [thread overview]
Message-ID: <86228AFD5BCD8E4EBFD2B90117B5E81E10F2FF2F@SHSMSX103.ccr.corp.intel.com> (raw)
In-Reply-To: <1445479809-5459-1-git-send-email-hengx.ding@intel.com>
Thanks Heng, please review my comments below.
> -----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
> packets in linerate now.
>
> 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 <hengx.ding@intel.com>
>
> 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
This module has been removed in latest dts. Please update your code to latest and then resend your patch.
> 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.
> +# <COPYRIGHT_TAG>
>
Please base on latest code, not remove copy right.
> """
> 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]
Please remove useless code.
> + 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()
No need to call unbind and bind function.
> + self.dut.send_expect(
> + "sed -i
> 's/CONFIG_RTE_PCI_CONFIG=.*$/CONFIG_RTE_PCI_CONFIG=y/' ./config/common_lin
> uxapp", "# ", 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_REQUES
> T_SIZE=4096/' ./config/common_linuxapp", "# ", 5)
Please add check for nic type, I think those setting is only for Fortville card.
> + 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()
> +
No need to call unbind and bind function.
> # 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
> +
> +
Prefer to move RFC2544 function to tester module. Thus this function can be used in other suites.
> 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):
> """
Is any reason for remove this function?
> 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.
> + """
> +
If this case only supported on specified nic, please update it into dpdk_support_test_case.xls.
> + 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):
There're so many similar test cases in this suite, could you combine them into one single case?
> + """
> + 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
prev parent reply other threads:[~2015-10-22 3:16 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-22 2:10 Ding Heng
2015-10-22 2:21 ` Xu, Qian Q
2015-10-22 2:41 ` Qiu, Michael
2015-10-22 3:16 ` Liu, Yong [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=86228AFD5BCD8E4EBFD2B90117B5E81E10F2FF2F@SHSMSX103.ccr.corp.intel.com \
--to=yong.liu@intel.com \
--cc=dts@dpdk.org \
--cc=hengx.ding@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).