From patchwork Tue Sep 24 17:24:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2012 Return-Path: Received: from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net [217.70.183.195]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0170162378 for ; Tue, 24 Sep 2019 19:23:37 +0200 (CEST) X-Originating-IP: 213.45.248.89 Received: from uno.homenet.telecomitalia.it (host89-248-dynamic.45-213-r.retail.telecomitalia.it [213.45.248.89]) (Authenticated sender: jacopo@jmondi.org) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 5A31560006 for ; Tue, 24 Sep 2019 17:23:36 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 24 Sep 2019 19:24:55 +0200 Message-Id: <20190924172503.30864-14-jacopo@jmondi.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190924172503.30864-1-jacopo@jmondi.org> References: <20190924172503.30864-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 13/21] test: serialization: Add control info 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: Tue, 24 Sep 2019 17:23:37 -0000 Test the serialization procedure of a ControlInfoMap by manually unwrapping a serialized data blob containing control info and validate them against the sensor subdevice reported ones. Signed-off-by: Jacopo Mondi --- test/serialization/control_info_list.cpp | 122 ++++++++++++++++++++++ test/serialization/meson.build | 1 + test/serialization/serialization_test.cpp | 103 ++++++++++++++++++ test/serialization/serialization_test.h | 21 ++++ 4 files changed, 247 insertions(+) create mode 100644 test/serialization/control_info_list.cpp diff --git a/test/serialization/control_info_list.cpp b/test/serialization/control_info_list.cpp new file mode 100644 index 000000000000..270f84cf7422 --- /dev/null +++ b/test/serialization/control_info_list.cpp @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * control_info.cpp - Serialize and de-serialize a list of control info + */ + +#include + +#include +#include +#include + +#include "device_enumerator.h" +#include "media_device.h" +#include "serializer.h" +#include "test.h" +#include "v4l2_subdevice.h" + +#include "serialization_test.h" + +using namespace std; +using namespace libcamera; + +class ControlInfoListSerializeTest : public SerializationTest +{ +public: + ControlInfoListSerializeTest() + : SerializationTest() + { + } + +private: + void initValidationMatrix() + { + const V4L2ControlInfoMap &controls = sensor_->controls(); + + unsigned int i = 0; + for (const auto &ctrl : controls) { + unsigned int v4l2Id = ctrl.first; + const V4L2ControlInfo &info = ctrl.second; + ControlId id; + + switch (v4l2Id) { + case V4L2_CID_BRIGHTNESS: + id = Brightness; + break; + case V4L2_CID_CONTRAST: + id = Contrast; + break; + case V4L2_CID_SATURATION: + id = Saturation; + break; + default: + continue; + } + + infoValidationMatrix[i][INFO_CTRL_ID] = id; + /* \todo Assume all controls have integers values. */ + infoValidationMatrix[i][INFO_CTRL_MIN] = info.min().getInt(); + infoValidationMatrix[i][INFO_CTRL_MAX] = info.max().getInt(); + infoValidationMatrix[i][INFO_CTRL_FLAG] = 0; + + numCtrls_++; + i++; + } + } + + int init() + { + int ret = SerializationTest::init(); + if (ret != TestPass) + return ret; + + ret = initSubdevice(); + if (ret < 0) + return ret; + + initValidationMatrix(); + + return TestPass; + } + + int run() + { + const ControlInfoMap &controls = camera_->controls(); + + std::unique_ptr blob = controls.serialize(); + if (!blob) { + cerr << "Failed to serialize the control info" << endl; + return TestFail; + } + + int ret = validateInfoBlobSize(blob.get()); + if (ret != TestPass) + return ret; + + /* Validate each serialized info data. */ + uint8_t *b = blob->data(); + for (unsigned int i = 0; i < numCtrls_; ++i) { + if (!validateInfoBlob(b)) + return TestFail; + + b += INFO_BLOB_SIZE; + } + + /* De-serialize a control info list and re-validate it. */ + ControlInfoMap newInfoMap; + newInfoMap.deserialize(blob->data(), blob->size()); + for (auto it : newInfoMap) { + ControlId id = it.first; + ControlInfo &info = it.second; + + if (!validateInfoValue(id, info)) + return TestFail; + } + + return TestPass; + } +}; + +TEST_REGISTER(ControlInfoListSerializeTest) diff --git a/test/serialization/meson.build b/test/serialization/meson.build index 511f05cbbd1f..510bd8c30d38 100644 --- a/test/serialization/meson.build +++ b/test/serialization/meson.build @@ -1,5 +1,6 @@ serialization_tests = [ [ 'control_list', 'control_list.cpp' ], + [ 'control_info_list', 'control_info_list.cpp' ], ] foreach t : serialization_tests diff --git a/test/serialization/serialization_test.cpp b/test/serialization/serialization_test.cpp index 8db70bb1de02..f0a9427d7b79 100644 --- a/test/serialization/serialization_test.cpp +++ b/test/serialization/serialization_test.cpp @@ -187,3 +187,106 @@ bool SerializationTest::validateDataValue(unsigned int id, const DataValue &data return true; } + +int SerializationTest::validateInfoBlobSize(DataBlob *blob) +{ + size_t blobSize = blob->size(); + if (blobSize % Serializer::BLOB_ALIGN_BYTES) { + cerr << "Serialized control info has incorrect alignement" + << endl; + return TestFail; + } + + size_t expectedSize = INFO_BLOB_SIZE * numCtrls_; + if (blobSize != expectedSize) { + cerr << "Serialized info list has incorrect size: " + << " expected size " << expectedSize + << " got " << blobSize << endl; + return TestFail; + } + + return TestPass; +} + +bool SerializationTest::validateInfoBlob(uint8_t *info) +{ + uint32_t id = *(reinterpret_cast(info)); + uint32_t size = *(reinterpret_cast(Serializer::INFO_BLOB_SIZE(info))); + + /* Manually access min and max assuming they're 32-bits integers. */ + uint32_t min = *(reinterpret_cast(info + 16)); + uint32_t max = *(reinterpret_cast(info + 24)); + bool found = false; + + cout << "Testing serialized info: " << id << " - " + << size << " - " << min << " - " << max << endl; + + for (unsigned int i = 0; i < numCtrls_; ++i) { + if (infoValidationMatrix[i][INFO_CTRL_ID] != id) + continue; + + found = true; + + unsigned int *entry = infoValidationMatrix[i]; + if (entry[INFO_CTRL_FLAG]) { + cerr << "The info with id " << id + << " has been serialized twice" << endl; + return false; + } + entry[INFO_CTRL_FLAG] = true; + + if (entry[INFO_CTRL_MIN] != min || + entry[INFO_CTRL_MAX] != max || + size != INFO_BLOB_DATA_SIZE) { + cerr << "The info with id " << id + << " has been wrongly serialized" << endl; + return false; + } + } + + if (!found) { + cerr << "Non-existing info with id " << id << endl; + return false; + } + + cout << "Serialization of info: " << id << " = Success." + << endl; + + return true; +} + +bool SerializationTest::validateInfoValue(unsigned int id, + const DataInfo &info) +{ + bool found = false; + uint32_t min = info.min().getInt(); + uint32_t max = info.max().getInt(); + + cout << "Testing de-serialized info: " << id + << " - " << min << " - " << max << endl; + + for (unsigned int i = 0; i < numCtrls_; ++i) { + if (infoValidationMatrix[i][INFO_CTRL_ID] != id) + continue; + + found = true; + + unsigned int *controlValidation = infoValidationMatrix[i]; + if (controlValidation[INFO_CTRL_MIN] != min || + controlValidation[INFO_CTRL_MAX] != max) { + cerr << "The info with id " << id + << " has been wrongly serialized" << endl; + return false; + } + } + + if (!found) { + cerr << "Non-existing info with id " << id << endl; + return false; + } + + cout << "De-serialization of info: " << id << " = Success." + << endl; + + return true; +} diff --git a/test/serialization/serialization_test.h b/test/serialization/serialization_test.h index 87dc5a84a505..7085f79ac0a7 100644 --- a/test/serialization/serialization_test.h +++ b/test/serialization/serialization_test.h @@ -45,6 +45,23 @@ protected: static constexpr unsigned int VALUE_BLOB_DATA_SIZE = 8; static constexpr unsigned int VALUE_BLOB_SIZE = 24; + /* Info validation matrix */ + unsigned int infoValidationMatrix[CTRL_MAX][4]; + + /* Indices on the info validation matrix fields. */ + static constexpr unsigned int INFO_CTRL_ID = 0; + static constexpr unsigned int INFO_CTRL_MIN = 1; + static constexpr unsigned int INFO_CTRL_MAX = 2; + static constexpr unsigned int INFO_CTRL_FLAG = 3; + + /* + * Serialized info sizes. + * \todo Assume a serialized info is 32 bytes in total (header + + * DataInfo), as values are simple integers. + */ + static constexpr unsigned int INFO_BLOB_DATA_SIZE = 16; + static constexpr unsigned int INFO_BLOB_SIZE = 32; + int init(); void cleanup(); @@ -54,6 +71,10 @@ protected: bool validateValueBlob(uint8_t *dataBlob); bool validateDataValue(unsigned int id, const DataValue &dataValue); + int validateInfoBlobSize(DataBlob *blob); + bool validateInfoBlob(uint8_t *infoBlob); + bool validateInfoValue(unsigned int id, const DataInfo &dataInfo); + std::unique_ptr enumerator_; std::shared_ptr media_; std::shared_ptr camera_;