Show a patch.

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

{
    "id": 1492,
    "url": "https://patchwork.libcamera.org/api/patches/1492/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/1492/",
    "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": "<20190621041519.29689-3-niklas.soderlund@ragnatech.se>",
    "date": "2019-06-21T04:15:19",
    "name": "[libcamera-devel,RFC,2/2] test: ipc: unix: Add test for IPCUnixSocket",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "46f845e9817d5d3e030ed4e7234f52fe586771a6",
    "submitter": {
        "id": 5,
        "url": "https://patchwork.libcamera.org/api/people/5/?format=api",
        "name": "Niklas Söderlund",
        "email": "niklas.soderlund@ragnatech.se"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/1492/mbox/",
    "series": [
        {
            "id": 369,
            "url": "https://patchwork.libcamera.org/api/series/369/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=369",
            "date": "2019-06-21T04:15:17",
            "name": "libcamera: ipc: unix: Add a IPC mechanism based on Unix sockets",
            "version": 1,
            "mbox": "https://patchwork.libcamera.org/series/369/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/1492/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/1492/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<niklas.soderlund@ragnatech.se>",
        "Received": [
            "from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net\n\t[195.74.38.228])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 7755361583\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 21 Jun 2019 06:16:23 +0200 (CEST)",
            "from bismarck.berto.se (unknown [145.14.112.32])\n\tby bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA\n\tid 2d3ab96c-93db-11e9-8601-0050569116f7;\n\tFri, 21 Jun 2019 06:15:17 +0200 (CEST)"
        ],
        "X-Halon-ID": "2d3ab96c-93db-11e9-8601-0050569116f7",
        "Authorized-sender": "niklas@soderlund.pp.se",
        "From": "=?utf-8?q?Niklas_S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Fri, 21 Jun 2019 06:15:19 +0200",
        "Message-Id": "<20190621041519.29689-3-niklas.soderlund@ragnatech.se>",
        "X-Mailer": "git-send-email 2.21.0",
        "In-Reply-To": "<20190621041519.29689-1-niklas.soderlund@ragnatech.se>",
        "References": "<20190621041519.29689-1-niklas.soderlund@ragnatech.se>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[libcamera-devel] [RFC 2/2] test: ipc: unix: Add test for\n\tIPCUnixSocket",
        "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": "Fri, 21 Jun 2019 04:16:23 -0000"
    },
    "content": "Test that the IPC supports sending data and file descriptors over the\nIPC medium. To be able execute the test two executables are needed, one\nto drive the test and act as the libcamera (master) and a one to act as\nthe IPA (slave).\n\nThe master drives the testing posting requests to the slave to process\nand sometime respond to. A few different tests are preformed.\n\n- Master sends a string to the slave which responds with the reversed\n  string. The master verifies that a reversed string is indeed returned.\n\n- Master sends a list of file descriptors and ask the salve to calculate\n  and respond with the sum of the size of the files. The master verifies\n  that the calculate size is correct.\n\n - Master send a pre-computed size and a list of file descriptors and\n   ask the slave to verify that the pre-computed size matches the sum of\n   the size of the file descriptors.\n\nSigned-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n---\n test/ipc/meson.build          |  20 ++++\n test/ipc/unixsocket-slave.cpp |  92 ++++++++++++++++\n test/ipc/unixsocket.cpp       | 200 ++++++++++++++++++++++++++++++++++\n test/ipc/unixsocket.h         |  27 +++++\n test/meson.build              |   1 +\n 5 files changed, 340 insertions(+)\n create mode 100644 test/ipc/meson.build\n create mode 100644 test/ipc/unixsocket-slave.cpp\n create mode 100644 test/ipc/unixsocket.cpp\n create mode 100644 test/ipc/unixsocket.h",
    "diff": "diff --git a/test/ipc/meson.build b/test/ipc/meson.build\nnew file mode 100644\nindex 0000000000000000..0a425d4e7241c753\n--- /dev/null\n+++ b/test/ipc/meson.build\n@@ -0,0 +1,20 @@\n+# Tests are listed in order of complexity.\n+# They are not alphabetically sorted.\n+ipc_tests = [\n+    [ 'unixsocket',  'unixsocket.cpp', 'unixsocket-slave', 'unixsocket-slave.cpp' ],\n+]\n+\n+foreach t : ipc_tests\n+    exe = executable(t[0], t[1],\n+                     dependencies : libcamera_dep,\n+                     link_with : test_libraries,\n+                     include_directories : test_includes_internal)\n+\n+    slave = executable(t[2], t[3],\n+                     dependencies : libcamera_dep,\n+                     include_directories : test_includes_internal)\n+\n+    test(t[0], exe, suite : 'ipc', is_parallel : false)\n+endforeach\n+\n+config_h.set('IPC_TEST_DIR', '\"' +  meson.current_build_dir() + '\"')\ndiff --git a/test/ipc/unixsocket-slave.cpp b/test/ipc/unixsocket-slave.cpp\nnew file mode 100644\nindex 0000000000000000..ec27f6bf29823173\n--- /dev/null\n+++ b/test/ipc/unixsocket-slave.cpp\n@@ -0,0 +1,92 @@\n+/* SPDX-License-Identifier: GPL-2.0-or-later */\n+/*\n+ * Copyright (C) 2019, Google Inc.\n+ *\n+ * unixsocket-slave.cpp - Unix socket IPC slave runner\n+ */\n+\n+#include \"unixsocket.h\"\n+\n+#include <algorithm>\n+#include <iostream>\n+#include <string.h>\n+#include <unistd.h>\n+\n+#include \"ipc_unixsocket.h\"\n+\n+using namespace std;\n+using namespace libcamera;\n+\n+int main(int argc, char **argv)\n+{\n+\tif (argc != 2) {\n+\t\tcerr << \"usage: %s <ipc fd>\" << endl;\n+\t\treturn EXIT_FAILURE;\n+\t}\n+\n+\tint ipcfd = std::stoi(argv[1]);\n+\tIPCUnixSocket ipc(ipcfd);\n+\n+\tif (ipc.connect()) {\n+\t\tcerr << \"Failed to connect to IPC\" << endl;\n+\t\treturn EXIT_FAILURE;\n+\t}\n+\n+\tbool run = true;\n+\twhile (run) {\n+\t\tint ret = 0;\n+\t\tIPCUnixSocket::Payload payload, response;\n+\n+\t\tret = ipc.recv(&payload, 100);\n+\t\tif (ret < 0) {\n+\t\t\tif (ret == -ETIMEDOUT)\n+\t\t\t\tcontinue;\n+\t\t\treturn ret;\n+\t\t}\n+\t\tswitch (payload.priv) {\n+\t\tcase CMD_CLOSE:\n+\t\t\trun = false;\n+\t\t\tbreak;\n+\t\tcase CMD_REVERESE: {\n+\t\t\tstd::string str(payload.data.begin(), payload.data.end());\n+\t\t\tstd::reverse(str.begin(), str.end());\n+\t\t\tresponse.data = std::vector<uint8_t>(str.begin(), str.end());\n+\t\t\tret = ipc.send(response);\n+\t\t\tif (ret < 0)\n+\t\t\t\treturn ret;\n+\t\t\tbreak;\n+\t\t}\n+\t\tcase CMD_LEN_CALC: {\n+\t\t\tint size = 0;\n+\t\t\tfor (int fd : payload.fds)\n+\t\t\t\tsize += calcLength(fd);\n+\n+\t\t\tresponse.data.resize(sizeof(size));\n+\t\t\tmemcpy(response.data.data(), &size, sizeof(size));\n+\t\t\tret = ipc.send(response);\n+\t\t\tif (ret < 0)\n+\t\t\t\treturn ret;\n+\t\t\tbreak;\n+\t\t}\n+\t\tcase CMD_LEN_CMP: {\n+\t\t\tint size = 0;\n+\t\t\tfor (int fd : payload.fds)\n+\t\t\t\tsize += calcLength(fd);\n+\n+\t\t\tint cmp;\n+\t\t\tmemcpy(&cmp, payload.data.data(), sizeof(cmp));\n+\n+\t\t\tif (cmp != size)\n+\t\t\t\treturn -ERANGE;\n+\t\t\tbreak;\n+\t\t}\n+\t\tdefault:\n+\t\t\tcerr << \"Unkown command \" << payload.priv << endl;\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\tipc.close();\n+\n+\treturn 0;\n+}\ndiff --git a/test/ipc/unixsocket.cpp b/test/ipc/unixsocket.cpp\nnew file mode 100644\nindex 0000000000000000..ad2609764166a852\n--- /dev/null\n+++ b/test/ipc/unixsocket.cpp\n@@ -0,0 +1,200 @@\n+/* SPDX-License-Identifier: GPL-2.0-or-later */\n+/*\n+ * Copyright (C) 2019, Google Inc.\n+ *\n+ * unixsocket.cpp - Unix socket IPC test\n+ */\n+\n+#include \"unixsocket.h\"\n+\n+#include <fcntl.h>\n+#include <iostream>\n+#include <string.h>\n+#include <sys/stat.h>\n+#include <sys/wait.h>\n+#include <unistd.h>\n+\n+#include \"ipc_unixsocket.h\"\n+#include \"test.h\"\n+\n+#define MASTER_BIN IPC_TEST_DIR \"/unixsocket\"\n+#define SLAVE_BIN IPC_TEST_DIR \"/unixsocket-slave\"\n+\n+using namespace std;\n+using namespace libcamera;\n+\n+class UnixSocketTest : public Test\n+{\n+protected:\n+\tint slaveStart(int fd)\n+\t{\n+\t\tpid_ = fork();\n+\n+\t\tif (pid_ == -1)\n+\t\t\treturn TestFail;\n+\n+\t\tif (!pid_) {\n+\t\t\tstd::string arg = std::to_string(fd);\n+\t\t\texecl(SLAVE_BIN, SLAVE_BIN, arg.c_str());\n+\n+\t\t\t/* Only get here if exec fails. */\n+\t\t\texit(TestFail);\n+\t\t}\n+\n+\t\treturn TestPass;\n+\t}\n+\n+\tint slaveStop()\n+\t{\n+\t\tint status;\n+\n+\t\tif (pid_ < 0)\n+\t\t\treturn TestFail;\n+\n+\t\tif (waitpid(pid_, &status, 0) < 0)\n+\t\t\treturn TestFail;\n+\n+\t\tif (!WIFEXITED(status) || WEXITSTATUS(status))\n+\t\t\treturn TestFail;\n+\n+\t\treturn TestPass;\n+\t}\n+\n+\tint testReverse()\n+\t{\n+\t\tstd::string input = \"FooBar\";\n+\t\tstd::string match = \"raBooF\";\n+\n+\t\tIPCUnixSocket::Payload payload, response;\n+\n+\t\tpayload.priv = CMD_REVERESE;\n+\t\tpayload.data = std::vector<uint8_t>(input.begin(), input.end());\n+\n+\t\tif (ipc_.call(payload, &response, 100))\n+\t\t\treturn TestFail;\n+\n+\t\tstd::string output(response.data.begin(), response.data.end());\n+\n+\t\tif (output != match)\n+\t\t\treturn TestFail;\n+\n+\t\treturn 0;\n+\t}\n+\n+\tint testCalc()\n+\t{\n+\t\tint fdM = open(MASTER_BIN, O_RDONLY);\n+\t\tint fdS = open(SLAVE_BIN, O_RDONLY);\n+\n+\t\tif (fdM < 0 || fdS < 0)\n+\t\t\treturn TestFail;\n+\n+\t\tint size = 0;\n+\t\tsize += calcLength(fdM);\n+\t\tsize += calcLength(fdS);\n+\n+\t\tIPCUnixSocket::Payload payload, response;\n+\n+\t\tpayload.priv = CMD_LEN_CALC;\n+\t\tpayload.fds.push_back(fdM);\n+\t\tpayload.fds.push_back(fdS);\n+\n+\t\tif (ipc_.call(payload, &response, 100))\n+\t\t\treturn TestFail;\n+\n+\t\tint output;\n+\t\tmemcpy(&output, response.data.data(), sizeof(output));\n+\n+\t\tif (output != size)\n+\t\t\treturn TestFail;\n+\n+\t\treturn 0;\n+\t}\n+\n+\tint testCmp()\n+\t{\n+\t\tint fdM = open(MASTER_BIN, O_RDONLY);\n+\t\tint fdS = open(SLAVE_BIN, O_RDONLY);\n+\n+\t\tif (fdM < 0 || fdS < 0)\n+\t\t\treturn TestFail;\n+\n+\t\tint size = 0;\n+\t\tsize += calcLength(fdM);\n+\t\tsize += calcLength(fdS);\n+\n+\t\tIPCUnixSocket::Payload payload, response;\n+\n+\t\tpayload.priv = CMD_LEN_CMP;\n+\t\tpayload.data.resize(sizeof(size));\n+\t\tmemcpy(payload.data.data(), &size, sizeof(size));\n+\t\tpayload.fds.push_back(fdM);\n+\t\tpayload.fds.push_back(fdS);\n+\n+\t\tif (ipc_.send(payload))\n+\t\t\treturn TestFail;\n+\n+\t\treturn 0;\n+\t}\n+\n+\tint testClose()\n+\t{\n+\t\tIPCUnixSocket::Payload payload;\n+\n+\t\tpayload.priv = CMD_CLOSE;\n+\n+\t\tif (ipc_.send(payload))\n+\t\t\treturn TestFail;\n+\n+\t\treturn 0;\n+\t}\n+\n+\tint run()\n+\t{\n+\t\tint slavefd;\n+\n+\t\tslavefd = ipc_.create();\n+\t\tif (slavefd < 0)\n+\t\t\treturn TestFail;\n+\n+\t\tif (slaveStart(slavefd))\n+\t\t\treturn TestFail;\n+\n+\t\tif (ipc_.connect()) {\n+\t\t\tcerr << \"Failed to connect to IPC\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\t\tif (testReverse()) {\n+\t\t\tcerr << \"String reverse fail\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tif (testCalc()) {\n+\t\t\tcerr << \"Size calc fail\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tif (testCmp()) {\n+\t\t\tcerr << \"Compare fail\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tif (testClose())\n+\t\t\treturn TestFail;\n+\n+\t\tprintf(\"Master OK!\\n\");\n+\n+\t\tipc_.close();\n+\n+\t\tif (slaveStop())\n+\t\t\treturn TestFail;\n+\n+\t\treturn TestPass;\n+\t}\n+\n+private:\n+\tpid_t pid_;\n+\tIPCUnixSocket ipc_;\n+};\n+\n+TEST_REGISTER(UnixSocketTest)\ndiff --git a/test/ipc/unixsocket.h b/test/ipc/unixsocket.h\nnew file mode 100644\nindex 0000000000000000..5ae223c76108a4f6\n--- /dev/null\n+++ b/test/ipc/unixsocket.h\n@@ -0,0 +1,27 @@\n+/* SPDX-License-Identifier: GPL-2.0-or-later */\n+/*\n+ * Copyright (C) 2019, Google Inc.\n+ *\n+ * unixsocket.h - Unix socket IPC test\n+ *\n+ */\n+#ifndef __LIBCAMERA_IPCUNIXSOCKET_TEST_H__\n+#define __LIBCAMERA_IPCUNIXSOCKET_TEST_H__\n+\n+#include <unistd.h>\n+\n+#define CMD_CLOSE 0\n+#define CMD_REVERESE 1\n+#define CMD_LEN_CALC 2\n+#define CMD_LEN_CMP 3\n+\n+int calcLength(int fd)\n+{\n+\tlseek(fd, 0, 0);\n+\tint size = lseek(fd, 0, SEEK_END);\n+\tlseek(fd, 0, 0);\n+\n+\treturn size;\n+}\n+\n+#endif /* __LIBCAMERA_IPCUNIXSOCKET_TEST_H__ */\ndiff --git a/test/meson.build b/test/meson.build\nindex c36ac24796367501..3666f6b2385bd4ca 100644\n--- a/test/meson.build\n+++ b/test/meson.build\n@@ -2,6 +2,7 @@ subdir('libtest')\n \n subdir('camera')\n subdir('ipa')\n+subdir('ipc')\n subdir('media_device')\n subdir('pipeline')\n subdir('stream')\n",
    "prefixes": [
        "libcamera-devel",
        "RFC",
        "2/2"
    ]
}