test suite reviews and discussions
 help / color / mirror / Atom feed
* [dts] [PATCH] L3fwd: Add RFC2544 support and able to print loss packets in linerate now.
@ 2015-10-22  2:10 Ding Heng
  2015-10-22  2:21 ` Xu, Qian Q
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Ding Heng @ 2015-10-22  2:10 UTC (permalink / raw)
  To: dts; +Cc: Ding Heng

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
 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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [dts] [PATCH] L3fwd: Add RFC2544 support and able to print loss packets in linerate now.
  2015-10-22  2:10 [dts] [PATCH] L3fwd: Add RFC2544 support and able to print loss packets in linerate now Ding Heng
@ 2015-10-22  2:21 ` Xu, Qian Q
  2015-10-22  2:41 ` Qiu, Michael
  2015-10-22  3:16 ` Liu, Yong
  2 siblings, 0 replies; 4+ messages in thread
From: Xu, Qian Q @ 2015-10-22  2:21 UTC (permalink / raw)
  To: Ding, HengX, dts; +Cc: Ding, HengX

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@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
 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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [dts] [PATCH] L3fwd: Add RFC2544 support and able to print loss packets in linerate now.
  2015-10-22  2:10 [dts] [PATCH] L3fwd: Add RFC2544 support and able to print loss packets in linerate now Ding Heng
  2015-10-22  2:21 ` Xu, Qian Q
@ 2015-10-22  2:41 ` Qiu, Michael
  2015-10-22  3:16 ` Liu, Yong
  2 siblings, 0 replies; 4+ messages in thread
From: Qiu, Michael @ 2015-10-22  2:41 UTC (permalink / raw)
  To: Ding, HengX, dts

You should remove "-P" option, and for RRC, the packet L2 should include
src mac

Thanks,
Michael


On 2015/10/22 10:10, Ding Heng wrote:
> 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
>  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):


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [dts] [PATCH] L3fwd: Add RFC2544 support and able to print loss packets in linerate now.
  2015-10-22  2:10 [dts] [PATCH] L3fwd: Add RFC2544 support and able to print loss packets in linerate now Ding Heng
  2015-10-22  2:21 ` Xu, Qian Q
  2015-10-22  2:41 ` Qiu, Michael
@ 2015-10-22  3:16 ` Liu, Yong
  2 siblings, 0 replies; 4+ messages in thread
From: Liu, Yong @ 2015-10-22  3:16 UTC (permalink / raw)
  To: Ding, HengX, dts; +Cc: Ding, HengX

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

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-10-22  3:16 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-22  2:10 [dts] [PATCH] L3fwd: Add RFC2544 support and able to print loss packets in linerate now 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 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).