Show a patch.

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

{
    "id": 1709,
    "url": "https://patchwork.libcamera.org/api/patches/1709/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/1709/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/projects/1/?format=api",
        "name": "libcamera",
        "link_name": "libcamera",
        "list_id": "libcamera_core",
        "list_email": "libcamera-devel@lists.libcamera.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": ""
    },
    "msgid": "<20190716070508.24589-3-paul.elder@ideasonboard.com>",
    "date": "2019-07-16T07:05:07",
    "name": "[libcamera-devel,v2,3/4] test: logging: add logging process test",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "ebe5507aa14a3afd8e9b55360b5066d6cbd6fa54",
    "submitter": {
        "id": 17,
        "url": "https://patchwork.libcamera.org/api/people/17/?format=api",
        "name": "Paul Elder",
        "email": "paul.elder@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/1709/mbox/",
    "series": [
        {
            "id": 435,
            "url": "https://patchwork.libcamera.org/api/series/435/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=435",
            "date": "2019-07-16T07:05:05",
            "name": "[libcamera-devel,v2,1/4] libcamera: logging: add syslog, stream, and nowhere logging targets",
            "version": 2,
            "mbox": "https://patchwork.libcamera.org/series/435/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/1709/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/1709/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<paul.elder@ideasonboard.com>",
        "Received": [
            "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 5511C61AC4\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 16 Jul 2019 09:05:23 +0200 (CEST)",
            "from emerald.amanokami.net (unknown\n\t[IPv6:2a00:79e1:abc:3602:b57a:2dda:be67:ac6e])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id D1E51564;\n\tTue, 16 Jul 2019 09:05:21 +0200 (CEST)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1563260722;\n\tbh=PXEJGWmjtr53BuygWSH12LWZDyh1PzFNMoJSnjKf3G0=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=o2/elEmEFMP612VBTk4FAPGQTK3QZQgXDsDY/gX+WTToC7JS/Zc3Rr5fvArurNAV8\n\tnbx4qfLzHs/LQqE5vkJlwUJiV+Q56HVKhGfSk+cOJVJc0CfvGEH8GaF07EHyU81I4Z\n\tzrYwhIQdmis52XSWwKpcfFRvRas2muIBEu5Bb8w8=",
        "From": "Paul Elder <paul.elder@ideasonboard.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Tue, 16 Jul 2019 16:05:07 +0900",
        "Message-Id": "<20190716070508.24589-3-paul.elder@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20190716070508.24589-1-paul.elder@ideasonboard.com>",
        "References": "<20190716070508.24589-1-paul.elder@ideasonboard.com>",
        "Subject": "[libcamera-devel] [PATCH v2 3/4] test: logging: add logging process\n\ttest",
        "X-BeenThere": "libcamera-devel@lists.libcamera.org",
        "X-Mailman-Version": "2.1.23",
        "Precedence": "list",
        "List-Id": "<libcamera-devel.lists.libcamera.org>",
        "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>",
        "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>",
        "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>",
        "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>",
        "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>",
        "X-List-Received-Date": "Tue, 16 Jul 2019 07:05:23 -0000"
    },
    "content": "Add a test to test that logging works in isolated child processes,\nOnly logSetFile is tested, because stdout and stderr are closed for\nisolated child processes, and syslog and the none logging destinations\nare expected to be the same as non-isolated processes.\n\nSigned-off-by: Paul Elder <paul.elder@ideasonboard.com>\n---\nChanges in v2:\n- unlink the log file\n- move random number generation and process completion connection to\n  init\n- other minor changes\n\n test/log_process.cpp | 153 +++++++++++++++++++++++++++++++++++++++++++\n test/meson.build     |   1 +\n 2 files changed, 154 insertions(+)\n create mode 100644 test/log_process.cpp",
    "diff": "diff --git a/test/log_process.cpp b/test/log_process.cpp\nnew file mode 100644\nindex 0000000..499a5a8\n--- /dev/null\n+++ b/test/log_process.cpp\n@@ -0,0 +1,153 @@\n+/* SPDX-License-Identifier: GPL-2.0-or-later */\n+/*\n+ * Copyright (C) 2019, Google Inc.\n+ *\n+ * log_process.cpp - Logging in isolated child process test\n+ */\n+\n+#include <fcntl.h>\n+#include <iostream>\n+#include <random>\n+#include <string.h>\n+#include <sys/stat.h>\n+#include <sys/types.h>\n+#include <unistd.h>\n+#include <vector>\n+\n+#include <libcamera/camera_manager.h>\n+#include <libcamera/event_dispatcher.h>\n+#include <libcamera/logging.h>\n+#include <libcamera/timer.h>\n+\n+#include \"log.h\"\n+#include \"process.h\"\n+#include \"test.h\"\n+#include \"utils.h\"\n+\n+using namespace std;\n+using namespace libcamera;\n+\n+static string message(\"hello from the child\");\n+\n+LOG_DEFINE_CATEGORY(LogProcessTest)\n+\n+class LogProcessTestChild\n+{\n+public:\n+\tint run(int status, int num)\n+\t{\n+\t\tusleep(50000);\n+\n+\t\tstring logPath = \"/tmp/libcamera.worker.test.\" +\n+\t\t\t\t to_string(num) + \".log\";\n+\t\tif (logSetFile(logPath.c_str()) < 0)\n+\t\t\treturn TestSkip;\n+\n+\t\tLOG(LogProcessTest, Warning) << message;\n+\n+\t\treturn status;\n+\t}\n+};\n+\n+class LogProcessTest : public Test\n+{\n+protected:\n+\tint init()\n+\t{\n+\t\trandom_device random;\n+\t\tnum_ = random();\n+\n+\t\tproc_.finished.connect(this, &LogProcessTest::procFinished);\n+\t\treturn 0;\n+\t}\n+\n+\tint run()\n+\t{\n+\t\tEventDispatcher *dispatcher = CameraManager::instance()->eventDispatcher();\n+\t\tTimer timeout;\n+\n+\t\tint exitCode = 42;\n+\t\tvector<std::string> args;\n+\t\targs.push_back(to_string(exitCode));\n+\t\targs.push_back(to_string(num_));\n+\t\tint ret = proc_.start(\"/proc/self/exe\", args);\n+\t\tif (ret) {\n+\t\t\tcerr << \"failed to start process\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\ttimeout.start(200);\n+\t\twhile (timeout.isRunning())\n+\t\t\tdispatcher->processEvents();\n+\n+\t\tif (exitStatus_ != Process::NormalExit) {\n+\t\t\tcerr << \"process did not exit normally\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tif (exitCode_ == TestSkip)\n+\t\t\treturn TestSkip;\n+\n+\t\tif (exitCode_ != exitCode) {\n+\t\t\tcerr << \"exit code should be \" << exitCode\n+\t\t\t     << \", actual is \" << exitCode_ << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tlogPath_ = \"/tmp/libcamera.worker.test.\" +\n+\t\t\t\t to_string(num_) + \".log\";\n+\t\tint fd = open(logPath_.c_str(), O_RDONLY, S_IRUSR);\n+\t\tif (fd < 0) {\n+\t\t\tcerr << \"failed to open tmp log file\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tchar buf[200];\n+\t\tmemset(buf, 0, sizeof(buf));\n+\t\tif (read(fd, buf, sizeof(buf)) < 0) {\n+\t\t\tcerr << \"Failed to read tmp log file\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\t\tclose(fd);\n+\n+\t\tstring str(buf);\n+\t\tif (str.find(message) == string::npos)\n+\t\t\treturn TestFail;\n+\n+\t\treturn TestPass;\n+\t}\n+\n+\tvoid cleanup()\n+\t{\n+\t\tunlink(logPath_.c_str());\n+\t}\n+\n+private:\n+\tvoid procFinished(Process *proc, enum Process::ExitStatus exitStatus, int exitCode)\n+\t{\n+\t\texitStatus_ = exitStatus;\n+\t\texitCode_ = exitCode;\n+\t}\n+\n+\tProcess proc_;\n+\tenum Process::ExitStatus exitStatus_;\n+\tstring logPath_;\n+\tint exitCode_;\n+\tint num_;\n+};\n+\n+/*\n+ * Can't use TEST_REGISTER() as single binary needs to act as both\n+ * parent and child processes.\n+ */\n+int main(int argc, char **argv)\n+{\n+\tif (argc == 3) {\n+\t\tint status = std::stoi(argv[1]);\n+\t\tint num = std::stoi(argv[2]);\n+\t\tLogProcessTestChild child;\n+\t\treturn child.run(status, num);\n+\t}\n+\n+\treturn LogProcessTest().execute();\n+}\ndiff --git a/test/meson.build b/test/meson.build\nindex ad1a2f2..658f283 100644\n--- a/test/meson.build\n+++ b/test/meson.build\n@@ -23,6 +23,7 @@ public_tests = [\n internal_tests = [\n     ['camera-sensor',                   'camera-sensor.cpp'],\n     ['log',                             'log.cpp'],\n+    ['log_process',                     'log_process.cpp'],\n     ['message',                         'message.cpp'],\n     ['signal-threads',                  'signal-threads.cpp'],\n     ['threads',                         'threads.cpp'],\n",
    "prefixes": [
        "libcamera-devel",
        "v2",
        "3/4"
    ]
}