[dts] [PATCH] L3fwd: Add RFC2544 support and able to print loss packets in linerate now.

Xu, Qian Q qian.q.xu at intel.com
Thu Oct 22 04:21:42 CEST 2015


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 and put framework codes changes into a patch. Any objection? 

Thanks
Qian

-----Original Message-----
From: dts [mailto:dts-bounces at dpdk.org] On Behalf Of Ding Heng
Sent: Thursday, October 22, 2015 10:10 AM
To: dts at 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 at 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
 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>
 
 """
 DPDK Test suite.
+
+
 Layer-3 forwarding test script.
 """
 
@@ -41,72 +14,55 @@ from plotting import Plotting
 from test_case import TestCase
 from exception import VerifyFailure
 from settings import HEADER_SIZE
+from etgen import IxiaPacketGenerator
+
+import time
+
+#
+#
+# Test class.
+#
 
 
 class TestL3fwd(TestCase):
 
     path = "./examples/l3fwd/build/"
 
-    test_cases_2_ports = {"1S/1C/1T": "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}), (P1,0,C{1.1.0})'",
-                          "1S/1C/2T": "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}), (P1,0,C{1.1.1})'",
-                          "1S/2C/1T": "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}), (P1,0,C{1.2.0})'"
-                          }
-
-    test_cases_4_ports = [(1, "1S/1C/1T",
-                           "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P1,0,C{1.1.0}),(P2,0,C{1.1.0}),(P3,0,C{1.1.0})'"),
-                          (1, "1S/1C/2T",
-                           "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P1,0,C{1.1.0}),(P2,0,C{1.1.1}),(P3,0,C{1.1.1})'"),
-                          (1, "1S/2C/1T",
-                           "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P1,0,C{1.1.0}),(P2,0,C{1.2.0}),(P3,0,C{1.2.0})'"),
-                          (1, "1S/2C/2T",
-                           "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P1,0,C{1.1.1}),(P2,0,C{1.2.0}),(P3,0,C{1.2.1})'"),
-                          (1, "1S/4C/1T",
-                           "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P1,0,C{1.2.0}),(P2,0,C{1.3.0}),(P3,0,C{1.4.0})'"),
-                          (1, "2S/1C/1T",
-                           "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{0.1.0}),(P1,0,C{0.1.0}),(P2,0,C{1.1.0}),(P3,0,C{1.1.0})'"),
-                          (1, "2S/1C/2T",
-                           "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{0.1.0}),(P1,0,C{0.1.1}),(P2,0,C{1.1.0}),(P3,0,C{1.1.1})'"),
-                          (1, "2S/2C/1T",
-                           "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{0.1.0}),(P1,0,C{0.2.0}),(P2,0,C{1.1.0}),(P3,0,C{1.2.0})'"),
-                          (2, "1S/1C/1T",
-                           "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P0,1,C{1.1.0}),(P1,0,C{1.1.0}),(P1,1,C{1.1.0}),(P2,0,C{1.1.0}),(P2,1,C{1.1.0}),(P3,0,C{1.1.0}),(P3,1,C{1.1.0})'"),
-                          (2, "1S/1C/2T",
-                           "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P0,1,C{1.1.0}),(P1,0,C{1.1.0}),(P1,1,C{1.1.0}),(P2,0,C{1.1.1}),(P2,1,C{1.1.1}),(P3,0,C{1.1.1}),(P3,1,C{1.1.1})'"),
-                          (2, "1S/2C/1T",
-                           "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P0,1,C{1.1.0}),(P1,0,C{1.1.0}),(P1,1,C{1.1.0}),(P2,0,C{1.2.0}),(P2,1,C{1.2.0}),(P3,0,C{1.2.0}),(P3,1,C{1.2.0})'"),
-                          (2, "1S/2C/2T",
-                           "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P0,1,C{1.1.0}),(P1,0,C{1.1.1}),(P1,1,C{1.1.1}),(P2,0,C{1.2.0}),(P2,1,C{1.2.0}),(P3,0,C{1.2.1}),(P3,1,C{1.2.1})'"),
-                          (2, "1S/4C/1T",
-                           "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P0,1,C{1.1.0}),(P1,0,C{1.2.0}),(P1,1,C{1.2.0}),(P2,0,C{1.3.0}),(P2,1,C{1.3.0}),(P3,0,C{1.4.0}),(P3,1,C{1.4.0})'"),
-                          (2, "1S/4C/2T",
-                           "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P0,1,C{1.1.1}),(P1,0,C{1.2.0}),(P1,1,C{1.2.1}),(P2,0,C{1.3.0}),(P2,1,C{1.3.1}),(P3,0,C{1.4.0}),(P3,1,C{1.4.1})'"),
-                          (2, "2S/1C/1T",
-                           "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{0.1.0}),(P0,1,C{0.1.0}),(P1,0,C{0.1.0}),(P1,1,C{0.1.0}),(P2,0,C{1.1.0}),(P2,1,C{1.1.0}),(P3,0,C{1.1.0}),(P3,1,C{1.1.0})'"),
-                          (2, "2S/1C/2T",
-                           "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{0.1.0}),(P0,1,C{0.1.0}),(P1,0,C{0.1.1}),(P1,1,C{0.1.1}),(P2,0,C{1.1.0}),(P2,1,C{1.1.0}),(P3,0,C{1.1.1}),(P3,1,C{1.1.1})'"),
-                          (2, "2S/2C/1T",
-                           "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{0.1.0}),(P0,1,C{0.1.0}),(P1,0,C{0.2.0}),(P1,1,C{0.2.0}),(P2,0,C{1.1.0}),(P2,1,C{1.1.0}),(P3,0,C{1.2.0}),(P3,1,C{1.2.0})'"),
-                          (2, "2S/2C/2T",
-                           "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{0.1.0}),(P0,1,C{0.1.1}),(P1,0,C{0.2.0}),(P1,1,C{0.2.1}),(P2,0,C{1.1.0}),(P2,1,C{1.1.1}),(P3,0,C{1.2.0}),(P3,1,C{1.2.1})'"),
-                          (2, "2S/4C/1T",
-                           "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{0.1.0}),(P0,1,C{0.2.0}),(P1,0,C{0.3.0}),(P1,1,C{0.4.0}),(P2,0,C{1.1.0}),(P2,1,C{1.2.0}),(P3,0,C{1.3.0}),(P3,1,C{1.4.0})'")
-                          ]
-
-    queues_4_ports = []
-
-    for case in test_cases_4_ports:
-        if case[0] * 4 not in queues_4_ports:
-            queues_4_ports.append(case[0] * 4)
+    test_cases_1_ports_1S_2C_1T = {
+        "1S/2C/1T": "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}), (P0,1,C{1.2.0})'"
+    }
+
+    test_cases_1_ports_1S_1C_1T = {
+        "1S/1C/1T": "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0})'"
+    }
+
+    test_cases_2_ports_1S_4C_1T = {
+        "1S/4C/1T": "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}), (P0,1,C{1.2.0}),(P1,0,C{1.3.0}),(P1,1,C{1.4.0})'"
+    }
+
+    test_cases_2_ports_1S_2C_1T = {
+        "1S/2C/1T": "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}), (P1,0,C{1.2.0})'"
+    }
+
+    test_cases_4_ports_1S_4C_1T = [
+        (4, "1S/4C/1T",
+         "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}),(P1,0,C{1.2.0}),(P2,0,C{1.3.0}),(P3,0,C{1.4.0})'")
+    ]
+
+    test_cases_4_ports_1S_1C_1T = [
+        (1, "1S/1C/1T",
+         "%s -c %s -n %d -- -p %s -P  --config '(P0,0,C{1.1.0}),(P1,0,C{1.1.0}),(P2,0,C{1.1.0}),(P3,0,C{1.1.0})'")
+    ]
 
     host_table = [
-        "{{IPv4(10,100,0,1), IPv4(1,2,3,4), 1, 10, IPPROTO_UDP}, P0}",
-        "{{IPv4(10,101,0,1), IPv4(1,2,3,4), 1, 10, IPPROTO_UDP}, P0}",
-        "{{IPv4(11,100,0,1), IPv4(1,2,3,4), 1, 11, IPPROTO_UDP}, P1}",
-        "{{IPv4(11,101,0,1), IPv4(1,2,3,4), 1, 11, IPPROTO_UDP}, P1}",
-        "{{IPv4(12,100,0,1), IPv4(1,2,3,4), 1, 12, IPPROTO_UDP}, P2}",
-        "{{IPv4(12,101,0,1), IPv4(1,2,3,4), 1, 12, IPPROTO_UDP}, P2}",
-        "{{IPv4(13,100,0,1), IPv4(1,2,3,4), 1, 13, IPPROTO_UDP}, P3}",
-        "{{IPv4(13,101,0,1), IPv4(1,2,3,4), 1, 13, IPPROTO_UDP}, P3}",
+        "{{IPv4(10,100,0,1), IPv4(0,0,0,0), 1, 10, IPPROTO_UDP}, P0}",
+        "{{IPv4(10,101,0,1), IPv4(0,0,0,0), 1, 10, IPPROTO_UDP}, P0}",
+        "{{IPv4(11,100,0,1), IPv4(0,0,0,0), 1, 11, IPPROTO_UDP}, P1}",
+        "{{IPv4(11,101,0,1), IPv4(0,0,0,0), 1, 11, IPPROTO_UDP}, P1}",
+        "{{IPv4(12,100,0,1), IPv4(0,0,0,0), 1, 12, IPPROTO_UDP}, P2}",
+        "{{IPv4(12,101,0,1), IPv4(0,0,0,0), 1, 12, IPPROTO_UDP}, P2}",
+        "{{IPv4(13,100,0,1), IPv4(0,0,0,0), 1, 13, IPPROTO_UDP}, P3}",
+        "{{IPv4(13,101,0,1), IPv4(0,0,0,0), 1, 13, IPPROTO_UDP}, P3}",
     ]
 
     lpm_table = [
@@ -120,9 +76,9 @@ class TestL3fwd(TestCase):
         "{IPv4(13,101,0,0), 24, P3}",
     ]
 
-    frame_sizes = [64]  # 65, 128
-
-    methods = ['lpm', 'exact']
+    frame_sizes = [64, 128, 256, 2048]
+    #frame_sizes = [64]
+    methods = ['lpm']
 
     #
     #
@@ -147,174 +103,32 @@ class TestL3fwd(TestCase):
     # Test cases.
     #
 
-    def plot_4_ports(self):
-
-        data = self.l3fwd_test_results['data']
-
-        # Create a plot for each number of queues for frame size and mode comparison
-        cores = '1S/1C/1T'
-        for queues in TestL3fwd.queues_4_ports:
-            ydata = []
-            lpm_ydata = []
-            exact_ydata = []
-            for frame_size in TestL3fwd.frame_sizes:
-                for row in data:
-                    if row[1] * 4 == queues and row[2] == cores and \
-                            row[0] == frame_size:
-                        if len(TestL3fwd.methods) == 2:
-                            lpm_ydata.append(row[4])
-                            exact_ydata.append(row[6])
-                        else:
-                            if 'lpm' in TestL3fwd.methods:
-                                lpm_ydata.append(row[4])
-                            if 'exact' in TestL3fwd.methods:
-                                exact_ydata.append(row[4])
-
-            if 'lpm' in TestL3fwd.methods:
-                ydata.append(lpm_ydata)
-            if 'exact' in TestL3fwd.methods:
-                ydata.append(exact_ydata)
-
-            if len(ydata[0]) == 0:
-                self.logger.warning('No data for plotting 1S/1C/1T')
-                break
-            else:
-                try:
-                    image_path = self.plotting.create_bars_plot(
-                        'test_perf_l3fwd_4ports_1S_1C_1T_%dRxQ' % queues,
-                        'LPM & Exact modes, 1S/1C/1T, %d Rx Queues, 4 ports' % queues,
-                        TestL3fwd.frame_sizes,
-                        ydata,
-                        ylabel='% linerate',
-                        legend=TestL3fwd.methods)
-
-                    dts.results_plot_print(image_path, 50)
-                except VerifyFailure as e:
-                    self.logger.error(str(e))
-
-        # Create a plot for each number of queues for core config and mode comparison
-        frame_size = TestL3fwd.frame_sizes[0]   # Frame size fixed to the first selected
-        for queues in TestL3fwd.queues_4_ports:
-
-            cores = []
-            for row in data:
-                if row[2] not in cores and \
-                   row[1] * 4 == queues:
-                    cores.append(row[2])
-
-            ydata = []
-            lpm_ydata = []
-            exact_ydata = []
-
-            for core in cores:
-                for row in data:
-                    if row[1] * 4 == queues and \
-                       row[2] == core and \
-                       row[0] == frame_size:
-                        if len(TestL3fwd.methods) == 2:
-                            lpm_ydata.append(row[4])
-                            exact_ydata.append(row[6])
-                        else:
-                            if 'lpm' in TestL3fwd.methods:
-                                lpm_ydata.append(row[4])
-                            if 'exact' in TestL3fwd.methods:
-                                exact_ydata.append(row[4])
-
-            if 'lpm' in TestL3fwd.methods:
-                ydata.append(lpm_ydata)
-            if 'exact' in TestL3fwd.methods:
-                ydata.append(exact_ydata)
-
-            try:
-                image_path = self.plotting.create_bars_plot(
-                    'test_perf_l3fwd_4ports_%d_%dRxQ' % (frame_size, queues),
-                    'LPM & Exact modes, %dB, %d Rx Queues, 4 ports' % (frame_size, queues),
-                    cores,
-                    ydata,
-                    ylabel='% linerate',
-                    legend=TestL3fwd.methods)
-
-                dts.results_plot_print(image_path)
-            except VerifyFailure as e:
-                self.logger.error(str(e))
-
-    def plot_2_ports(self):
-
-        data = self.l3fwd_test_results['data']
-
-        cores = []
-        for row in data:
-            if row[2] not in cores:
-                cores.append(row[2])
-
-        # Create a plot for each mode for frame size and cores comparison
-        for mode in TestL3fwd.methods:
-            mode_ydata = []
-
-            for core in cores:
-                core_ydata = []
-                for row in data:
-                    if row[5] == mode and row[2] == core:
-                        core_ydata.append(float(row[4]))
-
-                mode_ydata.append(core_ydata)
-
-            image_path = self.plotting.create_bars_plot(
-                'test_perf_l3fwd_2ports_%s' % mode,
-                'L3fwd %s mode, 2 ports' % mode,
-                TestL3fwd.frame_sizes,
-                mode_ydata,
-                ylabel='% linerate',
-                legend=cores)
-
-            dts.results_plot_print(image_path, 50)
-
-        # If testing only one mode, do nothing else.
-        if len(TestL3fwd.methods) == 1:
-            return
-
-        # Create a plot for 1st core config for mode and frame size comparison
-        core = '1S/1C/1T'
-
-        ydata = []
-        for mode in TestL3fwd.methods:
-            mode_ydata = []
-            for frame_size in TestL3fwd.frame_sizes:
-                for row in data:
-                    if row[2] == core and row[0] == frame_size and \
-                            row[5] == mode:
-                        mode_ydata.append(float(row[4]))
-
-            ydata.append(mode_ydata)
-
-        str_frame_sizes = []
-        for frame_size in TestL3fwd.frame_sizes:
-            str_frame_sizes.append(str(frame_size))
-
-        image_path = self.plotting.create_bars_plot(
-            'test_perf_l3fwd_2ports_1S_1C_1T',
-            'L3fwd 1S/1C/1T cores, 2 ports',
-            TestL3fwd.frame_sizes,
-            ydata,
-            ylabel='% linerate',
-            legend=TestL3fwd.methods)
-
-        dts.results_plot_print(image_path)
-
     def set_up_all(self):
         """
         Run at the start of each test suite.
-
-
         L3fwd Prerequisites
         """
+
+        self.dut.unbind_interfaces_linux()
+        self.dut.send_expect(
+            "sed -i 's/CONFIG_RTE_PCI_CONFIG=.*$/CONFIG_RTE_PCI_CONFIG=y/' ./config/common_linuxapp", "# ", 5)
+        self.dut.send_expect(
+            "sed -i 's/CONFIG_RTE_PCI_EXTENDED_TAG=.*$/CONFIG_RTE_PCI_EXTENDED_TAG=\"on\"/' ./config/common_linuxapp", "# ", 5)
+        self.dut.send_expect(
+            "sed -i 's/CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=.*$/CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=y/' ./config/common_linuxapp", "# ", 5)
+        self.dut.send_expect(
+            "sed -i 's/CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE=.*$/CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE=4096/' ./config/common_linuxapp", "# ", 5)
+        self.dut.send_expect("export RTE_TARGET=" + self.target, "#")
+        self.dut.send_expect("export RTE_SDK=`pwd`", "#")
+        self.dut.send_expect("rm -rf %s" % self.target, "# ", 5)
+        self.dut.build_install_dpdk(self.target)
+        time.sleep(10)
+        self.dut.bind_interfaces_linux()
+
         # Based on h/w type, choose how many ports to use
-        ports = self.dut.get_ports(socket=1)
+        ports = self.dut.get_ports(self.nic, socket=1)
         if not ports:
-            ports = self.dut.get_ports(socket=0)
-
-        # Verify that enough ports are available
-        self.verify(len(ports) >= 2, "Insufficient ports for speed testing")
+            ports = self.dut.get_ports(self.nic, socket=0)
 
         # Verify that enough threads are available
         cores = self.dut.get_core_list("2S/4C/2T")
@@ -322,14 +136,16 @@ class TestL3fwd(TestCase):
 
         global valports
         valports = [_ for _ in ports if self.tester.get_local_port(_) != -1]
-        self.verify(len(valports) >= 2, "Insufficient active ports for speed testing")
+        self.verify(
+            len(valports) >= 2, "Insufficient active ports for speed testing")
 
         pat = re.compile("P([0123])")
 
         # Prepare long prefix match table, replace P(x) port pattern
         lpmStr = "static struct ipv4_l3fwd_route ipv4_l3fwd_route_array[] = {\\\n"
         for idx in range(len(TestL3fwd.lpm_table)):
-            TestL3fwd.lpm_table[idx] = pat.sub(self.portRepl, TestL3fwd.lpm_table[idx])
+            TestL3fwd.lpm_table[idx] = pat.sub(
+                self.portRepl, TestL3fwd.lpm_table[idx])
             lpmStr = lpmStr + ' ' * 4 + TestL3fwd.lpm_table[idx] + ",\\\n"
         lpmStr = lpmStr + "};"
         self.logger.debug(lpmStr)
@@ -337,30 +153,37 @@ class TestL3fwd(TestCase):
         # Prepare host route table, replace P(x) port pattern
         exactStr = "static struct ipv4_l3fwd_route ipv4_l3fwd_route_array[] = {\\\n"
         for idx in range(len(TestL3fwd.host_table)):
-            TestL3fwd.host_table[idx] = pat.sub(self.portRepl, TestL3fwd.host_table[idx])
+            TestL3fwd.host_table[idx] = pat.sub(
+                self.portRepl, TestL3fwd.host_table[idx])
             exactStr = exactStr + ' ' * 4 + TestL3fwd.host_table[idx] + ",\\\n"
         exactStr = exactStr + "};"
         self.logger.debug(exactStr)
 
         # Compile l3fwd with LPM lookup.
-        self.dut.send_expect(r"sed -i '/ipv4_l3fwd_route_array\[\].*{/,/^\}\;/c\\%s' examples/l3fwd/main.c" % lpmStr, "# ")
-        out = self.dut.build_dpdk_apps("./examples/l3fwd", "USER_FLAGS=-DAPP_LOOKUP_METHOD=1")
+        self.dut.send_expect(
+            r"sed -i '/ipv4_l3fwd_route_array\[\].*{/,/^\}\;/c\\%s' examples/l3fwd/main.c" % lpmStr, "# ")
+        out = self.dut.build_dpdk_apps(
+            "./examples/l3fwd", "USER_FLAGS=-DAPP_LOOKUP_METHOD=1")
         self.verify("Error" not in out, "compilation error 1")
         self.verify("No such file" not in out, "compilation error 2")
 
         # Backup the LPM exe and clean up the build.
-        self.dut.send_expect("mv -f examples/l3fwd/build/l3fwd examples/l3fwd/build/l3fwd_lpm", "# ")
+        self.dut.send_expect(
+            "mv -f examples/l3fwd/build/l3fwd examples/l3fwd/build/l3fwd_lpm", "# ")
         out = self.dut.send_expect("make clean -C examples/l3fwd", "# ")
 
-        # Compile l3fwd with hash/exact lookup.
-        self.dut.send_expect(r"sed -i -e '/ipv4_l3fwd_route_array\[\].*{/,/^\}\;/c\\%s' examples/l3fwd/main.c" % exactStr, "# ")
-        out = self.dut.build_dpdk_apps("./examples/l3fwd", "USER_FLAGS=-DAPP_LOOKUP_METHOD=0")
-
-        self.verify("Error" not in out, "compilation error 1")
-        self.verify("No such file" not in out, "compilation error 2")
-
-        # Backup the Hash/Exact exe.
-        self.dut.send_expect("mv -f examples/l3fwd/build/l3fwd examples/l3fwd/build/l3fwd_exact", "# ")
+#        # Compile l3fwd with hash/exact lookup.
+#        self.dut.send_expect(
+#            r"sed -i -e '/ipv4_l3fwd_route_array\[\].*{/,/^\}\;/c\\%s' examples/l3fwd/main.c" % exactStr, "# ")
+#        out = self.dut.build_dpdk_apps(
+#            "./examples/l3fwd", "USER_FLAGS=-DAPP_LOOKUP_METHOD=0")
+#
+#        self.verify("Error" not in out, "compilation error 1")
+#        self.verify("No such file" not in out, "compilation error 2")
+#
+#        # Backup the Hash/Exact exe.
+#        self.dut.send_expect(
+#            "mv -f examples/l3fwd/build/l3fwd examples/l3fwd/build/l3fwd_exact", "# ")
 
         self.l3fwd_test_results = {'header': [],
                                    'data': []}
@@ -374,14 +197,14 @@ class TestL3fwd(TestCase):
 
         """
         return [
-            'IP(src="1.2.3.4",dst="10.100.0.1")/UDP(sport=10,dport=1)',
-            'IP(src="1.2.3.4",dst="10.101.0.1")/UDP(sport=10,dport=1)',
-            'IP(src="1.2.3.4",dst="11.100.0.1")/UDP(sport=11,dport=1)',
-            'IP(src="1.2.3.4",dst="11.101.0.1")/UDP(sport=11,dport=1)',
-            'IP(src="1.2.3.4",dst="12.100.0.1")/UDP(sport=12,dport=1)',
-            'IP(src="1.2.3.4",dst="12.101.0.1")/UDP(sport=12,dport=1)',
-            'IP(src="1.2.3.4",dst="13.100.0.1")/UDP(sport=13,dport=1)',
-            'IP(src="1.2.3.4",dst="13.101.0.1")/UDP(sport=13,dport=1)']
+            'IP(src="0.0.0.0",dst="11.100.0.1")',
+            'IP(src="0.0.0.0",dst="11.101.0.1")',
+            'IP(src="0.0.0.0",dst="10.100.0.1")',
+            'IP(src="0.0.0.0",dst="10.101.0.1")',
+            'IP(src="0.0.0.0",dst="13.100.0.1")',
+            'IP(src="0.0.0.0",dst="13.101.0.1")',
+            'IP(src="0.0.0.0",dst="12.100.0.1")',
+            'IP(src="0.0.0.0",dst="12.101.0.1")']
 
     def repl(self, match):
         pid = match.group(1)
@@ -398,6 +221,33 @@ class TestL3fwd(TestCase):
 
         return '%s,%s,%s' % (str(valports[int(pid)]), qid, lcid)
 
+    def RFC2544(self, portlist, delay=120):
+	"""
+	zero_rate: dpdk will not lost packet in this line rate.
+	loss_rate: dpdk will loss packet in this line rate.
+	test_rate: the line rate we are going to test.
+	"""
+	zero_rate = 0.0
+        loss_rate = 100.0
+        test_rate = 100.0
+
+        while (loss_rate - zero_rate) > 0.002:
+		self.logger.info("test rate: %f " % test_rate)
+		if test_rate == 100:
+                	lost, tx_num, rx_num = self.tester.traffic_generator_loss(portlist, test_rate, delay)
+		else:
+			lost, _, _  = self.tester.traffic_generator_loss(portlist, test_rate, delay)
+		if lost != 0:
+                        loss_rate = test_rate
+                        test_rate = (test_rate + zero_rate)/2
+                else:
+                        zero_rate = test_rate
+                        test_rate = (test_rate + loss_rate)/2
+
+        self.logger.info("zero loss rate is %s" % test_rate)
+	return test_rate, tx_num, rx_num
+
+
     def get_throughput(self, frame_size, rx_queues_per_port, cores_config, command_line):
         """
         Get the throughput for a test case from test_cases_4_ports.
@@ -421,10 +271,17 @@ class TestL3fwd(TestCase):
         # First, measure by two different methods
         for method in TestL3fwd.methods:
             # start l3fwd
-            method_command_line = command_line % (TestL3fwd.path + "l3fwd_" + method,
-                                                  core_mask,
-                                                  self.dut.get_memory_channels(),
-                                                  dts.create_mask(valports[:4]))
+            if frame_size == 2048:
+
+                method_command_line = command_line % (TestL3fwd.path + "l3fwd_" + method, core_mask,
+                 self.dut.get_memory_channels(), dts.create_mask(valports[:4]))
+
+                method_command_line += " --enable-jumbo --max-pkt-len " + "%d" % frame_size
+
+            else:
+                method_command_line = command_line % (TestL3fwd.path + "l3fwd_" + method, core_mask,
+                 self.dut.get_memory_channels(),
+                 dts.create_mask(valports[:4]))
 
             dts.report(method_command_line + "\n", frame=True, annex=True)
 
@@ -434,25 +291,48 @@ class TestL3fwd(TestCase):
             tgen_input = []
             for rxPort in range(4):
                 if rxPort % 2 == 0:
-                    tx_interface = self.tester.get_local_port(valports[rxPort + 1])
+                    tx_interface = self.tester.get_local_port(
+                        valports[rxPort + 1])
                 else:
-                    tx_interface = self.tester.get_local_port(valports[rxPort - 1])
+                    tx_interface = self.tester.get_local_port(
+                        valports[rxPort - 1])
 
                 rx_interface = self.tester.get_local_port(valports[rxPort])
-                tgen_input.append((tx_interface, rx_interface, "dst%d.pcap" % valports[rxPort]))
+                tgen_input.append(
+                    (tx_interface, rx_interface, "dst%d.pcap" % valports[rxPort]))
 
             # FIX ME
-            bps[method], pps[method] = self.tester.traffic_generator_throughput(tgen_input)
+		
+            bps[method], pps[
+                method] = self.tester.traffic_generator_throughput(tgen_input)
             self.verify(pps[method] > 0, "No traffic detected")
             pps[method] /= 1000000.0
             pct[method] = pps[method] * 100 / float(self.wirespeed(self.nic,
-                                                                   frame_size,
-                                                                   4))
+                                                                   frame_size,4))
+#	    if RFC2544 == True:
+#		zero_rate = 0.0
+#		loss_rate = 100.0
+#		test_rate = 100.0
+#
+#		while (loss_rate - zero_rate) > 0.002:
+#			print "test_rate is %s!!!!!!!!!!!!!!" % test_rate
+#			if self.tester.traffic_generator_loss(tgen_input, test_rate, 60) != 0:
+#				stable_flag = 0
+#				loss_rate = test_rate
+#				test_rate = (test_rate + zero_rate)/2
+#			else:
+#				stable_flag = stable_flag + 1
+#				zero_rate = test_rate
+#				test_rate = (test_rate + loss_rate)/2
+#            	
+#		print "zero loss rate is %s" % test_rate
+#			
 
             # stop l3fwd
             self.dut.send_expect("^C", "#")
 
-        data_row = [frame_size, rx_queues_per_port, cores_config]
+#       data_row = [frame_size, rx_queues_per_port, cores_config]
+        data_row = [frame_size]
         for method in TestL3fwd.methods:
             data_row.append(pps[method])
             data_row.append(pct[method])
@@ -467,21 +347,22 @@ class TestL3fwd(TestCase):
         """
         pass
 
-    def test_perf_l3fwd_4ports(self):
+    def test_perf_l3fwd_4ports_1S_4C_1T(self):
         """
         L3fwd main 4 ports.
         """
 
         # Based on h/w type, choose how many ports to use
-        ports = self.dut.get_ports()
+        ports = self.dut.get_ports(self.nic)
         # Verify that enough ports are available
         self.verify(len(ports) >= 4, "Insufficient ports for speed testing")
 
-        header_row = ["Frame size", "RX Queues/NIC Port", "S/C/T"]
+#        header_row = ["Frame size", "RX Queues/NIC Port", "S/C/T"]
+        header_row = ["Frame Size(bytes)"]
 
         for method in TestL3fwd.methods:
-            header_row.append('%s Mpps' % method)
-            header_row.append('% linerate')
+            header_row.append('Throughput(Mpps)')
+            header_row.append('linerate%')
 
         dts.results_table_add_header(header_row)
         self.l3fwd_test_results['header'] = header_row
@@ -490,13 +371,15 @@ class TestL3fwd(TestCase):
         for frame_size in TestL3fwd.frame_sizes:
 
             # Prepare traffic flow
-            payload_size = frame_size - HEADER_SIZE['udp'] - \
+            payload_size = frame_size -  \
                 HEADER_SIZE['ip'] - HEADER_SIZE['eth']
 
             for _port in range(4):
                 dmac = self.dut.get_mac_address(valports[_port])
-                flows = ['Ether(dst="%s")/%s/("X"*%d)' % (dmac, flow, payload_size) for flow in self.flows()[_port * 2:(_port + 1) * 2]]
-                self.tester.scapy_append('wrpcap("dst%d.pcap", [%s])' % (valports[_port], string.join(flows, ',')))
+                flows = ['Ether(dst="%s")/%s/("X"*%d)' % (dmac, flow, payload_size)
+                         for flow in self.flows()[_port * 2:(_port + 1) * 2]]
+                self.tester.scapy_append(
+                    'wrpcap("dst%d.pcap", [%s])' % (valports[_port], string.join(flows, ',')))
 
             self.tester.scapy_execute()
 
@@ -506,25 +389,25 @@ class TestL3fwd(TestCase):
                        frame=True, annex=True)
 
             # Get the number of sockets of the board
-            number_sockets = self.dut.send_expect("grep \"processor\|physical id\|core id\|^$\" /proc/cpuinfo | grep physical | sort -u | wc -l", "# ")
+            number_sockets = self.dut.send_expect(
+                "grep \"processor\|physical id\|core id\|^$\" /proc/cpuinfo | grep physical | sort -u | wc -l", "# ")
             number_sockets = int(number_sockets.split('\r\n')[0])
 
             # Run case by case
-            for test_case in TestL3fwd.test_cases_4_ports:
+            for test_case in TestL3fwd.test_cases_4_ports_1S_4C_1T:
 
                 # Check if the board has sockets enough for the test case
                 if number_sockets >= int(test_case[1].split('/')[0][0]):
                     self.get_throughput(frame_size, *test_case)
 
-        self.plot_4_ports()
         dts.results_table_print()
 
-    def test_perf_l3fwd_2ports(self):
+    def no_test_perf_l3fwd_2ports_1S_4C_1T(self):
         """
         L3fwd main 2 ports.
         """
 
-        header_row = ["Frame", "Ports", "S/C/T", "Mpps", "% linerate", "mode"]
+        header_row = ["Frame Size(bytes)", "Throughput(Mpps)", "linerate%"]
         self.l3fwd_test_results['header'] = header_row
         dts.results_table_add_header(header_row)
         self.l3fwd_test_results['data'] = []
@@ -532,24 +415,26 @@ class TestL3fwd(TestCase):
         for frame_size in TestL3fwd.frame_sizes:
 
             # Prepare traffic flow
-            payload_size = frame_size - HEADER_SIZE['udp'] - \
+            payload_size = frame_size -  \
                 HEADER_SIZE['ip'] - HEADER_SIZE['eth']
 
-            flows = ['Ether()/%s/("X"*%d)' % (flow, payload_size) for flow in self.flows()[:4]]
+            flows = ['Ether()/%s/("X"*%d)' % (flow, payload_size)
+                     for flow in self.flows()[:4]]
 
             dts.report("Flows for 2 ports, %d frame size.\n" % (frame_size),
                        annex=True)
             dts.report("%s" % string.join(flows, '\n'),
                        frame=True, annex=True)
 
-            self.tester.scapy_append('wrpcap("test2ports.pcap", [%s])' % string.join(flows, ','))
+            self.tester.scapy_append(
+                'wrpcap("test2ports.pcap", [%s])' % string.join(flows, ','))
             self.tester.scapy_execute()
 
             # Prepare the command line
             global corelist
             pat = re.compile("P([0123]),([0123]),(C\{\d.\d.\d\})")
             coreMask = {}
-            rtCmdLines = dict(TestL3fwd.test_cases_2_ports)
+            rtCmdLines = dict(TestL3fwd.test_cases_2_ports_1S_4C_1T)
             for key in rtCmdLines.keys():
                 corelist = []
                 while pat.search(rtCmdLines[key]):
@@ -572,8 +457,14 @@ class TestL3fwd(TestCase):
                     dts.report(info, annex=True)
 
                     subtitle.append(cores)
-                    cmdline = rtCmdLines[cores] % (TestL3fwd.path + "l3fwd_" + mode, coreMask[cores],
-                                                   self.dut.get_memory_channels(), dts.create_mask(valports[:2]))
+                    if frame_size == 2048:
+                        cmdline = rtCmdLines[cores] % (TestL3fwd.path + "l3fwd_" + mode, coreMask[cores],
+                         self.dut.get_memory_channels(), dts.create_mask(valports[:2]))
+
+                        cmdline = cmdline + " --enable-jumbo --max-pkt-len " + "%d" % frame_size
+                    else:
+                        cmdline = rtCmdLines[cores] % (TestL3fwd.path + "l3fwd_" + mode, coreMask[cores],
+                         self.dut.get_memory_channels(), dts.create_mask(valports[:2]))
 
                     dts.report(cmdline + "\n", frame=True, annex=True)
 
@@ -584,30 +475,407 @@ class TestL3fwd(TestCase):
                     for rxPort in range(2):
                         # No use on rx/tx limitation
                         if rxPort % 2 == 0:
-                            txIntf = self.tester.get_local_port(valports[rxPort + 1])
+                            txIntf = self.tester.get_local_port(
+                                valports[rxPort + 1])
                         else:
-                            txIntf = self.tester.get_local_port(valports[rxPort - 1])
+                            txIntf = self.tester.get_local_port(
+                                valports[rxPort - 1])
 
                         rxIntf = self.tester.get_local_port(valports[rxPort])
 
                         tgenInput.append((txIntf, rxIntf, "test2ports.pcap"))
 
-                    _, pps = self.tester.traffic_generator_throughput(tgenInput)
+                    _, pps = self.tester.traffic_generator_throughput(
+                        tgenInput)
                     self.verify(pps > 0, "No traffic detected")
                     pps /= 1000000.0
                     linerate = self.wirespeed(self.nic, frame_size, 2)
                     pct = pps * 100 / linerate
 
+                    latencys = self.tester.traffic_generator_latency(tgenInput)
+                    print latencys
+
+                    index += 1
+
+                    # Stop l3fwd
+                    self.dut.send_expect("^C", "#")
+
+                    data_row = [frame_size, str(pps), str(pct)]
+                    dts.results_table_add_row(data_row)
+
+                    self.l3fwd_test_results['data'].append(data_row)
+
+        dts.results_table_print()
+
+    def no_test_perf_l3fwd_1ports_1S_2C_1T(self):
+        """
+        L3fwd main 1 ports.
+        """
+
+        header_row = ["Frame Size(bytes)", "Throughput(Mpps)", "linerate%",
+                      "Latency  Max(ns)", "Latency  Average(ns)", "Latency  Min(ns)"]
+        self.l3fwd_test_results['header'] = header_row
+        dts.results_table_add_header(header_row)
+        self.l3fwd_test_results['data'] = []
+
+        for frame_size in TestL3fwd.frame_sizes:
+
+            # Prepare traffic flow
+            payload_size = frame_size - \
+                HEADER_SIZE['ip'] - HEADER_SIZE['eth']
+
+            flows = ['Ether()/%s/("X"*%d)' % (flow, payload_size)
+                     for flow in self.flows()[:1]]
+
+            dts.report("Flows for 1 ports, %d frame size.\n" % (frame_size),
+                       annex=True)
+            dts.report("%s" % string.join(flows, '\n'),
+                       frame=True, annex=True)
+
+            self.tester.scapy_append(
+                'wrpcap("test2ports.pcap", [%s])' % string.join(flows, ','))
+            self.tester.scapy_execute()
+
+            # Prepare the command line
+            global corelist
+            global corelist_jumboframe
+            pat = re.compile("P([0123]),([0123]),(C\{\d.\d.\d\})")
+            coreMask = {}
+
+            rtCmdLines = dict(TestL3fwd.test_cases_1_ports_1S_2C_1T)
+
+            for key in rtCmdLines.keys():
+                corelist = []
+                while pat.search(rtCmdLines[key]):
+                    rtCmdLines[key] = pat.sub(self.repl, rtCmdLines[key])
+                self.logger.info("%s\n" % str(corelist))
+                coreMask[key] = dts.create_mask(set(corelist))
+
+            # measure by two different mode
+            for mode in TestL3fwd.methods:
+
+                # start l3fwd
+                index = 0
+                subtitle = []
+                for cores in rtCmdLines.keys():
+
+                    info = "Executing l3fwd using %s mode, 1 ports, %s and %d frame size.\n" % (
+                           mode, cores, frame_size)
+
+                    self.logger.info(info)
+                    dts.report(info, annex=True)
+
+                    subtitle.append(cores)
+
+                    if frame_size == 2048:
+                        cmdline = rtCmdLines[cores] % (TestL3fwd.path + "l3fwd_" + mode, coreMask[cores],
+                         self.dut.get_memory_channels(), dts.create_mask(valports[:1]))
+                        cmdline = cmdline + " --enable-jumbo --max-pkt-len " + "%d" % frame_size
+                    else:
+                        cmdline = rtCmdLines[cores] % (TestL3fwd.path + "l3fwd_" + mode, coreMask[cores],
+                         self.dut.get_memory_channels(), dts.create_mask(valports[:1]))
+
+                    dts.report(cmdline + "\n", frame=True, annex=True)
+
+                    out = self.dut.send_expect(cmdline, "L3FWD:", 120)
+
+                    # Measure test
+                    tgenInput = []
+                    for rxPort in range(1):
+                        txIntf = self.tester.get_local_port(valports[rxPort])
+                        rxIntf = self.tester.get_local_port(valports[rxPort])
+
+                        tgenInput.append((txIntf, rxIntf, "test2ports.pcap"))
+
+                    _, pps = self.tester.traffic_generator_throughput(
+                        tgenInput)
+                    self.verify(pps > 0, "No traffic detected")
+                    pps /= 1000000.0
+                    linerate = self.wirespeed(self.nic, frame_size, 1)
+                    pct = pps * 100 / linerate
+
+                    latencys = self.tester.traffic_generator_latency(tgenInput)
+                    print latencys
+
+                    index += 1
+
+                    # Stop l3fwd
+                    self.dut.send_expect("^C", "#")
+
+                    for latency in latencys:
+                        data_row = [frame_size, str(pps), str(pct), str(
+                            latency['max']), str(latency['average']), str(latency['min'])]
+                    dts.results_table_add_row(data_row)
+                    self.l3fwd_test_results['data'].append(data_row)
+
+        dts.results_table_print()
+
+    def test_perf_l3fwd_4ports_1S_1C_1T(self):
+        """
+        L3fwd main 4 ports.
+        """
+
+        # Based on h/w type, choose how many ports to use
+        ports = self.dut.get_ports(self.nic)
+        # Verify that enough ports are available
+        self.verify(len(ports) >= 4, "Insufficient ports for speed testing")
+
+#        header_row = ["Frame size", "RX Queues/NIC Port", "S/C/T"]
+        header_row = ["Frame Size(bytes)"]
+
+        for method in TestL3fwd.methods:
+            header_row.append('Throughput(Mpps)')
+            header_row.append('linerate%')
+
+        dts.results_table_add_header(header_row)
+        self.l3fwd_test_results['header'] = header_row
+        self.l3fwd_test_results['data'] = []
+
+        for frame_size in TestL3fwd.frame_sizes:
+
+            # Prepare traffic flow
+            payload_size = frame_size -  \
+                HEADER_SIZE['ip'] - HEADER_SIZE['eth']
+
+            for _port in range(4):
+                
+                dmac = self.dut.get_mac_address(valports[_port])
+                print dmac,"\n"
+                flows = ['Ether(dst="%s")/%s/("X"*%d)' % (dmac, flow, payload_size)
+                         for flow in self.flows()[_port * 2:(_port + 1) * 2]]
+                self.tester.scapy_append(
+                    'wrpcap("dst%d.pcap", [%s])' % (valports[_port], string.join(flows, ',')))
+
+            self.tester.scapy_execute()
+
+            dts.report("Flows for 4 ports, %d frame size.\n" % (frame_size),
+                       annex=True)
+            dts.report("%s" % string.join(flows, '\n'),
+                       frame=True, annex=True)
+
+            # Get the number of sockets of the board
+            number_sockets = self.dut.send_expect(
+                "grep \"processor\|physical id\|core id\|^$\" /proc/cpuinfo | grep physical | sort -u | wc -l", "# ")
+            number_sockets = int(number_sockets.split('\r\n')[0])
+
+            # Run case by case
+            for test_case in TestL3fwd.test_cases_4_ports_1S_1C_1T:
+
+                # Check if the board has sockets enough for the test case
+                if number_sockets >= int(test_case[1].split('/')[0][0]):
+                    self.get_throughput(frame_size, *test_case)
+
+        dts.results_table_print()
+
+    def test_perf_l3fwd_2ports_1S_2C_1T(self):
+        """
+        L3fwd main 2 ports.
+        """
+
+        header_row = ["Frame Size", "Throughput(Mpps)", "linerate%", "LR_loss_pkts(2mins)", "LR_tx_pkts(2mins)", "LR_rx_pkts(2mins)"]
+        self.l3fwd_test_results['header'] = header_row
+        dts.results_table_add_header(header_row)
+        self.l3fwd_test_results['data'] = []
+
+        for frame_size in TestL3fwd.frame_sizes:
+
+            # Prepare traffic flow
+            payload_size = frame_size - \
+                HEADER_SIZE['ip'] - HEADER_SIZE['eth']
+
+            flows = ['Ether()/%s/("X"*%d)' % (flow, payload_size)
+                     for flow in self.flows()[:4]]
+
+            dts.report("Flows for 2 ports, %d frame size.\n" % (frame_size),
+                       annex=True)
+            dts.report("%s" % string.join(flows, '\n'),
+                       frame=True, annex=True)
+
+            self.tester.scapy_append(
+                'wrpcap("test2ports.pcap", [%s])' % string.join(flows, ','))
+            self.tester.scapy_execute()
+
+            # Prepare the command line
+            global corelist
+            pat = re.compile("P([0123]),([0123]),(C\{\d.\d.\d\})")
+            coreMask = {}
+            rtCmdLines = dict(TestL3fwd.test_cases_2_ports_1S_2C_1T)
+            for key in rtCmdLines.keys():
+                corelist = []
+                while pat.search(rtCmdLines[key]):
+                    rtCmdLines[key] = pat.sub(self.repl, rtCmdLines[key])
+                self.logger.info("%s\n" % str(corelist))
+                coreMask[key] = dts.create_mask(set(corelist))
+
+            # measure by two different mode
+            for mode in TestL3fwd.methods:
+
+                # start l3fwd
+                index = 0
+                subtitle = []
+                for cores in rtCmdLines.keys():
+
+                    info = "Executing l3fwd using %s mode, 2 ports, %s and %d frame size.\n" % (
+                           mode, cores, frame_size)
+
+                    self.logger.info(info)
+                    dts.report(info, annex=True)
+
+                    subtitle.append(cores)
+                    if frame_size == 2048:
+                        cmdline = rtCmdLines[cores] % (TestL3fwd.path + "l3fwd_" + mode, coreMask[cores],
+                         self.dut.get_memory_channels(), dts.create_mask(valports[:2]))
+
+                        cmdline = cmdline + " --enable-jumbo --max-pkt-len " + "%d" % frame_size
+                    else:
+                        cmdline = rtCmdLines[cores] % (TestL3fwd.path + "l3fwd_" + mode, coreMask[cores],
+                         self.dut.get_memory_channels(), dts.create_mask(valports[:2]))
+
+                    dts.report(cmdline + "\n", frame=True, annex=True)
+
+                    out = self.dut.send_expect(cmdline, "L3FWD:", 120)
+
+                    # Measure test
+                    tgenInput = []
+                    for rxPort in range(2):
+                        # No use on rx/tx limitation
+                        if rxPort % 2 == 0:
+                            txIntf = self.tester.get_local_port(
+                                valports[rxPort + 1])
+                        else:
+                            txIntf = self.tester.get_local_port(
+                                valports[rxPort - 1])
+
+                        rxIntf = self.tester.get_local_port(valports[rxPort])
+
+                        tgenInput.append((txIntf, rxIntf, "test2ports.pcap"))
+
+                    _, pps = self.tester.traffic_generator_throughput(
+                        tgenInput)
+                    self.verify(pps > 0, "No traffic detected")
+                    pps /= 1000000.0
+                    linerate = self.wirespeed(self.nic, frame_size, 2)
+                    pct = pps * 100 / linerate
+		    zero_loss_rate, tx_num, rx_num = self.RFC2544(tgenInput)
+		    loss_num = tx_num - rx_num
+
+                    latencys = self.tester.traffic_generator_latency(tgenInput)
+                    print latencys
+
+                    index += 1
+
+                    # Stop l3fwd
+                    self.dut.send_expect("^C", "#")
+
+                    data_row = [frame_size, str(pps), str(pct), str(loss_num), str(tx_num), str(rx_num)]
+                    dts.results_table_add_row(data_row)
+
+                    self.l3fwd_test_results['data'].append(data_row)
+
+        dts.results_table_print()
+
+    def test_perf_l3fwd_1ports_1S_1C_1T(self):
+        """
+        L3fwd main 1 ports.
+        """
+
+        header_row = ["Frame Size(bytes)", "Throughput(Mpps)", "linerate%",
+                      "Latency  Max(ns)", "Latency  Average(ns)", "Latency  Min(ns)"]
+        self.l3fwd_test_results['header'] = header_row
+        dts.results_table_add_header(header_row)
+        self.l3fwd_test_results['data'] = []
+
+        for frame_size in TestL3fwd.frame_sizes:
+
+            # Prepare traffic flow
+            payload_size = frame_size - \
+                HEADER_SIZE['ip'] - HEADER_SIZE['eth']
+
+            flows = ['Ether()/%s/("X"*%d)' % (flow, payload_size)
+                     for flow in self.flows()[:1]]
+
+            dts.report("Flows for 1 ports, %d frame size.\n" % (frame_size),
+                       annex=True)
+            dts.report("%s" % string.join(flows, '\n'),
+                       frame=True, annex=True)
+
+            self.tester.scapy_append(
+                'wrpcap("test2ports.pcap", [%s])' % string.join(flows, ','))
+            self.tester.scapy_execute()
+
+            # Prepare the command line
+            global corelist
+            global corelist_jumboframe
+            pat = re.compile("P([0123]),([0123]),(C\{\d.\d.\d\})")
+            coreMask = {}
+
+            rtCmdLines = dict(TestL3fwd.test_cases_1_ports_1S_1C_1T)
+
+            for key in rtCmdLines.keys():
+                corelist = []
+                while pat.search(rtCmdLines[key]):
+                    rtCmdLines[key] = pat.sub(self.repl, rtCmdLines[key])
+                self.logger.info("%s\n" % str(corelist))
+                coreMask[key] = dts.create_mask(set(corelist))
+
+            # measure by two different mode
+            for mode in TestL3fwd.methods:
+
+                # start l3fwd
+                index = 0
+                subtitle = []
+                for cores in rtCmdLines.keys():
+
+                    info = "Executing l3fwd using %s mode, 1 ports, %s and %d frame size.\n" % (
+                           mode, cores, frame_size)
+
+                    self.logger.info(info)
+                    dts.report(info, annex=True)
+
+                    subtitle.append(cores)
+
+                    if frame_size == 2048:
+                        cmdline = rtCmdLines[cores] % (TestL3fwd.path + "l3fwd_" + mode, coreMask[cores],
+                         self.dut.get_memory_channels(), dts.create_mask(valports[:1]))
+
+                        cmdline = cmdline + " --enable-jumbo --max-pkt-len " + "%d" % frame_size
+                    else:
+                        cmdline = rtCmdLines[cores] % (TestL3fwd.path + "l3fwd_" + mode, coreMask[cores],
+                         self.dut.get_memory_channels(), dts.create_mask(valports[:1]))
+
+                    dts.report(cmdline + "\n", frame=True, annex=True)
+
+                    out = self.dut.send_expect(cmdline, "L3FWD:", 120)
+
+                    # Measure test
+                    tgenInput = []
+                    for rxPort in range(1):
+                        txIntf = self.tester.get_local_port(valports[rxPort])
+                        rxIntf = self.tester.get_local_port(valports[rxPort])
+
+                        tgenInput.append((txIntf, rxIntf, "test2ports.pcap"))
+
+                    _, pps = self.tester.traffic_generator_throughput(
+                        tgenInput)
+                    self.verify(pps > 0, "No traffic detected")
+                    pps /= 1000000.0
+                    linerate = self.wirespeed(self.nic, frame_size, 1)
+                    pct = pps * 100 / linerate
+
+                    latencys = self.tester.traffic_generator_latency(tgenInput)
+                    print latencys
+
                     index += 1
 
                     # Stop l3fwd
                     self.dut.send_expect("^C", "#")
 
-                    data_row = [frame_size, 2, cores, str(pps), str(pct), mode]
+                    for latency in latencys:
+                        data_row = [frame_size, str(pps), str(pct), str(
+                            latency['max']), str(latency['average']), str(latency['min'])]
                     dts.results_table_add_row(data_row)
                     self.l3fwd_test_results['data'].append(data_row)
 
-        self.plot_2_ports()
         dts.results_table_print()
 
     def ip(self, port, frag, src, proto, tos, dst, chksum, len, options, version, flags, ihl, ttl, id):
-- 
1.9.3



More information about the dts mailing list