[dts] [PATCH V1 2/3] metrics: upload automation script

yufengx.mo at intel.com yufengx.mo at intel.com
Wed Jun 6 07:36:58 CEST 2018


From: yufengmx <yufengx.mo at intel.com>


This automation script is for metrics feature.

The Metrics implements a mechanism by which *producers* can publish numeric
information for later querying by *consumers*. Here dpdk-procinfo process is the
*consumers*. latency stats and bit rate are the two implements based
on metrics lib.

Signed-off-by: yufengmx <yufengx.mo at intel.com>
---
 tests/TestSuite_metrics.py | 891 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 891 insertions(+)
 create mode 100644 tests/TestSuite_metrics.py

diff --git a/tests/TestSuite_metrics.py b/tests/TestSuite_metrics.py
new file mode 100644
index 0000000..29b4790
--- /dev/null
+++ b/tests/TestSuite_metrics.py
@@ -0,0 +1,891 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2018 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 metrics
+'''
+
+import re
+import time
+import sys, os
+import utils
+import shutil
+from collections import defaultdict
+
+from test_case import TestCase
+from pmd_output import PmdOutput
+from exception import VerifyFailure
+from etgen import IxiaPacketGenerator
+from settings import HEADER_SIZE, SCAPY2IXIA
+from packet import Packet
+import serializer
+
+class TestMetrics(TestCase, IxiaPacketGenerator):
+
+    def clear_ASLR(self):
+        '''
+        DPDK don't support ASLR open under multiprocess status, so close it
+        '''
+        cmd = "echo 0 > /proc/sys/kernel/randomize_va_space"
+        self.dut_2.send_expect(cmd, "# ", timeout=10)
+        time.sleep(2)
+
+    def reset_ASLR(self):
+        '''
+        reset ASLR to original status
+        '''
+        cmd = "echo 2 > /proc/sys/kernel/randomize_va_space"
+        self.dut_2.send_expect(cmd, "# ", timeout=10)
+        time.sleep(4)
+
+    def save_ref_data(self, ref_data, ref_data_path):
+        data_name = 'ref_data'
+        # save to pickle file
+        pkl = serializer.SerializerBase()
+        pkl.set_serialized_filename(ref_data_path)
+        pkl.save(data_name, ref_data)
+        pkl.save_to_file()
+
+    def load_ref_data(self, ref_data_path):
+        data_name = 'ref_data'
+        # save to pickle file
+        pkl = serializer.SerializerBase()
+        pkl.set_serialized_filename(ref_data_path)
+        pkl.load_from_file()
+        return pkl.volatile_cache[data_name]
+
+    def result_parse(self, stat_data, data_type, port_id='0'):
+        #config_streams()
+        check = getattr(self, "{0}_check_data".format(data_type))
+        ref_data_path = self.ref_data_path.format(data_type)
+        # if no ref data file exist, save one 
+        if not os.path.exists(ref_data_path):
+            ref_stats_ex = stat_data
+            self.save_ref_data(ref_stats_ex, ref_data_path)
+            self.logger.info("save this testing data as reference data")
+        ref_data = self.load_ref_data(ref_data_path)
+        for sub_stat in stat_data:
+            test_configs = sub_stat['test_configs']
+            for sub_ref_stat in ref_data:
+                test_ref_configs = sub_ref_stat['test_configs']
+                if cmp(test_configs, test_ref_configs) == 0:
+                    break
+            else:
+                self.logger.warning("missing testing content")
+                continue
+            check(sub_stat, sub_ref_stat, port_id)
+
+    def get_pkt(self, payload_size):
+        fmt = 'wrpcap("pause_rx.pcap", [Ether()/IP()/UDP()/("X"*{0})])'.format
+        return fmt(payload_size)
+
+    def check_packet_transmission(self, pkt_types):
+        time.sleep(1)
+        for pkt_type in pkt_types:
+            pkt = Packet(pkt_type=pkt_type)
+            refPacket = "/root/{0}_ref.pcap".format(pkt_type)
+            pkt.pktgen.write_pcap(refPacket)
+            pkt.send_pkt(tx_port=self.src_intf)
+            time.sleep(2)
+            # check dut testpmd packet received information
+            out = self.dut.get_session_output(timeout=2)
+            time.sleep(1)
+
+    def preset_testpmd(self, core_mask, options):
+        self.testpmd.start_testpmd( core_mask,
+                                    param=' '.join(['--port-topology=loop',
+                                                    options]))
+        self.execute_testpmd_cmd(self.preset_testpmd_cmds)
+        self.test_pmd_status = True
+        self.preset_testpmd_cmds = list()
+        time.sleep(1)
+
+    def execute_testpmd_cmd(self, cmds):
+        if len(cmds) == 0:
+            return
+        for item in cmds:
+            if len(item) == 2:
+                output = self.testpmd.execute_cmd(item[0], int(item[1]))
+            else:
+                output = self.testpmd.execute_cmd(item[0])
+            self.logger.info(output)
+        time.sleep(2)
+
+    def stop_testpmd(self):
+        time.sleep(1)
+        testpmd_cmds =[['stop']]
+        self.execute_testpmd_cmd(testpmd_cmds)
+        time.sleep(1)
+
+    def close_testpmd(self):
+        if not self.test_pmd_status:
+            return
+        time.sleep(1)
+        self.testpmd.quit()
+        time.sleep(1)
+        self.test_pmd_status = False
+
+    def execute_dpdk_proc(self, required_type=None):
+        self.dut_2.send_expect( self.dpdk_proc_cmd, "# ")
+        time.sleep(2)
+        msg = self.dut_2.session.get_session_before(0.5)
+        if not required_type:
+            expect_content = self.latency_content + self.bit_rate_content
+        elif required_type == 'latency':
+            expect_content = self.latency_content
+        elif required_type == 'bit rate':
+            expect_content = self.bit_rate_content
+
+        missing_content = []
+        for item in expect_content:
+            if item not in msg:
+                missing_content.append(item)
+        if missing_content:
+            self.logger.error(os.linesep.join(["metrics has no these data::"] 
+                                              + missing_content))
+            self.logger.info(msg)
+
+            #raise VerifyFailure("{0} exception ! ".format(self.query_tool))
+        self.logger.info("{0}".format(msg))
+        return msg
+
+    def ixia_pre(self):
+        pass
+
+    def check_dpdk_proc_tool(self, msg, flag=None):
+        # check data statistic tool boot up status
+        # send a specified packet, check tool output data format
+        # check loop mode/chained mode statistics data format
+        portStatus = {}
+        curPortNo = None
+        portPat = "metrics for port (\d)+.*#"
+        for item2 in msg.splitlines():
+            item = item2.strip(os.linesep)
+            if 'metrics' in item:
+                curPortNo = "".join(re.findall(portPat, item, re.M))
+                portStatus[curPortNo] = {}
+            if  curPortNo == None:
+                continue
+            if ":" in item:
+                status = item.strip().split(': ')
+                if len(status) == 2:
+                    portStatus[curPortNo][status[0]] = int(status[1].strip())
+
+        retPortStatus = {}
+        for item in portStatus:
+            if flag == 'bit rate':
+                if item == '':
+                    continue
+                retPortStatus[item] = {}
+                for item2 in self.bit_rate_content:
+                    retPortStatus[item][item2] = portStatus[item][item2]
+            elif flag == 'latency':
+                if item != '':
+                    continue
+                retPortStatus[item] = {}
+                for item2 in self.latency_content:
+                    retPortStatus[item][item2] = portStatus[item][item2]
+            else:
+                retPortStatus = portStatus
+
+        return retPortStatus
+
+    def bit_rate_check_data(self, stats, ref_stats, port_id):
+        expected_rate = 1/10e2
+        running_stats = stats['running']
+        self.compare_with_ref(stats, ref_stats, port_id, expected_rate)
+        #----------------
+        # check stats data of ixia stop
+        #---------------- 
+        stop_stats = stats['stop']
+        # check peak_bits_out/peak_bits_in
+        # it should be the same as running data
+        check_keys = ['peak_bits_out', 'peak_bits_in']
+        for key in check_keys:
+            running_data = running_stats[-1][port_id][key]
+            stop_data = stop_stats[0][port_id][key]
+            rate = abs(stop_data - running_data)/running_data
+            if rate < expected_rate:
+                msg = "peak_bits_out/peak_bits_in are correct after stop ixia"
+            else:
+                msg = ("peak_bits_out/peak_bits_in data are more than "
+                       "expect {0}").format(expected_rate)
+                self.logger.error(msg)
+                raise VerifyFailure(msg)
+            self.logger.info(msg)
+        # check mean_bits_in/mean_bits_out, it should be zero
+        even_stats = defaultdict(long)
+        for item in stop_stats:
+            for key, value in item[port_id].items():
+                even_stats[key] += value
+        check_keys = ['mean_bits_in', 'mean_bits_out']
+        for key in check_keys:
+            if key in even_stats:
+                if even_stats[key] != 0:
+                    msg = "{0} data is not zero".format(key)
+                    self.logger.error(msg)
+                    raise VerifyFailure(msg)
+                else:
+                    msg = "{0} data is correct after stop ixia".format(key)
+                    self.logger.info(msg)
+        # check ewma_bits_out/ewma_bits_in, 
+        # it should have a none-zero data at first group data
+        check_keys = ['ewma_bits_out', 'ewma_bits_in']
+        for key in check_keys:
+            if key in stop_stats[0]:
+                if stop_stats[0][key] == 0:
+                    msg = ("{0} data should not be zero "
+                           "at once at the time of stopping ixia").format(key)
+                    self.logger.error(msg)
+                    raise VerifyFailure(msg)
+                else:
+                    msg = "{0} data is correct after stop ixia".format(key)
+                    self.logger.info(msg)
+        # it should be zero at last group data
+        for key in check_keys:
+            if key in stop_stats[-1]:
+                if stop_stats[-1][key] != 0:
+                    msg = ("{0} data is not zero after "
+                           "stop a long time").format(key)
+                    self.logger.error(msg)
+                    raise VerifyFailure(msg)
+                else:
+                    msg = "{0} data is correct after stop ixia".format(key)
+                    self.logger.info(msg)
+
+    def latency_stat_check_data(self, stats, ref_stats, port_id):
+        expected_rate = 8/10e1
+        running_stats = stats['running']
+        stop_stats = stats['stop']
+        check_keys = ['min_latency_ns', 'max_latency_ns']
+        # compare with reference data
+        self.compare_with_ref(stats, ref_stats, port_id, expected_rate)
+        #----------------
+        # check stats data of ixia stop
+        #---------------- 
+        # all should be the same as running data
+        for key in check_keys:
+            running_data = running_stats[0][port_id][key]
+            stop_data = stop_stats[-1][port_id][key]
+            rate = abs(stop_data - running_data)/running_data
+            if rate < expected_rate:
+                msg = "{0} is correct after stop ixia".format(key)
+            else:
+                msg = "{0} data is {1}% more than expected".format(key,
+                                                                   rate*100)
+            self.logger.info(msg)
+        # ``jitter_ns`` is not a reliable value on packet > 1024, so ignore it
+        check_keys = ['avg_latency_ns']
+        #expected_rate = float(1/10)
+        # all should be the same as running data
+        for key in check_keys:
+            running_data = running_stats[0][port_id][key]
+            stop_data = stop_stats[-1][port_id][key]
+            rate = abs(stop_data - running_data)/running_data
+            if rate < expected_rate:
+                msg = "{0} is correct after stop ixia".format(key)
+            else:
+                msg = "{0} data is {1}% more than expected".format(key,
+                                                                   rate*100)
+            self.logger.info(msg)
+        # the sample data should be the same
+        last_stat = stop_stats[0]
+        for stat in stop_stats[1:]:
+            if cmp(last_stat, stat) != 0:
+                msg = "stat data after stop should be kept".format(key)
+                break
+        else:
+            msg = "stat data of stop is correct"
+        self.logger.info(msg)
+
+    def compare_with_ref(self, stats, ref_stats, port_id, expected_rate):
+        #----------------
+        # check stats data of ixia on running status
+        #---------------- 
+        # all stats data should be closed to reference sample data
+        # one type data is calculated by all group data's average value
+        ref_running_stats = ref_stats['running']
+        ref_even_stats = defaultdict(long)
+        for item in ref_running_stats:
+            for key, value in item[port_id].items():
+                ref_even_stats[key] += value
+        
+        running_stats = stats['running']
+        even_stats = defaultdict(long)
+        for item in running_stats:
+            for key, value in item[port_id].items():
+                even_stats[key] += value
+        if cmp(sorted(even_stats.keys()), sorted(ref_even_stats.keys())) != 0:
+            msg = "original data have different values as current data"
+            self.logger.error(msg)
+            raise VerifyFailure(msg)
+            return
+        for key in even_stats:
+            current_value = even_stats[key]
+            ref_value = ref_even_stats[key]
+            rate = float(abs(float(current_value - ref_value))/float(ref_value))
+            if rate < expected_rate:
+                msg = "{0} is correct".format(key)
+                self.logger.info(msg)
+            else:
+                msg = ("{0} data is {1}% more than "
+                       "reference data").format(key, rate*100)
+                self.logger.error(msg)
+                #raise VerifyFailure(msg)
+
+    def calculate_latency_deviation(self, ixia_result, dpdk_result):
+        compare_group = {"max latency" : [ixia_result["max"], 
+                                          dpdk_result["max_latency_ns"]],
+                         "min latency" : [ixia_result["min"],
+                                          dpdk_result["min_latency_ns"]],
+                         "average latency" : [ixia_result["average"],
+                                              dpdk_result["avg_latency_ns"]],
+                         "jitter value" : ["12", dpdk_result["jitter_ns"]],}
+        maxWidth = max(map(lambda x: len(x), compare_group.keys()))
+        for item, value in compare_group.items():
+            percent = round((float(value[0])/(float(value[1] or 1)*10))*100, 2)
+            tagStr = "{0}".format(item).ljust(maxWidth) + " deviation: "
+            msg = tagStr + "{0}%".format(percent)
+            self.logger.info(msg)
+        return
+
+    def display_metrics_data(self, port_status):
+        textLength = max(map(lambda x: len(x), self.display_seq))
+        for port in sorted(port_status.keys()):
+            port_value = port_status[port]
+            if port != None and port!= '' and int(port) == self.test_port:
+                self.logger.info("port {0}".format(port))
+                for key in self.display_seq:
+                    value = port_value[key]
+                    self.logger.info("{0} = [{1}]".format(
+                                            key.ljust(textLength), value))
+            else:
+                maxvalue = max(map(lambda x: int(x), port_value.values()))
+                if not maxvalue:
+                    continue
+                self.logger.info("port {0}".format(port))
+                for key in self.display_seq:
+                    value = port_value[key]
+                    if value:
+                        self.logger.info("{0} = [{1}]".format(
+                                                    key.ljust(textLength),
+                                                    value))
+
+    def set_up_all(self):
+        self.dut_ports = self.dut.get_ports(self.nic)
+        self.verify(len(self.dut_ports) >= 1, 'Insufficient ports')
+        self.src_intf = self.tester.get_interface(self.tester.get_local_port(0))
+        self.test_port = 0
+        # secondary process command (testpmd) 
+        self.preset_testpmd_cmds = list()
+        self.testpmd = PmdOutput(self.dut)
+        self.test_pmd_status = False
+        # secondary process command (dpdk-procinfo)
+        self.dut_2 = self.dut.new_session()
+        self.query_tool = "dpdk-procinfo"
+        option = " --  --metrics"
+        self.dpdk_proc_cmd = os.sep.join([self.dut.base_dir, self.target,
+                                "app/{0}".format(self.query_tool)]) + option
+        # package size
+        self.latency_content = ['min_latency_ns', 'max_latency_ns',
+                                'avg_latency_ns', 'jitter_ns']
+        self.bit_rate_content = ['mean_bits_in', 'peak_bits_in', 
+                                 'mean_bits_out','peak_bits_out',
+                                 'ewma_bits_in', 'ewma_bits_out']
+        self.display_seq = self.latency_content + self.bit_rate_content
+        # This configuration is used for daily testing
+        # testing packet frame size
+        self.test_frame_sizes = [64, 256, 1024]
+        #self.test_frame_sizes = [64, 72, 128, 128+8, 256, 512, 512+8, 1024]
+        self.max_times = [60*15]
+        self.query_max = 15
+        self.query_times_after_stop = 5
+        data_type = 'daily'
+        #data_type = 'full'
+
+        self.clear_ASLR()
+        # set configs for saving data using pickle   
+        ref_dir = '/root'
+        folder = 'metrics_{0}'.format(data_type)
+        base_path = os.sep.join([ref_dir, folder])
+        if not os.path.exists(base_path):
+            os.makedirs(base_path)
+        self.ref_data_path = os.sep.join([base_path, '{0}_data.pkl'])
+
+    def set_up(self):
+        pass
+
+    def tear_down(self):
+        self.close_testpmd()
+
+    def tear_down_all(self):
+        if self.dut_2:
+            self.reset_ASLR()
+            self.dut_2.close()
+            self.dut_2 = None
+
+    def test_basic(self):
+        '''
+        use to do metrics feature testing
+        '''
+        testpmd_cmds =[['set fwd io'],
+                    ['set verbose 1'],
+                    ['start']]
+        pkt_types = {'TCP': ""}
+
+        self.execute_testpmd_cmd(testpmd_cmds)
+        # get original data
+        msg = self.execute_dpdk_proc()
+        pre_status = self.check_dpdk_proc_tool(msg)
+        for port, port_value in pre_status.items():
+            for key in self.display_seq:
+                value = port_value[key]
+                if int(value) == 0:
+                    continue
+                msg = "{0} {1} value is error <{2}>".format(port, key, value)
+                self.logger.error(msg)
+                raise VerifyFailure(msg)
+
+        # send out packet
+        self.check_packet_transmission(pkt_types)
+        # get transmission data
+        msg = self.execute_dpdk_proc()
+        post_status = self.check_dpdk_proc_tool(msg)
+        msg = self.execute_dpdk_proc()
+        second_post_status = self.check_dpdk_proc_tool(msg)
+        self.display_metrics_data(post_status)
+        # compare twice query data
+        if cmp(post_status, second_post_status) != 0:
+            msg = "data has changed when do multi query operation !!! "
+            self.logger.error(msg)
+            self.display_metrics_data(second_post_status)
+
+    def ixia_traffic_start(self, frame_size, rate_percent=100):
+        pause_time = 65535
+        pause_rate = 0.50
+        # calculate number of packets
+        expect_pps = self.wirespeed(self.nic, frame_size, 1) * 1000000.0
+        # get line rate
+        linerate = expect_pps * (frame_size + 20) * 8
+        # calculate default sleep time for one pause frame
+        sleep = (1 / linerate) * pause_time * 512
+        # calculate packets dropped in sleep time
+        self.n_pkts = int((sleep / (1 / expect_pps)) * (1 / pause_rate))
+        #
+        tgen_input = []
+        headers_size = sum(map(lambda x: HEADER_SIZE[x], 
+                               ['eth', 'ip', 'udp']))
+    
+        payload_size = frame_size - headers_size
+        self.logger.warning(str(payload_size))
+        self.tester.scapy_append(self.get_pkt(payload_size))
+        self.tester.scapy_execute()
+        # rx and tx is the same port
+        #for cnt in range(len(self.dut_ports)):
+        # only use ixia link peer
+        for cnt in range(len(self.dut_ports)):
+            if self.tester.get_local_port_type(cnt) != 'ixia':
+                continue
+            tester_port = self.tester.get_local_port(self.dut_ports[cnt])
+            tgen_input.append((tester_port, tester_port, "pause_rx.pcap"))
+        #----------------------------------------------
+        # run traffic
+        self.tester.loop_traffic_generator_throughput(tgen_input, rate_percent)
+        return tgen_input, expect_pps
+
+    def ixia_traffic_start2(self, frame_size, rate_percent=100):
+        pause_time = 65535
+        pause_rate = 0.50
+        # calculate number of packets
+        expect_pps = self.wirespeed(self.nic, frame_size, 1) * 1000000.0
+        # get line rate
+        linerate = expect_pps * (frame_size + 20) * 8
+        # calculate default sleep time for one pause frame
+        sleep = (1 / linerate) * pause_time * 512
+        # calculate packets dropped in sleep time
+        self.n_pkts = int((sleep / (1 / expect_pps)) * (1 / pause_rate))
+        #
+        tgen_input = []
+        headers_size = sum(map(lambda x: HEADER_SIZE[x], 
+                               ['eth', 'ip', 'udp']))
+        payload_size = frame_size - headers_size
+        self.logger.warning(str(payload_size))
+        self.tester.scapy_append(self.get_pkt(payload_size))
+        self.tester.scapy_execute()
+        # rx and tx is the same port
+        for cnt in range(len(self.dut_ports)):
+            if self.tester.get_local_port_type(cnt) != 'ixia':
+                continue
+            tester_port = self.tester.get_local_port(self.dut_ports[cnt])
+            tgen_input.append((tester_port, tester_port, "pause_rx.pcap"))
+        #----------------------------------------------
+        # run traffic
+        self.tester.loop_traffic_generator_latency(tgen_input, rate_percent)
+        return tgen_input, expect_pps
+
+    def test_perf_bit_rate(self):
+        """
+        testing metrics bit rate
+        """
+        start_time = time.time()
+        lasting_time = 60*15
+        self.logger.info("start time is [%d]s"%(start_time))
+        # set testpmd on ready status
+        testpmd_cmds =[['stop'], ['set fwd io'],
+                       ['set verbose 1'], ['start']]
+        options = '--bitrate-stats=2'
+        self.preset_testpmd('1S/2C/1T', options)
+        stats = []
+        for testing_time in self.max_times:
+            for frame_size in self.test_frame_sizes:
+                # run testpmd
+                self.execute_testpmd_cmd(testpmd_cmds)
+                # save testing configuration
+                sub_stats = {}
+                stats.append(sub_stats)
+                sub_stats['test_configs'] = {}
+                test_configs = sub_stats['test_configs']
+                test_configs['frame_size'] = frame_size
+                test_configs['testing time'] = testing_time
+                max_query_max = self.query_max
+                wait_interval = testing_time/max_query_max
+                test_configs['query interval time'] = wait_interval
+                tgen_input, expect_pps = self.ixia_traffic_start(frame_size)
+                # initialize bit rate result
+                bit_rate_results = []
+                bit_rate_stop_results = []
+                bit_rate_ixia_results = []
+                # query metrics status at a interval
+                max_query_count = max_query_max
+                while max_query_count:
+                    time.sleep(wait_interval)
+                    msg = self.execute_dpdk_proc('bit rate')
+                    bit_rate_results.append(
+                                self.check_dpdk_proc_tool(msg, 'bit rate'))
+                    max_query_count -= 1
+                sub_stats['running'] = bit_rate_results
+                #---------------------
+                msgs = ["stop continuous packet transmission sampling",
+                   "next to sample statistics after stop packet transmission"]
+                self.logger.warning(os.linesep.join(msgs))
+                rx_bps, rx_pps = \
+                  self.tester.stop_traffic_generator_throughput_loop(tgen_input)
+                bit_rate_ixia_results.append([rx_pps, rx_bps, expect_pps])
+                sub_stats['ixia_stats'] = bit_rate_ixia_results
+                # sample data after stop 
+                max_query_count = self.query_times_after_stop
+                while max_query_count:
+                    time.sleep(wait_interval)
+                    msg = self.execute_dpdk_proc('bit rate')
+                    bit_rate_stop_results.append(
+                                    self.check_dpdk_proc_tool(msg, 'bit rate'))
+                    max_query_count -= 1
+                sub_stats['stop'] = bit_rate_stop_results
+                #----------------------------
+                # check statistic status after stop testpmd
+                msg = "verify bit rate statistics stop after stop testpmd::"
+                self.logger.warning(msg)
+                self.stop_testpmd()
+                stop_testpmd_results = []
+                max_query_count = 2
+                while max_query_count:
+                    time.sleep(wait_interval)
+                    msg = self.execute_dpdk_proc('bit rate')
+                    stop_testpmd_results.append(
+                                    self.check_dpdk_proc_tool(msg, 'bit rate'))
+                    max_query_count -= 1
+                # compare results
+                cnt = 1
+                first_result = stop_testpmd_results[0]
+                second_result = stop_testpmd_results[1]
+                if cmp(first_result, second_result) == 0:
+                    msg = ("bit rate statistics stop successful "
+                           "after stop testpmd")
+                    self.logger.warning(msg)
+                else:
+                    msg = "bit rate statistics fail to stop after stop testpmd"
+                    self.logger.error(msg)
+                #-----------------------------------------------------
+                end_time = time.time()
+                self.logger.info("current time is [%d]s"%(end_time))
+                if end_time - start_time > lasting_time:
+                    pass
+                else:
+                    msg = "left time is [%d]s"%(lasting_time - 
+                                                (end_time - start_time))
+                    self.logger.info(msg)
+                #####################################################
+                msgs = [
+                    "frame_size [{0}]".format(frame_size),
+                    "testing time [{0}]".format(testing_time),
+                    "query interval time [{0}]".format(wait_interval)]
+                self.logger.info(os.linesep.join(msgs))
+                self.logger.warning("dpdk bit rate statistics ::")
+                cnt = 1
+                for result in bit_rate_results:
+                    msg = "-"*10 + "No.{0} query result".format(cnt) + "-"*10
+                    self.logger.warning(msg)
+                    for key, value in sorted(result.items()):
+                        self.logger.info("Port {0} statistics:".format(key))
+                        self.logger.info(value)
+                    cnt += 1
+                #-----------------------------------------------
+                # used for debug
+                msg = "dpdk bit rate statistics after stop transmission::"
+                self.logger.warning(msg)
+                cnt = 1
+                for result in bit_rate_stop_results:
+                    msg = "-"*10 + "No.{0} query result".format(cnt) + "-"*10
+                    self.logger.warning(msg)
+                    for key, value in sorted(result.items()):
+                        self.logger.info("Port {0} statistics:".format(key))
+                        self.logger.info(value)
+                    cnt += 1
+                #----------------------------
+                self.logger.warning("ixia bit rate statistics ::")
+                for rx_pps, rx_bps, expect_pps in bit_rate_ixia_results:
+                    msgs = [
+                        "expect_pps  {0} Mpps".format(expect_pps),
+                        "rx_pps      {0} Mpps".format(rx_pps),
+                        "rx_bps      {0} Mbps".format(rx_bps)]
+                    self.logger.info(os.linesep.join(msgs))
+        # executing testing data check
+        self.result_parse(stats, data_type = 'bit_rate')
+
+    def test_perf_bit_rate_peak(self):
+        """ testing bit rate change with higher rate """
+        for frame_size in self.test_frame_sizes:
+            # set testpmd on ready status
+            testpmd_cmds =[['set fwd io'], ['set verbose 1'], ['start']]
+            options = '--bitrate-stats=2'
+            self.preset_testpmd('1S/2C/1T', options)
+            self.execute_testpmd_cmd(testpmd_cmds)
+            max_bit_rate_in = 0
+            max_bit_rate_out = 0
+            testing_time = 60*3
+            rate_percents = [100, 80, 40, 20]
+            for rate_percent in rate_percents:
+                max_query_max = self.query_max
+                wait_interval = testing_time/max_query_max
+                tgen_input, expect_pps = self.ixia_traffic_start(frame_size,
+                                                                 rate_percent)
+                # initialize bit rate result
+                bit_rate_results = []
+                bit_rate_stop_results = []
+                bit_rate_ixia_results = []
+
+                max_query_count = max_query_max
+                while max_query_count:
+                    time.sleep(wait_interval)
+                    msg = self.execute_dpdk_proc('bit rate')
+                    bit_rate_results.append(
+                                    self.check_dpdk_proc_tool(msg, 'bit rate'))
+                    max_query_count -= 1
+                msgs = ["stop continuous packet transmission sampling",
+                  "next to sample statistics after stop packet transmission"]
+                self.logger.warning(os.linesep.join(msgs))
+                rx_bps, rx_pps = \
+                 self.tester.stop_traffic_generator_throughput_loop(tgen_input)
+                bit_rate_ixia_results.append([rx_pps, rx_bps, expect_pps])
+                # sample data after stop 
+                max_query_count = self.query_times_after_stop
+                while max_query_count:
+                    time.sleep(wait_interval)
+                    msg = self.execute_dpdk_proc('bit rate')
+                    bit_rate_stop_results.append(
+                                self.check_dpdk_proc_tool(msg, 'bit rate'))
+                    max_query_count -= 1
+                #######################################################
+                msgs = [
+                    "frame_size [{0}]".format(frame_size),
+                    "query interval time [{0}]".format(wait_interval)]
+                self.logger.info(os.linesep.join(msgs))
+                self.logger.warning("dpdk bit rate statistics ::")
+                cnt = 1
+                peak_in = 0
+                peak_out = 0
+                for result in bit_rate_results:
+                    msg = "-"*10 + "No.{0} query result".format(cnt) + "-"*10
+                    self.logger.warning(msg)
+                    for key, value in sorted(result.items()):
+                        self.logger.info("Port {0} statistics:".format(key))
+                        self.logger.info(value)
+                        if value['peak_bits_in'] > peak_in:
+                            peak_in = value['peak_bits_in']
+                        if value['peak_bits_out'] > peak_out:
+                            peak_out = value['peak_bits_out']
+                    cnt += 1
+                #-----------------------------------------------
+                # check peak bit rate
+                if peak_in <= 0 or peak_out <= 0:
+                    msg = "peak_bits(in/out) value should not be zero"
+                    raise VerifyFailure(msg)
+                # save maximum bit rate value of ``peak_bits_in``
+                # since ixia work with decreasing traffic rate, 
+                # max_bit_rate should keep the first value
+                #------------ check in statistcis
+                if max_bit_rate_in == 0:
+                    max_bit_rate_in = peak_in
+                elif max_bit_rate_in != peak_in:
+                    fmt = ("peak bit rate(in) should be {0}, "
+                           "current value is {1}").format
+                    msg = fmt(max_bit_rate_in, peak_in)
+                    raise VerifyFailure(msg)
+                #------------ check out statistcis
+                if max_bit_rate_out == 0:
+                    max_bit_rate_out = peak_out
+                elif max_bit_rate_out != peak_out:
+                    fmt = ("peak bit rate(out) should be {0}, "
+                           "current value is {1}").format
+                    msg = fmt(max_bit_rate_out, peak_out)
+                    raise VerifyFailure(msg)
+                #-----------------------------------------------
+                # used for debug
+                msg = "dpdk bit rate statistics after stop transmission::"
+                self.logger.warning(msg)
+                cnt = 1
+                for result in bit_rate_stop_results:
+                    msg = "-"*10 + "No.{0} query result".format(cnt) + "-"*10
+                    self.logger.warning(msg)
+                    for key, value in sorted(result.items()):
+                        self.logger.info("Port {0} statistics:".format(key))
+                        self.logger.info(value)
+                    cnt += 1
+
+                self.logger.warning("ixia bit rate statistics ::")
+                for rx_pps, rx_bps, expect_pps in bit_rate_ixia_results:
+                    msgs = ["expect_pps  {0} Mpps".format(expect_pps),
+                            "rx_pps      {0} Mpps".format(rx_pps),
+                            "rx_bps      {0} Mbps".format(rx_bps)]
+                    self.logger.info(os.linesep.join(msgs))
+
+    def test_perf_latency_stat(self):
+        """
+        Test 
+        """
+        start_time = time.time()
+        lasting_time = 60*15
+        query_interval = 0
+        self.logger.info("start time is [%d]s"%(start_time))
+        max_time = self.max_times
+        # set packet for send
+        # pause frame basic configuration
+        # set testpmd on ready status
+        testpmd_cmds =[['stop'],
+                       ['set fwd io'],
+                       ['set verbose 1'],
+                       ['start']]
+        options = '--latencystats=2'
+        self.preset_testpmd('1S/2C/1T', options)
+        stats = []
+        for testing_time in self.max_times:
+            for frame_size in self.test_frame_sizes:
+                # run testpmd
+                self.execute_testpmd_cmd(testpmd_cmds)
+                # save testing configuration
+                sub_stats = {}
+                stats.append(sub_stats)
+                sub_stats['test_configs'] = {}
+                test_configs = sub_stats['test_configs']
+                test_configs['frame_size'] = frame_size
+                test_configs['testing time'] = testing_time
+                # start run traffic
+                tgen_input, expect_pps = self.ixia_traffic_start2(frame_size)
+                latency_results = []
+                latency_stop_results = []
+                latency_ixia_results = []
+                # set query interval
+                max_query_max = self.query_max
+                wait_interval = testing_time/max_query_max
+                max_query_count = max_query_max
+                while max_query_count:
+                    time.sleep(wait_interval)
+                    msg = self.execute_dpdk_proc('latency')
+                    latency_results.append(
+                                    self.check_dpdk_proc_tool(msg, 'latency'))
+                    max_query_count -= 1
+                sub_stats['running'] = latency_results
+                msgs = ["stop continuous packet transmission sampling",
+                    "next to sample statistics after stop packet transmission"]
+                self.logger.warning(os.linesep.join(msgs))
+                latencys  = \
+                    self.tester.stop_traffic_generator_latency(tgen_input)
+                latency_ixia_results.append([latencys])
+                sub_stats['ixia_stats'] = latency_ixia_results
+                max_query_count = self.query_times_after_stop
+                while max_query_count:
+                    time.sleep(wait_interval)
+                    msg = self.execute_dpdk_proc('latency')
+                    latency_stop_results.append(
+                                    self.check_dpdk_proc_tool(msg, 'latency'))
+                    max_query_count -= 1
+                sub_stats['stop'] = latency_stop_results
+                #---------------------------------------------------------
+                end_time = time.time()
+                self.logger.info("current time is [%d]s"%(end_time))
+                if end_time - start_time > lasting_time:
+                    pass
+                else:
+                    self.logger.info("left time is [%d]s"%(lasting_time - 
+                                                    (end_time - start_time)))
+                ############################################################
+                msgs = [
+                    "frame_size [{0}]".format(frame_size),
+                    "testing time [{0}]".format(testing_time),
+                    "query interval time [{0}]".format(wait_interval)]
+                self.logger.info(os.linesep.join(msgs))
+                self.logger.warning("dpdk latency statistics ::")
+                cnt = 1
+                for result in latency_results:
+                    msg = "-"*10 + "No.{0} query result".format(cnt) + "-"*10
+                    self.logger.warning(msg)
+                    for key, value in sorted(result.items()):
+                        self.logger.info("Port {0} statistics:".format(key))
+                        self.logger.info(value)
+                    cnt += 1
+                #-----------------------------------------------
+                # used for debug
+                msg = "dpdk latency statistics after stop transmission::"
+                self.logger.warning(msg)
+                cnt = 1
+                for result in latency_stop_results:
+                    msg = "-"*10 + "No.{0} query result".format(cnt) + "-"*10
+                    self.logger.warning(msg)
+                    for key, value in sorted(result.items()):
+                        self.logger.info("Port {0} statistics:".format(key))
+                        self.logger.info(value)
+                    cnt += 1
+
+                self.logger.warning("ixia latency statistics ::")
+                for latencys in latency_ixia_results:
+                    self.logger.info("latencys(ns) {0}".format(latencys))
+
+        self.result_parse(stats, data_type = 'latency_stat', port_id='')
-- 
1.9.3



More information about the dts mailing list