get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/114811/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 114811,
    "url": "http://patches.dpdk.org/api/patches/114811/?format=api",
    "web_url": "http://patches.dpdk.org/project/dts/patch/20220811111658.78579-4-yaqi.tang@intel.com/",
    "project": {
        "id": 3,
        "url": "http://patches.dpdk.org/api/projects/3/?format=api",
        "name": "DTS",
        "link_name": "dts",
        "list_id": "dts.dpdk.org",
        "list_email": "dts@dpdk.org",
        "web_url": "",
        "scm_url": "git://dpdk.org/tools/dts",
        "webscm_url": "http://git.dpdk.org/tools/dts/",
        "list_archive_url": "https://inbox.dpdk.org/dts",
        "list_archive_url_format": "https://inbox.dpdk.org/dts/{}",
        "commit_url_format": ""
    },
    "msgid": "<20220811111658.78579-4-yaqi.tang@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dts/20220811111658.78579-4-yaqi.tang@intel.com",
    "date": "2022-08-11T11:16:58",
    "name": "[V3,3/3] tests/ice_iavf_packet_pacing: ice enable packet pacing",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "91b726ebe393300fe31180b4bfc5e2b834c65eed",
    "submitter": {
        "id": 2357,
        "url": "http://patches.dpdk.org/api/people/2357/?format=api",
        "name": "Yaqi Tang",
        "email": "yaqi.tang@intel.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dts/patch/20220811111658.78579-4-yaqi.tang@intel.com/mbox/",
    "series": [
        {
            "id": 24251,
            "url": "http://patches.dpdk.org/api/series/24251/?format=api",
            "web_url": "http://patches.dpdk.org/project/dts/list/?series=24251",
            "date": "2022-08-11T11:16:55",
            "name": "ice iavf enable packet pacing",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/24251/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/114811/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/114811/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dts-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 16786A0545;\n\tThu, 11 Aug 2022 05:18:58 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 11AB842B96;\n\tThu, 11 Aug 2022 05:18:58 +0200 (CEST)",
            "from mga04.intel.com (mga04.intel.com [192.55.52.120])\n by mails.dpdk.org (Postfix) with ESMTP id F41EA42B98\n for <dts@dpdk.org>; Thu, 11 Aug 2022 05:18:54 +0200 (CEST)",
            "from orsmga006.jf.intel.com ([10.7.209.51])\n by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 10 Aug 2022 20:18:54 -0700",
            "from dpdk-yaqi.sh.intel.com ([10.67.119.99])\n by orsmga006.jf.intel.com with ESMTP; 10 Aug 2022 20:18:52 -0700"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1660187935; x=1691723935;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=CViMHbCXLYS3EhH1kLNm0eS5qG8zWoTm4+E70mb1GLI=;\n b=Hlgbbz4UULv/bTkuWM4GTUolAFRL+Bv6qtWG3kCJcRaTqUc/an62SE9K\n ns56murHrFpXTnx9bHsa4S1QPyHaAd1gshvnUZzbcniVvDwPqNvfpL/xd\n HqqlCJuUwhCGn6ZKzFBq81gFAhjBLFJsT/vIH41MHmGmddsQAt09R5fDX\n MVwLV/XKTz5yYQ9EPziL5u1F5phhF9GuSbExc/XjQRWoSZQi+J/vWqNvB\n WZ9NjIdn5G6Zf5jDXylpRyI0+lEigmqFEv/OEsYw6/Rp9Xqg6GVx/1mNA\n AXIc2TQ/vW/YNlqhG156ZxmxNDuEZVyXLICXhU7BHsqUtyQPo5RMx1nEs A==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6400,9594,10435\"; a=\"290001142\"",
            "E=Sophos;i=\"5.93,228,1654585200\"; d=\"scan'208\";a=\"290001142\"",
            "E=Sophos;i=\"5.93,228,1654585200\"; d=\"scan'208\";a=\"581490819\""
        ],
        "X-ExtLoop1": "1",
        "From": "Yaqi Tang <yaqi.tang@intel.com>",
        "To": "dts@dpdk.org",
        "Cc": "Yaqi Tang <yaqi.tang@intel.com>",
        "Subject": "[dts][PATCH V3 3/3] tests/ice_iavf_packet_pacing: ice enable packet\n pacing",
        "Date": "Thu, 11 Aug 2022 11:16:58 +0000",
        "Message-Id": "<20220811111658.78579-4-yaqi.tang@intel.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20220811111658.78579-1-yaqi.tang@intel.com>",
        "References": "<20220811111658.78579-1-yaqi.tang@intel.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-BeenThere": "dts@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "test suite reviews and discussions <dts.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dts>,\n <mailto:dts-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dts/>",
        "List-Post": "<mailto:dts@dpdk.org>",
        "List-Help": "<mailto:dts-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dts>,\n <mailto:dts-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dts-bounces@dpdk.org"
    },
    "content": "ICE support queue rate limitation configure, and parse the quanta_size for IGP pacing.\n\nSigned-off-by: Yaqi Tang <yaqi.tang@intel.com>\n---\n tests/TestSuite_ice_iavf_packet_pacing.py | 641 ++++++++++++++++++++++\n 1 file changed, 641 insertions(+)\n create mode 100644 tests/TestSuite_ice_iavf_packet_pacing.py",
    "diff": "diff --git a/tests/TestSuite_ice_iavf_packet_pacing.py b/tests/TestSuite_ice_iavf_packet_pacing.py\nnew file mode 100644\nindex 00000000..46b8e341\n--- /dev/null\n+++ b/tests/TestSuite_ice_iavf_packet_pacing.py\n@@ -0,0 +1,641 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2010-2022 Intel Corporation\n+#\n+\n+import copy\n+import os\n+import re\n+import time\n+from pprint import pformat\n+\n+from framework.packet import Packet\n+from framework.pktgen import PacketGeneratorHelper\n+from framework.pmd_output import PmdOutput\n+from framework.settings import HEADER_SIZE\n+from framework.test_case import TestCase\n+from framework.utils import GREEN, RED\n+\n+\n+class IAVFPacketPacingTest(TestCase):\n+    def set_up_all(self):\n+        \"\"\"\n+        Run at the start of each test suite.\n+        \"\"\"\n+        self.verify(\n+            self.nic in [\"ICE_25G-E810C_SFP\", \"ICE_100G-E810C_QSFP\"],\n+            \"%s nic not support vf timestamp\" % self.nic,\n+        )\n+        self.dut_ports = self.dut.get_ports(self.nic)\n+        self.ports_socket = self.dut.get_numa_id(self.dut_ports[0])\n+        # Verify that enough ports are available\n+        self.verify(len(self.dut_ports) >= 1, \"Insufficient ports\")\n+        self.tester_port0 = self.tester.get_local_port(self.dut_ports[0])\n+        self.tester_iface0 = self.tester.get_interface(self.tester_port0)\n+        self.pkt = Packet()\n+        self.pmdout = PmdOutput(self.dut)\n+\n+        self.vf_driver = self.get_suite_cfg()[\"vf_driver\"]\n+        if self.vf_driver is None:\n+            self.vf_driver = \"vfio-pci\"\n+        self.pf0_intf = self.dut.ports_info[self.dut_ports[0]][\"intf\"]\n+\n+        # get dts output path\n+        if self.logger.log_path.startswith(os.sep):\n+            self.output_path = self.logger.log_path\n+        else:\n+            cur_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))\n+            self.output_path = os.sep.join([cur_path, self.logger.log_path])\n+        # create an instance to set stream field setting\n+        self.pktgen_helper = PacketGeneratorHelper()\n+        self.path = self.dut.apps_name[\"test-pmd\"]\n+\n+    def set_up(self):\n+        \"\"\"\n+        Run before each test case.\n+        \"\"\"\n+        pass\n+\n+    def launch_testpmd(self, allowlist, line_option=\"\"):\n+        \"\"\"\n+        start testpmd\n+        \"\"\"\n+        # Prepare testpmd EAL and parameters\n+        output = self.pmdout.start_testpmd(\n+            socket=self.ports_socket,\n+            prefix=\"tx\",\n+            eal_param=allowlist,\n+            param=line_option,\n+        )\n+        # test link status\n+        res = self.pmdout.wait_link_status_up(\"all\", timeout=15)\n+        self.verify(res is True, \"there have port link is down\")\n+        return output\n+\n+    def close_testpmd(self):\n+        self.dut.send_expect(\"quit\", \"# \", 30)\n+        time.sleep(5)\n+\n+    def create_vf(self, vf_num):\n+        self.dut.bind_interfaces_linux(\"ice\")\n+        self.dut.generate_sriov_vfs_by_port(self.dut_ports[0], vf_num)\n+        self.sriov_vfs_port = self.dut.ports_info[self.dut_ports[0]][\"vfs_port\"]\n+        self.dut.send_expect(\"ifconfig %s up\" % self.pf0_intf, \"# \")\n+        if vf_num >= 2:\n+            self.dut.send_expect(\n+                \"ip link set dev %s vf 0 trust on\" % self.pf0_intf, \"# \"\n+            )\n+            self.dut.send_expect(\n+                \"ip link set %s vf 1 mac 00:11:22:33:44:55\" % self.pf0_intf, \"#\"\n+            )\n+            self.vf0_pci = self.sriov_vfs_port[0].pci\n+            self.vf1_pci = self.sriov_vfs_port[1].pci\n+        else:\n+            self.dut.send_expect(\n+                \"ip link set %s vf 0 mac 00:11:22:33:44:55\" % self.pf0_intf, \"#\"\n+            )\n+            self.vf0_pci = self.sriov_vfs_port[0].pci\n+        try:\n+            for port in self.sriov_vfs_port:\n+                port.bind_driver(self.vf_driver)\n+        except Exception as e:\n+            self.destroy_vf()\n+            raise Exception(e)\n+\n+    def destroy_vf(self):\n+        self.dut.destroy_sriov_vfs_by_port(self.dut_ports[0])\n+        self.dut.send_expect(\"rmmod ice\", \"# \", 15)\n+        self.dut.send_expect(\"modprobe ice\", \"# \", 15)\n+\n+    def testpmd_query_stats(self):\n+        output = self.dut.send_expect(\"show port stats all\", \"testpmd> \", 20)\n+        self.logger.info(output)\n+        if not output:\n+            return\n+        port_pat = \".*NIC statistics for (port \\d+) .*\"\n+        tx_pat = \".*Tx-pps:\\s+(\\d+)\\s+Tx-bps:\\s+(\\d+).*\"\n+        port = re.findall(port_pat, output, re.M)\n+        tx = re.findall(tx_pat, output, re.M)\n+        if not port or not tx:\n+            return\n+        stat = {}\n+        for port_id, (tx_pps, tx_bps) in zip(port, tx):\n+            stat[port_id] = {\n+                \"tx_pps\": float(tx_pps),\n+                \"tx_bps\": float(tx_bps),\n+            }\n+        self.pmd_stat = stat\n+\n+    def get_queue_packets_stats(self, port):\n+        output = self.dut.send_expect(\"stop\", \"testpmd> \")\n+        self.logger.info(output)\n+        p = re.compile(\"TX Port= %d/Queue=.*\\n.*TX-packets: ([0-9]+)\\s\" % port)\n+        queue_pkts = p.findall(output)\n+        queue_pkts = list(map(int, queue_pkts))\n+        if not queue_pkts:\n+            return {}\n+        return queue_pkts\n+\n+    def is_expected_throughput(self, expected, pmd_stat):\n+        _expected, unit, port = expected\n+        port = port\n+        real_stat = pmd_stat.get(f\"port {port}\", {})\n+        key = \"tx_bps\"\n+        real_bps = real_stat.get(key) or 0\n+        if real_bps == 0 and _expected == 0:\n+            return True\n+        if not _expected:\n+            return False\n+        bias = 10\n+        if unit == \"MBps\":\n+            _bias = 100 * abs((real_bps / 8 / 1e6 - _expected) / _expected)\n+            return _bias < bias\n+        return True\n+\n+    def set_fields(self):\n+        fields_config = {\n+            \"ip\": {\n+                \"src\": {\n+                    \"start\": \"198.18.0.0\",\n+                    \"end\": \"198.18.0.255\",\n+                    \"step\": 1,\n+                    \"action\": \"random\",\n+                },\n+            },\n+        }\n+        return fields_config\n+\n+    def check_traffic(self, expected, frame_size=64):\n+        # create pcap file\n+        dmac = \"00:11:22:33:44:55\"\n+        payload_size = frame_size - HEADER_SIZE[\"ip\"] - HEADER_SIZE[\"eth\"]\n+        pcap = os.sep.join([self.output_path, \"dts0.pcap\"])\n+        self.tester.scapy_append(\n+            'wrpcap(\"%s\", [Ether(dst=\"%s\")/IP(src=\"198.18.0.0\",dst=\"198.28.0.0\")/(\"X\"*%d)])'\n+            % (pcap, dmac, payload_size)\n+        )\n+        self.tester.scapy_execute()\n+        tgen_input = []\n+        tgen_input.append(\n+            (\n+                self.tester.get_local_port(self.dut_ports[0]),\n+                self.tester.get_local_port(self.dut_ports[0]),\n+                \"%s\" % pcap,\n+            )\n+        )\n+\n+        # clear streams before add new streams\n+        vm_config = self.set_fields()\n+        self.tester.pktgen.clear_streams()\n+\n+        streams = self.pktgen_helper.prepare_stream_from_tginput(\n+            tgen_input, 100, vm_config, self.tester.pktgen\n+        )\n+        traffic_opt = {\n+            \"method\": \"throughput\",\n+            \"duration\": 20,\n+            \"interval\": 15,\n+            \"callback\": self.testpmd_query_stats,\n+        }\n+        results = []\n+        result = self.tester.pktgen.measure_throughput(\n+            stream_ids=[0], options=traffic_opt\n+        )\n+\n+        pmd_stat = self.pmd_stat\n+        status = self.is_expected_throughput(expected, pmd_stat)\n+        msg = (\n+            f\"{pformat(expected)}\"\n+            \" not get expected throughput value, real is: \"\n+            f\"{pformat(pmd_stat)}\"\n+        )\n+        self.verify(status, msg)\n+\n+        _, _, port = expected\n+        queue_pkts = self.get_queue_packets_stats(port)\n+        results.append([result, pmd_stat, queue_pkts])\n+        return results\n+\n+    def check_queue_pkts_ratio(self, expected, result):\n+        total_pkts = sum(result)\n+        total_ratio = sum(expected)\n+        ratio = []\n+        for idx, result in enumerate(result):\n+            percentage = 100 * result / total_pkts\n+            ratio.append(percentage)\n+        bias = 10\n+        for idx, percentage in enumerate(expected):\n+            percentage = 100 * percentage / total_ratio\n+            _bias = 100 * abs(ratio[idx] - percentage) / percentage\n+            self.logger.info((ratio[idx], percentage))\n+            if _bias < bias:\n+                continue\n+            else:\n+                msg = \"can not get expected queue ratio\"\n+                self.verify(False, msg)\n+\n+    def check_output(self, expected, output):\n+        if isinstance(expected, str):\n+            expected = [expected]\n+        for _expected in expected:\n+            self.verify(\n+                _expected in output, f\"expected <{_expected}> message not display\"\n+            )\n+\n+    def verify_without_quanta_size_check_peak_tb_rate(self):\n+        allowlist = f\"-a {self.vf0_pci}\"\n+        line_option = \"\"\n+        self.launch_testpmd(allowlist, line_option)\n+        self.dut.send_expect(\"port stop all\", \"testpmd> \")\n+        self.dut.send_expect(\n+            \"add port tm node shaper profile 0 1 1000000 0 612980769 0 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm nonleaf node 0 1000 -1 0 1 0 -1 1 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm nonleaf node 0 900 1000 0 1 1 -1 1 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 0 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\"port tm hierarchy commit 0 no\", \"testpmd> \")\n+        self.dut.send_expect(\"port start all\", \"testpmd> \")\n+        self.dut.send_expect(\"set fwd mac\", \"testpmd> \")\n+        self.dut.send_expect(\"start\", \"testpmd> \")\n+\n+        expected_throughput = (612, \"MBps\", 0)\n+\n+        results = self.check_traffic(expected_throughput)\n+\n+    def verify_single_queue_check_peak_tb_rate(self):\n+        allowlist = f\"-a {self.vf0_pci},quanta_size=1024\"\n+        line_option = \"\"\n+        self.launch_testpmd(allowlist, line_option)\n+        self.dut.send_expect(\"port stop all\", \"testpmd> \")\n+        self.dut.send_expect(\n+            \"add port tm node shaper profile 0 1 1000000 0 612980769 0 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm nonleaf node 0 1000 -1 0 1 0 -1 1 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm nonleaf node 0 900 1000 0 1 1 -1 1 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 0 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\"port tm hierarchy commit 0 no\", \"testpmd> \")\n+        self.dut.send_expect(\"port start all\", \"testpmd> \")\n+        self.dut.send_expect(\"set fwd mac\", \"testpmd> \")\n+        self.dut.send_expect(\"start\", \"testpmd> \")\n+\n+        expected_throughput = (612, \"MBps\", 0)\n+\n+        results = self.check_traffic(expected_throughput)\n+\n+    def verify_multi_queues_check_peak_tb_rate(self):\n+        allowlist = f\"-a {self.vf0_pci},quanta_size=1024\"\n+        line_option = \"--rxq=8 --txq=8\"\n+        self.launch_testpmd(allowlist, line_option)\n+        self.dut.send_expect(\"port stop all\", \"testpmd> \")\n+        self.dut.send_expect(\n+            \"add port tm node shaper profile 0 1 1000000 0 100000000 0 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm nonleaf node 0 1000 -1 0 1 0 -1 1 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm nonleaf node 0 900 1000 0 1 1 -1 1 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 0 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 1 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 2 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 3 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 4 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 5 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 6 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 7 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\"port tm hierarchy commit 0 no\", \"testpmd> \")\n+        self.dut.send_expect(\"port start all\", \"testpmd> \")\n+        self.dut.send_expect(\"set fwd mac\", \"testpmd> \")\n+        self.dut.send_expect(\"start\", \"testpmd> \")\n+\n+        expected_throughput = (800, \"MBps\", 0)\n+        expected_ratio = [1, 1, 1, 1, 1, 1, 1, 1]\n+\n+        results = self.check_traffic(expected_throughput)\n+        self.check_queue_pkts_ratio(expected_ratio, results[-1][-1])\n+\n+    def verify_modify_quanta_size_check_peak_tb_rate(self):\n+        allowlist = f\"-a {self.vf0_pci},quanta_size=4096\"\n+        line_option = \"--rxq=8 --txq=8\"\n+        self.launch_testpmd(allowlist, line_option)\n+        self.dut.send_expect(\"port stop all\", \"testpmd> \")\n+        self.dut.send_expect(\n+            \"add port tm node shaper profile 0 1 1000000 0 100000000 0 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm nonleaf node 0 1000 -1 0 1 0 -1 1 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm nonleaf node 0 900 1000 0 1 1 -1 1 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 0 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 1 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 2 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 3 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 4 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 5 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 6 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 7 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\"port tm hierarchy commit 0 no\", \"testpmd> \")\n+        self.dut.send_expect(\"port start all\", \"testpmd> \")\n+        self.dut.send_expect(\"set fwd mac\", \"testpmd> \")\n+        self.dut.send_expect(\"start\", \"testpmd> \")\n+\n+        expected_throughput = (800, \"MBps\", 0)\n+        expected_ratio = [1, 1, 1, 1, 1, 1, 1, 1]\n+\n+        results = self.check_traffic(expected_throughput)\n+        self.check_queue_pkts_ratio(expected_ratio, results[-1][-1])\n+\n+    def verify_multi_queues_with_diff_rate_limit_check_peak_tb_rate(self):\n+        allowlist = f\"-a {self.vf0_pci},quanta_size=1024\"\n+        line_option = \"--rxq=8 --txq=8\"\n+        self.launch_testpmd(allowlist, line_option)\n+        self.dut.send_expect(\"port stop all\", \"testpmd> \")\n+        self.dut.send_expect(\n+            \"add port tm node shaper profile 0 1 1000000 0 10000000 0 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm node shaper profile 0 2 1000000 0 20000000 0 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm node shaper profile 0 3 1000000 0 30000000 0 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm node shaper profile 0 4 1000000 0 40000000 0 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm node shaper profile 0 5 1000000 0 50000000 0 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm node shaper profile 0 6 1000000 0 60000000 0 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm node shaper profile 0 7 1000000 0 70000000 0 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm node shaper profile 0 8 1000000 0 80000000 0 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm nonleaf node 0 1000 -1 0 1 0 -1 1 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm nonleaf node 0 900 1000 0 1 1 -1 1 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 0 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 1 900 0 1 2 2 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 2 900 0 1 2 3 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 3 900 0 1 2 4 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 4 900 0 1 2 5 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 5 900 0 1 2 6 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 6 900 0 1 2 7 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 7 900 0 1 2 8 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\"port tm hierarchy commit 0 no\", \"testpmd> \")\n+        self.dut.send_expect(\"port start all\", \"testpmd> \")\n+        self.dut.send_expect(\"set fwd mac\", \"testpmd> \")\n+        self.dut.send_expect(\"start\", \"testpmd> \")\n+\n+        expected_throughput = (360, \"MBps\", 0)\n+        expected_ratio = [1, 2, 3, 4, 5, 6, 7, 8]\n+\n+        results = self.check_traffic(expected_throughput)\n+        self.check_queue_pkts_ratio(expected_ratio, results[-1][-1])\n+\n+    def verify_port_rate_limit_less_than_queue_rate_limit(self):\n+        allowlist = f\"-a {self.vf0_pci},cap=dcf -a {self.vf1_pci},quanta_size=1024\"\n+        line_option = \"--rxq=8 --txq=8 --port-topology=loop\"\n+        self.launch_testpmd(allowlist, line_option)\n+        self.dut.send_expect(\"port stop all\", \"testpmd> \")\n+        self.dut.send_expect(\n+            \"add port tm node shaper profile 0 1 1000000 0 100000000 0 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm node shaper profile 1 2 1000000 0 612980769 0 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm nonleaf node 0 1000 -1 0 1 0 -1 1 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm nonleaf node 0 900 1000 0 1 1 -1 1 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 0 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 1 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm nonleaf node 1 1000 -1 0 1 0 -1 1 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm nonleaf node 1 900 1000 0 1 1 -1 1 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 1 0 900 0 1 2 2 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 1 1 900 0 1 2 2 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 1 2 900 0 1 2 2 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 1 3 900 0 1 2 2 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 1 4 900 0 1 2 2 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 1 5 900 0 1 2 2 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 1 6 900 0 1 2 2 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 1 7 900 0 1 2 2 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\"port tm hierarchy commit 0 no\", \"testpmd> \")\n+        self.dut.send_expect(\"port tm hierarchy commit 1 no\", \"testpmd> \")\n+        self.dut.send_expect(\"port start all\", \"testpmd> \")\n+        self.dut.send_expect(\"set fwd mac\", \"testpmd> \")\n+        self.dut.send_expect(\"start\", \"testpmd> \")\n+\n+        expected_throughput = (100, \"MBps\", 1)\n+        expected_ratio = [1, 1, 1, 1, 1, 1, 1, 1]\n+\n+        results = self.check_traffic(expected_throughput)\n+        self.check_queue_pkts_ratio(expected_ratio, results[-1][-1])\n+\n+    def verify_port_rate_limit_more_than_queue_rate_limit(self):\n+        allowlist = f\"-a {self.vf0_pci},cap=dcf -a {self.vf1_pci},quanta_size=1024\"\n+        line_option = \"--rxq=8 --txq=8 --port-topology=loop\"\n+        self.launch_testpmd(allowlist, line_option)\n+        self.dut.send_expect(\"port stop all\", \"testpmd> \")\n+        self.dut.send_expect(\n+            \"add port tm node shaper profile 0 1 1000000 0 200000000 0 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm node shaper profile 1 2 1000000 0 10000000 0 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm nonleaf node 0 1000 -1 0 1 0 -1 1 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm nonleaf node 0 900 1000 0 1 1 -1 1 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 0 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 0 1 900 0 1 2 1 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm nonleaf node 1 1000 -1 0 1 0 -1 1 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm nonleaf node 1 900 1000 0 1 1 -1 1 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 1 0 900 0 1 2 2 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 1 1 900 0 1 2 2 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 1 2 900 0 1 2 2 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 1 3 900 0 1 2 2 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 1 4 900 0 1 2 2 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 1 5 900 0 1 2 2 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 1 6 900 0 1 2 2 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\n+            \"add port tm leaf node 1 7 900 0 1 2 2 0 0xffffffff 0 0\", \"testpmd> \"\n+        )\n+        self.dut.send_expect(\"port tm hierarchy commit 0 no\", \"testpmd> \")\n+        self.dut.send_expect(\"port tm hierarchy commit 1 no\", \"testpmd> \")\n+        self.dut.send_expect(\"port start all\", \"testpmd> \")\n+        self.dut.send_expect(\"set fwd mac\", \"testpmd> \")\n+        self.dut.send_expect(\"start\", \"testpmd> \")\n+\n+        expected_throughput = (80, \"MBps\", 1)\n+        expected_ratio = [1, 1, 1, 1, 1, 1, 1, 1]\n+\n+        results = self.check_traffic(expected_throughput)\n+        self.check_queue_pkts_ratio(expected_ratio, results[-1][-1])\n+\n+    def test_perf_without_quanta_size_check_peak_tb_rate(self):\n+        self.create_vf(vf_num=1)\n+        self.verify_without_quanta_size_check_peak_tb_rate()\n+\n+    def test_perf_single_queue_check_peak_tb_rate(self):\n+        self.create_vf(vf_num=1)\n+        self.verify_single_queue_check_peak_tb_rate()\n+\n+    def test_perf_multi_queues_check_peak_tb_rate(self):\n+        self.create_vf(vf_num=1)\n+        self.verify_multi_queues_check_peak_tb_rate()\n+\n+    def test_perf_modify_quanta_size_check_peak_tb_rate(self):\n+        self.create_vf(vf_num=1)\n+        self.verify_modify_quanta_size_check_peak_tb_rate()\n+\n+    def test_perf_invalid_quanta_size_check_peak_tb_rate(self):\n+        self.create_vf(vf_num=1)\n+        output = self.launch_testpmd(\n+            allowlist=f\"-a {self.vf0_pci},quanta_size=1000\", line_option=\"\"\n+        )\n+        expected = \"iavf_parse_devargs(): invalid quanta size\"\n+        self.check_output(expected, output)\n+\n+    def test_perf_multi_queues_with_diff_rate_limit_check_peak_tb_rate(self):\n+        self.create_vf(vf_num=1)\n+        self.verify_multi_queues_with_diff_rate_limit_check_peak_tb_rate()\n+\n+    def test_perf_port_rate_limit_less_than_queue_rate_limit(self):\n+        self.create_vf(vf_num=2)\n+        self.verify_port_rate_limit_less_than_queue_rate_limit()\n+\n+    def test_perf_port_rate_limit_more_than_queue_rate_limit(self):\n+        self.create_vf(vf_num=2)\n+        self.verify_port_rate_limit_more_than_queue_rate_limit()\n+\n+    def tear_down(self):\n+        \"\"\"\n+        Run after each test case.\n+        \"\"\"\n+        self.close_testpmd()\n+        self.destroy_vf()\n+\n+    def tear_down_all(self):\n+        \"\"\"\n+        Run after each test suite.\n+        \"\"\"\n+        self.dut.kill_all()\n",
    "prefixes": [
        "V3",
        "3/3"
    ]
}