[dts] [PATCH V1]The Quota and Watermark sample application performs forwarding for each packet that is received on a given port, Internally, packets are pulled from the ports by the master logical core and put on a variable length processing pipeline, each stage of which being connected by rings. It is a test suite for this application.This commit move quota watermark test suite from internal fd11_dtf_merge branch to dts org master branch, add functional test case for basic work flow testing.

Yufen Mo yufengx.mo at intel.com
Thu Apr 21 08:14:31 CEST 2016


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

Signed-off-by: yufengmx <yufengx.mo at intel.com>
---
 test_plans/quota_watermark_test_plan.rst | 190 ++++++++++++
 tests/TestSuite_quota_watermark.py       | 482 +++++++++++++++++++++++++++++++
 2 files changed, 672 insertions(+)
 create mode 100644 test_plans/quota_watermark_test_plan.rst
 create mode 100644 tests/TestSuite_quota_watermark.py

diff --git a/test_plans/quota_watermark_test_plan.rst b/test_plans/quota_watermark_test_plan.rst
new file mode 100644
index 0000000..3d4c2ef
--- /dev/null
+++ b/test_plans/quota_watermark_test_plan.rst
@@ -0,0 +1,190 @@
+.. Copyright (c) <2013>, Intel Corporation
+   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.
+
+
+
+====================
+Quota and Water-mark
+====================
+
+This document provides test plan for benchmarking of the Quota and Water-mark 
+sample application. This is a simple example app featuring packet processing 
+using Intel® Data Plane Development Kit (Intel® DPDK) that show-cases the use 
+of a quota as the maximum number of packets enqueue/dequeue at a time and low 
+and high water-marks to signal low and high ring usage respectively. 
+Additionally, it shows how ring water-marks can be used to feedback congestion 
+notifications to data producers by temporarily stopping processing overloaded 
+rings and sending Ethernet flow control frames.
+
+
+Prerequisites
+-------------
+
+2x Intel® 82599 (Niantic) NICs (2x 10GbE full duplex optical ports per NIC) 
+plugged into the available PCIe Gen2 8-lane slots in two different 
+configurations: 
+1. card0 and card1 attached to socket0.
+2. card0 attached to socket0 and card1 to socket1. 
+
+Test cases
+----------
+
+The idea behind the testing process is to send a fixed number of frames from 
+the traffic generator to the DUT while these are being forwarded back by the 
+app and measure some of statistics. Those configurable parameters exposed by 
+the control app will be modified to see how these affect into the app's 
+performance.Functional test is only used for checking packet transfer flow with
+low watermark packets.
+
+The statistics to be measured are explained below. 
+A table will be presented showing all the different permutations.
+
+
+- Ring size
+
+  - Size of the rings that interconnect two adjacent cores within the 
+    pipeline.
+
+- Quota
+
+  - Value controls how many packets are being moved through the pipeline per 
+    en-queue and de-queue.
+
+- Low water-mark
+
+  - Global threshold that will resume en-queuing on a ring once its usage 
+    goes below it.
+
+- High water-mark
+
+  - Threshold that will stop en-queuing on rings for which the usage has it.
+
+- Frames sent
+
+  - Number of frames sent from the traffic generator.
+
+- Frames received
+
+  - Number of frames received on the traffic generator once they were 
+    forwarded back by the app.
+
+- Control flow frames received
+  
+  - Number of Control flow frames (PAUSE frame defined by the IEEE 802.3x 
+    standard) received on the traffic generator TX port.
+
+- Transmit rate (Mpps)
+  
+  - Rate of transmission. It is calculated dividing the number of sent 
+    packets over the time it took the traffic generator to send them.
+
+
+  +-----------+-------+----------------+-----------------+-------------+-----------------+------------------------------+----------------------+
+  | Ring size | Quota | Low water-mark | High water-mark | Frames sent | Frames received | Control flow frames received | Transmit rate (Mpps) |
+  +===========+=======+================+=================+=============+=================+==============================+======================+
+  | 64        | 5     | 1              | 5               | 15000000    |                 |                              |                      |
+  +-----------+-------+----------------+-----------------+-------------+-----------------+------------------------------+----------------------+
+  | 64        | 5     | 10             | 20              | 15000000    |                 |                              |                      |
+  +-----------+-------+----------------+-----------------+-------------+-----------------+------------------------------+----------------------+
+  | 64        | 5     | 10             | 99              | 15000000    |                 |                              |                      |
+  +-----------+-------+----------------+-----------------+-------------+-----------------+------------------------------+----------------------+
+  | 64        | 5     | 60             | 99              | 15000000    |                 |                              |                      |
+  +-----------+-------+----------------+-----------------+-------------+-----------------+------------------------------+----------------------+
+  | 64        | 5     | 90             | 99              | 15000000    |                 |                              |                      |
+  +-----------+-------+----------------+-----------------+-------------+-----------------+------------------------------+----------------------+
+  | 64        | 5     | 10             | 80              | 15000000    |                 |                              |                      |
+  +-----------+-------+----------------+-----------------+-------------+-----------------+------------------------------+----------------------+
+  | 64        | 5     | 50             | 80              | 15000000    |                 |                              |                      |
+  +-----------+-------+----------------+-----------------+-------------+-----------------+------------------------------+----------------------+
+  
+  
+Test Case 1: Quota and Water-mark one socket (functional)
+==========================================
+Using No.1 card configuration.
+
+This test case calls the application using cores and ports masks similar to 
+the ones shown below. 
+
+- Core mask ``0xFF00``
+- Port mask ``0x280``
+
+This core mask will make use of eight physical cores within the same socket. 
+The used ports belong to different NIC’s attached to the same socket.
+
+Sample command::
+  
+  ./examples/quota_watermark/qw/build/qw -c 0xFF00 -n 4 -- -p 0x280
+  
+After boot up qw and qwctl, send IP packets by scapy with low watermark value.
+Command format::
+   sendp([Ether()/IP()/("X"*26)]*<low watermark value>, iface="<port name>")
+   
+Sample command::
+	sendp([Ether()/IP()/("X"*26)]*10, iface="p785p1")
+
+Test Case 2: Quota and Water-mark one socket (performance)
+==========================================
+
+This test case calls the application using cores and ports masks similar to 
+the ones shown below.
+
+- Core mask ``0xFF00``
+- Port mask ``0x280``
+
+This core mask will make use of eight physical cores within the same socket. 
+The used ports belong to different NIC’s attached to the same socket.
+
+Sample command::
+  
+  ./examples/quota_watermark/qw/build/qw -c 0xFF00 -n 4 -- -p 0x280
+
+
+Test Case 3: Quota and Water-mark two sockets (performance)
+===========================================
+
+
+This test case calls the application using a core and port mask similar to the 
+ones shown below.
+
+- Core mask ``0x0FF0``
+- Port mask ``0x202``
+
+This core mask will make use of eight physical cores; four within the first 
+socket and four on the second one. The RX port will be attached to the first 
+socket whereas the TX is to the second. This configuration will provoke the 
+traffic going through the pipeline pass through the ``QPI`` channel.
+
+Sample command::
+
+  ./examples/quota_watermark/qw/build/qw -c 0x8180706 -n 4 -- -p 0x202
+
+
diff --git a/tests/TestSuite_quota_watermark.py b/tests/TestSuite_quota_watermark.py
new file mode 100644
index 0000000..ba7262d
--- /dev/null
+++ b/tests/TestSuite_quota_watermark.py
@@ -0,0 +1,482 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2016 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.
+
+Quota & Watermark example app test cases.
+
+"""
+import time
+import dts
+from test_case import TestCase
+from etgen import IxiaPacketGenerator
+from packet import Packet, sniff_packets, load_sniff_packets
+
+test_config = {
+    'frames_to_sent': 15 * 10 ** 6,
+    'ring_sizes': [64, 256, 1024],
+    'low_high_watermarks': [
+        (0o1, 0o5), 
+        (10, 20), 
+        (10, 99),
+        (60, 99), 
+        (90, 99), 
+        (10, 80),
+        (50, 80), 
+        (70, 80), 
+        (70, 90),
+        (80, 90)
+    ],
+    'quota_values': [5, 32, 60],
+}
+
+#
+#
+# Test class.
+#
+
+
+class TestQuotaWatermark(TestCase, IxiaPacketGenerator):
+
+    #
+    #
+    #
+    # Test cases.
+    #
+
+    def set_up_all(self):
+        """
+        Run at the start of each test suite.
+
+        Quota watermark prerequisites.
+        """
+
+        self.tester.extend_external_packet_generator(TestQuotaWatermark, self)
+
+    def add_report_headers(self, core_mask, port_mask):
+        """
+        Adds the table header and some info about the executed test
+        """
+        dts.report('Core mask: %s' % core_mask)
+        dts.report('Port mask: %s' % port_mask)
+        dts.results_table_add_header([
+            'Ring size',
+            'Quota',
+            'Low water-mark',
+            'High water-mark',
+            'Frames sent',
+            'Frames received',
+            'Control flow frames received',
+            'Transmit rate (Mpps)'
+        ])
+
+    def set_app_ring_size(self, ring_size):
+        """
+        Changes the ring size by modifying the example app code.
+        """
+
+        sed_command = (r"sed -i 's/^\(.*RING_SIZE\)\s*[[:digit:]]*/\1 %d/' " +
+                       r"examples/quota_watermark/include/conf.h")
+        self.dut.send_expect(sed_command % int(ring_size), '# ')
+
+    def compile_quota_watermark_example_apps(self):
+        """
+        Builds the example app and checks for errors.
+        """
+
+        out = self.dut.send_expect("make -C examples/quota_watermark", "# ")
+        self.verify("Error" not in out and "No such file" not in out,
+                    "Compilation error")
+
+    def execute_qw_app(self, core_mask, port_mask, memory_channels):
+        """
+        Executes the main example app in the background.
+        """
+
+        command = ('./examples/quota_watermark/qw/qw/%s/qw -c {core_mask}' % self.target +
+                   ' -n {memory_channels} -- -p {port_mask} 2>&1 > output.log &')
+        self.dut.send_expect(command.format(**locals()), '# ')
+
+    def execute_qwctl_app(self, memory_channels):
+        """
+        Executes the control app and returns waiting for commands.
+        """
+
+        command = './examples/quota_watermark/qwctl/qwctl/%s/qwctl -c 1 -n %s --proc-type=secondary'
+        command = command % (self.target, str(memory_channels))
+        result = self.dut.send_expect(command, 'qwctl> ')
+        self.verify('Error' not in result, 'qwctl app failed to execute')
+
+    def execute_quota_watermark_example_apps(self, core_mask, port_mask, memory_channels):
+        """
+        Execute both example apps and checks for errors.
+        """
+        
+        self.execute_qw_app(core_mask, port_mask, memory_channels)
+        # We wait until the app starts and writes its output down to the log
+        # file
+        time.sleep(15)
+        result = self.dut.send_expect('cat output.log', '# ')
+        self.verify('USER1: receive_stage() started' in result,
+                    'qw app failed to execute')
+        self.execute_qwctl_app(memory_channels)
+
+    def close_quota_watermark_example_apps(self):
+        """
+        Close control app sending Ctrl-D. This app is always in foreground.
+        Also kills the main app which is in the background.
+        """
+
+        self.dut.send_expect('^D', '# ')
+        self.dut.send_expect('killall qw', '# ')
+
+    def send_qwctl_command(self, command, unexpected_outputs):
+        """
+        Sends a command to the control app and checks the given unexpected output
+        is not in the app's output.
+        """
+
+        result = self.dut.send_expect(command, 'qwctl>')
+        for output in unexpected_outputs:
+            self.verify(output not in result, "`%s' is incorrect" % command)
+
+    def set_quota_value(self, quota):
+        """
+        Sets the global quota value.
+        """
+
+        self.send_qwctl_command('set quota %d' % quota,
+                                ['quota must be between'])
+
+    def set_low_watermark(self, low_watermark):
+        """
+        Sets the global low watermark value.
+        """
+
+        self.send_qwctl_command('set low_watermark %d' % low_watermark,
+                                ['low_watermark must be between'])
+
+    def set_high_watermark_single_core_port(self, core, port, high_watermark):
+        """
+        Sets the high watermark value for a given ring identified by a core
+        and port number.
+        """
+
+        command = 'set core%d_port%d %d' % \
+                  (int(core), int(port), int(high_watermark))
+        unexpected = [
+            'ring high watermark must be between', 'Cannot find ring']
+        self.send_qwctl_command(command, unexpected)
+
+    def set_high_watermark_all_cores_ports(self, cores, ports, high_watermark):
+        """
+        Sets high watermark value to a list of cores/ports. Due to the app's way
+        to work the last core doesn't have any ring to enqueue in, that's why the
+        last core is avoided.
+        """
+
+        cores.sort(key=lambda core: int(core))
+        for core in cores[:-1]:
+            for port in ports:
+                self.set_high_watermark_single_core_port(
+                    core, port, high_watermark)
+
+    def prepare_scapy_packet(self, pkt_cnt=1):
+        """
+        Creates a simple scapy packet to run the tests with
+        """
+
+        self.tester.scapy_append('flow=[Ether()/IP()/("X"*26)]*%d'%pkt_cnt)
+        self.tester.scapy_append('wrpcap("file.pcap", flow)')
+        self.tester.scapy_execute()
+
+    def get_ports_config(self, dut_rx_port, dut_tx_port):
+        """
+        Creates a usable data structure where the ports configuration is stored.
+        """
+
+        ports_config = {}
+        ports_config['dut_rx'] = dut_rx_port
+        ports_config['dut_tx'] = dut_tx_port
+        ports_config[
+            'dut_port_mask'] = dts.create_mask([ports_config['dut_tx'],
+                                                ports_config['dut_rx']])
+        ports_config['tester_rx'] = self.tester.get_local_port(
+            ports_config['dut_rx'])
+        ports_config['tester_tx'] = self.tester.get_local_port(
+            ports_config['dut_tx'])
+        return ports_config
+
+    def generate_tgen_input(self, ports_config, pkt_cnt=1):
+        """
+        Generates the argument that the external traffic generator function
+        waits to receive as argument.
+        """
+
+        self.prepare_scapy_packet(pkt_cnt)
+        tgen_input = [[ports_config['tester_tx'],
+                       ports_config['tester_rx'],
+                       'file.pcap']]
+        return tgen_input
+
+    def send_pcap_pkt_by_scapy(self, tester=None, file='', intf=''):
+        if intf == '' or file == '' or tester is None:
+            print "Invalid option for send packet by scapy"
+            return
+
+        content = 'pkts=rdpcap(\"%s\");sendp(pkts, iface=\"%s\");exit()' % (file, intf)
+        cmd_file = '/tmp/scapy_%s.cmd' % intf
+
+        tester.create_file(content, cmd_file)
+        tester.send_expect("scapy -c scapy_%s.cmd &" % intf, "# ")
+
+    def iterate_through_qw_ring_sizes(self, ports_config, core_config):
+        """
+        It goes through the different ring values compiling the apps, executing
+        them, running the other test permutations and finally closing the apps.
+        The rings are the first to be covered because we need to build/start/stop
+        the apps to change them.
+        """
+
+        dut_ports = [ports_config['dut_rx'], ports_config['dut_tx']]
+        memory_channels = self.dut.get_memory_channels()
+        tgen_input = self.generate_tgen_input(ports_config)
+
+        for ring_size in test_config['ring_sizes']:
+            self.set_app_ring_size(ring_size)
+            self.compile_quota_watermark_example_apps()
+            self.execute_quota_watermark_example_apps(core_config['mask'],
+                                                      ports_config['dut_port_mask'],
+                                                      memory_channels)
+            self.iterate_through_qw_quota_watermarks( core_config['cores'], 
+                                                      dut_ports, 
+                                                      tgen_input, 
+                                                      ring_size)
+            self.close_quota_watermark_example_apps()
+
+    def iterate_through_qw_quota_watermarks(self, cores, ports, tgen_input, ring_size):
+        """
+        Goes through the other test permutations changing the quota and water-marks
+        values, calling IXIA and storing the results in the result table.
+        """
+
+        for quota in test_config['quota_values']:
+            for low_watermark, high_watermark in test_config['low_high_watermarks']:
+                self.set_quota_value(quota)
+                self.set_low_watermark(low_watermark)
+                self.set_high_watermark_all_cores_ports(cores, ports, high_watermark)
+                self.num_of_frames = test_config['frames_to_sent']
+                test_stats = self.tester.traffic_generator_throughput(tgen_input)
+
+                dts.results_table_add_row([ring_size, quota, low_watermark, high_watermark] +
+                                          test_stats)
+
+    def check_packets_transfer(self, tx_port, rx_port, tgen_input, pkt_cnt=1):
+        '''
+        check packets transmission status
+        '''
+        # check forwarded mac has been changed
+        rev_port = self.tester.get_local_port(rx_port)
+        send_port = self.tester.get_local_port(tx_port)
+        dst_mac = self.dut.get_mac_address(rx_port)
+        rx_intf = self.tester.get_interface(rev_port)
+        tx_intf = self.tester.get_interface(send_port)
+        # send and sniff packet
+        rx_inst = sniff_packets(rx_intf, timeout=5)
+        self.send_pcap_pkt_by_scapy(self.tester, tgen_input[0][2], tx_intf)
+        pkts = load_sniff_packets(rx_inst)
+        self.verify(len(pkts) == pkt_cnt, "Packet not forwarded as expected")
+
+        return
+
+    def get_setting_parameters(self, para_type):
+        '''
+        get setting parameters from performance setting 
+        '''
+        settings = test_config[para_type][:1]
+        
+        return settings
+
+    def func_iterate_through_qw_quota_watermarks(self, cores, ports_config, ports, ring_size):
+        """
+        Goes through the other test permutations changing the quota and water-marks
+        values, send packets by scapy and check packets transmission status.
+        """
+        for quota in self.get_setting_parameters('quota_values'):
+            for low_watermark, high_watermark in self.get_setting_parameters('low_high_watermarks'):
+                self.set_quota_value(quota)
+                self.set_low_watermark(low_watermark)
+                self.set_high_watermark_all_cores_ports( cores, ports, high_watermark)
+                tgen_input = self.generate_tgen_input(ports_config, pkt_cnt=low_watermark)
+                test_stats = self.check_packets_transfer(ports[0], ports[1], tgen_input, pkt_cnt=low_watermark)
+
+    def func_iterate_through_qw_ring_sizes(self, ports_config, core_config):
+        """
+        It goes through the different ring values compiling the apps, executing
+        them, running the other test permutations and finally closing the apps.
+        The rings are the first to be covered because we need to build/start/stop
+        the apps to change them.
+        """
+
+        dut_ports = [ports_config['dut_rx'], ports_config['dut_tx']]
+        memory_channels = self.dut.get_memory_channels()
+        
+        for ring_size in self.get_setting_parameters('ring_sizes'):
+            self.set_app_ring_size(ring_size)
+            self.compile_quota_watermark_example_apps()
+            self.execute_quota_watermark_example_apps(core_config['mask'],
+                                                      ports_config['dut_port_mask'],
+                                                      memory_channels)
+            self.func_iterate_through_qw_quota_watermarks( core_config['cores'],
+                                                           ports_config, 
+                                                           dut_ports,
+                                                           ring_size)
+            self.close_quota_watermark_example_apps()
+
+    def config_ixia_stream(self, rate_percent, flows):
+        """
+        Work around that overrides the etgen.confStream function in order to
+        change the way that IXIA gets called.
+        In this case IXIA sends a fixed number of packets and then stops.
+        """
+
+        self.add_tcl_cmd("ixGlobalSetDefault")
+        self.add_tcl_cmd("stream config -rateMode usePercentRate")
+        self.add_tcl_cmd("stream config -percentPacketRate %s" % rate_percent)
+
+        # We define one burst with num_frames packets on it and we also want IXIA
+        # to stop once all of them have been sent.
+        self.add_tcl_cmd("stream config -numBursts 1")
+        self.add_tcl_cmd("stream config -numFrames %d" % self.num_of_frames)
+        self.add_tcl_cmd("stream config -dma stopStream")
+
+    def configure_transmission(self):
+        """
+        Work around that substitute the etgen.Throughput function.
+        It makes IXIA to send a fixed number of packets and waits until is done.
+        Returns several stat values needed by the test cases.
+        """
+
+        # This basically means "start the packets transmission and don't return
+        # until you are done". Thanks to that, after we "source ixiaConfig.tcl" we
+        # are 100% sure that all the packets have been sent and IXIA is pretty much
+        # done so we can read the stats.
+        self.add_tcl_cmd("ixStartTransmit portList")
+        self.add_tcl_cmd('after 1000')
+        self.add_tcl_cmd('ixCheckTransmitDone portList')
+        # end configure_transmission
+
+    def get_transmission_results(self, rx_port_list, tx_port_list):
+        frames_received = 0
+        for port in rx_port_list:
+            self.stat_get_stat_all_stats(port)
+            frames_received += self.get_frames_received()
+
+        frames_sent = 0
+        control_flow_received = 0
+        transmit_duration = 0
+        for port in tx_port_list:
+            self.stat_get_stat_all_stats(port)
+            control_flow_received += self.get_flow_control_frames()
+            frames_sent += self.get_frames_sent()
+            # Time in nanoseconds
+            transmit_duration += self.get_transmit_duration()
+
+        rate = self.packet_2_millpacket(
+            frames_sent) / self.nanosec_2_sec(transmit_duration)
+        return [frames_sent, frames_received, control_flow_received, rate]
+
+    def nanosec_2_sec(self, nano_secs):
+        return float(nano_secs) / 10e9
+
+    def packet_2_millpacket(self, num_of_pkt):
+        return float(num_of_pkt) / 10e6
+
+    def test_quota_watermark(self):
+        """
+        Test case that runs the different test permutations by using cores on
+        a single socket and two ports attached to it.
+        """
+
+        dut_ports = self.dut.get_ports(self.nic, perf=True)
+        self.verify(len(dut_ports) >= 2,
+                    "Insufficient ports for speed testing")
+        ports_config = self.get_ports_config(dut_ports[0], dut_ports[1])
+
+        cores_one_socket = self.dut.get_core_list('1S/4C/1T')
+        core_config = {
+            'cores': cores_one_socket,
+            'mask': dts.create_mask(cores_one_socket)
+        }
+
+        self.func_iterate_through_qw_ring_sizes(ports_config, core_config)
+
+    def test_perf_quota_watermark_one_socket(self):
+        """
+        Test case that runs the different test permutations by using cores on
+        a single socket and two ports attached to it.
+        """
+
+        dut_ports = self.dut.get_ports(self.nic, perf=True)
+        self.verify(len(dut_ports) >= 2, "Insufficient ports for speed testing")
+        ports_config = self.get_ports_config(dut_ports[2], dut_ports[3])
+
+        cores_one_socket = self.dut.get_core_list('1S/4C/1T')
+        core_config = {
+            'cores':   cores_one_socket,
+            'mask':    dts.create_mask(cores_one_socket)
+        }
+
+        self.add_report_headers( core_config['mask'], 
+                                 ports_config['dut_port_mask'])
+        self.iterate_through_qw_ring_sizes(ports_config, core_config)
+        dts.results_table_print()
+
+    def test_perf_quota_watermark_two_sockets(self):
+        """
+        Test case that runs the different test permutations by using cores on
+        two different sockets with a port attached to each one of them.
+        """
+
+        dut_ports = self.dut.get_ports(self.nic, perf=True)
+        self.verify(len(dut_ports) >= 4, "Insufficient ports for speed testing")
+        ports_config = self.get_ports_config(dut_ports[0], dut_ports[3])
+
+        cores_two_sockets = self.dut.get_core_list('2S/4C/1T')
+        core_config = {
+            'cores': cores_two_sockets,
+            'mask': dts.create_mask(cores_two_sockets)
+        }
+
+        self.add_report_headers( core_config['mask'], ports_config['dut_port_mask'])
+        self.iterate_through_qw_ring_sizes(ports_config, core_config)
+        dts.results_table_print()
-- 
1.9.3



More information about the dts mailing list