get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 89466,
    "url": "https://patches.dpdk.org/api/patches/89466/?format=api",
    "web_url": "https://patches.dpdk.org/project/dts/patch/20210318092215.27270-3-haiyangx.zhao@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": "<20210318092215.27270-3-haiyangx.zhao@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dts/20210318092215.27270-3-haiyangx.zhao@intel.com",
    "date": "2021-03-18T09:22:12",
    "name": "[V2,2/5] framework/test_case: handle the VerifySkip exception and add some functions",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": false,
    "hash": "ba562c2ef45d11fb718ee18a7924815d3c5b90e1",
    "submitter": {
        "id": 1978,
        "url": "https://patches.dpdk.org/api/people/1978/?format=api",
        "name": "Zhao, HaiyangX",
        "email": "haiyangx.zhao@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dts/patch/20210318092215.27270-3-haiyangx.zhao@intel.com/mbox/",
    "series": [
        {
            "id": 15762,
            "url": "https://patches.dpdk.org/api/series/15762/?format=api",
            "web_url": "https://patches.dpdk.org/project/dts/list/?series=15762",
            "date": "2021-03-18T09:22:10",
            "name": "framework: add a proposal of recognizing pkgs",
            "version": 2,
            "mbox": "https://patches.dpdk.org/series/15762/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/89466/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/89466/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 94E55A0561;\n\tThu, 18 Mar 2021 10:31:18 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 8FE9D140F2C;\n\tThu, 18 Mar 2021 10:31:18 +0100 (CET)",
            "from mga09.intel.com (mga09.intel.com [134.134.136.24])\n by mails.dpdk.org (Postfix) with ESMTP id E307A140F17\n for <dts@dpdk.org>; Thu, 18 Mar 2021 10:31:16 +0100 (CET)",
            "from orsmga008.jf.intel.com ([10.7.209.65])\n by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 18 Mar 2021 02:31:16 -0700",
            "from unknown (HELO localhost.localdomain) ([10.240.183.57])\n by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 18 Mar 2021 02:31:14 -0700"
        ],
        "IronPort-SDR": [
            "\n AFjW9EpV1ewD7qcIvzLCzsqHaH85TSsLLO55r9U5EUkynHaysb6wjBdIb184CRqps+llRa6yZV\n 2oDitJNbDEBg==",
            "\n 47zIuwYtjsd0T0weME49KiLkJ6sX+VJtuEb8Qvbu2QDAp2j6nNu+18uIQAKxI6mgRjJs9rhFkE\n r+JSoIhzQ8ew=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6000,8403,9926\"; a=\"189731907\"",
            "E=Sophos;i=\"5.81,258,1610438400\"; d=\"scan'208\";a=\"189731907\"",
            "E=Sophos;i=\"5.81,258,1610438400\"; d=\"scan'208\";a=\"413013393\""
        ],
        "From": "Haiyang Zhao <haiyangx.zhao@intel.com>",
        "To": "dts@dpdk.org",
        "Cc": "lijuan.tu@intel.com,\n\tHaiyang Zhao <haiyangx.zhao@intel.com>",
        "Date": "Thu, 18 Mar 2021 17:22:12 +0800",
        "Message-Id": "<20210318092215.27270-3-haiyangx.zhao@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20210318092215.27270-1-haiyangx.zhao@intel.com>",
        "References": "<20210318092215.27270-1-haiyangx.zhao@intel.com>",
        "Subject": "[dts] [PATCH V2 2/5] framework/test_case: handle the VerifySkip\n exception and add some functions",
        "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",
        "Sender": "\"dts\" <dts-bounces@dpdk.org>"
    },
    "content": "handle the VerfiySkip exception and mark the related case with N/A in result.\nadd some functions to check if the nic or pkg support current case.\n\nSigned-off-by: Haiyang Zhao <haiyangx.zhao@intel.com>\n---\n framework/test_case.py | 102 +++++++++++++++++++++++++++++++++++------\n 1 file changed, 89 insertions(+), 13 deletions(-)",
    "diff": "diff --git a/framework/test_case.py b/framework/test_case.py\nindex 57bea562..3347adad 100644\n--- a/framework/test_case.py\n+++ b/framework/test_case.py\n@@ -38,7 +38,7 @@ import traceback\n import signal\n import time\n \n-from exception import VerifyFailure, TimeoutException\n+from exception import VerifyFailure, VerifySkip, TimeoutException\n from settings import DRIVERS, NICS, get_nic_name, load_global_setting\n from settings import PERF_SETTING, FUNC_SETTING, DEBUG_SETTING\n from settings import DEBUG_CASE_SETTING, HOST_DRIVER_SETTING\n@@ -48,6 +48,7 @@ from test_result import ResultTable, Result\n from logger import getLogger\n from config import SuiteConf\n from utils import BLUE, RED\n+from functools import wraps\n \n class TestCase(object):\n \n@@ -68,15 +69,10 @@ class TestCase(object):\n         self._check_and_reconnect(crb=self.tester)\n \n         # convert netdevice to codename\n-        self.nics = []\n-        for portid in range(len(self.dut.ports_info)):\n-            nic_type = self.dut.ports_info[portid]['type']\n-            self.nics.append(get_nic_name(nic_type))\n-        if len(self.nics):\n-            self.nic = self.nics[0]\n-        else:\n-            self.nic = ''\n-        self.kdriver = self._get_nic_driver(self.nic)\n+        self.nic = self.dut.nic.name\n+        self.nic_obj = self.dut.nic\n+        self.kdriver = self.dut.nic.default_driver\n+        self.pkg = self.dut.nic.pkg\n \n         # result object for save suite result\n         self._suite_result = Result()\n@@ -168,6 +164,12 @@ class TestCase(object):\n                 print(RED(\"History dump finished.\"))\n             raise VerifyFailure(description)\n \n+    def skip_case(self, passed, description):\n+        if not passed:\n+            if self._enable_debug:\n+                print(\"skip case: \\\"%s\\\" \" % RED(description))\n+            raise VerifySkip(description)\n+\n     def _get_nic_driver(self, nic_name):\n         if nic_name in list(DRIVERS.keys()):\n             return DRIVERS[nic_name]\n@@ -257,17 +259,28 @@ class TestCase(object):\n         try:\n             self.set_up_all()\n             return True\n-        except Exception:\n+        except VerifySkip as v:\n+            self.logger.info('set_up_all SKIPPED:\\n' + traceback.format_exc())\n+            # record all cases N/A\n+            if self._enable_func:\n+                for case_obj in self._get_functional_cases():\n+                    self._suite_result.test_case = case_obj.__name__\n+                    self._suite_result.test_case_skip(str(v))\n+            if self._enable_perf:\n+                for case_obj in self._get_performance_cases():\n+                    self._suite_result.test_case = case_obj.__name__\n+                    self._suite_result.test_case_skip(str(v))\n+        except Exception as v:\n             self.logger.error('set_up_all failed:\\n' + traceback.format_exc())\n             # record all cases blocked\n             if self._enable_func:\n                 for case_obj in self._get_functional_cases():\n                     self._suite_result.test_case = case_obj.__name__\n-                    self._suite_result.test_case_blocked('set_up_all failed')\n+                    self._suite_result.test_case_blocked('set_up_all failed: {}'.format(str(v)))\n             if self._enable_perf:\n                 for case_obj in self._get_performance_cases():\n                     self._suite_result.test_case = case_obj.__name__\n-                    self._suite_result.test_case_blocked('set_up_all failed')\n+                    self._suite_result.test_case_blocked('set_up_all failed: {}'.format(str(v)))\n             return False\n \n     def _execute_test_case(self, case_obj):\n@@ -328,6 +341,10 @@ class TestCase(object):\n             self._suite_result.test_case_failed(str(v))\n             self._rst_obj.write_result(\"FAIL\")\n             self.logger.error('Test Case %s Result FAILED: ' % (case_name) + str(v))\n+        except VerifySkip as v:\n+            self._suite_result.test_case_skip(str(v))\n+            self._rst_obj.write_result(\"N/A\")\n+            self.logger.info('Test Case %s N/A: ' % (case_name))\n         except KeyboardInterrupt:\n             self._suite_result.test_case_blocked(\"Skipped\")\n             self.logger.error('Test Case %s SKIPPED: ' % (case_name))\n@@ -504,3 +521,62 @@ class TestCase(object):\n             bitrate *= 100\n \n         return bitrate * num_ports / 8 / (frame_size + 20)\n+\n+\n+def skip_unsupported_pkg(pkgs):\n+    \"\"\"\n+    Skip case which are not supported by the input pkgs\n+    \"\"\"\n+    if isinstance(pkgs, str):\n+        pkgs = [pkgs]\n+\n+    def decorator(func):\n+        @wraps(func)\n+        def wrapper(*args, **kwargs):\n+            test_case = args[0]\n+            pkg_type = test_case.pkg.get('type')\n+            pkg_version = test_case.pkg.get('version')\n+            if not pkg_type or not pkg_version:\n+                raise VerifyFailure('Failed due to pkg is empty'.format(test_case.pkg))\n+            for pkg in pkgs:\n+                if pkg in pkg_type:\n+                    raise VerifySkip('{} {} do not support this case'.format(pkg_type, pkg_version))\n+            return func(*args, **kwargs)\n+        return wrapper\n+    return decorator\n+\n+\n+def skip_unsupported_nic(nics):\n+    \"\"\"\n+    Skip case which are not supported by the input nics\n+    \"\"\"\n+    if isinstance(nics, str):\n+        nics = [nics]\n+\n+    def decorator(func):\n+        @wraps(func)\n+        def wrapper(*args, **kwargs):\n+            test_case = args[0]\n+            if test_case.nic in nics:\n+                raise VerifySkip('{} do not support this case'.format(test_case.nic))\n+            return func(*args, **kwargs)\n+        return wrapper\n+    return decorator\n+\n+\n+def check_supported_nic(nics):\n+    \"\"\"\n+    check if the test case is supported by the input nics\n+    \"\"\"\n+    if isinstance(nics, str):\n+        nics = [nics]\n+\n+    def decorator(func):\n+        @wraps(func)\n+        def wrapper(*args, **kwargs):\n+            test_case = args[0]\n+            if test_case.nic not in nics:\n+                raise VerifySkip('{} do not support this case'.format(test_case.nic))\n+            return func(*args, **kwargs)\n+        return wrapper\n+    return decorator\n",
    "prefixes": [
        "V2",
        "2/5"
    ]
}