From patchwork Fri Nov 8 20:54:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2313 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7F2CD61516 for ; Fri, 8 Nov 2019 21:54:28 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1DE17A2A; Fri, 8 Nov 2019 21:54:28 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1573246468; bh=n6tFsNdq4kKSyjfbA/24/q0hZV5IBeeMjcD060i+gCY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AD6ISf/90phM+YR/EA5dGEpk64R9rV5h7RV9bklo+06bQB5LcSETH2tItSO4CWDZl H8MRmMyyYzLmDz2IxdEM8asxrBMs9rEf+bUBAwJcxNbUNxfWCN7Frzd/n2U6RjyzmW 9XTufEXTTJ3CgPnSTOvShtKWSU0Xm8pPp6ifn5rw= From: Laurent Pinchart 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 Subject: [libcamera-devel] [PATCH v2 17/24] test: Add control serialization test X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 08 Nov 2019 20:54:29 -0000 From: Jacopo Mondi Add a test that exercises the ControlSerializer to serialize and deserialize ControlInfoMap and ControlList. Signed-off-by: Jacopo Mondi Signed-off-by: Laurent Pinchart Reviewed-by: Niklas Söderlund --- test/meson.build | 1 + test/serialization/control_serialization.cpp | 161 +++++++++++++++++++ test/serialization/meson.build | 11 ++ test/serialization/serialization_test.cpp | 89 ++++++++++ test/serialization/serialization_test.h | 33 ++++ 5 files changed, 295 insertions(+) create mode 100644 test/serialization/control_serialization.cpp create mode 100644 test/serialization/meson.build create mode 100644 test/serialization/serialization_test.cpp create mode 100644 test/serialization/serialization_test.h diff --git a/test/meson.build b/test/meson.build index adb5b29e69f3..1bb2161dc05a 100644 --- a/test/meson.build +++ b/test/meson.build @@ -8,6 +8,7 @@ subdir('log') subdir('media_device') subdir('pipeline') subdir('process') +subdir('serialization') subdir('stream') subdir('v4l2_subdevice') subdir('v4l2_videodevice') diff --git a/test/serialization/control_serialization.cpp b/test/serialization/control_serialization.cpp new file mode 100644 index 000000000000..adfb498b5bd2 --- /dev/null +++ b/test/serialization/control_serialization.cpp @@ -0,0 +1,161 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * control_serialization.cpp - Serialize and deserialize controls + */ + +#include + +#include +#include +#include + +#include "byte_stream_buffer.h" +#include "control_serializer.h" +#include "serialization_test.h" +#include "test.h" + +using namespace std; +using namespace libcamera; + +class ControlSerializationTest : public SerializationTest +{ +protected: + int run() override + { + ControlSerializer serializer; + ControlSerializer deserializer; + + std::vector infoData; + std::vector listData; + + size_t size; + int ret; + + /* Create a control list with three controls. */ + const ControlInfoMap &infoMap = camera_->controls(); + ControlList list(infoMap); + + list.set(controls::Brightness, 255); + list.set(controls::Contrast, 128); + list.set(controls::Saturation, 50); + + /* + * Serialize the control list, this should fail as the control + * info map hasn't been serialized. + */ + size = serializer.binarySize(list); + listData.resize(size); + ByteStreamBuffer buffer(listData.data(), listData.size()); + + ret = serializer.serialize(list, buffer); + if (!ret) { + cerr << "List serialization without info map should have failed" + << endl; + return TestFail; + } + + if (buffer.overflow() || buffer.offset()) { + cerr << "Failed list serialization modified the buffer" + << endl; + return TestFail; + } + + /* Serialize the control info map. */ + size = serializer.binarySize(infoMap); + infoData.resize(size); + buffer = ByteStreamBuffer(infoData.data(), infoData.size()); + + ret = serializer.serialize(infoMap, buffer); + if (ret < 0) { + cerr << "Failed to serialize ControlInfoMap" << endl; + return TestFail; + } + + if (buffer.overflow()) { + cerr << "Overflow when serializing ControlInfoMap" << endl; + return TestFail; + } + + /* Serialize the control list, this should now succeed. */ + size = serializer.binarySize(list); + listData.resize(size); + buffer = ByteStreamBuffer(listData.data(), listData.size()); + + ret = serializer.serialize(list, buffer); + if (ret) { + cerr << "Failed to serialize ControlList" << endl; + return TestFail; + } + + if (buffer.overflow()) { + cerr << "Overflow when serializing ControlList" << endl; + return TestFail; + } + + /* + * Deserialize the control list, this should fail as the control + * info map hasn't been deserialized. + */ + buffer = ByteStreamBuffer(const_cast(listData.data()), + listData.size()); + + ControlList newList = deserializer.deserialize(buffer); + if (!newList.empty()) { + cerr << "List deserialization without info map should have failed" + << endl; + return TestFail; + } + + if (buffer.overflow()) { + cerr << "Failed list deserialization modified the buffer" + << endl; + return TestFail; + } + + /* Deserialize the control info map and verify the contents. */ + buffer = ByteStreamBuffer(const_cast(infoData.data()), + infoData.size()); + + ControlInfoMap newInfoMap = deserializer.deserialize(buffer); + if (newInfoMap.empty()) { + cerr << "Failed to deserialize ControlInfoMap" << endl; + return TestFail; + } + + if (buffer.overflow()) { + cerr << "Overflow when deserializing ControlInfoMap" << endl; + return TestFail; + } + + if (!equals(infoMap, newInfoMap)) { + cerr << "Deserialized map doesn't match original" << endl; + return TestFail; + } + + /* Deserialize the control list and verify the contents. */ + buffer = ByteStreamBuffer(const_cast(listData.data()), + listData.size()); + + newList = deserializer.deserialize(buffer); + if (newList.empty()) { + cerr << "Failed to deserialize ControlList" << endl; + return TestFail; + } + + if (buffer.overflow()) { + cerr << "Overflow when deserializing ControlList" << endl; + return TestFail; + } + + if (!equals(list, newList)) { + cerr << "Deserialized list doesn't match original" << endl; + return TestFail; + } + + return TestPass; + } +}; + +TEST_REGISTER(ControlSerializationTest) diff --git a/test/serialization/meson.build b/test/serialization/meson.build new file mode 100644 index 000000000000..d78d92e61887 --- /dev/null +++ b/test/serialization/meson.build @@ -0,0 +1,11 @@ +serialization_tests = [ + [ 'control_serialization', 'control_serialization.cpp' ], +] + +foreach t : serialization_tests + exe = executable(t[0], [t[1], 'serialization_test.cpp'], + dependencies : libcamera_dep, + link_with : test_libraries, + include_directories : test_includes_internal) + test(t[0], exe, suite : 'serialization', is_parallel : true) +endforeach diff --git a/test/serialization/serialization_test.cpp b/test/serialization/serialization_test.cpp new file mode 100644 index 000000000000..68e0512a04ca --- /dev/null +++ b/test/serialization/serialization_test.cpp @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * serialization_test.cpp - Base class for serialization tests + */ + +#include "serialization_test.h" + +#include +#include +#include + +#include +#include +#include + +#include "test.h" + +using namespace std; +using namespace libcamera; + +bool SerializationTest::equals(const ControlInfoMap &lhs, const ControlInfoMap &rhs) +{ + std::map rlhs; + std::transform(lhs.begin(), lhs.end(), std::inserter(rlhs, rlhs.end()), + [](const ControlInfoMap::value_type &v) + -> decltype(rlhs)::value_type + { + return { v.first->id(), v.second }; + }); + + std::map rrhs; + std::transform(rhs.begin(), rhs.end(), std::inserter(rrhs, rrhs.end()), + [](const ControlInfoMap::value_type &v) + -> decltype(rrhs)::value_type + { + return { v.first->id(), v.second }; + }); + + if (rlhs == rrhs) + return true; + + cerr << "lhs:" << endl; + for (const auto &value : rlhs) + cerr << "- " << value.first << ": " + << value.second.toString() << endl; + + cerr << "rhs:" << endl; + for (const auto &value : rrhs) + cerr << "- " << value.first << ": " + << value.second.toString() << endl; + + return false; +} + +bool SerializationTest::equals(const ControlList &lhs, const ControlList &rhs) +{ + std::map rlhs; + std::transform(lhs.begin(), lhs.end(), std::inserter(rlhs, rlhs.end()), + [](const std::pair &v) + -> decltype(rlhs)::value_type + { + return { v.first, v.second }; + }); + + std::map rrhs; + std::transform(rhs.begin(), rhs.end(), std::inserter(rrhs, rrhs.end()), + [](const std::pair &v) + -> decltype(rrhs)::value_type + { + return { v.first, v.second }; + }); + + if (rlhs == rrhs) + return true; + + cerr << "lhs:" << endl; + for (const auto &value : rlhs) + cerr << "- " << value.first << ": " + << value.second.toString() << endl; + + cerr << "rhs:" << endl; + for (const auto &value : rrhs) + cerr << "- " << value.first << ": " + << value.second.toString() << endl; + + return false; +} diff --git a/test/serialization/serialization_test.h b/test/serialization/serialization_test.h new file mode 100644 index 000000000000..fe77221ef5d0 --- /dev/null +++ b/test/serialization/serialization_test.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * serialization_test.h - Base class for serialization tests + */ +#ifndef __LIBCAMERA_SERIALIZATION_TEST_H__ +#define __LIBCAMERA_SERIALIZATION_TEST_H__ + +#include +#include +#include + +#include "camera_test.h" +#include "test.h" + +using namespace libcamera; + +class SerializationTest : public CameraTest, public Test +{ +public: + SerializationTest() + : CameraTest("VIMC Sensor B") + { + } + + static bool equals(const ControlInfoMap &lhs, + const ControlInfoMap &rhs); + static bool equals(const ControlList &lhs, + const ControlList &rhs); +}; + +#endif /* __LIBCAMERA_SERIALIZATION_TEST_H__ */