Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/109302/?format=api
http://patches.dpdk.org/api/patches/109302/?format=api", "web_url": "http://patches.dpdk.org/project/dpdk/patch/20220406151903.2916254-4-juraj.linkes@pantheon.tech/", "project": { "id": 1, "url": "http://patches.dpdk.org/api/projects/1/?format=api", "name": "DPDK", "link_name": "dpdk", "list_id": "dev.dpdk.org", "list_email": "dev@dpdk.org", "web_url": "http://core.dpdk.org", "scm_url": "git://dpdk.org/dpdk", "webscm_url": "http://git.dpdk.org/dpdk", "list_archive_url": "https://inbox.dpdk.org/dev", "list_archive_url_format": "https://inbox.dpdk.org/dev/{}", "commit_url_format": "" }, "msgid": "<20220406151903.2916254-4-juraj.linkes@pantheon.tech>", "list_archive_url": "https://inbox.dpdk.org/dev/20220406151903.2916254-4-juraj.linkes@pantheon.tech", "date": "2022-04-06T15:18:43", "name": "[RFC,v1,03/23] dts: merge DTS framework/pmd_output.py to DPDK", "commit_ref": null, "pull_url": null, "state": "rfc", "archived": true, "hash": "15162e1fcedc05fdc65f6ef5420c27ffe1114805", "submitter": { "id": 1626, "url": "http://patches.dpdk.org/api/people/1626/?format=api", "name": "Juraj Linkeš", "email": "juraj.linkes@pantheon.tech" }, "delegate": { "id": 1, "url": "http://patches.dpdk.org/api/users/1/?format=api", "username": "tmonjalo", "first_name": "Thomas", "last_name": "Monjalon", "email": "thomas@monjalon.net" }, "mbox": "http://patches.dpdk.org/project/dpdk/patch/20220406151903.2916254-4-juraj.linkes@pantheon.tech/mbox/", "series": [ { "id": 22381, "url": "http://patches.dpdk.org/api/series/22381/?format=api", "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=22381", "date": "2022-04-06T15:18:40", "name": "merge DTS test resource files to DPDK", "version": 1, "mbox": "http://patches.dpdk.org/series/22381/mbox/" } ], "comments": "http://patches.dpdk.org/api/patches/109302/comments/", "check": "warning", "checks": "http://patches.dpdk.org/api/patches/109302/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<dev-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 E1C75A0509;\n\tWed, 6 Apr 2022 17:19:27 +0200 (CEST)", "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 61A9B428A4;\n\tWed, 6 Apr 2022 17:19:11 +0200 (CEST)", "from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20])\n by mails.dpdk.org (Postfix) with ESMTP id 06DAD42878\n for <dev@dpdk.org>; Wed, 6 Apr 2022 17:19:10 +0200 (CEST)", "from localhost (localhost [127.0.0.1])\n by lb.pantheon.sk (Postfix) with ESMTP id 0856C184FF0;\n Wed, 6 Apr 2022 17:19:08 +0200 (CEST)", "from lb.pantheon.sk ([127.0.0.1])\n by localhost (lb.pantheon.sk [127.0.0.1]) (amavisd-new, port 10024)\n with ESMTP id LPtmJfUomrov; Wed, 6 Apr 2022 17:19:07 +0200 (CEST)", "from entguard.lab.pantheon.local (unknown [46.229.239.141])\n by lb.pantheon.sk (Postfix) with ESMTP id 2E240184FF1;\n Wed, 6 Apr 2022 17:19:05 +0200 (CEST)" ], "X-Virus-Scanned": "amavisd-new at siecit.sk", "From": "=?utf-8?q?Juraj_Linke=C5=A1?= <juraj.linkes@pantheon.tech>", "To": "thomas@monjalon.net, david.marchand@redhat.com,\n Honnappa.Nagarahalli@arm.com, ohilyard@iol.unh.edu, lijuan.tu@intel.com", "Cc": "dev@dpdk.org, =?utf-8?q?Juraj_Linke=C5=A1?= <juraj.linkes@pantheon.tech>", "Subject": "[RFC PATCH v1 03/23] dts: merge DTS framework/pmd_output.py to DPDK", "Date": "Wed, 6 Apr 2022 15:18:43 +0000", "Message-Id": "<20220406151903.2916254-4-juraj.linkes@pantheon.tech>", "X-Mailer": "git-send-email 2.25.1", "In-Reply-To": "<20220406151903.2916254-1-juraj.linkes@pantheon.tech>", "References": "<20220406151903.2916254-1-juraj.linkes@pantheon.tech>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-BeenThere": "dev@dpdk.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "DPDK patches and discussions <dev.dpdk.org>", "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>", "List-Archive": "<http://mails.dpdk.org/archives/dev/>", "List-Post": "<mailto:dev@dpdk.org>", "List-Help": "<mailto:dev-request@dpdk.org?subject=help>", "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>", "Errors-To": "dev-bounces@dpdk.org" }, "content": "---\n dts/framework/pmd_output.py | 341 ++++++++++++++++++++++++++++++++++++\n 1 file changed, 341 insertions(+)\n create mode 100644 dts/framework/pmd_output.py", "diff": "diff --git a/dts/framework/pmd_output.py b/dts/framework/pmd_output.py\nnew file mode 100644\nindex 0000000000..f27c2513af\n--- /dev/null\n+++ b/dts/framework/pmd_output.py\n@@ -0,0 +1,341 @@\n+# BSD LICENSE\n+#\n+# Copyright(c) 2020 Intel Corporation. All rights reserved\n+# All rights reserved.\n+#\n+# Redistribution and use in source and binary forms, with or without\n+# modification, are permitted provided that the following conditions\n+# are met:\n+#\n+# * Redistributions of source code must retain the above copyright\n+# notice, this list of conditions and the following disclaimer.\n+# * Redistributions in binary form must reproduce the above copyright\n+# notice, this list of conditions and the following disclaimer in\n+# the documentation and/or other materials provided with the\n+# distribution.\n+# * Neither the name of Intel Corporation nor the names of its\n+# contributors may be used to endorse or promote products derived\n+# from this software without specific prior written permission.\n+#\n+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+\n+import os\n+import re\n+from time import sleep\n+\n+from .settings import PROTOCOL_PACKET_SIZE, TIMEOUT, get_nic_driver\n+from .utils import create_mask\n+\n+\n+class PmdOutput:\n+\n+ \"\"\"\n+ Module for get all statics value by port in testpmd\n+ \"\"\"\n+\n+ def __init__(self, dut, session=None):\n+ self.dut = dut\n+ if session is None:\n+ session = dut\n+ self.session = session\n+ self.dut.testpmd = self\n+ self.rx_pkts_prefix = \"RX-packets:\"\n+ self.rx_missed_prefix = \"RX-missed:\"\n+ self.rx_bytes_prefix = \"RX-bytes:\"\n+ self.rx_badcrc_prefix = \"RX-badcrc:\"\n+ self.rx_badlen_prefix = \"RX-badlen:\"\n+ self.rx_error_prefix = \"RX-errors:\"\n+ self.rx_nombuf_prefix = \"RX-nombuf:\"\n+ self.tx_pkts_prefix = \"TX-packets:\"\n+ self.tx_error_prefix = \"TX-errors:\"\n+ self.tx_bytes_prefix = \"TX-bytes:\"\n+ self.bad_ipcsum_prefix = \"Bad-ipcsum:\"\n+ self.bad_l4csum_prefix = \"Bad-l4csum:\"\n+ self.set_default_corelist()\n+\n+ def get_pmd_value(self, prefix, out):\n+ pattern = re.compile(prefix + \"(\\s+)([0-9]+)\")\n+ m = pattern.search(out)\n+ if m is None:\n+ return None\n+ else:\n+ return int(m.group(2))\n+\n+ def set_default_corelist(self):\n+ \"\"\"\n+ set default cores for start testpmd\n+ \"\"\"\n+ core_number = len(self.dut.cores)\n+ if core_number < 2:\n+ raise ValueError(f\"Not enough cores on DUT {self.dut}\")\n+ else:\n+ self.default_cores = \"1S/2C/1T\"\n+\n+ def get_pmd_stats(self, portid):\n+ stats = {}\n+ out = self.session.send_expect(\"show port stats %d\" % portid, \"testpmd> \")\n+ stats[\"RX-packets\"] = self.get_pmd_value(self.rx_pkts_prefix, out)\n+ stats[\"RX-missed\"] = self.get_pmd_value(self.rx_missed_prefix, out)\n+ stats[\"RX-bytes\"] = self.get_pmd_value(self.rx_bytes_prefix, out)\n+\n+ stats[\"RX-badcrc\"] = self.get_pmd_value(self.rx_badcrc_prefix, out)\n+ stats[\"RX-badlen\"] = self.get_pmd_value(self.rx_badlen_prefix, out)\n+ stats[\"RX-errors\"] = self.get_pmd_value(self.rx_error_prefix, out)\n+ stats[\"RX-nombuf\"] = self.get_pmd_value(self.rx_nombuf_prefix, out)\n+ stats[\"TX-packets\"] = self.get_pmd_value(self.tx_pkts_prefix, out)\n+ stats[\"TX-errors\"] = self.get_pmd_value(self.tx_error_prefix, out)\n+ stats[\"TX-bytes\"] = self.get_pmd_value(self.tx_bytes_prefix, out)\n+\n+ # display when testpmd config forward engine to csum\n+ stats[\"Bad-ipcsum\"] = self.get_pmd_value(self.bad_ipcsum_prefix, out)\n+ stats[\"Bad-l4csum\"] = self.get_pmd_value(self.bad_l4csum_prefix, out)\n+ return stats\n+\n+ def get_pmd_cmd(self):\n+ return self.command\n+\n+ def start_testpmd(\n+ self,\n+ cores=\"default\",\n+ param=\"\",\n+ eal_param=\"\",\n+ socket=0,\n+ fixed_prefix=False,\n+ expected=\"testpmd> \",\n+ timeout=120,\n+ **config,\n+ ):\n+ \"\"\"\n+ start testpmd with input parameters.\n+ :param cores: eg:\n+ cores='default'\n+ cores='1S/4C/1T'\n+ :param param: dpdk application (testpmd) parameters\n+ :param eal_param: user defined DPDK eal parameters, eg:\n+ eal_param='-a af:00.0 -a af:00.1,proto_xtr=vlan',\n+ eal_param='-b af:00.0 --file-prefix=vf0',\n+ eal_param='--no-pci',\n+ :param socket: physical CPU socket index\n+ :param fixed_prefix: use fixed file-prefix or not, when it is true,\n+ the file-prefix will not be added a timestamp\n+ :param config: kwargs user defined eal parameters, eg:\n+ set PCI allow list: ports=[0,1], port_options={0: \"proto_xtr=vlan\"},\n+ set PCI block list: b_ports=['0000:1a:00.0'],\n+ disable PCI: no_pci=True,\n+ add virtual device: vdevs=['net_vhost0,iface=vhost-net,queues=1']\n+ :return: output of launching testpmd\n+ \"\"\"\n+ eal_param = \" \" + eal_param + \" \"\n+ eal_param = eal_param.replace(\" -w \", \" -a \")\n+ re_file_prefix = \"--file-prefix[\\s*=]\\S+\\s\"\n+ file_prefix_str = re.findall(re_file_prefix, eal_param)\n+ if file_prefix_str:\n+ tmp = re.split(\"(=|\\s+)\", file_prefix_str[-1].strip())\n+ file_prefix = tmp[-1].strip()\n+ config[\"prefix\"] = file_prefix\n+ eal_param = re.sub(re_file_prefix, \"\", eal_param)\n+ config[\"other_eal_param\"] = eal_param\n+\n+ config[\"cores\"] = cores\n+ if (\n+ \" -w \" not in eal_param\n+ and \" -a \" not in eal_param\n+ and \" -b \" not in eal_param\n+ and \"ports\" not in config\n+ and \"b_ports\" not in config\n+ and \" --no-pci \" not in eal_param\n+ and (\n+ \"no_pci\" not in config\n+ or (\"no_pci\" in config and config[\"no_pci\"] != True)\n+ )\n+ ):\n+ config[\"ports\"] = [\n+ self.dut.ports_info[i][\"pci\"] for i in range(len(self.dut.ports_info))\n+ ]\n+ all_eal_param = self.dut.create_eal_parameters(\n+ fixed_prefix=fixed_prefix, socket=socket, **config\n+ )\n+\n+ app_name = self.dut.apps_name[\"test-pmd\"]\n+ command = app_name + \" %s -- -i %s\" % (all_eal_param, param)\n+ command = command.replace(\" \", \" \")\n+ if self.session != self.dut:\n+ self.session.send_expect(\"cd %s\" % self.dut.base_dir, \"# \")\n+ out = self.session.send_expect(command, expected, timeout)\n+ self.command = command\n+ # wait 10s to ensure links getting up before test start.\n+ sleep(10)\n+ return out\n+\n+ def execute_cmd(\n+ self, pmd_cmd, expected=\"testpmd> \", timeout=TIMEOUT, alt_session=False\n+ ):\n+ if \"dut\" in str(self.session):\n+ return self.session.send_expect(\n+ \"%s\" % pmd_cmd, expected, timeout=timeout, alt_session=alt_session\n+ )\n+ else:\n+ return self.session.send_expect(\"%s\" % pmd_cmd, expected, timeout=timeout)\n+\n+ def get_output(self, timeout=1):\n+ if \"dut\" in str(self.session):\n+ return self.session.get_session_output(timeout=timeout)\n+ else:\n+ return self.session.get_session_before(timeout=timeout)\n+\n+ def get_value_from_string(self, key_str, regx_str, string):\n+ \"\"\"\n+ Get some values from the given string by the regular expression.\n+ \"\"\"\n+ pattern = r\"(?<=%s)%s\" % (key_str, regx_str)\n+ s = re.compile(pattern)\n+ res = s.search(string)\n+ if type(res).__name__ == \"NoneType\":\n+ return \" \"\n+ else:\n+ return res.group(0)\n+\n+ def get_all_value_from_string(self, key_str, regx_str, string):\n+ \"\"\"\n+ Get some values from the given string by the regular expression.\n+ \"\"\"\n+ pattern = r\"(?<=%s)%s\" % (key_str, regx_str)\n+ s = re.compile(pattern)\n+ res = s.findall(string)\n+ if type(res).__name__ == \"NoneType\":\n+ return \" \"\n+ else:\n+ return res\n+\n+ def get_detail_from_port_info(self, key_str, regx_str, port):\n+ \"\"\"\n+ Get the detail info from the output of pmd cmd 'show port info <port num>'.\n+ \"\"\"\n+ out = self.session.send_expect(\"show port info %d\" % port, \"testpmd> \")\n+ find_value = self.get_value_from_string(key_str, regx_str, out)\n+ return find_value\n+\n+ def get_port_mac(self, port_id):\n+ \"\"\"\n+ Get the specified port MAC.\n+ \"\"\"\n+ return self.get_detail_from_port_info(\n+ \"MAC address: \", \"([0-9A-F]{2}:){5}[0-9A-F]{2}\", port_id\n+ )\n+\n+ def get_firmware_version(self, port_id):\n+ \"\"\"\n+ Get the firmware version.\n+ \"\"\"\n+ return self.get_detail_from_port_info(\"Firmware-version: \", \"\\S.*\", port_id)\n+\n+ def get_port_connect_socket(self, port_id):\n+ \"\"\"\n+ Get the socket id which the specified port is connecting with.\n+ \"\"\"\n+ return self.get_detail_from_port_info(\"Connect to socket: \", \"\\d+\", port_id)\n+\n+ def get_port_memory_socket(self, port_id):\n+ \"\"\"\n+ Get the socket id which the specified port memory is allocated on.\n+ \"\"\"\n+ return self.get_detail_from_port_info(\n+ \"memory allocation on the socket: \", \"\\d+\", port_id\n+ )\n+\n+ def get_port_link_status(self, port_id):\n+ \"\"\"\n+ Get the specified port link status now.\n+ \"\"\"\n+ return self.get_detail_from_port_info(\"Link status: \", \"\\S+\", port_id)\n+\n+ def get_port_link_speed(self, port_id):\n+ \"\"\"\n+ Get the specified port link speed now.\n+ \"\"\"\n+ return self.get_detail_from_port_info(\"Link speed: \", \"\\d+\", port_id)\n+\n+ def get_port_link_duplex(self, port_id):\n+ \"\"\"\n+ Get the specified port link mode, duplex or simplex.\n+ \"\"\"\n+ return self.get_detail_from_port_info(\"Link duplex: \", \"\\S+\", port_id)\n+\n+ def get_port_promiscuous_mode(self, port_id):\n+ \"\"\"\n+ Get the promiscuous mode of port.\n+ \"\"\"\n+ return self.get_detail_from_port_info(\"Promiscuous mode: \", \"\\S+\", port_id)\n+\n+ def get_port_allmulticast_mode(self, port_id):\n+ \"\"\"\n+ Get the allmulticast mode of port.\n+ \"\"\"\n+ return self.get_detail_from_port_info(\"Allmulticast mode: \", \"\\S+\", port_id)\n+\n+ def check_tx_bytes(self, tx_bytes, exp_bytes=0):\n+ \"\"\"\n+ fortville nic will send lldp packet when nic setup with testpmd.\n+ so should used (tx_bytes - exp_bytes) % PROTOCOL_PACKET_SIZE['lldp']\n+ for check tx_bytes count right\n+ \"\"\"\n+ # error_flag is true means tx_bytes different with expect bytes\n+ error_flag = 1\n+ for size in PROTOCOL_PACKET_SIZE[\"lldp\"]:\n+ error_flag = error_flag and (tx_bytes - exp_bytes) % size\n+\n+ return not error_flag\n+\n+ def get_port_vlan_offload(self, port_id):\n+ \"\"\"\n+ Function: get the port vlan setting info.\n+ return value:\n+ 'strip':'on'\n+ 'filter':'on'\n+ 'qinq':'off'\n+ \"\"\"\n+ vlan_info = {}\n+ vlan_info[\"strip\"] = self.get_detail_from_port_info(\"strip \", \"\\S+\", port_id)\n+ vlan_info[\"filter\"] = self.get_detail_from_port_info(\"filter\", \"\\S+\", port_id)\n+ vlan_info[\"qinq\"] = self.get_detail_from_port_info(\n+ \"qinq\\(extend\\) \", \"\\S+\", port_id\n+ )\n+ return vlan_info\n+\n+ def quit(self):\n+ self.session.send_expect(\"quit\", \"# \")\n+\n+ def wait_link_status_up(self, port_id, timeout=10):\n+ \"\"\"\n+ check the link status is up\n+ if not, loop wait\n+ \"\"\"\n+ for i in range(timeout):\n+ out = self.session.send_expect(\n+ \"show port info %s\" % str(port_id), \"testpmd> \"\n+ )\n+ status = self.get_all_value_from_string(\"Link status: \", \"\\S+\", out)\n+ if \"down\" not in status:\n+ break\n+ sleep(1)\n+ return \"down\" not in status\n+\n+ def get_max_rule_number(self, obj, out):\n+ res = re.search(\n+ r\"fd_fltr_guar\\s+=\\s+(\\d+).*fd_fltr_best_effort\\s+=\\s+(\\d+)\\.\", out\n+ )\n+ obj.verify(res, \"'fd_fltr_guar' and 'fd_fltr_best_effort not found'\")\n+ fltr_guar, fltr_best = res.group(1), res.group(2)\n+ max_rule = int(fltr_guar) + int(fltr_best)\n+ obj.logger.info(f\"this Card max rule number is :{max_rule}\")\n+ return max_rule\n", "prefixes": [ "RFC", "v1", "03/23" ] }{ "id": 109302, "url": "