[dts] [DTS][PATCH V1 2/2] add test suite for performance thread perf test

Wang Fei feix.y.wang at intel.com
Tue Aug 28 14:43:02 CEST 2018


Signed-off-by: Wang Fei <feix.y.wang at intel.com>
---
 tests/TestSuite_performance_thread.py | 247 ++++++++++++++++++++++++++
 1 file changed, 247 insertions(+)
 create mode 100644 tests/TestSuite_performance_thread.py

diff --git a/tests/TestSuite_performance_thread.py b/tests/TestSuite_performance_thread.py
new file mode 100644
index 0000000..e1e5be6
--- /dev/null
+++ b/tests/TestSuite_performance_thread.py
@@ -0,0 +1,247 @@
+# 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.
+
+"""
+DPDK Test suite.
+Performance-Thread test script.
+"""
+
+import utils
+
+from test_case import TestCase
+from settings import HEADER_SIZE
+from etgen import IxiaPacketGenerator
+import pdb
+
+class TestPerformanceThread(TestCase, IxiaPacketGenerator):
+
+    def set_up_all(self):
+        self.ports = self.dut.get_ports()
+        self.verify(len(self.ports) >= 2, "Insufficent Ports")
+        self.socket = self.dut.get_numa_id(self.ports[0])
+        self.port0_mac = self.dut.get_mac_address(self.ports[0])
+        self.port1_mac = self.dut.get_mac_address(self.ports[1])
+
+        self.tester.extend_external_packet_generator(TestPerformanceThread, self)
+
+        self.frame_sizes = [64, 128, 256, 512, 1024, 2000]
+        self.headers_size = HEADER_SIZE['eth'] + HEADER_SIZE['ip'] + HEADER_SIZE['tcp']
+        self.nb_cores = [2, 4, 8, 16]
+        self.path = "examples/performance-thread/l3fwd-thread/build/l3fwd-thread"
+
+        #results table header
+        self.header = ["Cores", "Fsize", "Unidirectional MPPS", "Line Rate(%)", "Bidirectional MPPS", "Line Rate(%)"]
+        
+        # compile performance_thread app
+        out = self.dut.build_dpdk_apps("./examples/performance-thread/l3fwd-thread")
+        self.verify("Error" not in out, "compilation error 1")
+        self.verify("No such file" not in out, "compilation error 2")
+
+    def set_up(self):
+        pass
+
+    def test_perf_one_lcore_per_pcore(self):
+        nb_cores = self.nb_cores
+        params = "-n 2 -- -P -p 3 --enable-jumbo --max-pkt-len=2500 --no-lthread"
+        test_data = {}
+        for cores in nb_cores:
+            _, core_mask = self.create_cores(cores)
+            _,rx, tx = self.config_rx_tx(cores)
+            app_cmdline = "{} -c {} {} --rx='{}' --tx='{}'".format(self.path, core_mask, params, rx, tx)
+            self.dut.send_expect(app_cmdline, "", 15)
+            test_data[cores] = self.start_traffic()
+            self.dut.send_expect("^C", "# ", 15)
+        self.print_result(test_data)
+
+    def test_perf_n_lthreads_per_pcore(self):
+        nb_cores = self.nb_cores
+        params = "-n 2 -- -P -p 3 --enable-jumbo --max-pkt-len=2500"
+        test_data = {}
+        for cores in nb_cores:
+            _, core_mask = self.create_cores(cores)
+            _,rx, tx = self.config_rx_tx(cores)
+            app_cmdline = "{} -c {} {} --rx='{}' --tx='{}'".format(self.path, core_mask, params, rx, tx)
+            self.dut.send_expect(app_cmdline, "", 15)
+            test_data[cores] = self.start_traffic()
+            self.dut.send_expect("^C", "# ", 15)
+        self.print_result(test_data)
+
+    def test_perf_n_lcore_per_pcore(self):
+        nb_cores = self.nb_cores
+        params = "-- -P -p 3 --enable-jumbo --max-pkt-len 2500 --no-lthread"
+        test_data = {}
+        for cores in nb_cores:
+            _, core_mask = self.create_cores(cores)
+            rxtx_config, rx, tx = self.config_rx_tx(cores)
+            #app_cmdline = "{} -c {} -n 2 --lcores='{}' {} --rx='{}' --tx='{}'".format(self.path, core_mask, rxtx_config, params, rx, tx)
+            app_cmdline = "{} -n 2 --lcores='{}' {} --rx='{}' --tx='{}'".format(self.path, rxtx_config, params, rx, tx)
+            self.dut.send_expect(app_cmdline, "", 15)
+            test_data[cores] = self.start_traffic()
+            self.dut.send_expect("^C", "# ", 15)
+        self.print_result(test_data)
+
+    def create_cores(self, nb_cores):
+        if nb_cores == 2:
+            core_config = "1S/2C/1T"
+        elif nb_cores == 4:
+            core_config = "1S/4C/1T"
+        elif nb_cores == 8:
+            core_config = "1S/8C/1T"
+        elif nb_cores == 16:
+            core_config = "1S/16C/1T"
+        core_list = self.dut.get_core_list(core_config, self.socket)
+        core_mask = utils.create_mask(core_list)
+        return core_list, core_mask
+
+    def config_rx_tx(self, cores):
+        socket = self.socket
+        ports = range(len(self.ports))
+        tx_config = ""
+        rx_config = ""
+        core_mask = ""
+        lcore_config = ""
+        assert cores in self.nb_cores
+
+        #config --tx and --tx params for performace thread app
+        if cores == 2:
+            core_list, core_mask = self.create_cores(cores)
+            lcore_config = "(%s-%s)@%s" % (core_list[0],core_list[-1], core_list[0])
+            rx = "({},{},{},{})".format(ports[0], 0, core_list[0], 0) + "," + \
+                 "({},{},{},{})".format(ports[1], 0, core_list[0], 0)
+            tx = "({},{})".format(core_list[1], 0)
+        elif cores == 4:
+            core_list, core_mask = self.create_cores(cores)
+            lcore_config = "(%s-%s)@%s" % (core_list[0], core_list[-1], core_list[0])
+            rx = "({},{},{},{})".format(ports[0], 0, core_list[0], 0) + "," + \
+                 "({},{},{},{})".format(ports[1], 0, core_list[1], 1)
+            tx = "({},{})".format(core_list[2], 0) + "," + \
+                 "({},{})".format(core_list[3], 1)
+        elif cores == 8:
+            core_list, core_mask = self.create_cores(cores)
+            lcore_config = "(%s-%s)@%s" % (core_list[0], core_list[-1], core_list[0])
+            rx = "({},{},{},{})".format(ports[0], 0, core_list[0], 0) + "," + \
+                 "({},{},{},{})".format(ports[0], 1, core_list[1], 1) + "," + \
+                 "({},{},{},{})".format(ports[1], 0, core_list[2], 2) + "," + \
+                 "({},{},{},{})".format(ports[1], 1, core_list[3], 3)
+            tx = "({},{})".format(core_list[4], 0) + "," + "({},{})".format(core_list[5], 1) + "," + \
+                 "({},{})".format(core_list[6], 2) + "," + "({},{})".format(core_list[7], 3)
+        elif cores == 16:
+            core_list, core_mask = self.create_cores(cores)
+            lcore_config = "(%s-%s)@%s" % (core_list[0], core_list[-1], core_list[0])
+            rx = "({},{},{},{})".format(ports[0], 0, core_list[0], 0) + "," + \
+                 "({},{},{},{})".format(ports[0], 1, core_list[1], 1) + "," + \
+                 "({},{},{},{})".format(ports[0], 2, core_list[2], 2) + "," + \
+                 "({},{},{},{})".format(ports[0], 3, core_list[3], 3) + "," + \
+                 "({},{},{},{})".format(ports[1], 0, core_list[4], 4) + "," + \
+                 "({},{},{},{})".format(ports[1], 1, core_list[5], 5) + "," + \
+                 "({},{},{},{})".format(ports[1], 2, core_list[6], 6) + "," + \
+                 "({},{},{},{})".format(ports[1], 3, core_list[7], 7)
+            tx = "({},{})".format(core_list[8], 0) + "," + "({},{})".format(core_list[9], 1) + "," + \
+                 "({},{})".format(core_list[10], 2) + "," + "({},{})".format(core_list[11], 3) + "," + \
+                 "({},{})".format(core_list[12], 4) + "," + "({},{})".format(core_list[13], 5) + "," + \
+                 "({},{})".format(core_list[14], 6) + "," + "({},{})".format(core_list[15], 7)
+        return lcore_config, rx, tx
+
+    def start_traffic(self):
+        frame_sizes = self.frame_sizes
+        headers_size = self.headers_size
+        ports = self.ports
+        dmac0 = self.port0_mac
+        dmac1 = self.port1_mac
+        
+        tgen_input_unidirection = []
+        tgen_input_unidirection.append((self.tester.get_local_port(ports[0]),
+                           self.tester.get_local_port(ports[1]),
+                           "stream0.pcap"))
+
+        tgen_input_bidirection = []
+        tgen_input_bidirection.append((self.tester.get_local_port(ports[0]),
+                                       self.tester.get_local_port(ports[1]),
+                                       "stream0.pcap"))
+        tgen_input_bidirection.append((self.tester.get_local_port(ports[1]),
+                                       self.tester.get_local_port(ports[0]),
+                                       "stream1.pcap"))
+
+        result_data = {}
+        for frame_size in frame_sizes:
+            # create pcap file
+            payload_size = frame_size - headers_size
+            self.tester.scapy_append(
+                'wrpcap("stream0.pcap", [Ether(src="52:00:00:00:00:00",dst="%s")/IP(src="1.2.3.4",dst="2.1.1.1")/TCP()/("X"*%d)])' % 
+                     (dmac0, payload_size))
+            self.tester.scapy_execute()
+            self.logger.info("Starting Uni-Direction Traffic For Frame Size: %s" % frame_size)
+            _, pps = self.tester.traffic_generator_throughput(tgen_input_unidirection, rate_percent=100, delay=20)
+            mpps = pps / 1000000.0
+            self.verify( mpps != 0, "Traffic Blocked")
+            wirespeed = self.wirespeed(self.nic, frame_size, 1)
+            rate = (mpps / wirespeed) * 100
+            result_data[frame_size] = [mpps, rate]
+
+            self.logger.info("Starting Bi-direction Traffic For Frame Size: %s" % frame_size)
+            self.tester.scapy_append(
+                'wrpcap("stream1.pcap", [Ether(src="52:00:00:00:00:00",dst="%s")/IP(src="1.2.3.4",dst="1.1.1.1")/TCP()/("X"*%d)])' % (
+                   dmac1, payload_size))
+            self.tester.scapy_execute()
+            _, pps = self.tester.traffic_generator_throughput(tgen_input_bidirection, rate_percent=100, delay=20)
+            mpps = pps / 1000000.0
+            self.verify( mpps != 0, "Traffic Blocked")
+            wirespeed = self.wirespeed(self.nic, frame_size, 2)
+            rate = (mpps / wirespeed) * 100
+            result_data[frame_size].extend([mpps, rate])
+
+        return result_data
+
+    def print_result(self, data):
+        '''
+        print test result table
+        '''
+        header = self.header
+        frame_sizes = self.frame_sizes
+        nb_cores = self.nb_cores
+
+        self.result_table_create(header)
+        try:
+            for nb_core in nb_cores:
+                for frame_size in frame_sizes:
+                    row = [nb_core, frame_size]
+                    row.extend(data[nb_core][frame_size])
+                    self.result_table_add(row)
+            self.result_table_print()
+        except:
+            raise
+
+    def tear_down(self):
+        pass
+
+    def tear_down_all(self):
+        pass
+
-- 
2.17.1



More information about the dts mailing list