get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 140119,
    "url": "http://patchwork.dpdk.org/api/patches/140119/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20240514201436.2496-2-jspewock@iol.unh.edu/",
    "project": {
        "id": 1,
        "url": "http://patchwork.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": "<20240514201436.2496-2-jspewock@iol.unh.edu>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20240514201436.2496-2-jspewock@iol.unh.edu",
    "date": "2024-05-14T20:14:33",
    "name": "[v1,1/4] dts: improve starting and stopping interactive shells",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "86020f3475688cb3ed9d87e24d817fa7f91d06c9",
    "submitter": {
        "id": 2772,
        "url": "http://patchwork.dpdk.org/api/people/2772/?format=api",
        "name": "Jeremy Spewock",
        "email": "jspewock@iol.unh.edu"
    },
    "delegate": {
        "id": 1,
        "url": "http://patchwork.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20240514201436.2496-2-jspewock@iol.unh.edu/mbox/",
    "series": [
        {
            "id": 31928,
            "url": "http://patchwork.dpdk.org/api/series/31928/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=31928",
            "date": "2024-05-14T20:14:32",
            "name": "Add second scatter test case",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/31928/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/140119/comments/",
    "check": "warning",
    "checks": "http://patchwork.dpdk.org/api/patches/140119/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 75E574402B;\n\tTue, 14 May 2024 22:15:05 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id C5476402DF;\n\tTue, 14 May 2024 22:15:02 +0200 (CEST)",
            "from mail-oo1-f101.google.com (mail-oo1-f101.google.com\n [209.85.161.101])\n by mails.dpdk.org (Postfix) with ESMTP id 56AAC402DF\n for <dev@dpdk.org>; Tue, 14 May 2024 22:15:01 +0200 (CEST)",
            "by mail-oo1-f101.google.com with SMTP id\n 006d021491bc7-5b2733389f9so3316725eaf.1\n for <dev@dpdk.org>; Tue, 14 May 2024 13:15:01 -0700 (PDT)",
            "from postal.iol.unh.edu (postal.iol.unh.edu.\n [2606:4100:3880:1234::84]) by smtp-relay.gmail.com with ESMTPS id\n 6a1803df08f44-6a15f23f2b4sm7509496d6.49.2024.05.14.13.15.00\n (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128);\n Tue, 14 May 2024 13:15:00 -0700 (PDT)",
            "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 14F1B605C373;\n Tue, 14 May 2024 16:15:00 -0400 (EDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=iol.unh.edu; s=unh-iol; t=1715717700; x=1716322500; 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=AHn+szi4mGLw/W8NcnSEVB7VaKey8Jt+M6Zt7nHd/VU=;\n b=Ckckt3X+QeBoxw9b05jdixp/QD90QQQc6/ymcx8YAArfktCCDVzLooiJE+DqE9q9YH\n o8zuNyTsM48TSrM5Tc955j0rPvHmLuS6gsN7UdLovC8ZigXJH5wyj6c4cEeWu4SzV6I4\n Icq+DbPaV5E5BeQHijsW4usJlIRxdApcD0Jao=",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1715717700; x=1716322500;\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=AHn+szi4mGLw/W8NcnSEVB7VaKey8Jt+M6Zt7nHd/VU=;\n b=rGtVhLQw8iUO/sjgQcsSpCNlf8AzFQtTa+LBaJJmVlcj5bmS9FiX02UNiRM9g0fyTp\n gQOqb71bdXXSGqxREjAUDRtMA101zbvX7dH7DpbdxPGQZRKpWMooBqSjGPSRP8ecg7Rt\n OVDIGy2qFyPRLvS0PJHSgs5ToeqBJvCP1nCOVJ7HCKPrNoyk5YYz0f4bAMeIWo3lcefX\n rzys+guscXY7H8iy+AyO3eQ0j1jlLYXNl9rD7p5YsAF1gV/UoXguilPbUuYoUUAeySrU\n p2GAJft6G8xINW0qmmJHJnd7/V8UmE4fSYxaXiz3kUtTG8ORPchvUf7Qr4g2UXG4CSsC\n 96Ew==",
        "X-Gm-Message-State": "AOJu0YzdSCEYEiCIBAsdL38VVLNnQ+KzyMSvsau/AusuAfMg/r+dSSZL\n b0jm05tPWrcPeBuCT0PJNGc7JdRXOwm6W7XO3+xfoGRDtDsNYdYh9YGoAWYykJ5Q/uzYCFokZey\n BtyIf/KS2pl6x/+aFlKgNz83sEXDOnr9NOJHBp5AC0hgdmdFv",
        "X-Google-Smtp-Source": "\n AGHT+IHAAij4M2yoUPMP1Wb3BmATxh2vhSxywV5NtjwEiQnpj3uk5yvPyUsh0to/kanzIuAQHI6rr+eXIqeY",
        "X-Received": "by 2002:a05:6359:7c1f:b0:193:fcb7:767c with SMTP id\n e5c5f4694b2df-193fcb7771fmr1117985655d.25.1715717700505;\n Tue, 14 May 2024 13:15:00 -0700 (PDT)",
        "X-Relaying-Domain": "iol.unh.edu",
        "From": "jspewock@iol.unh.edu",
        "To": "yoan.picchi@foss.arm.com, Honnappa.Nagarahalli@arm.com,\n paul.szczepanek@arm.com, juraj.linkes@pantheon.tech, probb@iol.unh.edu,\n Luca.Vizzarro@arm.com, wathsala.vithanage@arm.com, thomas@monjalon.net",
        "Cc": "dev@dpdk.org,\n\tJeremy Spewock <jspewock@iol.unh.edu>",
        "Subject": "[PATCH v1 1/4] dts: improve starting and stopping interactive shells",
        "Date": "Tue, 14 May 2024 16:14:33 -0400",
        "Message-ID": "<20240514201436.2496-2-jspewock@iol.unh.edu>",
        "X-Mailer": "git-send-email 2.44.0",
        "In-Reply-To": "<20240514201436.2496-1-jspewock@iol.unh.edu>",
        "References": "<20240514201436.2496-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\nThe InteractiveShell class currently relies on being cleaned up and\nshutdown at the time of garbage collection, but this cleanup of the class\ndoes no verification that the session is still running prior to cleanup.\nSo, if a user were to call this method themselves prior to garbage\ncollection, it would be called twice and throw an exception when the\ndesired behavior is to do nothing since the session is already cleaned\nup. This is solved by using a weakref and a finalize class which\nachieves the same result of calling the method at garbage collection,\nbut also ensures that it is called exactly once.\n\nAdditionally, this fixes issues regarding starting a primary DPDK\napplication while another is still cleaning up via a retry when starting\ninteractive shells. It also adds catch for attempting to send a command\nto an interactive shell that is not running to create a more descriptive\nerror message.\n\nSigned-off-by: Jeremy Spewock <jspewock@iol.unh.edu>\n---\n .../remote_session/interactive_shell.py       | 51 ++++++++++++++++---\n dts/framework/remote_session/testpmd_shell.py |  4 +-\n 2 files changed, 45 insertions(+), 10 deletions(-)",
    "diff": "diff --git a/dts/framework/remote_session/interactive_shell.py b/dts/framework/remote_session/interactive_shell.py\nindex 5cfe202e15..d1a9d8a6d2 100644\n--- a/dts/framework/remote_session/interactive_shell.py\n+++ b/dts/framework/remote_session/interactive_shell.py\n@@ -14,12 +14,14 @@\n environment variable configure the timeout of getting the output from command execution.\n \"\"\"\n \n+import weakref\n from abc import ABC\n from pathlib import PurePath\n from typing import Callable, ClassVar\n \n from paramiko import Channel, SSHClient, channel  # type: ignore[import]\n \n+from framework.exception import InteractiveCommandExecutionError\n from framework.logger import DTSLogger\n from framework.settings import SETTINGS\n \n@@ -32,6 +34,10 @@ class InteractiveShell(ABC):\n     and collecting input until reaching a certain prompt. All interactive applications\n     will use the same SSH connection, but each will create their own channel on that\n     session.\n+\n+    Attributes:\n+        is_started: :data:`True` if the application has started successfully, :data:`False`\n+            otherwise.\n     \"\"\"\n \n     _interactive_session: SSHClient\n@@ -41,6 +47,7 @@ class InteractiveShell(ABC):\n     _logger: DTSLogger\n     _timeout: float\n     _app_args: str\n+    _finalizer: weakref.finalize\n \n     #: Prompt to expect at the end of output when sending a command.\n     #: This is often overridden by subclasses.\n@@ -58,6 +65,8 @@ class InteractiveShell(ABC):\n     #: for DPDK on the node will be prepended to the path to the executable.\n     dpdk_app: ClassVar[bool] = False\n \n+    is_started: bool = False\n+\n     def __init__(\n         self,\n         interactive_session: SSHClient,\n@@ -93,17 +102,39 @@ def __init__(\n     def _start_application(self, get_privileged_command: Callable[[str], str] | None) -> None:\n         \"\"\"Starts a new interactive application based on the path to the app.\n \n-        This method is often overridden by subclasses as their process for\n-        starting may look different.\n+        This method is often overridden by subclasses as their process for starting may look\n+        different. Initialization of the shell on the host can be retried up to 5 times. This is\n+        done because some DPDK applications need slightly more time after exiting their script to\n+        clean up EAL before others can start.\n+\n+        When the application is started we also bind a class for finalization to this instance of\n+        the shell to ensure proper cleanup of the application.\n \n         Args:\n             get_privileged_command: A function (but could be any callable) that produces\n                 the version of the command with elevated privileges.\n         \"\"\"\n+        self._finalizer = weakref.finalize(self, self._close)\n+        max_retries = 5\n+        self._ssh_channel.settimeout(1)\n         start_command = f\"{self.path} {self._app_args}\"\n         if get_privileged_command is not None:\n             start_command = get_privileged_command(start_command)\n-        self.send_command(start_command)\n+        self.is_started = True\n+        for retry in range(max_retries):\n+            try:\n+                self.send_command(start_command)\n+                break\n+            except TimeoutError:\n+                self._logger.info(\n+                    \"Interactive shell failed to start, retrying... \"\n+                    f\"({retry+1} out of {max_retries})\"\n+                )\n+        else:\n+            self._ssh_channel.settimeout(self._timeout)\n+            self.is_started = False  # update state on failure to start\n+            raise InteractiveCommandExecutionError(\"Failed to start application.\")\n+        self._ssh_channel.settimeout(self._timeout)\n \n     def send_command(self, command: str, prompt: str | None = None) -> str:\n         \"\"\"Send `command` and get all output before the expected ending string.\n@@ -125,6 +156,10 @@ def send_command(self, command: str, prompt: str | None = None) -> str:\n         Returns:\n             All output in the buffer before expected string.\n         \"\"\"\n+        if not self.is_started:\n+            raise InteractiveCommandExecutionError(\n+                f\"Cannot send command {command} to application because the shell is not running.\"\n+            )\n         self._logger.info(f\"Sending: '{command}'\")\n         if prompt is None:\n             prompt = self._default_prompt\n@@ -140,11 +175,11 @@ def send_command(self, command: str, prompt: str | None = None) -> str:\n         self._logger.debug(f\"Got output: {out}\")\n         return out\n \n-    def close(self) -> None:\n-        \"\"\"Properly free all resources.\"\"\"\n+    def _close(self) -> None:\n+        self.is_started = False\n         self._stdin.close()\n         self._ssh_channel.close()\n \n-    def __del__(self) -> None:\n-        \"\"\"Make sure the session is properly closed before deleting the object.\"\"\"\n-        self.close()\n+    def close(self) -> None:\n+        \"\"\"Properly free all resources.\"\"\"\n+        self._finalizer()\ndiff --git a/dts/framework/remote_session/testpmd_shell.py b/dts/framework/remote_session/testpmd_shell.py\nindex f6783af621..cb4642bf3d 100644\n--- a/dts/framework/remote_session/testpmd_shell.py\n+++ b/dts/framework/remote_session/testpmd_shell.py\n@@ -227,10 +227,10 @@ def set_forward_mode(self, mode: TestPmdForwardingModes, verify: bool = True):\n                 f\"Test pmd failed to set fwd mode to {mode.value}\"\n             )\n \n-    def close(self) -> None:\n+    def _close(self) -> None:\n         \"\"\"Overrides :meth:`~.interactive_shell.close`.\"\"\"\n         self.send_command(\"quit\", \"\")\n-        return super().close()\n+        return super()._close()\n \n     def get_capas_rxq(\n         self, supported_capabilities: MutableSet, unsupported_capabilities: MutableSet\n",
    "prefixes": [
        "v1",
        "1/4"
    ]
}