get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 135211,
    "url": "http://patches.dpdk.org/api/patches/135211/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20231214221012.9598-3-jspewock@iol.unh.edu/",
    "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": "<20231214221012.9598-3-jspewock@iol.unh.edu>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20231214221012.9598-3-jspewock@iol.unh.edu",
    "date": "2023-12-14T22:10:07",
    "name": "[v4,1/7] dts: add required methods to testpmd_shell",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "66ad0d26f5609ee3759f60663679e3600db810fc",
    "submitter": {
        "id": 2772,
        "url": "http://patches.dpdk.org/api/people/2772/?format=api",
        "name": "Jeremy Spewock",
        "email": "jspewock@iol.unh.edu"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20231214221012.9598-3-jspewock@iol.unh.edu/mbox/",
    "series": [
        {
            "id": 30563,
            "url": "http://patches.dpdk.org/api/series/30563/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=30563",
            "date": "2023-12-14T22:10:07",
            "name": "[v4,1/7] dts: add required methods to testpmd_shell",
            "version": 4,
            "mbox": "http://patches.dpdk.org/series/30563/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/135211/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/135211/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 E229B436F4;\n\tThu, 14 Dec 2023 23:11:23 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id DBAD843361;\n\tThu, 14 Dec 2023 23:11:20 +0100 (CET)",
            "from mail-oo1-f97.google.com (mail-oo1-f97.google.com\n [209.85.161.97]) by mails.dpdk.org (Postfix) with ESMTP id ED07E43360\n for <dev@dpdk.org>; Thu, 14 Dec 2023 23:11:19 +0100 (CET)",
            "by mail-oo1-f97.google.com with SMTP id\n 006d021491bc7-591553d3835so46019eaf.3\n for <dev@dpdk.org>; Thu, 14 Dec 2023 14:11:19 -0800 (PST)",
            "from postal.iol.unh.edu (postal.iol.unh.edu.\n [2606:4100:3880:1234::84]) by smtp-relay.gmail.com with ESMTPS id\n k10-20020a63d84a000000b005b25a04cf8csm1160262pgj.8.2023.12.14.14.11.17\n (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128);\n Thu, 14 Dec 2023 14:11:19 -0800 (PST)",
            "from iol.unh.edu (unknown\n [IPv6:2606:4100:3880:1271:90f9:1b64:f6e6:867f])\n by postal.iol.unh.edu (Postfix) with ESMTP id E7E15605C311;\n Thu, 14 Dec 2023 17:11:16 -0500 (EST)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=iol.unh.edu; s=unh-iol; t=1702591879; x=1703196679; darn=dpdk.org;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=88XdtApir5U8j5YeQD5l7pC22oM/mR+hQkO3JnGHsXY=;\n b=I2d9kisWebtdB5ny1RyWDS9yBriKM/x9KtPfVpcXbXSaEhEXKaqV+EZQgqPf4i8OiI\n HxElwSSYRB6PHv/DY/pvHPXO+dpAYRevTgRTKELPyTK8XCMEajHtjhH4hDN/gcCvqDWZ\n 4M805QNJOXNO26RIl3y03MXcAzJWkQOjs0JZg=",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1702591879; x=1703196679;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc\n :subject:date:message-id:reply-to;\n bh=88XdtApir5U8j5YeQD5l7pC22oM/mR+hQkO3JnGHsXY=;\n b=rVXL88E6bCgPbjqO8lnsfH7eCrhZ3c5uI/O4m3n+JyKCHnddI9wIw1YVB+sNCDxwCl\n MItUdnZr+WH+9ZzrVFCVXD2hUJkcMaU8Y2BwX4BPORfMEKS4+iIapJytnCcj2vERZE56\n WFkEigP6zooe66Fozk1u7erKjNW9X4241PAJcVLPI8jo+HwurIqEHwkLPgsT5aLfLrO1\n 5DreaJrKbUr8QMUbNRQckuE1xAaTG5VPlDtnYv370HUuwdC91yh7mp2/JltkxyKo+PfW\n k++5NQcrL+fuUm9IE6GfWM/uwSI1L+eJsnWeLowyyKLbHlwbv7cXJCPIXIV475YkAhcM\n bdVQ==",
        "X-Gm-Message-State": "AOJu0YwTmMnQH+uh+Jovmd/3Uhuzh/QPU5m6yg6OvSHzSC1It3xapOzA\n wDzZpnlfi4Cbf/8V7oE5EnHWAmpWXda6cEd61NTJH4KisBnklzXZVEP26CrJNAaLjQ==",
        "X-Google-Smtp-Source": "\n AGHT+IFgWo3CtFvJQLuKv61Angp6shOtaLC3fEZHnWB3jrv6XxI4rHCTFz6UJ9o63wxL+uELWbHj4ZLbg0kC",
        "X-Received": "by 2002:a05:6359:4598:b0:170:6ba9:9dac with SMTP id\n no24-20020a056359459800b001706ba99dacmr15015787rwb.61.1702591879169;\n Thu, 14 Dec 2023 14:11:19 -0800 (PST)",
        "X-Relaying-Domain": "iol.unh.edu",
        "From": "jspewock@iol.unh.edu",
        "To": "Honnappa.Nagarahalli@arm.com, juraj.linkes@pantheon.tech,\n thomas@monjalon.net, wathsala.vithanage@arm.com, probb@iol.unh.edu,\n paul.szczepanek@arm.com, yoan.picchi@foss.arm.com, ferruh.yigit@amd.com,\n andrew.rybchenko@oktetlabs.ru",
        "Cc": "dev@dpdk.org,\n\tJeremy Spewock <jspewock@iol.unh.edu>",
        "Subject": "[PATCH v4 1/7] dts: add required methods to testpmd_shell",
        "Date": "Thu, 14 Dec 2023 17:10:07 -0500",
        "Message-ID": "<20231214221012.9598-3-jspewock@iol.unh.edu>",
        "X-Mailer": "git-send-email 2.43.0",
        "In-Reply-To": "<20231113202833.12900-1-jspewock@iol.unh.edu>",
        "References": "<20231113202833.12900-1-jspewock@iol.unh.edu>",
        "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": "From: Jeremy Spewock <jspewock@iol.unh.edu>\n\nAdded a method within the testpmd interactive shell that polls the\nstatus of ports and verifies that the link status on a given port is\n\"up.\" Polling will continue until either the link comes up, or the\ntimeout is reached. Also added methods for starting and stopping packet\nforwarding in testpmd and a method for setting the forwarding mode on\ntestpmd. The method for starting packet forwarding will also attempt to\nverify that forwarding did indeed start by default.\n\nSigned-off-by: Jeremy Spewock <jspewock@iol.unh.edu>\n---\n dts/framework/exception.py                    |  4 +\n .../remote_session/remote/testpmd_shell.py    | 92 +++++++++++++++++++\n 2 files changed, 96 insertions(+)",
    "diff": "diff --git a/dts/framework/exception.py b/dts/framework/exception.py\nindex b362e42924..e36db20e32 100644\n--- a/dts/framework/exception.py\n+++ b/dts/framework/exception.py\n@@ -119,6 +119,10 @@ def __str__(self) -> str:\n         return f\"Command {self.command} returned a non-zero exit code: {self.command_return_code}\"\n \n \n+class InteractiveCommandExecutionError(DTSError):\n+    severity: ClassVar[ErrorSeverity] = ErrorSeverity.REMOTE_CMD_EXEC_ERR\n+\n+\n class RemoteDirectoryExistsError(DTSError):\n     \"\"\"\n     Raised when a remote directory to be created already exists.\ndiff --git a/dts/framework/remote_session/remote/testpmd_shell.py b/dts/framework/remote_session/remote/testpmd_shell.py\nindex 08ac311016..b5e4cba9b3 100644\n--- a/dts/framework/remote_session/remote/testpmd_shell.py\n+++ b/dts/framework/remote_session/remote/testpmd_shell.py\n@@ -1,9 +1,15 @@\n # SPDX-License-Identifier: BSD-3-Clause\n # Copyright(c) 2023 University of New Hampshire\n \n+import time\n+from enum import auto\n from pathlib import PurePath\n from typing import Callable\n \n+from framework.exception import InteractiveCommandExecutionError\n+from framework.settings import SETTINGS\n+from framework.utils import StrEnum\n+\n from .interactive_shell import InteractiveShell\n \n \n@@ -17,6 +23,37 @@ def __str__(self) -> str:\n         return self.pci_address\n \n \n+class TestPmdForwardingModes(StrEnum):\n+    r\"\"\"The supported packet forwarding modes for :class:`~TestPmdShell`\\s\"\"\"\n+\n+    #:\n+    io = auto()\n+    #:\n+    mac = auto()\n+    #:\n+    macswap = auto()\n+    #:\n+    flowgen = auto()\n+    #:\n+    rxonly = auto()\n+    #:\n+    txonly = auto()\n+    #:\n+    csum = auto()\n+    #:\n+    icmpecho = auto()\n+    #:\n+    ieee1588 = auto()\n+    #:\n+    noisy = auto()\n+    #:\n+    fivetswap = \"5tswap\"\n+    #:\n+    shared_rxq = \"shared-rxq\"\n+    #:\n+    recycle_mbufs = auto()\n+\n+\n class TestPmdShell(InteractiveShell):\n     path: PurePath = PurePath(\"app\", \"dpdk-testpmd\")\n     dpdk_app: bool = True\n@@ -28,6 +65,27 @@ def _start_application(self, get_privileged_command: Callable[[str], str] | None\n         self._app_args += \" -- -i\"\n         super()._start_application(get_privileged_command)\n \n+    def start(self, verify: bool = True) -> None:\n+        \"\"\"Start packet forwarding with the current configuration.\n+\n+        Args:\n+            verify: If :data:`True` , a second start command will be sent in an attempt to verify\n+                packet forwarding started as expected.\n+\n+        Raises:\n+            InteractiveCommandExecutionError: If `verify` is :data:`True` and forwarding fails to\n+                start.\n+        \"\"\"\n+        self.send_command(\"start\")\n+        if verify:\n+            # If forwarding was already started, sending \"start\" again should tell us\n+            if \"Packet forwarding already started\" not in self.send_command(\"start\"):\n+                raise InteractiveCommandExecutionError(\"Testpmd failed to start packet forwarding.\")\n+\n+    def stop(self) -> None:\n+        \"\"\"Stop packet forwarding.\"\"\"\n+        self.send_command(\"stop\")\n+\n     def get_devices(self) -> list[TestPmdDevice]:\n         \"\"\"Get a list of device names that are known to testpmd\n \n@@ -43,3 +101,37 @@ def get_devices(self) -> list[TestPmdDevice]:\n             if \"device name:\" in line.lower():\n                 dev_list.append(TestPmdDevice(line))\n         return dev_list\n+\n+    def wait_link_status_up(self, port_id: int, timeout=SETTINGS.timeout) -> bool:\n+        \"\"\"Wait until the link status on the given port is \"up\".\n+\n+        Arguments:\n+            port_id: Port to check the link status on.\n+            timeout: Time to wait for the link to come up. The default value for this\n+                argument is set using the :option:`-t, --timeout` command-line argument\n+                or the :envvar:`DTS_TIMEOUT` environment variable.\n+\n+        Returns:\n+            If the link came up in time or not.\n+        \"\"\"\n+        time_to_stop = time.time() + timeout\n+        while time.time() < time_to_stop:\n+            port_info = self.send_command(f\"show port info {port_id}\")\n+            if \"Link status: up\" in port_info:\n+                break\n+            time.sleep(0.5)\n+        else:\n+            self._logger.error(f\"The link for port {port_id} did not come up in the given timeout.\")\n+        return \"Link status: up\" in port_info\n+\n+    def set_forward_mode(self, mode: TestPmdForwardingModes):\n+        \"\"\"Set packet forwarding mode.\n+\n+        Args:\n+            mode: The forwarding mode to use.\n+        \"\"\"\n+        self.send_command(f\"set fwd {mode.value}\")\n+\n+    def close(self) -> None:\n+        self.send_command(\"exit\", \"\")\n+        return super().close()\n",
    "prefixes": [
        "v4",
        "1/7"
    ]
}