From c0b437fd6cf7ca2e91eb749a25539f217722c66e Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Tue, 22 Oct 2019 01:58:15 +0200 Subject: test: Add control serialization test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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/serialization/control_serialization.cpp | 166 +++++++++++++++++++++++++++ test/serialization/meson.build | 11 ++ test/serialization/serialization_test.cpp | 89 ++++++++++++++ test/serialization/serialization_test.h | 33 ++++++ 4 files changed, 299 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 (limited to 'test/serialization') diff --git a/test/serialization/control_serialization.cpp b/test/serialization/control_serialization.cpp new file mode 100644 index 00000000..2989b527 --- /dev/null +++ b/test/serialization/control_serialization.cpp @@ -0,0 +1,166 @@ +/* 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 init() override + { + return status_; + } + + 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 00000000..d78d92e6 --- /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 00000000..68e0512a --- /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 00000000..fe77221e --- /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__ */ -- cgit v1.2.1