Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/121643/?format=api
http://patches.dpdk.org/api/patches/121643/?format=api", "web_url": "http://patches.dpdk.org/project/dts/patch/20230106093209.317472-6-songx.jiale@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": "<20230106093209.317472-6-songx.jiale@intel.com>", "list_archive_url": "https://inbox.dpdk.org/dts/20230106093209.317472-6-songx.jiale@intel.com", "date": "2023-01-06T09:32:07", "name": "[V2,5/7] tests/vf_pmd_stacked_bonded: add cases to test vf bonding", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "294ba987236cbbe7fa370ddb1ad72d7a1966ebed", "submitter": { "id": 2352, "url": "http://patches.dpdk.org/api/people/2352/?format=api", "name": "Jiale, SongX", "email": "songx.jiale@intel.com" }, "delegate": null, "mbox": "http://patches.dpdk.org/project/dts/patch/20230106093209.317472-6-songx.jiale@intel.com/mbox/", "series": [ { "id": 26404, "url": "http://patches.dpdk.org/api/series/26404/?format=api", "web_url": "http://patches.dpdk.org/project/dts/list/?series=26404", "date": "2023-01-06T09:32:02", "name": "add cases to test vf bonding", "version": 2, "mbox": "http://patches.dpdk.org/series/26404/mbox/" } ], "comments": "http://patches.dpdk.org/api/patches/121643/comments/", "check": "pending", "checks": "http://patches.dpdk.org/api/patches/121643/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 361B3A00C2;\n\tFri, 6 Jan 2023 02:34:33 +0100 (CET)", "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 2B16C42D26;\n\tFri, 6 Jan 2023 02:34:33 +0100 (CET)", "from mga03.intel.com (mga03.intel.com [134.134.136.65])\n by mails.dpdk.org (Postfix) with ESMTP id 09A1D4021F\n for <dts@dpdk.org>; Fri, 6 Jan 2023 02:34:30 +0100 (CET)", "from orsmga005.jf.intel.com ([10.7.209.41])\n by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 05 Jan 2023 17:34:30 -0800", "from unknown (HELO localhost.localdomain) ([10.239.252.20])\n by orsmga005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 05 Jan 2023 17:34:28 -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=1672968871; x=1704504871;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=nE1H+P8OIffJjO3ZWI+kc8oR6Vm5iZCnI9WnnsEsF+U=;\n b=nDEuvcaA5zCj8HjjPw3exEIHbKdeH7CkE6V++5Hq+8EozIpRgZby6NTr\n 0DLIrIHgEiFX3TvKHhmv3zDE2IwNysodmrguCpzkxIksdU1HB4cA1qQwY\n X4eSGSrA906YuPiPSnGHWKSRhrVirfmGK/QtylMSl9pmkufIc+A+WrI5y\n PYP8XqXS3LjWuLcmJ24qITNFc8zbOrluy3AVQ7Nck9+wb7SKKOI3TtpUY\n q2oNdmhrEQLa954nQhgvVUJHwgZdTHqImjpjWSykcOJKwtlvMMp3/COuP\n qp/No+jsy+HjqYSn7k4f+rkSZAsB8eVB0eHfURBt1gIMh6cAjRYIkuoiW A==;", "X-IronPort-AV": [ "E=McAfee;i=\"6500,9779,10581\"; a=\"324391125\"", "E=Sophos;i=\"5.96,303,1665471600\"; d=\"scan'208\";a=\"324391125\"", "E=McAfee;i=\"6500,9779,10581\"; a=\"829755003\"", "E=Sophos;i=\"5.96,303,1665471600\"; d=\"scan'208\";a=\"829755003\"" ], "From": "Song Jiale <songx.jiale@intel.com>", "To": "dts@dpdk.org", "Cc": "Song Jiale <songx.jiale@intel.com>", "Subject": "[dts] [PATCH V2 5/7] tests/vf_pmd_stacked_bonded: add cases to test\n vf bonding", "Date": "Fri, 6 Jan 2023 09:32:07 +0000", "Message-Id": "<20230106093209.317472-6-songx.jiale@intel.com>", "X-Mailer": "git-send-email 2.25.1", "In-Reply-To": "<20230106093209.317472-1-songx.jiale@intel.com>", "References": "<20230106093209.317472-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\nv2:\n -modify class name\n\n tests/TestSuite_vf_pmd_stacked_bonded.py | 614 +++++++++++++++++++++++\n 1 file changed, 614 insertions(+)\n create mode 100644 tests/TestSuite_vf_pmd_stacked_bonded.py", "diff": "diff --git a/tests/TestSuite_vf_pmd_stacked_bonded.py b/tests/TestSuite_vf_pmd_stacked_bonded.py\nnew file mode 100644\nindex 00000000..742eb841\n--- /dev/null\n+++ b/tests/TestSuite_vf_pmd_stacked_bonded.py\n@@ -0,0 +1,614 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2023 Intel Corporation\n+#\n+\n+import time\n+import traceback\n+\n+# import dts/framework libs\n+import framework.utils as utils\n+\n+# import bonding lib\n+import tests.bonding as bonding\n+from framework.exception import VerifyFailure\n+from framework.test_case import TestCase\n+\n+from .bonding import (\n+ FRAME_SIZE_64,\n+ MODE_ACTIVE_BACKUP,\n+ MODE_ALB_BALANCE,\n+ MODE_BROADCAST,\n+ MODE_LACP,\n+ MODE_ROUND_ROBIN,\n+ MODE_TLB_BALANCE,\n+ MODE_XOR_BALANCE,\n+)\n+\n+\n+class TestVFPmdStackedBonded(TestCase):\n+\n+ #\n+ # On dut, dpdk bonding\n+ #\n+ def check_bonded_device_queue_config(self, *devices):\n+ \"\"\"\n+ check if master bonded device/slave device queue configuration\n+ is the same.\n+ \"\"\"\n+ # get master bonded device queue configuration\n+ master = self.bond_inst.get_port_info(devices[0], \"queue_config\")\n+ # get slave device queue configuration\n+ for port_id in devices[1:]:\n+ config = self.bond_inst.get_port_info(port_id, \"queue_config\")\n+ if config == master:\n+ continue\n+ msg = (\n+ \"slave bonded port [{0}] is \" \"different to top bonded port [{1}]\"\n+ ).format(port_id, devices[0])\n+ raise VerifyFailure(\"bonded device queue config:: \" + msg)\n+\n+ def set_stacked_bonded(self, slaveGrpOne, slaveGrpTwo, bond_mode, ignore=False):\n+ \"\"\"\n+ set stacked bonded mode for a custom bonding mode\n+ \"\"\"\n+ inst = self.bond_inst\n+ socket_id = self.dut.get_numa_id(self.bond_slave)\n+ # create first bonded device 1, add slaves in it\n+ bond_port_1 = inst.create_bonded_device(bond_mode, socket_id)\n+ inst.add_slave(bond_port_1, False, \"\", *slaveGrpOne)\n+ # create second bonded device 2, add slaves in it\n+ bond_port_2 = inst.create_bonded_device(bond_mode, socket_id)\n+ inst.add_slave(bond_port_2, False, \"\", *slaveGrpTwo)\n+ # create master bonded device 3, which is the top bonded device\n+ master_bond_port = inst.create_bonded_device(bond_mode, socket_id)\n+ # add bond bonded device 1 to bonded device 3\n+ # check bonding config status\n+ inst.add_slave(master_bond_port, False, \"\", *[bond_port_1])\n+ # add bonded device 2 to bonded device 3\n+ # check bonding config status\n+ inst.add_slave(master_bond_port, False, \"\", *[bond_port_2])\n+ # check if master bonding/each slaves queue configuration is the same.\n+ if not ignore:\n+ self.check_bonded_device_queue_config(\n+ *[master_bond_port, bond_port_1, bond_port_2]\n+ )\n+\n+ return [bond_port_1, bond_port_2, master_bond_port]\n+\n+ def set_third_stacked_bonded(self, bond_port, bond_mode):\n+ \"\"\"\n+ set third level stacked bonded to check if stacked level can be set\n+ more than 2\n+ \"\"\"\n+ inst = self.bond_inst\n+ socket_id = self.dut.get_numa_id(self.bond_slave)\n+ third_bond_port = inst.create_bonded_device(bond_mode, socket_id)\n+ inst.add_slave(third_bond_port, False, \"\", *[bond_port])\n+\n+ def duplicate_add_stacked_bonded(self, bond_port_1, bond_port_2, master_bond_port):\n+ \"\"\"\n+ check if adding duplicate stacked bonded device is forbidden\n+ \"\"\"\n+ inst = self.bond_inst\n+ # check exception process\n+ expected_str = \"Slave device is already a slave of a bonded device\"\n+ # add bonded device 1 to bonded device 3\n+ # check bonding config status\n+ inst.add_slave(master_bond_port, False, expected_str, *[bond_port_1])\n+ # add bonded device 2 to bonded device 3\n+ # check bonding config status\n+ inst.add_slave(master_bond_port, False, expected_str, *[bond_port_2])\n+\n+ def preset_stacked_bonded(self, slaveGrpOne, slaveGrpTwo, bond_mode):\n+ bond_port_1, bond_port_2, master_bond_port = self.set_stacked_bonded(\n+ slaveGrpOne, slaveGrpTwo, bond_mode, ignore=True\n+ )\n+ portList = [\n+ slaveGrpOne[0],\n+ slaveGrpTwo[0],\n+ bond_port_1,\n+ bond_port_2,\n+ master_bond_port,\n+ ]\n+ cmds = [\n+ [\"port stop all\", \"\"],\n+ [\"set portlist \" + \",\".join([str(port) for port in portList]), \"\"],\n+ # start top level bond port only, and let it propagate the start\n+ # action to slave bond ports and its the real nics.\n+ [\"port start {}\".format(master_bond_port), \" \", 15],\n+ ]\n+ self.bond_inst.d_console(cmds)\n+ # blank space command is used to skip LSC event to avoid core dumped issue\n+ time.sleep(5)\n+ cmds = [[\" \", \"\"], [\"start\", \"\"]]\n+ self.bond_inst.d_console(cmds)\n+ time.sleep(5)\n+\n+ return bond_port_1, bond_port_2, master_bond_port\n+\n+ def send_packets_by_scapy(self, **kwargs):\n+ tx_iface = kwargs.get(\"port topo\")[0]\n+ # set interface ready to send packet\n+ self.dut1 = self.dut.new_session()\n+ cmd = \"ifconfig {0} up\".format(tx_iface)\n+ self.dut1.send_expect(cmd, \"# \", 30)\n+ send_pkts = kwargs.get(\"stream\")\n+ # stream config\n+ stream_configs = kwargs.get(\"traffic configs\")\n+ count = stream_configs.get(\"count\")\n+ interval = stream_configs.get(\"interval\", 0.01)\n+ # run traffic\n+ self.dut1.send_expect(\"scapy\", \">>> \", 30)\n+ cmd = (\n+ \"sendp(\"\n+ + send_pkts[0].command()\n+ + f',iface=\"{tx_iface}\",count={count},inter={interval},verbose=False)'\n+ )\n+ self.dut1.send_expect(cmd, \">>> \")\n+ self.dut1.send_expect(\"quit()\", \"# \")\n+ self.dut.close_session(self.dut1)\n+\n+ #\n+ # packet transmission\n+ #\n+ def traffic(self, traffic_config, ports, tport_is_up=True):\n+ # get ports statistics before sending packets\n+ stats_pre = self.bond_inst.get_all_stats(ports)\n+ # send packets\n+ if tport_is_up:\n+ self.bond_inst.send_packet(traffic_config)\n+ else:\n+ self.send_packets_by_scapy(**traffic_config)\n+ # get ports statistics after sending packets\n+ stats_post = self.bond_inst.get_all_stats(ports)\n+ # calculate ports statistics result\n+ for port_id in ports:\n+ stats_post[port_id][\"RX-packets\"] -= stats_pre[port_id][\"RX-packets\"]\n+ stats_post[port_id][\"TX-packets\"] -= stats_pre[port_id][\"TX-packets\"]\n+\n+ return stats_post\n+\n+ def config_port_traffic(self, tx_port, rx_port, total_pkt):\n+ \"\"\"set traffic configuration\"\"\"\n+ traffic_config = {\n+ \"port topo\": [tx_port, rx_port],\n+ \"stream\": self.bond_inst.set_stream_to_slave_port(rx_port),\n+ \"traffic configs\": {\n+ \"count\": total_pkt,\n+ },\n+ }\n+\n+ return traffic_config\n+\n+ def active_slave_rx(self, slave, bond_port, mode):\n+ msg = \"send packet to active slave port <{0}>\".format(slave)\n+ self.logger.info(msg)\n+ if slave in [0, 1]:\n+ tx_intf = self.tester.get_interface(\n+ self.tester.get_local_port(self.dut_ports[0])\n+ )\n+ elif slave in [2, 3]:\n+ tx_intf = self.tester.get_interface(\n+ self.tester.get_local_port(self.dut_ports[1])\n+ )\n+ else:\n+ self.verify(False, \"Error slave port <{0}>\".format(slave))\n+ # get traffic config\n+ traffic_config = self.config_port_traffic(tx_intf, slave, self.total_pkt)\n+ # select ports for statistics\n+ ports = [slave, bond_port]\n+ # run traffic\n+ stats = self.traffic(traffic_config, ports)\n+ # check slave statistics\n+ msg = \"port <{0}> Data not received by port <{1}>\".format(tx_intf, slave)\n+ # here using `>=` to ignore some miscellaneous packets, e.g. lldp\n+ self.verify(stats[slave][\"RX-packets\"] >= self.total_pkt, msg)\n+ msg = \"tester port {0} <----> VF port {1} is ok\".format(tx_intf, slave)\n+ self.logger.info(msg)\n+ # check bond port statistics\n+ # here using `>=` to ignore some miscellaneous packets, e.g. lldp\n+ self.verify(\n+ stats[slave][\"RX-packets\"] >= self.total_pkt,\n+ \"Bond port have error RX packet in XOR\",\n+ )\n+\n+ def inactive_slave_rx(self, slave, bond_port, mode):\n+ msg = \"send packet to inactive slave port <{0}>\".format(slave)\n+ self.logger.info(msg)\n+ tx_intf = self.dport_ifaces\n+ # get traffic config\n+ traffic_config = self.config_port_traffic(tx_intf, slave, self.total_pkt)\n+ # select ports for statistics\n+ ports = [slave, bond_port]\n+ # run traffic\n+ stats = self.traffic(traffic_config, ports, tport_is_up=False)\n+ # check slave statistics\n+ msg = (\"port <{0}> Data received by port <{1}>, \" \"but should not.\").format(\n+ tx_intf, slave\n+ )\n+ self.verify(stats[slave][\"RX-packets\"] == 0, msg)\n+ msg = \"tester port {0} <-| |-> VF port {1} is blocked\".format(tx_intf, slave)\n+ self.logger.info(msg)\n+ # check bond port statistics\n+ self.verify(\n+ stats[slave][\"RX-packets\"] == 0,\n+ \"Bond port have error RX packet in {0}\".format(mode),\n+ )\n+\n+ def set_port_status(self, vfs_id, tport_inface, status):\n+ # stop slave link by force\n+ cmd = \"ifconfig {0} {1}\".format(tport_inface, status)\n+ self.tester.send_expect(cmd, \"# \")\n+ time.sleep(3)\n+ vfs_id = vfs_id if isinstance(vfs_id, list) else [vfs_id]\n+ for vf in vfs_id:\n+ cur_status = self.bond_inst.get_port_info(vf, \"link_status\")\n+ self.logger.info(\"port {0} is [{1}]\".format(vf, cur_status))\n+ self.verify(cur_status == status, \"expected status is [{0}]\".format(status))\n+\n+ def check_traffic_with_one_slave_down(self, mode):\n+ \"\"\"\n+ Verify that transmitting packets correctly when set one slave of\n+ the bonded device link down.\n+ \"\"\"\n+ results = []\n+ # -------------------------------\n+ # boot up testpmd\n+ self.bond_inst.start_testpmd(self.eal_param)\n+ self.bond_inst.d_console(\"set fwd mac\")\n+ try:\n+ slaves = {\"active\": [], \"inactive\": []}\n+ # -------------------------------\n+ # preset stacked bonded device\n+ slaveGrpOne = self.slaveGrpOne\n+ slaveGrpTwo = self.slaveGrpTwo\n+ bond_port_1, bond_port_2, master_bond_port = self.preset_stacked_bonded(\n+ slaveGrpOne, slaveGrpTwo, mode\n+ )\n+ # ---------------------------------------------------\n+ # set one slave of first bonded device and second bonded device link down\n+ bond1_primary_slave = slaveGrpOne[0]\n+ bond2_primary_slave = slaveGrpTwo[0]\n+ # self.bond_inst.set_dut_port_status(primary_slave, \"down\")\n+ self.set_port_status(\n+ vfs_id=[0, 1], tport_inface=self.tport_iface0, status=\"down\"\n+ )\n+ slaves[\"inactive\"].append(bond1_primary_slave)\n+ # get slave status\n+ primary_port, active_slaves = self.bond_inst.get_active_slaves(bond_port_1)\n+ slaves[\"active\"].extend(active_slaves)\n+ if bond1_primary_slave in slaves[\"active\"]:\n+ msg = \"{0} should not be in active slaves list\".format(\n+ bond1_primary_slave\n+ )\n+ raise Exception(msg)\n+ slaves[\"inactive\"].append(bond2_primary_slave)\n+ # check active slaves\n+ primary_port_2, active_slaves_2 = self.bond_inst.get_active_slaves(\n+ bond_port_2\n+ )\n+ slaves[\"active\"].extend(active_slaves_2)\n+ if bond2_primary_slave in slaves[\"active\"]:\n+ msg = \"{0} should not be in active slaves list\".format(\n+ bond2_primary_slave\n+ )\n+ raise Exception(msg)\n+ # traffic testing\n+ # active slave traffic testing\n+ for slave in slaves[\"active\"]:\n+ self.active_slave_rx(slave, master_bond_port, mode)\n+ # inactive slave traffic testing\n+ for slave in slaves[\"inactive\"]:\n+ self.inactive_slave_rx(slave, master_bond_port, mode)\n+ except Exception as e:\n+ results.append(e)\n+ self.logger.error(traceback.format_exc())\n+ finally:\n+ self.bond_inst.close_testpmd()\n+\n+ return results\n+\n+ def check_traffic(self, mode):\n+ \"\"\"normal traffic with all slaves are under active status.\n+ verify the RX packets are all correct with stacked bonded device.\n+ bonded device's statistics should be the sum of slaves statistics.\n+ \"\"\"\n+ self.bond_inst.start_testpmd(self.eal_param)\n+ self.bond_inst.d_console(\"set fwd mac\")\n+ slaveGrpOne = self.slaveGrpOne\n+ slaveGrpTwo = self.slaveGrpTwo\n+ bond_port_1, bond_port_2, master_bond_port = self.preset_stacked_bonded(\n+ slaveGrpOne, slaveGrpTwo, mode\n+ )\n+ results = []\n+ # check first bonded device\n+ try:\n+ self.logger.info(\"check first bonded device\")\n+ # active slave traffic testing\n+ for slave in slaveGrpOne:\n+ self.active_slave_rx(slave, bond_port_1, mode)\n+ except Exception as e:\n+ results.append(e)\n+ # check second bonded device\n+ try:\n+ self.logger.info(\"check second bonded device\")\n+ # active slave traffic testing\n+ for slave in slaveGrpOne:\n+ self.active_slave_rx(slave, bond_port_2, mode)\n+ except Exception as e:\n+ results.append(e)\n+\n+ # check top bonded device\n+ try:\n+ self.logger.info(\"check master bonded device\")\n+ # active slave traffic testing\n+ for slave in slaveGrpOne + slaveGrpTwo:\n+ self.active_slave_rx(slave, master_bond_port, mode)\n+ except Exception as e:\n+ results.append(e)\n+\n+ self.bond_inst.close_testpmd()\n+\n+ return results\n+\n+ def backup_check_traffic(self):\n+ mode = MODE_ACTIVE_BACKUP\n+ msg = \"begin checking bonding backup(stacked) mode transmission\"\n+ self.logger.info(msg)\n+ results = self.check_traffic(mode)\n+ if results:\n+ for item in results:\n+ self.logger.error(item)\n+ raise VerifyFailure(\"backup(stacked) mode: rx failed\")\n+\n+ def backup_check_traffic_with_slave_down(self):\n+ mode = MODE_ACTIVE_BACKUP\n+ self.logger.info(\n+ \"begin checking bonding backup(stacked) \"\n+ \"mode transmission with one slave down\"\n+ )\n+ results = self.check_traffic_with_one_slave_down(mode)\n+ if results:\n+ for item in results:\n+ self.logger.error(item)\n+ msg = \"backup(stacked) mode: rx with one slave down failed\"\n+ raise VerifyFailure(msg)\n+\n+ def xor_check_rx(self):\n+ mode = MODE_XOR_BALANCE\n+ msg = \"begin checking bonding xor(stacked) mode transmission\"\n+ self.logger.info(msg)\n+ results = self.check_traffic(mode)\n+ if results:\n+ for item in results:\n+ self.logger.error(item)\n+ raise VerifyFailure(\"xor(stacked) mode: rx failed\")\n+\n+ def xor_check_stacked_rx_one_slave_down(self):\n+ mode = MODE_XOR_BALANCE\n+ self.logger.info(\n+ \"begin checking bonding xor(stacked) mode \"\n+ \"transmission with one slave down\"\n+ )\n+ results = self.check_traffic_with_one_slave_down(mode)\n+ if results:\n+ for item in results:\n+ self.logger.error(item)\n+ msg = \"xor(stacked) mode: rx with one slave down failed\"\n+ raise VerifyFailure(msg)\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+ self.dut_ports = self.dut.get_ports()\n+ self.dport_info0 = self.dut.ports_info[self.dut_ports[0]]\n+ self.dport_ifaces = self.dport_info0[\"intf\"]\n+ num_ports = len(self.dut_ports)\n+ self.verify(num_ports == 2 or num_ports == 4, \"Insufficient ports\")\n+ tester_port0 = self.tester.get_local_port(self.dut_ports[0])\n+ self.tport_iface0 = self.tester.get_interface(tester_port0)\n+ self.flag = \"link-down-on-close\"\n+ self.default_stats = self.tester.get_priv_flags_state(\n+ self.tport_iface0, self.flag\n+ )\n+ self.tester.send_expect(\n+ \"ethtool --set-priv-flags %s %s on\" % (self.tport_iface0, self.flag), \"# \"\n+ )\n+ tester_port1 = self.tester.get_local_port(self.dut_ports[1])\n+ self.tport_iface1 = self.tester.get_interface(tester_port1)\n+ self.tester.send_expect(\n+ \"ethtool --set-priv-flags %s %s on\" % (self.tport_iface1, self.flag), \"# \"\n+ )\n+ # separate ports into two group as first level bond ports' slaves\n+ self.slaveGrpOne = [0, 2]\n+ self.slaveGrpTwo = [1, 3]\n+ self.bond_slave = self.dut_ports[0]\n+ # initialize bonding common methods name\n+ self.total_pkt = 100\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 tear_down_all(self):\n+ \"\"\"\n+ Run after each test suite.\n+ \"\"\"\n+ self.tester.send_expect(\n+ \"ethtool --set-priv-flags %s %s %s\"\n+ % (self.tport_iface0, self.flag, self.default_stats),\n+ \"# \",\n+ )\n+ self.tester.send_expect(\n+ \"ethtool --set-priv-flags %s %s %s\"\n+ % (self.tport_iface1, self.flag, self.default_stats),\n+ \"# \",\n+ )\n+\n+ def set_up(self):\n+ \"\"\"\n+ Run before each test case.\n+ \"\"\"\n+ self.create_vfs(pfs_id=self.dut_ports[0:2], vf_num=2)\n+ self.eal_param = \"\"\n+ for pci in self.vfs_pci:\n+ self.eal_param += \" -a %s\" % pci\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_sriov_vfs_by_port(self.dut_ports[0])\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+ self.destroy_iavf()\n+ for port in self.dut_ports:\n+ tport = self.tester.get_local_port(port)\n+ tport_iface = self.tester.get_interface(tport)\n+ cmd = \"ifconfig {0} up\".format(tport_iface)\n+ self.tester.send_expect(cmd, \"# \")\n+\n+ def test_basic_behav(self):\n+ \"\"\"\n+ Test Case: basic behavior\n+ allow a bonded device to be added to another bonded device.\n+ There's two limitations to create master bonding:\n+\n+ - Total depth of nesting is limited to two levels,\n+ - 802.3ad mode is not supported if one or more slaves is a bond device\n+\n+ note: There 802.3ad mode can not be supported on this bond device.\n+\n+ This case is aimed at testing basic behavior of stacked bonded commands.\n+\n+ \"\"\"\n+ # ------------------------------------------------\n+ # check stacked bonded status, except mode 4 (802.3ad)\n+ mode_list = [\n+ MODE_ROUND_ROBIN,\n+ MODE_ACTIVE_BACKUP,\n+ MODE_XOR_BALANCE,\n+ MODE_BROADCAST,\n+ MODE_TLB_BALANCE,\n+ MODE_ALB_BALANCE,\n+ ]\n+ slaveGrpOne = self.slaveGrpOne\n+ slaveGrpTwo = self.slaveGrpTwo\n+ check_result = []\n+ for bond_mode in mode_list:\n+ self.logger.info(\"begin mode <{0}> checking\".format(bond_mode))\n+ # boot up testpmd\n+ self.bond_inst.start_testpmd(self.eal_param)\n+ self.bond_inst.d_console(\"set fwd mac\")\n+ try:\n+ self.logger.info(\"check bonding mode <{0}>\".format(bond_mode))\n+ # set up stacked bonded status\n+ bond_port_1, bond_port_2, master_bond_port = self.set_stacked_bonded(\n+ slaveGrpOne, slaveGrpTwo, bond_mode\n+ )\n+ # check duplicate add slave\n+ self.duplicate_add_stacked_bonded(\n+ bond_port_1, bond_port_2, master_bond_port\n+ )\n+ # check stacked limitation\n+ self.set_third_stacked_bonded(master_bond_port, bond_mode)\n+ # quit testpmd, it is not supported to reset testpmd\n+ self.logger.info(\"mode <{0}> done !\".format(bond_mode))\n+ check_result.append([bond_mode, None])\n+ except Exception as e:\n+ check_result.append([bond_mode, e])\n+ self.logger.error(e)\n+ finally:\n+ self.bond_inst.close_testpmd()\n+ time.sleep(5)\n+ # ------------------------------------------------\n+ # 802.3ad mode is not supported\n+ # if one or more slaves is a bond device\n+ # so it should raise a exception\n+ msg = \"\"\n+ try:\n+ # boot up testpmd\n+ self.bond_inst.start_testpmd(self.eal_param)\n+ # set up stacked bonded status\n+ self.set_stacked_bonded(slaveGrpOne, slaveGrpTwo, MODE_LACP)\n+ # quit testpmd, it is not supported to reset testpmd\n+ msg = \"802.3ad mode hasn't been forbidden to \" \"use stacked bonded setting\"\n+ check_result.append([MODE_LACP, msg])\n+ except Exception as e:\n+ check_result.append([MODE_LACP, None])\n+ finally:\n+ self.bond_inst.close_testpmd()\n+\n+ exception_flag = False\n+ for bond_mode, e in check_result:\n+ msg = \"mode <{0}>\".format(bond_mode)\n+ if e:\n+ self.logger.info(msg)\n+ self.logger.error(e)\n+ exception_flag = True\n+ else:\n+ self.logger.info(msg + \" done !\")\n+ # if some checking item is failed, raise exception\n+ if exception_flag:\n+ raise VerifyFailure(\"some test items failed\")\n+ else:\n+ self.logger.info(\"all test items have done !\")\n+\n+ def test_mode_backup_rx(self):\n+ \"\"\"\n+ Test Case: active-backup stacked bonded rx traffic\n+ \"\"\"\n+ self.backup_check_traffic()\n+\n+ def test_mode_backup_one_slave_down(self):\n+ \"\"\"\n+ Test Case: active-backup stacked bonded rx traffic with slave down\n+ \"\"\"\n+ self.backup_check_traffic_with_slave_down()\n+\n+ def test_mode_xor_rx(self):\n+ \"\"\"\n+ Test Case: balance-xor stacked bonded rx traffic\n+ \"\"\"\n+ self.xor_check_rx()\n+\n+ def test_mode_xor_rx_one_slave_down(self):\n+ \"\"\"\n+ Test Case: balance-xor stacked bonded rx traffic with slave down\n+ \"\"\"\n+ self.xor_check_stacked_rx_one_slave_down()\n", "prefixes": [ "V2", "5/7" ] }{ "id": 121643, "url": "