get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 121591,
    "url": "https://patches.dpdk.org/api/patches/121591/?format=api",
    "web_url": "https://patches.dpdk.org/project/dts/patch/20230105104056.234069-4-songx.jiale@intel.com/",
    "project": {
        "id": 3,
        "url": "https://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": "<20230105104056.234069-4-songx.jiale@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dts/20230105104056.234069-4-songx.jiale@intel.com",
    "date": "2023-01-05T10:40:52",
    "name": "[V1,3/7] tests/vf_pmd_bonded_8023ad: add case to test vf bonding",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "b5f9c9d9d317c689c588f6757bab3bc4f1af14a0",
    "submitter": {
        "id": 2352,
        "url": "https://patches.dpdk.org/api/people/2352/?format=api",
        "name": "Jiale, SongX",
        "email": "songx.jiale@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dts/patch/20230105104056.234069-4-songx.jiale@intel.com/mbox/",
    "series": [
        {
            "id": 26391,
            "url": "https://patches.dpdk.org/api/series/26391/?format=api",
            "web_url": "https://patches.dpdk.org/project/dts/list/?series=26391",
            "date": "2023-01-05T10:40:49",
            "name": "add cases to test vf bonding",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/26391/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/121591/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/121591/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 99EF1A00C4;\n\tThu,  5 Jan 2023 03:43:16 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 878A242D21;\n\tThu,  5 Jan 2023 03:43:16 +0100 (CET)",
            "from mga05.intel.com (mga05.intel.com [192.55.52.43])\n by mails.dpdk.org (Postfix) with ESMTP id EB77A40041\n for <dts@dpdk.org>; Thu,  5 Jan 2023 03:43:14 +0100 (CET)",
            "from fmsmga008.fm.intel.com ([10.253.24.58])\n by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 04 Jan 2023 18:43:12 -0800",
            "from unknown (HELO localhost.localdomain) ([10.239.252.20])\n by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 04 Jan 2023 18:43:11 -0800"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1672886595; x=1704422595;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=prB6MdGDMnqGQFVchdKPk1tUcc/GqdHSOiucLOKHJcY=;\n b=lXf/v2hxzqH5tC3hL3D9EhA3ruOjrKnKlnvQUHFbdIqHsguy+aYvK9sF\n WmTQX9ayiHsmi3kQpm/HpoRhLrlZ6G5FFev/TgauTl7f/CexlAOZQnf2x\n yDf5oP137Y8S2GNynGNV+I27edFGoWGVHC8PiV19KBuVFQk8PZOu5FW/U\n K9RqyCxmQzbpIUxfqq0Ysm5fiy8vBpDu9F/3+vqwW4IH45YuamoQlYzMs\n 98hGPaOircBn52bBRLK+K+VM6sM+LYNHYjijOFZLcG/3EJ+1BO9bd15rh\n 3khNMehAjuYiLKaBYWmFbaS7+D/7j7Og60jI4e3xEEPyhpWEeiWDqpi+D Q==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6500,9779,10580\"; a=\"408351314\"",
            "E=Sophos;i=\"5.96,301,1665471600\"; d=\"scan'208\";a=\"408351314\"",
            "E=McAfee;i=\"6500,9779,10580\"; a=\"718660528\"",
            "E=Sophos;i=\"5.96,301,1665471600\"; d=\"scan'208\";a=\"718660528\""
        ],
        "From": "Song Jiale <songx.jiale@intel.com>",
        "To": "dts@dpdk.org",
        "Cc": "Song Jiale <songx.jiale@intel.com>",
        "Subject": "[dts] [PATCH V1 3/7] tests/vf_pmd_bonded_8023ad: add case to test vf\n bonding",
        "Date": "Thu,  5 Jan 2023 10:40:52 +0000",
        "Message-Id": "<20230105104056.234069-4-songx.jiale@intel.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20230105104056.234069-1-songx.jiale@intel.com>",
        "References": "<20230105104056.234069-1-songx.jiale@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": "add case to test vf bonding.\n\nSigned-off-by: Song Jiale <songx.jiale@intel.com>\n---\n tests/TestSuite_vf_pmd_bonded_8023ad.py | 650 ++++++++++++++++++++++++\n 1 file changed, 650 insertions(+)\n create mode 100644 tests/TestSuite_vf_pmd_bonded_8023ad.py",
    "diff": "diff --git a/tests/TestSuite_vf_pmd_bonded_8023ad.py b/tests/TestSuite_vf_pmd_bonded_8023ad.py\nnew file mode 100644\nindex 00000000..5c6cda99\n--- /dev/null\n+++ b/tests/TestSuite_vf_pmd_bonded_8023ad.py\n@@ -0,0 +1,650 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 23.03 Intel Corporation\n+#\n+\n+import time\n+import traceback\n+\n+# import bonding lib(common methods for pmd bonding command)\n+import tests.bonding as bonding\n+from framework.exception import VerifyFailure\n+from framework.test_case import TestCase\n+\n+from .bonding import FRAME_SIZE_64, MODE_LACP\n+\n+\n+######################\n+# bonding 802.3ad mode\n+######################\n+class TestBonding8023AD(TestCase):\n+    AGG_MODES = [\"bandwidth\", \"stable\", \"count\"]\n+    DEDICATED_QUEUES = [\"disable\", \"enable\"]\n+\n+    #\n+    # On dut, dpdk bonding\n+    #\n+\n+    def set_8023ad_agg_mode(self, bond_port, mode=\"bandwidth\"):\n+        \"\"\"\n+        set bonding agg_mode <port_id> <agg_name>\n+\n+        Set 802.11AD Aggregator Mode\n+        \"\"\"\n+        cmd = \"set bonding agg_mode %d %s\" % (bond_port, mode)\n+        self.bond_inst.d_console(cmd)\n+        cur_mode = self.bond_inst.get_bonding_info(bond_port, \"agg_mode\")\n+        if mode == cur_mode:\n+            fmt = \"set bonding agg_mode <{0}> successfully\"\n+            self.logger.info(fmt.format(mode))\n+        else:\n+            msg = \"failed to set bonding agg_mode <{0}>\".format(mode)\n+            self.logger.error(msg)\n+            raise VerifyFailure(msg)\n+\n+    def get_8023ad_agg_mode(self, bond_port):\n+        \"\"\"\n+        get 802.3ad mode  aggregator Mode\n+        \"\"\"\n+        cur_mode = self.bond_inst.get_bonding_info(bond_port, \"agg_mode\")\n+        return cur_mode\n+\n+    def set_8023ad_dedicated_queues(self, bond_port, status=\"disable\"):\n+        \"\"\"\n+        set 802.11AD dedicated_queues mode(enable|disable)\n+        \"\"\"\n+        cmds = [\n+            [\n+                \"set bonding lacp dedicated_queues %s %s\" % (bond_port, status),\n+                [\"\", \"port %s failed\" % bond_port, False],\n+                2,\n+            ],\n+        ]\n+        out = self.bond_inst.d_console(cmds)\n+        # when set 'hw'\n+        if status == \"enable\":\n+            expected_msg = \"queues for LACP control packets enabled\"\n+            err_fmt = \"link bonding mode 4 (802.3ad) set {0} failed\"\n+            self.verify(expected_msg in out, err_fmt.format(status))\n+        elif status == \"disable\":\n+            expected_msg = \"queues for LACP control packets disabled\"\n+            err_fmt = \"link bonding mode 4 (802.3ad) set {0} failed\"\n+            self.verify(expected_msg in out, err_fmt.format(status))\n+\n+    def set_special_command(self, bond_port):\n+        cmds = [\n+            \"set bonding lacp dedicated_queues {} enable\".format(bond_port),\n+            \"set allmulti 0 on\",\n+            \"set allmulti 1 on\",\n+            \"set allmulti {} on\".format(bond_port),\n+            \"set portlist {}\".format(bond_port),\n+        ]\n+        [self.bond_inst.d_console([cmd, \"testpmd>\", 15]) for cmd in cmds]\n+\n+    def set_8023ad_bonded(self, slaves, bond_mode, ignore=True):\n+        \"\"\"set 802.3ad bonded mode for the specified bonding mode\"\"\"\n+        specified_socket = self.dut.get_numa_id(slaves[0])\n+        # create bonded device, add slaves in it\n+        bond_port = self.bond_inst.create_bonded_device(bond_mode, specified_socket)\n+        if not ignore:\n+            # when no slave attached, mac should be 00:00:00:00:00:00\n+            self.bonding_8023ad_check_macs_without_slaves(bond_port)\n+        # add slave\n+        self.bond_inst.add_slave(bond_port, False, \"\", *slaves)\n+        # set special command\n+        self.set_special_command(bond_port)\n+        return bond_port\n+\n+    def set_8023ad_bonded2(self, slaves, bond_mode, ignore=True):\n+        \"\"\"set 802.3ad bonded mode for the specified bonding mode\"\"\"\n+        specified_socket = self.dut.get_numa_id(slaves[0])\n+        # create bonded device, add slaves in it\n+        bond_port = self.bond_inst.create_bonded_device(bond_mode, specified_socket)\n+        if not ignore:\n+            # when no slave attached, mac should be 00:00:00:00:00:00\n+            self.bonding_8023ad_check_macs_without_slaves(bond_port)\n+        # add slave\n+        self.bond_inst.add_slave(bond_port, False, \"\", *slaves)\n+        return bond_port\n+\n+    def get_pci_link(self, slaves):\n+        \"\"\"get slaves ports pci address\"\"\"\n+        slaves_pci = []\n+        for port_id in slaves:\n+            slaves_pci.append(self.dut.ports_info[port_id][\"pci\"])\n+        if not slaves_pci:\n+            msg = \"can't find tx_port pci\"\n+            self.logger.error(msg)\n+            raise VerifyFailure(msg)\n+        return slaves_pci\n+\n+    def set_bond_port_ready(self, tx_port, bond_port):\n+        cmd = \"set portlist {0},{1}\".format(tx_port, bond_port)\n+        self.bond_inst.d_console(cmd)\n+        # for port link up is slow and unstable,\n+        # every port should start one by one\n+        cmds = []\n+        port_num = len(self.sriov_vfs_port)\n+        start_fmt = \"port start {0}\".format\n+        for cnt in range(port_num):\n+            cmds.append([start_fmt(cnt), \"\", 5])\n+        self.bond_inst.d_console(cmds)\n+        time.sleep(10)\n+        self.bond_inst.d_console([start_fmt(self.bond_port), \"\", 15])\n+        time.sleep(5)\n+        self.bond_inst.d_console([\"start\", \"\", 10])\n+        self.verify(\n+            self.bond_inst.testpmd.wait_link_status_up(\"all\"),\n+            \"Failed to set bond port ready!!!\",\n+        )\n+\n+    def run_8023ad_pre(self, slaves, bond_mode):\n+        bond_port = self.set_8023ad_bonded(slaves, bond_mode)\n+        # should set port to stop and make sure port re-sync with parter when\n+        # testpmd linking with switch equipment\n+        cmds = [\"port stop all\", \"\", 15]\n+        self.bond_inst.d_console(cmds)\n+        time.sleep(2)\n+        cmds = [\"port start all\", \"\", 10]\n+        self.bond_inst.d_console(cmds)\n+        self.verify(\n+            self.bond_inst.testpmd.wait_link_status_up(\"all\"),\n+            \"run_8023ad_pre: Failed to start all port\",\n+        )\n+        return bond_port\n+\n+    def bonding_8023ad_check_macs_without_slaves(self, bond_port):\n+        query_type = \"mac\"\n+        bond_port_mac = self.bond_inst.get_port_mac(bond_port, query_type)\n+        default_mac = \"00:00:00:00:00:00\"\n+        if bond_port_mac == default_mac:\n+            msg = \"bond port default mac is [{0}]\".format(default_mac)\n+            self.logger.info(msg)\n+        else:\n+            fmt = \"bond port default mac is [{0}], not expected mac\"\n+            msg = fmt.format(bond_port_mac)\n+            self.logger.warning(msg)\n+\n+    def bonding_8023ad_check_macs(self, slaves, bond_port):\n+        \"\"\"check if bonded device's mac is one of its slaves mac\"\"\"\n+        query_type = \"mac\"\n+        bond_port_mac = self.bond_inst.get_port_mac(bond_port, query_type)\n+        if bond_port_mac == \"00:00:00:00:00:00\":\n+            msg = \"bond port hasn't set mac address\"\n+            self.logger.info(msg)\n+            return\n+\n+        for port_id in slaves:\n+            slave_mac = self.bond_inst.get_port_info(port_id, query_type)\n+            if bond_port_mac == slave_mac:\n+                fmt = \"bonded device's mac is slave [{0}]'s mac [{1}]\"\n+                msg = fmt.format(port_id, slave_mac)\n+                self.logger.info(msg)\n+                return port_id\n+        else:\n+            fmt = \"bonded device's current mac [{0}] \" + \"is not one of its slaves mac\"\n+            msg = fmt.format(bond_port_mac)\n+            # it is not supported by dpdk, but supported by linux normal\n+            # bonding/802.3ad tool\n+            self.logger.warning(\"bonding_8023ad_check_macs: \" + msg)\n+\n+    def check_bonded_device_mac_change(self, slaves, bond_port):\n+        remove_slave = 0\n+        cur_slaves = slaves[1:]\n+        self.bond_inst.remove_slaves(bond_port, False, *[remove_slave])\n+        self.bonding_8023ad_check_macs(cur_slaves, bond_port)\n+\n+    def check_bonded_device_start(self, bond_port):\n+        cmds = [\n+            [\"port stop all\", \"\", 15],\n+            [\"port start %s\" % bond_port, \"\", 10],\n+            [\"start\", [\" \", \"core dump\", False]],\n+        ]\n+        self.bond_inst.d_console(cmds)\n+        time.sleep(2)\n+\n+    def stop_bonded_device(self, bond_port):\n+        cmds = [\n+            [\"stop\", \"\", 10],\n+            [\"port stop %s\" % bond_port, \"\", 10],\n+        ]\n+        self.bond_inst.d_console(cmds)\n+        time.sleep(2)\n+\n+    def check_bonded_device_up_down(self, bond_port):\n+        # stop bonded device\n+        cmd = \"port stop {0}\".format(bond_port)\n+        self.bond_inst.d_console(cmd)\n+        status = self.bond_inst.get_port_info(bond_port, \"link_status\")\n+        if status != \"down\":\n+            msg = \"bond port {0} fail to set down\".format(bond_port)\n+            self.logger.error(msg)\n+            raise VerifyFailure(msg)\n+        else:\n+            msg = \"bond port {0} set down successful !\".format(bond_port)\n+            self.logger.info(msg)\n+        # start bonded device\n+        cmds = [\"port start {0}\".format(bond_port), \"\", 10]\n+        self.bond_inst.d_console(cmds)\n+        self.verify(\n+            self.bond_inst.testpmd.wait_link_status_up(\"all\", timeout=30),\n+            \"bond port {0} fail to set up\".format(bond_port),\n+        )\n+\n+    def check_bonded_device_promisc_mode(self, slaves, bond_port):\n+        # disable bonded device promiscuous mode\n+        cmd = \"set promisc {0} off\".format(bond_port)\n+        self.bond_inst.d_console(cmd)\n+        time.sleep(2)\n+        status = self.bond_inst.get_port_info(bond_port, \"promiscuous_mode\")\n+        if status != \"disabled\":\n+            fmt = \"bond port {0} fail to set promiscuous mode disabled\"\n+            msg = fmt.format(bond_port)\n+            self.logger.warning(msg)\n+        else:\n+            fmt = \"bond port {0} set promiscuous mode disabled successful !\"\n+            msg = fmt.format(bond_port)\n+            self.logger.info(msg)\n+        self.bond_inst.d_console(\"start\")\n+        time.sleep(2)\n+        # check slave promiscuous mode\n+        for port_id in slaves:\n+            status = self.bond_inst.get_port_info(port_id, \"promiscuous_mode\")\n+            if status != \"disabled\":\n+                fmt = (\n+                    \"slave port {0} promiscuous mode \"\n+                    \"isn't the same as bond port 'disabled', \"\n+                )\n+                msg = fmt.format(port_id)\n+                self.logger.warning(msg)\n+                # dpdk developer hasn't completed this function as linux\n+                # document description about `Promiscuous mode`, ignore it here\n+                # temporarily\n+                # raise VerifyFailure(msg)\n+            else:\n+                fmt = \"slave port {0} promiscuous mode is 'disabled' too\"\n+                msg = fmt.format(port_id)\n+                self.logger.info(msg)\n+        # enable bonded device promiscuous mode\n+        cmd = \"set promisc {0} on\".format(bond_port)\n+        self.bond_inst.d_console(cmd)\n+        time.sleep(3)\n+        status = self.bond_inst.get_port_info(bond_port, \"promiscuous_mode\")\n+        if status != \"enabled\":\n+            fmt = \"bond port {0} fail to set promiscuous mode enabled\"\n+            msg = fmt.format(bond_port)\n+            self.logger.error(msg)\n+            raise VerifyFailure(msg)\n+        else:\n+            fmt = \"bond port {0} set promiscuous mode enabled successful !\"\n+            msg = fmt.format(bond_port)\n+            self.logger.info(msg)\n+        # check slave promiscuous mode\n+        for port_id in slaves:\n+            status = self.bond_inst.get_port_info(port_id, \"promiscuous_mode\")\n+            if status != \"enabled\":\n+                fmt = (\n+                    \"slave port {0} promiscuous mode \"\n+                    + \"isn't the same as bond port 'enabled'\"\n+                )\n+                msg = fmt.format(port_id)\n+                self.logger.warning(msg)\n+                # dpdk developer hasn't completed this function as linux\n+                # document description about `Promiscuous mode`, ignore it here\n+                # temporarily\n+                # raise VerifyFailure(msg)\n+            else:\n+                fmt = \"slave port {0} promiscuous mode is 'enabled' too\"\n+                msg = fmt.format(port_id)\n+                self.logger.info(msg)\n+\n+    def check_8023ad_agg_modes(self, slaves, bond_mode):\n+        \"\"\"check aggregator mode\"\"\"\n+        check_results = []\n+        default_agg_mode = \"stable\"\n+        for mode in self.AGG_MODES:\n+            try:\n+                self.bond_inst.start_testpmd(self.eal_param)\n+                bond_port = self.set_8023ad_bonded(slaves, bond_mode)\n+                cur_agg_mode = self.get_8023ad_agg_mode(bond_port)\n+                if cur_agg_mode != default_agg_mode:\n+                    fmt = \"link bonding mode 4 (802.3ad) default agg mode \" \"isn't {0}\"\n+                    msg = fmt.format(default_agg_mode)\n+                    self.logger.warning(msg)\n+                # ignore default mode\n+                if mode == default_agg_mode:\n+                    fmt = \"link bonding mode 4 (802.3ad) \" \"current agg mode is {0}\"\n+                    msg = fmt.format(mode)\n+                    self.logger.info(msg)\n+                    continue\n+                cmds = [[\"port stop all\", \"\", 15], [\"port start all\", \"\", 15]]\n+                self.bond_inst.d_console(cmds)\n+                self.set_8023ad_agg_mode(bond_port, mode)\n+            except Exception as e:\n+                check_results.append(e)\n+                print(traceback.format_exc())\n+            finally:\n+                self.bond_inst.close_testpmd()\n+                time.sleep(2)\n+\n+        if check_results:\n+            for result in check_results:\n+                self.logger.error(result)\n+            raise VerifyFailure(\"check_8023ad_agg_modes is failed\")\n+\n+    def check_8023ad_dedicated_queues(self, slaves, bond_mode):\n+        \"\"\"check 802.3ad dedicated queues\"\"\"\n+        check_results = []\n+        default_slow_queue = \"unknown\"\n+        for mode in self.DEDICATED_QUEUES:\n+            try:\n+                self.bond_inst.start_testpmd(self.eal_param)\n+                bond_port = self.set_8023ad_bonded2(slaves, bond_mode)\n+                self.set_8023ad_dedicated_queues(bond_port, mode)\n+            except Exception as e:\n+                check_results.append(e)\n+                print(traceback.format_exc())\n+            finally:\n+                self.bond_inst.close_testpmd()\n+                time.sleep(2)\n+\n+        if check_results:\n+            for result in check_results:\n+                self.logger.error(result)\n+            raise VerifyFailure(\"check_8023ad_dedicated_queues is failed\")\n+\n+    def get_commandline_options(self, agg_mode):\n+        # get bonding port configuration\n+        slave_pcis = self.vfs_pci\n+        # create commandline option format\n+        bonding_name = \"net_bonding0\"\n+        slaves_pci = [\"slave=\" + pci for pci in slave_pcis]\n+        bonding_mode = \"mode={0}\".format(str(MODE_LACP))\n+        agg_config = \"agg_mode={0}\"\n+        vdev_format = \",\".join([bonding_name] + slaves_pci + [bonding_mode, agg_config])\n+        # command line option\n+        mode = str(MODE_LACP)\n+        option = vdev_format.format(agg_mode)\n+        vdev_option = \" --vdev '{0}'\".format(option)\n+        # 802.3ad bond port only create one, it must be the max port number\n+        bond_port = len(self.sriov_vfs_port)\n+        return bond_port, vdev_option\n+\n+    def run_test_pre(self, agg_mode):\n+        # get bonding port configuration\n+        bond_port, vdev_option = self.get_commandline_options(agg_mode)\n+        self.bond_port = bond_port\n+        # boot up testpmd\n+        eal_param = self.eal_param + vdev_option\n+        self.bond_inst.start_testpmd(eal_option=eal_param)\n+        cur_slaves, cur_agg_mode = self.bond_inst.get_bonding_info(\n+            bond_port, [\"slaves\", \"agg_mode\"]\n+        )\n+        if agg_mode != cur_agg_mode:\n+            fmt = \"expected agg mode is [{0}], current agg mode is [{1}]\"\n+            msg = fmt.format(agg_mode, cur_agg_mode)\n+            self.logger.warning(msg)\n+        # get forwarding port\n+        for port_id in range(len(self.sriov_vfs_port)):\n+            # select a non-slave port as forwarding port to do transmitting\n+            if str(port_id) not in cur_slaves:\n+                tx_port_id = port_id\n+                break\n+        else:\n+            tx_port_id = bond_port\n+        # enable dedicated queue\n+        self.set_8023ad_dedicated_queues(bond_port, \"enable\")\n+        self.set_bond_port_ready(tx_port_id, bond_port)\n+        slaves = [int(slave) for slave in cur_slaves]\n+\n+        return bond_port, slaves, tx_port_id\n+\n+    def run_dpdk_functional_pre(self):\n+        mode = MODE_LACP\n+        slaves = self.vf_ports[:]\n+        self.bond_inst.start_testpmd(self.eal_param)\n+        bond_port = self.run_8023ad_pre(slaves, mode)\n+        return slaves, bond_port\n+\n+    def run_dpdk_functional_post(self):\n+        self.bond_inst.close_testpmd()\n+\n+    def check_cmd_line_option_status(self, agg_mode, bond_port, slaves):\n+        mode = str(MODE_LACP)\n+        msgs = []\n+        (\n+            cur_mode,\n+            cur_slaves,\n+            cur_active_slaves,\n+            cur_agg_mode,\n+        ) = self.bond_inst.get_bonding_info(\n+            bond_port, [\"mode\", \"slaves\", \"active_slaves\", \"agg_mode\"]\n+        )\n+        # check bonding mode\n+        if mode != cur_mode:\n+            fmt = \"expected mode is [{0}], current mode is [{1}]\"\n+            msg = fmt.format(mode, cur_mode)\n+            msgs.append(msg)\n+        # check bonding 802.3ad agg mode\n+        if agg_mode != cur_agg_mode:\n+            fmt = \"expected agg mode is [{0}], current agg mode is [{1}]\"\n+            msg = fmt.format(agg_mode, cur_agg_mode)\n+            msgs.append(msg)\n+        # check bonded slaves\n+        _cur_slaves = [int(id) for id in cur_slaves]\n+        if not _cur_slaves or sorted(slaves) != sorted(_cur_slaves):\n+            slaves_str = \" \".join([str(id) for id in slaves])\n+            cur_slaves_str = (\n+                \" \".join([str(id) for id in _cur_slaves]) if _cur_slaves else \"\"\n+            )\n+            msg_format = \"expected slaves is [{0}], current slaves is [{1}]\"\n+            msg = msg_format.format(slaves_str, cur_slaves_str)\n+            msgs.append(msg)\n+        # check active slaves status before ports start\n+        if cur_active_slaves:\n+            check_active_slaves = [int(id) for id in cur_active_slaves]\n+            if sorted(slaves) != sorted(check_active_slaves):\n+                slaves_str = \" \".join([str(id) for id in slaves])\n+                msg_fmt = (\n+                    \"expected active slaves is [{0}], \" \"current active slaves is [{1}]\"\n+                )\n+                msg = msg_fmt.format(slaves_str, cur_active_slaves)\n+                msgs.append(msg)\n+        else:\n+            msg = \"active slaves should not be empty\"\n+            self.logger.warning(msg)\n+            msgs.append(msg)\n+        # check status after ports start\n+        self.bond_inst.start_ports()\n+        # set bonded device to active status\n+        cur_active_slaves = [\n+            int(id)\n+            for id in self.bond_inst.get_bonding_info(bond_port, \"active_slaves\")\n+        ]\n+        if not cur_active_slaves or sorted(slaves) != sorted(cur_active_slaves):\n+            slaves_str = \" \".join([str(id) for id in slaves])\n+            active_str = (\n+                \" \".join([str(id) for id in cur_active_slaves])\n+                if cur_active_slaves\n+                else \"\"\n+            )\n+            msg_fmt = (\n+                \"expected active slaves is [{0}], \" \"current active slaves is [{1}]\"\n+            )\n+            msg = msg_fmt.format(slaves_str, active_str)\n+            msgs.append(msg)\n+        return msgs\n+\n+    #\n+    # Test cases.\n+    #\n+    def set_up_all(self):\n+        \"\"\"\n+        Run before each test suite\n+        \"\"\"\n+        self.verify(\"bsdapp\" not in self.target, \"Bonding not support freebsd\")\n+        # ------------------------------------------------------------\n+        # link peer resource\n+        self.dut_ports = self.dut.get_ports()\n+        required_link = 2\n+        self.dport_info0 = self.dut.ports_info[self.dut_ports[0]]\n+        self.dport_ifaces = self.dport_info0[\"intf\"]\n+        self.verify(len(self.dut_ports) >= required_link, \"Insufficient ports\")\n+        # Create a vf for each pf and get all vf info,\n+        self.dut.restore_interfaces()\n+        self.create_vfs(pfs_id=self.dut_ports[0:2], vf_num=1)\n+        self.vf_ports = list(range(len(self.vfs_pci)))\n+        self.eal_param = str()\n+        for pci in self.vfs_pci:\n+            self.eal_param += \"-a {} \".format(pci)\n+        # ------------------------------------------------------------\n+        # 802.3ad related\n+        self.bond_port = None\n+        self.bond_slave = self.dut_ports[0]\n+        # ----------------------------------------------------------------\n+        # initialize bonding common methods name\n+        config = {\n+            \"parent\": self,\n+            \"pkt_name\": \"udp\",\n+            \"pkt_size\": FRAME_SIZE_64,\n+            \"src_mac\": \"52:00:00:00:00:03\",\n+            \"src_ip\": \"10.239.129.65\",\n+            \"src_port\": 61,\n+            \"dst_ip\": \"10.239.129.88\",\n+            \"dst_port\": 53,\n+        }\n+        self.bond_inst = bonding.PmdBonding(**config)\n+\n+    def set_up(self):\n+        \"\"\"\n+        Run before each test case.\n+        \"\"\"\n+        pass\n+\n+    def create_vfs(self, pfs_id, vf_num):\n+        self.sriov_vfs_port = []\n+        self.vfs_pci = []\n+        self.dut.bind_interfaces_linux(self.kdriver)\n+        pfs_id = pfs_id if isinstance(pfs_id, list) else [pfs_id]\n+        for pf_id in pfs_id:\n+            self.dut.generate_sriov_vfs_by_port(pf_id, vf_num)\n+            self.sriov_vfs_port += self.dut.ports_info[self.dut_ports[pf_id]][\n+                \"vfs_port\"\n+            ]\n+        for vf in self.sriov_vfs_port:\n+            self.vfs_pci.append(vf.pci)\n+        try:\n+            for port in self.sriov_vfs_port:\n+                port.bind_driver(self.drivername)\n+        except Exception as e:\n+            self.destroy_iavf()\n+            raise Exception(e)\n+\n+    def destroy_iavf(self):\n+        self.dut.destroy_all_sriov_vfs()\n+\n+    def tear_down(self):\n+        \"\"\"\n+        Run after each test case.\n+        \"\"\"\n+        try:\n+            self.bond_inst.close_testpmd()\n+        except Exception:\n+            self.dut.kill_all()\n+\n+    def tear_down_all(self):\n+        \"\"\"\n+        Run after each test suite.\n+        \"\"\"\n+        self.destroy_iavf()\n+\n+    def test_basic_behav_startStop(self):\n+        \"\"\"\n+        Test Case : basic behavior start/stop\n+        \"\"\"\n+        msg = \"\"\n+        slaves, bond_port = self.run_dpdk_functional_pre()\n+        try:\n+            for _ in range(10):\n+                self.check_bonded_device_start(bond_port)\n+                self.stop_bonded_device(bond_port)\n+        except Exception as e:\n+            print(traceback.format_exc())\n+            msg = \"bonding 8023ad check start/stop failed\"\n+        self.run_dpdk_functional_post()\n+        if msg:\n+            raise VerifyFailure(msg)\n+\n+    def test_basic_behav_mac(self):\n+        \"\"\"\n+        Test Case : basic behavior mac\n+        \"\"\"\n+        msg = \"\"\n+        slaves, bond_port = self.run_dpdk_functional_pre()\n+        try:\n+            self.bonding_8023ad_check_macs(slaves, bond_port)\n+            self.check_bonded_device_mac_change(slaves, bond_port)\n+        except Exception as e:\n+            msg = \"bonding 8023ad check mac failed\"\n+        self.run_dpdk_functional_post()\n+        if msg:\n+            raise VerifyFailure(msg)\n+\n+    def test_basic_behav_upDown(self):\n+        \"\"\"\n+        Test Case : basic behavior link up/down\n+        \"\"\"\n+        msg = \"\"\n+        slaves, bond_port = self.run_dpdk_functional_pre()\n+        try:\n+            self.check_bonded_device_up_down(bond_port)\n+        except Exception as e:\n+            msg = \"bonding 8023ad check link up/down failed\"\n+        self.run_dpdk_functional_post()\n+        if msg:\n+            raise VerifyFailure(msg)\n+\n+    def test_basic_behav_promisc_mode(self):\n+        \"\"\"\n+        Test Case : basic behavior promiscuous  mode\n+        \"\"\"\n+        msg = \"\"\n+        slaves, bond_port = self.run_dpdk_functional_pre()\n+        try:\n+            self.check_bonded_device_promisc_mode(slaves, bond_port)\n+        except Exception as e:\n+            msg = \"bonding 8023ad check promisc mode failed\"\n+        self.run_dpdk_functional_post()\n+        if msg:\n+            raise VerifyFailure(msg)\n+\n+    def test_command_line_option(self):\n+        \"\"\"\n+        Test Case : command line option\n+        \"\"\"\n+        agg_modes_msgs = []\n+        for agg_mode in self.AGG_MODES:\n+            bond_port, cur_slaves, tx_port_id = self.run_test_pre(agg_mode)\n+            msgs = self.check_cmd_line_option_status(agg_mode, bond_port, cur_slaves)\n+            if msgs:\n+                agg_modes_msgs.append((msgs, agg_mode))\n+            self.bond_inst.close_testpmd()\n+        if agg_modes_msgs:\n+            msgs = \"\"\n+            for msg, agg_mode in agg_modes_msgs:\n+                self.logger.warning(msg)\n+                msgs += \"fail to config from command line at {0}  \".format(agg_mode)\n+            raise VerifyFailure(msgs)\n+\n+    def test_basic_behav_agg_mode(self):\n+        \"\"\"\n+        Test Case : basic behavior agg mode\n+        \"\"\"\n+        mode = MODE_LACP\n+        self.check_8023ad_agg_modes(self.vf_ports, mode)\n+\n+    def test_basic_dedicated_queues(self):\n+        \"\"\"\n+        Test Case : basic behavior dedicated queues\n+        \"\"\"\n+        mode = MODE_LACP\n+        self.check_8023ad_dedicated_queues(self.vf_ports, mode)\n",
    "prefixes": [
        "V1",
        "3/7"
    ]
}