[dts] [PATCH] l3fwd: optimize l3fwd performance suite

Yong Liu yong.liu at intel.com
Thu Feb 26 03:56:10 CET 2015


Unify 2 ports and 4 ports performance functions, for they have the same logic.
Config IXIA flow with random source ip address, thus will seperate flows into
several queues. Remove unless plot function.

Signed-off-by: Marvinliu <yong.liu at intel.com>

diff --git a/tests/TestSuite_l3fwd.py b/tests/TestSuite_l3fwd.py
index 65fa6f7..d8f02c9 100644
--- a/tests/TestSuite_l3fwd.py
+++ b/tests/TestSuite_l3fwd.py
@@ -1,6 +1,6 @@
 # BSD LICENSE
 #
-# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -37,67 +37,47 @@ Layer-3 forwarding test script.
 import dts
 import string
 import re
-from plotting import Plotting
 from test_case import TestCase
+from etgen import IxiaPacketGenerator
 from exception import VerifyFailure
 from settings import HEADER_SIZE
 
 
-class TestL3fwd(TestCase):
-
+class TestL3fwd(TestCase, IxiaPacketGenerator):
     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_2_ports = {
+        "1S/1C/2T  (1Q/port)": "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0})'",
+        "1S/1C/2T  (1Q/port)": "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}), (P1,0,C{1.1.1})'",
+        "1S/2C/1T  (1Q/port)": "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}), (P1,0,C{1.2.0})'",
+        "1S/2C/2T  (1Q/port)": "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}), (P1,0,C{1.2.1})'",
+        "1S/2C/4T  (2Q/port)": "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}), (P0,1,C{1.2.1}),(P1,0,C{1.3.0}),(P1,1,C{1.4.1})'",
+        "1S/4C/4T  (2Q/port)": "%s -c %s -n %d -- -p %s -P --config '(P0,0,C{1.1.0}), (P0,1,C{1.2.1}),(P1,0,C{1.3.0}),(P1,1,C{1.4.1})'"
+    }
+
+    test_cases_4_ports = {
+        "1S/1C/1T (1Q/port)": "%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})'",
+        "1S/1C/2T (1Q/port)": "%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})'",
+        "1S/2C/1T (1Q/port)": "%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})'",
+        "1S/2C/2T (1Q/port)": "%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})'",
+        "1S/4C/1T (1Q/port)": "%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})'",
+        "2S/1C/1T (1Q/port)": "%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})'",
+        "2S/1C/2T (1Q/port)": "%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})'",
+        "2S/2C/1T (1Q/port)": "%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})'",
+
+        "1S/1C/1T (2Q/port)": "%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})'",
+        "1S/1C/2T (2Q/port)": "%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})'",
+        "1S/2C/1T (2Q/port)": "%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})'",
+        "1S/2C/2T (2Q/port)": "%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})'",
+        "1S/4C/1T (2Q/port)": "%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})'",
+        "1S/4C/2T (2Q/port)": "%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})'",
+        "2S/1C/1T (2Q/port)": "%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})'",
+        "2S/1C/2T (2Q/port)": "%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})'",
+        "2S/2C/1T (2Q/port)": "%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})'",
+        "2S/2C/2T (2Q/port)": "%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})'",
+        "2S/4C/1T (2Q/port)": "%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})'"
                           }
 
-    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)
-
     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}",
@@ -120,14 +100,11 @@ class TestL3fwd(TestCase):
         "{IPv4(13,101,0,0), 24, P3}",
     ]
 
-    frame_sizes = [64]  # 65, 128
+    frame_sizes = [128]
 
     methods = ['lpm', 'exact']
 
-    #
-    #
     # Utility methods and other non-test code.
-    #
     # Insert or move non-test functions here.
     def portRepl(self, match):
         """
@@ -141,166 +118,6 @@ class TestL3fwd(TestCase):
         else:
             return '%s' % valports[int(portid)]
 
-    #
-    #
-    #
-    # 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.
@@ -308,24 +125,24 @@ class TestL3fwd(TestCase):
 
         L3fwd Prerequisites
         """
-        # Based on h/w type, choose how many ports to use
-        ports = self.dut.get_ports(socket=1)
-        if not ports:
-            ports = self.dut.get_ports(socket=0)
+        # Update packet generator ip function
+        self.tester.extend_external_packet_generator(TestL3fwd, self)
+
+        # Performance validation force to use same socket nic
+        self.ports = self.dut.get_ports_performance(force_same_socket=True,
+                                               force_different_nic=False)
 
         # Verify that enough ports are available
-        self.verify(len(ports) >= 2, "Insufficient ports for speed testing")
+        self.verify(len(self.ports) >= 2, "Insufficient ports for speed testing")
 
         # Verify that enough threads are available
         cores = self.dut.get_core_list("2S/4C/2T")
         self.verify(cores is not None, "Insufficient cores for speed testing")
 
         global valports
-        valports = [_ for _ in ports if self.tester.get_local_port(_) != -1]
-        self.verify(len(valports) >= 2, "Insufficient active ports for speed testing")
+        valports = [_ for _ in self.ports if self.tester.get_local_port(_) != -1]
 
         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)):
@@ -362,11 +179,6 @@ class TestL3fwd(TestCase):
         # 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': []}
-
-        self.plotting = Plotting(self.dut.crb['name'], self.target, self.nic)
-
     def flows(self):
         """
         Return a list of packets that implements the flows described in the
@@ -398,11 +210,10 @@ class TestL3fwd(TestCase):
 
         return '%s,%s,%s' % (str(valports[int(pid)]), qid, lcid)
 
-    def get_throughput(self, frame_size, rx_queues_per_port, cores_config, command_line):
+    def get_throughput(self, port_num, frame_size, test_case, command_line):
         """
         Get the throughput for a test case from test_cases_4_ports.
         """
-
         output_pattern = re.compile("P([0123]),([0123]),(C\{\d.\d.\d\})")
 
         bps = dict()
@@ -412,19 +223,39 @@ class TestL3fwd(TestCase):
         global corelist
         corelist = []
 
+        conf_regex = "(.*) \((.*)\)"
+        m = re.match(conf_regex, test_case)
+        if m is not None:
+            cores_config = m.group(1)
+            rx_queues_per_port = m.group(2)
+
         while output_pattern.search(command_line):
             command_line = output_pattern.sub(self.repl, command_line)
 
         self.logger.debug("%s\n" % str(corelist))
         core_mask = dts.create_mask(set(corelist))
 
+        # Prepare traffic flow
+        payload_size = frame_size - HEADER_SIZE['udp'] - \
+            HEADER_SIZE['ip'] - HEADER_SIZE['eth']
+
+        for _port in range(port_num):
+            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, ',')))
+        self.tester.scapy_execute()
+
+        dts.report("Flows for %d ports, %d frame size.\n" % (port_num, frame_size), annex=True)
+        dts.report("%s" % string.join(flows, '\n'), frame=True, annex=True)
+
+        # Get the number of sockets of the board
         # 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]))
+                                                  dts.create_mask(valports[:port_num]))
 
             dts.report(method_command_line + "\n", frame=True, annex=True)
 
@@ -432,7 +263,7 @@ class TestL3fwd(TestCase):
 
             # measure test
             tgen_input = []
-            for rxPort in range(4):
+            for rxPort in range(port_num):
                 if rxPort % 2 == 0:
                     tx_interface = self.tester.get_local_port(valports[rxPort + 1])
                 else:
@@ -448,18 +279,16 @@ class TestL3fwd(TestCase):
             pct[method] = pps[method] * 100 / float(self.wirespeed(self.nic,
                                                                    frame_size,
                                                                    4))
-
             # stop l3fwd
             self.dut.send_expect("^C", "#")
 
-        data_row = [frame_size, rx_queues_per_port, cores_config]
-        for method in TestL3fwd.methods:
+            data_row = [frame_size, rx_queues_per_port, cores_config]
             data_row.append(pps[method])
             data_row.append(pct[method])
+            data_row.append(method)
 
         # generate report table
         dts.results_table_add_row(data_row)
-        self.l3fwd_test_results['data'].append(data_row)
 
     def set_up(self):
         """
@@ -471,143 +300,36 @@ class TestL3fwd(TestCase):
         """
         L3fwd main 4 ports.
         """
-
-        # Based on h/w type, choose how many ports to use
-        ports = self.dut.get_ports()
         # 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"]
-
-        for method in TestL3fwd.methods:
-            header_row.append('%s Mpps' % method)
-            header_row.append('% linerate')
+        self.verify(len(self.ports) >= 4, "Insufficient ports for speed testing")
 
+        header_row = ["Frame", "Ports", "S/C/T", "Mpps", "% linerate", "mode"]
         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['udp'] - \
-                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, ',')))
-
-            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:
-
                 # 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)
+                if number_sockets >= int(test_case.split('/')[0][0]):
+                    self.get_throughput(4, frame_size, test_case, TestL3fwd.test_cases_4_ports[test_case])
 
-        self.plot_4_ports()
         dts.results_table_print()
 
     def test_perf_l3fwd_2ports(self):
         """
         L3fwd main 2 ports.
         """
-
         header_row = ["Frame", "Ports", "S/C/T", "Mpps", "% linerate", "mode"]
-        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:
+            for test_case in TestL3fwd.test_cases_2_ports:
+                self.get_throughput(2, frame_size, test_case, TestL3fwd.test_cases_2_ports[test_case])
 
-            # Prepare traffic flow
-            payload_size = frame_size - HEADER_SIZE['udp'] - \
-                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)
-            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)
-                    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
-
-                    index += 1
-
-                    # Stop l3fwd
-                    self.dut.send_expect("^C", "#")
-
-                    data_row = [frame_size, 2, cores, str(pps), str(pct), mode]
-                    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):
@@ -628,6 +350,7 @@ class TestL3fwd(TestCase):
         """
         Run after each test case.
         """
+        self.dut.kill_all()
         pass
 
     def tear_down_all(self):
-- 
1.9.3



More information about the dts mailing list