[{"id":14403,"web_url":"https://patchwork.libcamera.org/comment/14403/","msgid":"<X+un4XnPfWHWtlR8@oden.dyn.berto.se>","date":"2020-12-29T22:04:17","subject":"Re: [libcamera-devel] [PATCH v6 2/4] tests: Add test for\n\tIPCPipeUnixSocket","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/people/5/","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"content":"Hi Paul,\n\nThanks for your work.\n\nOn 2020-12-24 17:17:11 +0900, Paul Elder wrote:\n> Test the IPC functions of IPCPipeUnixSocket.\n> \n> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>\n> \n> ---\n> No change in v6\n> \n> Changes in v5:\n> - rename IPAIPCUnixSocket to IPCPipeUnixSocket\n> - use IPCMessage\n> \n> No change in v4\n> \n> Changes in v3:\n> - use readHeader, writeHeader, and eraseHeader as static class functions\n>   of IPAIPCUnixSocket\n> \n> New in v2\n> ---\n>  test/ipc/meson.build        |   3 +-\n>  test/ipc/unixsocket_ipc.cpp | 237 ++++++++++++++++++++++++++++++++++++\n>  2 files changed, 239 insertions(+), 1 deletion(-)\n>  create mode 100644 test/ipc/unixsocket_ipc.cpp\n> \n> diff --git a/test/ipc/meson.build b/test/ipc/meson.build\n> index 650df1d6..ecb6d022 100644\n> --- a/test/ipc/meson.build\n> +++ b/test/ipc/meson.build\n> @@ -1,7 +1,8 @@\n>  # SPDX-License-Identifier: CC0-1.0\n>  \n>  ipc_tests = [\n> -    [ 'unixsocket',  'unixsocket.cpp' ],\n> +    [ 'unixsocket_ipc', 'unixsocket_ipc.cpp' ],\n> +    [ 'unixsocket',     'unixsocket.cpp' ],\n>  ]\n>  \n>  foreach t : ipc_tests\n> diff --git a/test/ipc/unixsocket_ipc.cpp b/test/ipc/unixsocket_ipc.cpp\n> new file mode 100644\n> index 00000000..827689f7\n> --- /dev/null\n> +++ b/test/ipc/unixsocket_ipc.cpp\n> @@ -0,0 +1,237 @@\n> +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> +/*\n> + * Copyright (C) 2020, Google Inc.\n> + *\n> + * unixsocket_ipc.cpp - Unix socket IPC test\n> + */\n> +\n> +#include <algorithm>\n> +#include <fcntl.h>\n> +#include <iostream>\n> +#include <stdlib.h>\n> +#include <string.h>\n> +#include <sys/stat.h>\n> +#include <sys/types.h>\n> +#include <sys/wait.h>\n> +#include <unistd.h>\n> +\n> +#include \"libcamera/internal/event_dispatcher.h\"\n> +#include \"libcamera/internal/ipa_data_serializer.h\"\n> +#include \"libcamera/internal/ipc_pipe.h\"\n> +#include \"libcamera/internal/ipc_pipe_unixsocket.h\"\n> +#include \"libcamera/internal/process.h\"\n> +#include \"libcamera/internal/thread.h\"\n> +#include \"libcamera/internal/timer.h\"\n> +#include \"libcamera/internal/utils.h\"\n> +\n> +#include \"test.h\"\n> +\n> +#define CMD_EXIT\t0\n> +#define CMD_GET_SYNC\t1\n> +#define CMD_SET_ASYNC\t2\n> +\n> +using namespace std;\n> +using namespace libcamera;\n> +\n> +class UnixSocketTestIPCSlave\n> +{\n> +public:\n> +\tUnixSocketTestIPCSlave()\n> +\t\t: value_(1337), exitCode_(EXIT_FAILURE), exit_(false)\n> +\t{\n> +\t\tdispatcher_ = Thread::current()->eventDispatcher();\n> +\t\tipc_.readyRead.connect(this, &UnixSocketTestIPCSlave::readyRead);\n> +\t}\n> +\n> +\tint run(int fd)\n> +\t{\n> +\t\tif (ipc_.bind(fd)) {\n> +\t\t\tcerr << \"Failed to connect to IPC channel\" << endl;\n> +\t\t\treturn EXIT_FAILURE;\n> +\t\t}\n> +\n> +\t\twhile (!exit_)\n> +\t\t\tdispatcher_->processEvents();\n> +\n> +\t\tipc_.close();\n> +\n> +\t\treturn exitCode_;\n> +\t}\n> +\n> +private:\n> +\tvoid readyRead(IPCUnixSocket *ipc)\n> +\t{\n> +\t\tIPCUnixSocket::Payload message;\n> +\t\tint ret;\n> +\n> +\t\tret = ipc->receive(&message);\n> +\t\tif (ret) {\n> +\t\t\tcerr << \"Receive message failed: \" << ret << endl;\n> +\t\t\treturn;\n> +\t\t}\n> +\n> +\t\tIPCMessage ipcMessage(message);\n> +\t\tuint32_t cmd = ipcMessage.header().cmd;\n> +\n> +\t\tswitch (cmd) {\n> +\t\tcase CMD_EXIT: {\n> +\t\t\texit_ = true;\n> +\t\t\tbreak;\n> +\t\t}\n> +\n> +\t\tcase CMD_GET_SYNC: {\n> +\t\t\tIPCMessage::Header header = { cmd, ipcMessage.header().cookie };\n> +\t\t\tIPCMessage response(header);\n> +\n> +\t\t\tvector<uint8_t> buf;\n> +\t\t\ttie(buf, ignore) = IPADataSerializer<int32_t>::serialize(value_);\n> +\t\t\tresponse.data().insert(response.data().end(), buf.begin(), buf.end());\n> +\n> +\t\t\tret = ipc_.send(response.payload());\n> +\t\t\tif (ret < 0) {\n> +\t\t\t\tcerr << \"Reply failed\" << endl;\n> +\t\t\t\tstop(ret);\n> +\t\t\t}\n> +\t\t\tbreak;\n> +\t\t}\n> +\n> +\t\tcase CMD_SET_ASYNC: {\n> +\t\t\tvalue_ = IPADataSerializer<int32_t>::deserialize(ipcMessage.data());\n> +\t\t\tbreak;\n> +\t\t}\n> +\t\t}\n> +\t}\n> +\n> +\tvoid stop(int code)\n> +\t{\n> +\t\texitCode_ = code;\n> +\t\texit_ = true;\n> +\t}\n> +\n> +\tint32_t value_;\n> +\n> +\tIPCUnixSocket ipc_;\n> +\tEventDispatcher *dispatcher_;\n> +\tint exitCode_;\n> +\tbool exit_;\n> +};\n> +\n> +class UnixSocketTestIPC : public Test\n> +{\n> +protected:\n> +\tint init()\n> +\t{\n> +\t\treturn 0;\n> +\t}\n> +\n> +\tint setVal(int32_t val)\n> +\t{\n> +\t\tIPCMessage buf;\n> +\t\ttie(buf.data(), ignore) = IPADataSerializer<int32_t>::serialize(val);\n> +\n> +\t\tint ret = ipc_->sendAsync(CMD_SET_ASYNC, buf);\n> +\t\tif (ret < 0) {\n> +\t\t\tcerr << \"Failed to call set value\" << endl;\n> +\t\t\treturn ret;\n> +\t\t}\n> +\n> +\t\treturn 0;\n> +\t}\n> +\n> +\tint getVal()\n> +\t{\n> +\t\tIPCMessage buf;\n> +\n> +\t\tint ret = ipc_->sendSync(CMD_GET_SYNC, {}, &buf);\n> +\t\tif (ret < 0) {\n> +\t\t\tcerr << \"Failed to call get value\" << endl;\n> +\t\t\treturn ret;\n> +\t\t}\n> +\n> +\t\treturn IPADataSerializer<int32_t>::deserialize(buf.data());\n> +\t}\n> +\n> +\tint exit()\n> +\t{\n> +\t\tint ret = ipc_->sendAsync(CMD_EXIT, {});\n> +\t\tif (ret < 0) {\n> +\t\t\tcerr << \"Failed to call exit\" << endl;\n> +\t\t\treturn ret;\n> +\t\t}\n> +\n> +\t\treturn 0;\n> +\t}\n> +\n> +\tint run()\n> +\t{\n> +\t\tchar selfpath[100];\n\nnit: I think to play it safe you could use MAX_PATH here.\n\n> +\t\tmemset(selfpath, 0, sizeof(selfpath));\n> +\t\tint ret = readlink(\"/proc/self/exe\", selfpath, sizeof(selfpath));\n> +\t\tif (ret < 0) {\n> +\t\t\tint err = errno;\n> +\t\t\tcerr << \"Failed to get path: \" << strerror(err) << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tipc_ = std::make_unique<IPCPipeUnixSocket>(\"\", selfpath);\n> +\t\tif (!ipc_->isConnected()) {\n> +\t\t\tcerr << \"Failed to create IPCPipe\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tret = getVal();\n> +\t\tif (ret < 0) {\n> +\t\t\tcerr << \"Failed to get initial value: \" << strerror(-ret) << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n\nI would drop this < 0 check as getVal() already prints an error in that \ncase.\n\n> +\t\tif (ret != 1337) {\n> +\t\t\tcerr << \"Wrong inital value, expected 1337, got \" << ret << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tret = setVal(9001);\n> +\t\tif (ret < 0) {\n> +\t\t\tcerr << \"Failed to set value: \" << strerror(-ret) << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tret = getVal();\n> +\t\tif (ret < 0) {\n> +\t\t\tcerr << \"Failed to get value: \" << strerror(-ret) << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n\nSame here.\n\nWhit this fixed,\n\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n\n> +\t\tif (ret != 9001) {\n> +\t\t\tcerr << \"Wrong set value, expected 9001, got \" << ret << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tret = exit();\n> +\t\tif (ret < 0) {\n> +\t\t\tcerr << \"Failed to exit: \" << strerror(-ret) << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\treturn TestPass;\n> +\t}\n> +\n> +private:\n> +\tProcessManager processManager_;\n> +\n> +\tunique_ptr<IPCPipeUnixSocket> ipc_;\n> +};\n> +\n> +/*\n> + * Can't use TEST_REGISTER() as single binary needs to act as both proxy\n> + * master and slave.\n> + */\n> +int main(int argc, char **argv)\n> +{\n> +\t/* IPCPipeUnixSocket passes IPA module path in argv[1] */\n> +\tif (argc == 3) {\n> +\t\tint ipcfd = std::stoi(argv[2]);\n> +\t\tUnixSocketTestIPCSlave slave;\n> +\t\treturn slave.run(ipcfd);\n> +\t}\n> +\n> +\treturn UnixSocketTestIPC().execute();\n> +}\n> -- \n> 2.27.0\n> \n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id C07F2C0F1C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 29 Dec 2020 22:04:21 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 4580E615B2;\n\tTue, 29 Dec 2020 23:04:21 +0100 (CET)","from mail-lf1-x136.google.com (mail-lf1-x136.google.com\n\t[IPv6:2a00:1450:4864:20::136])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B87A56031F\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 29 Dec 2020 23:04:19 +0100 (CET)","by mail-lf1-x136.google.com with SMTP id a12so33821070lfl.6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 29 Dec 2020 14:04:19 -0800 (PST)","from localhost (h-209-203.A463.priv.bahnhof.se. [155.4.209.203])\n\tby smtp.gmail.com with ESMTPSA id\n\tr135sm5833043lff.240.2020.12.29.14.04.18\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tTue, 29 Dec 2020 14:04:18 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=ragnatech-se.20150623.gappssmtp.com\n\theader.i=@ragnatech-se.20150623.gappssmtp.com\n\theader.b=\"klG/sGmc\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ragnatech-se.20150623.gappssmtp.com; s=20150623;\n\th=date:from:to:cc:subject:message-id:references:mime-version\n\t:content-disposition:content-transfer-encoding:in-reply-to;\n\tbh=dTC1DsWVcEcr23VMneXet88OxBx041JhN4Q2IJiYyc4=;\n\tb=klG/sGmcYh+3i8qMWXVxYM8jPRsiai6KOObMuWD0p8IxMTnmvQ96CkEydawkrNvHDP\n\t2CBTb+TkAOOk2NQcWC8oXJIzx8g2s2FJtgVeUIcxEcfUc//WaI9jIGsrW0ekFY7FHPz6\n\tcIxUdNOWmZ6Y5B+QJ0ORVNa1ab8PviaKyoj0nzekOGXSVyacOVDdJMdlsAadkhBvQKnk\n\tHVvOeinTQJptA/AnmYsmN4iLsfgKygfZRMUlYBcA5hNp6pWLo6aK1X1IZeheQc3GLC2U\n\tSWhIkjd+Ggy0bjBZPVJ/GAPOBj2AFh4Gf+khDD6rYublFTNYFPCa0W/0xfQfAWrw8LpW\n\t/0dQ==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:date:from:to:cc:subject:message-id:references\n\t:mime-version:content-disposition:content-transfer-encoding\n\t:in-reply-to;\n\tbh=dTC1DsWVcEcr23VMneXet88OxBx041JhN4Q2IJiYyc4=;\n\tb=VYvpF/D8ciXSHWbPoRDaITSxxZqT6ml+DcvIEGu5+Zkbuns87ayYrd4h/M2O2RHG18\n\tXFELQlmr9lGtFISLZddMIybFCpnfp88+rpKD54+ZCLZ5XyeH5AruCZaQXbFKQUfayECF\n\tKSdQcuSm289ZNfu4rQ1xDpl+BZ+oqkeROPua2jVyABnRayGqFx78XeHCQnR5zV4kytrx\n\t7A+hIb7bx/3Mp4AlbhR1OEebLMUS6mIxEwpnFqAktz68sW6leJfXOODIBN0BJz0ckvTJ\n\tz4xuGpXjZX4e3j1W7AyWtuuqdD9n4pOjQAMRsAjByd4KHcimkX3w3frn0tE4Sl250Mjq\n\tLBrw==","X-Gm-Message-State":"AOAM533RjLiiyuIE1slAGXj1D9FbjVJHKCyYaMhJBUxw8RwxEkKF52Tx\n\tk+PLi7zYWPKw+22qrIN+kPKA19/JYVDECw==","X-Google-Smtp-Source":"ABdhPJwzNnZpcPSDT26PZsgXiWSC3VxoFAuznRvfclc9GxqnopQPAyvzVvsjBI4tNtd+EgYX2RAezQ==","X-Received":"by 2002:ac2:5194:: with SMTP id\n\tu20mr20468005lfi.353.1609279459081; \n\tTue, 29 Dec 2020 14:04:19 -0800 (PST)","Date":"Tue, 29 Dec 2020 23:04:17 +0100","From":"Niklas =?iso-8859-1?q?S=F6derlund?= <niklas.soderlund@ragnatech.se>","To":"Paul Elder <paul.elder@ideasonboard.com>","Message-ID":"<X+un4XnPfWHWtlR8@oden.dyn.berto.se>","References":"<20201224081713.41742-1-paul.elder@ideasonboard.com>\n\t<20201224081713.41742-3-paul.elder@ideasonboard.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20201224081713.41742-3-paul.elder@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v6 2/4] tests: Add test for\n\tIPCPipeUnixSocket","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","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>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"iso-8859-1\"","Content-Transfer-Encoding":"quoted-printable","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]