Show a patch.

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

{
    "id": 2313,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/2313/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/2313/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/1.1/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": "<20191108205409.18845-18-laurent.pinchart@ideasonboard.com>",
    "date": "2019-11-08T20:54:02",
    "name": "[libcamera-devel,v2,17/24] test: Add control serialization test",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "3dabae508f5766011592764edfa58e4e976518b8",
    "submitter": {
        "id": 2,
        "url": "https://patchwork.libcamera.org/api/1.1/people/2/?format=api",
        "name": "Laurent Pinchart",
        "email": "laurent.pinchart@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/2313/mbox/",
    "series": [
        {
            "id": 568,
            "url": "https://patchwork.libcamera.org/api/1.1/series/568/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=568",
            "date": "2019-11-08T20:53:45",
            "name": "Control serialization and IPA C API",
            "version": 2,
            "mbox": "https://patchwork.libcamera.org/series/568/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/2313/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/2313/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<laurent.pinchart@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 7F2CD61516\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri,  8 Nov 2019 21:54:28 +0100 (CET)",
            "from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi\n\t[81.175.216.236])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 1DE17A2A;\n\tFri,  8 Nov 2019 21:54:28 +0100 (CET)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1573246468;\n\tbh=n6tFsNdq4kKSyjfbA/24/q0hZV5IBeeMjcD060i+gCY=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=AD6ISf/90phM+YR/EA5dGEpk64R9rV5h7RV9bklo+06bQB5LcSETH2tItSO4CWDZl\n\tH8MRmMyyYzLmDz2IxdEM8asxrBMs9rEf+bUBAwJcxNbUNxfWCN7Frzd/n2U6RjyzmW\n\t9XTufEXTTJ3CgPnSTOvShtKWSU0Xm8pPp6ifn5rw=",
        "From": "Laurent Pinchart <laurent.pinchart@ideasonboard.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Fri,  8 Nov 2019 22:54:02 +0200",
        "Message-Id": "<20191108205409.18845-18-laurent.pinchart@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.23.0",
        "In-Reply-To": "<20191108205409.18845-1-laurent.pinchart@ideasonboard.com>",
        "References": "<20191108205409.18845-1-laurent.pinchart@ideasonboard.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[libcamera-devel] [PATCH v2 17/24] test: Add control serialization\n\ttest",
        "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>",
        "X-List-Received-Date": "Fri, 08 Nov 2019 20:54:29 -0000"
    },
    "content": "From: Jacopo Mondi <jacopo@jmondi.org>\n\nAdd a test that exercises the ControlSerializer to serialize and\ndeserialize ControlInfoMap and ControlList.\n\nSigned-off-by: Jacopo Mondi <jacopo@jmondi.org>\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\n test/meson.build                             |   1 +\n test/serialization/control_serialization.cpp | 161 +++++++++++++++++++\n test/serialization/meson.build               |  11 ++\n test/serialization/serialization_test.cpp    |  89 ++++++++++\n test/serialization/serialization_test.h      |  33 ++++\n 5 files changed, 295 insertions(+)\n create mode 100644 test/serialization/control_serialization.cpp\n create mode 100644 test/serialization/meson.build\n create mode 100644 test/serialization/serialization_test.cpp\n create mode 100644 test/serialization/serialization_test.h",
    "diff": "diff --git a/test/meson.build b/test/meson.build\nindex adb5b29e69f3..1bb2161dc05a 100644\n--- a/test/meson.build\n+++ b/test/meson.build\n@@ -8,6 +8,7 @@ subdir('log')\n subdir('media_device')\n subdir('pipeline')\n subdir('process')\n+subdir('serialization')\n subdir('stream')\n subdir('v4l2_subdevice')\n subdir('v4l2_videodevice')\ndiff --git a/test/serialization/control_serialization.cpp b/test/serialization/control_serialization.cpp\nnew file mode 100644\nindex 000000000000..adfb498b5bd2\n--- /dev/null\n+++ b/test/serialization/control_serialization.cpp\n@@ -0,0 +1,161 @@\n+/* SPDX-License-Identifier: GPL-2.0-or-later */\n+/*\n+ * Copyright (C) 2019, Google Inc.\n+ *\n+ * control_serialization.cpp - Serialize and deserialize controls\n+ */\n+\n+#include <iostream>\n+\n+#include <libcamera/camera.h>\n+#include <libcamera/control_ids.h>\n+#include <libcamera/controls.h>\n+\n+#include \"byte_stream_buffer.h\"\n+#include \"control_serializer.h\"\n+#include \"serialization_test.h\"\n+#include \"test.h\"\n+\n+using namespace std;\n+using namespace libcamera;\n+\n+class ControlSerializationTest : public SerializationTest\n+{\n+protected:\n+\tint run() override\n+\t{\n+\t\tControlSerializer serializer;\n+\t\tControlSerializer deserializer;\n+\n+\t\tstd::vector<uint8_t> infoData;\n+\t\tstd::vector<uint8_t> listData;\n+\n+\t\tsize_t size;\n+\t\tint ret;\n+\n+\t\t/* Create a control list with three controls. */\n+\t\tconst ControlInfoMap &infoMap = camera_->controls();\n+\t\tControlList list(infoMap);\n+\n+\t\tlist.set(controls::Brightness, 255);\n+\t\tlist.set(controls::Contrast, 128);\n+\t\tlist.set(controls::Saturation, 50);\n+\n+\t\t/*\n+\t\t * Serialize the control list, this should fail as the control\n+\t\t * info map hasn't been serialized.\n+\t\t */\n+\t\tsize = serializer.binarySize(list);\n+\t\tlistData.resize(size);\n+\t\tByteStreamBuffer buffer(listData.data(), listData.size());\n+\n+\t\tret = serializer.serialize(list, buffer);\n+\t\tif (!ret) {\n+\t\t\tcerr << \"List serialization without info map should have failed\"\n+\t\t\t     << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tif (buffer.overflow() || buffer.offset()) {\n+\t\t\tcerr << \"Failed list serialization modified the buffer\"\n+\t\t\t     << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\t/* Serialize the control info map. */\n+\t\tsize = serializer.binarySize(infoMap);\n+\t\tinfoData.resize(size);\n+\t\tbuffer = ByteStreamBuffer(infoData.data(), infoData.size());\n+\n+\t\tret = serializer.serialize(infoMap, buffer);\n+\t\tif (ret < 0) {\n+\t\t\tcerr << \"Failed to serialize ControlInfoMap\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tif (buffer.overflow()) {\n+\t\t\tcerr << \"Overflow when serializing ControlInfoMap\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\t/* Serialize the control list, this should now succeed. */\n+\t\tsize = serializer.binarySize(list);\n+\t\tlistData.resize(size);\n+\t\tbuffer = ByteStreamBuffer(listData.data(), listData.size());\n+\n+\t\tret = serializer.serialize(list, buffer);\n+\t\tif (ret) {\n+\t\t\tcerr << \"Failed to serialize ControlList\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tif (buffer.overflow()) {\n+\t\t\tcerr << \"Overflow when serializing ControlList\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\t/*\n+\t\t * Deserialize the control list, this should fail as the control\n+\t\t * info map hasn't been deserialized.\n+\t\t */\n+\t\tbuffer = ByteStreamBuffer(const_cast<const uint8_t *>(listData.data()),\n+\t\t\t\t\t  listData.size());\n+\n+\t\tControlList newList = deserializer.deserialize<ControlList>(buffer);\n+\t\tif (!newList.empty()) {\n+\t\t\tcerr << \"List deserialization without info map should have failed\"\n+\t\t\t     << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tif (buffer.overflow()) {\n+\t\t\tcerr << \"Failed list deserialization modified the buffer\"\n+\t\t\t     << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\t/* Deserialize the control info map and verify the contents. */\n+\t\tbuffer = ByteStreamBuffer(const_cast<const uint8_t *>(infoData.data()),\n+\t\t\t\t\t  infoData.size());\n+\n+\t\tControlInfoMap newInfoMap = deserializer.deserialize<ControlInfoMap>(buffer);\n+\t\tif (newInfoMap.empty()) {\n+\t\t\tcerr << \"Failed to deserialize ControlInfoMap\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tif (buffer.overflow()) {\n+\t\t\tcerr << \"Overflow when deserializing ControlInfoMap\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tif (!equals(infoMap, newInfoMap)) {\n+\t\t\tcerr << \"Deserialized map doesn't match original\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\t/* Deserialize the control list and verify the contents. */\n+\t\tbuffer = ByteStreamBuffer(const_cast<const uint8_t *>(listData.data()),\n+\t\t\t\t\t  listData.size());\n+\n+\t\tnewList = deserializer.deserialize<ControlList>(buffer);\n+\t\tif (newList.empty()) {\n+\t\t\tcerr << \"Failed to deserialize ControlList\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tif (buffer.overflow()) {\n+\t\t\tcerr << \"Overflow when deserializing ControlList\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tif (!equals(list, newList)) {\n+\t\t\tcerr << \"Deserialized list doesn't match original\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\treturn TestPass;\n+\t}\n+};\n+\n+TEST_REGISTER(ControlSerializationTest)\ndiff --git a/test/serialization/meson.build b/test/serialization/meson.build\nnew file mode 100644\nindex 000000000000..d78d92e61887\n--- /dev/null\n+++ b/test/serialization/meson.build\n@@ -0,0 +1,11 @@\n+serialization_tests = [\n+    [ 'control_serialization',    'control_serialization.cpp' ],\n+]\n+\n+foreach t : serialization_tests\n+    exe = executable(t[0], [t[1], 'serialization_test.cpp'],\n+                     dependencies : libcamera_dep,\n+                     link_with : test_libraries,\n+                     include_directories : test_includes_internal)\n+    test(t[0], exe, suite : 'serialization', is_parallel : true)\n+endforeach\ndiff --git a/test/serialization/serialization_test.cpp b/test/serialization/serialization_test.cpp\nnew file mode 100644\nindex 000000000000..68e0512a04ca\n--- /dev/null\n+++ b/test/serialization/serialization_test.cpp\n@@ -0,0 +1,89 @@\n+/* SPDX-License-Identifier: GPL-2.0-or-later */\n+/*\n+ * Copyright (C) 2019, Google Inc.\n+ *\n+ * serialization_test.cpp - Base class for serialization tests\n+ */\n+\n+#include \"serialization_test.h\"\n+\n+#include <algorithm>\n+#include <iostream>\n+#include <map>\n+\n+#include <libcamera/camera.h>\n+#include <libcamera/camera_manager.h>\n+#include <libcamera/controls.h>\n+\n+#include \"test.h\"\n+\n+using namespace std;\n+using namespace libcamera;\n+\n+bool SerializationTest::equals(const ControlInfoMap &lhs, const ControlInfoMap &rhs)\n+{\n+\tstd::map<unsigned int, ControlRange> rlhs;\n+\tstd::transform(lhs.begin(), lhs.end(), std::inserter(rlhs, rlhs.end()),\n+\t\t\t[](const ControlInfoMap::value_type &v)\n+\t\t\t\t-> decltype(rlhs)::value_type\n+\t\t\t{\n+\t\t\t\treturn { v.first->id(), v.second };\n+\t\t\t});\n+\n+\tstd::map<unsigned int, ControlRange> rrhs;\n+\tstd::transform(rhs.begin(), rhs.end(), std::inserter(rrhs, rrhs.end()),\n+\t\t\t[](const ControlInfoMap::value_type &v)\n+\t\t\t\t-> decltype(rrhs)::value_type\n+\t\t\t{\n+\t\t\t\treturn { v.first->id(), v.second };\n+\t\t\t});\n+\n+\tif (rlhs == rrhs)\n+\t\treturn true;\n+\n+\tcerr << \"lhs:\" << endl;\n+\tfor (const auto &value : rlhs)\n+\t\tcerr << \"- \" << value.first << \": \"\n+\t\t     << value.second.toString() << endl;\n+\n+\tcerr << \"rhs:\" << endl;\n+\tfor (const auto &value : rrhs)\n+\t\tcerr << \"- \" << value.first << \": \"\n+\t\t     << value.second.toString() << endl;\n+\n+\treturn false;\n+}\n+\n+bool SerializationTest::equals(const ControlList &lhs, const ControlList &rhs)\n+{\n+\tstd::map<unsigned int, ControlValue> rlhs;\n+\tstd::transform(lhs.begin(), lhs.end(), std::inserter(rlhs, rlhs.end()),\n+\t\t\t[](const std::pair<unsigned int, ControlValue> &v)\n+\t\t\t\t-> decltype(rlhs)::value_type\n+\t\t\t{\n+\t\t\t\treturn { v.first, v.second };\n+\t\t\t});\n+\n+\tstd::map<unsigned int, ControlValue> rrhs;\n+\tstd::transform(rhs.begin(), rhs.end(), std::inserter(rrhs, rrhs.end()),\n+\t\t\t[](const std::pair<unsigned int, ControlValue> &v)\n+\t\t\t\t-> decltype(rrhs)::value_type\n+\t\t\t{\n+\t\t\t\treturn { v.first, v.second };\n+\t\t\t});\n+\n+\tif (rlhs == rrhs)\n+\t\treturn true;\n+\n+\tcerr << \"lhs:\" << endl;\n+\tfor (const auto &value : rlhs)\n+\t\tcerr << \"- \" << value.first << \": \"\n+\t\t     << value.second.toString() << endl;\n+\n+\tcerr << \"rhs:\" << endl;\n+\tfor (const auto &value : rrhs)\n+\t\tcerr << \"- \" << value.first << \": \"\n+\t\t     << value.second.toString() << endl;\n+\n+\treturn false;\n+}\ndiff --git a/test/serialization/serialization_test.h b/test/serialization/serialization_test.h\nnew file mode 100644\nindex 000000000000..fe77221ef5d0\n--- /dev/null\n+++ b/test/serialization/serialization_test.h\n@@ -0,0 +1,33 @@\n+/* SPDX-License-Identifier: GPL-2.0-or-later */\n+/*\n+ * Copyright (C) 2019, Google Inc.\n+ *\n+ * serialization_test.h - Base class for serialization tests\n+ */\n+#ifndef __LIBCAMERA_SERIALIZATION_TEST_H__\n+#define __LIBCAMERA_SERIALIZATION_TEST_H__\n+\n+#include <libcamera/camera.h>\n+#include <libcamera/camera_manager.h>\n+#include <libcamera/controls.h>\n+\n+#include \"camera_test.h\"\n+#include \"test.h\"\n+\n+using namespace libcamera;\n+\n+class SerializationTest : public CameraTest, public Test\n+{\n+public:\n+\tSerializationTest()\n+\t\t: CameraTest(\"VIMC Sensor B\")\n+\t{\n+\t}\n+\n+\tstatic bool equals(const ControlInfoMap &lhs,\n+\t\t\t   const ControlInfoMap &rhs);\n+\tstatic bool equals(const ControlList &lhs,\n+\t\t\t   const ControlList &rhs);\n+};\n+\n+#endif /* __LIBCAMERA_SERIALIZATION_TEST_H__ */\n",
    "prefixes": [
        "libcamera-devel",
        "v2",
        "17/24"
    ]
}