Source files in libcamera start by a comment block header, which includes the file name and a one-line description of the file contents. While the latter is useful to get a quick overview of the file contents at a glance, the former is mostly a source of inconvenience. The name in the comments can easily get out of sync with the file name when files are renamed, and copy & paste during development have often lead to incorrect names being used to start with. Readers of the source code are expected to know which file they're looking it. Drop the file name from the header comment block. The change was generated with the following script: ---------------------------------------- dirs="include/libcamera src test utils" declare -rA patterns=( ['c']=' \* ' ['cpp']=' \* ' ['h']=' \* ' ['py']='# ' ['sh']='# ' ) for ext in ${!patterns[@]} ; do files=$(for dir in $dirs ; do find $dir -name "*.${ext}" ; done) pattern=${patterns[${ext}]} for file in $files ; do name=$(basename ${file}) sed -i "s/^\(${pattern}\)${name} - /\1/" "$file" done done ---------------------------------------- This misses several files that are out of sync with the comment block header. Those will be addressed separately and manually. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
297 lines
6.4 KiB
C++
297 lines
6.4 KiB
C++
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
/*
|
|
* Copyright (C) 2018, Google Inc.
|
|
*
|
|
* Miscellaneous utility tests
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include <map>
|
|
#include <optional>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <libcamera/base/span.h>
|
|
#include <libcamera/base/utils.h>
|
|
|
|
#include <libcamera/geometry.h>
|
|
|
|
#include "test.h"
|
|
|
|
using namespace std;
|
|
using namespace libcamera;
|
|
using namespace std::literals::chrono_literals;
|
|
|
|
class UtilsTest : public Test
|
|
{
|
|
protected:
|
|
int testDirname()
|
|
{
|
|
static const std::vector<std::string> paths = {
|
|
"",
|
|
"///",
|
|
"/bin",
|
|
"/usr/bin",
|
|
"//etc////",
|
|
"//tmp//d//",
|
|
"current_file",
|
|
"./current_file",
|
|
"./current_dir/",
|
|
"current_dir/",
|
|
};
|
|
|
|
static const std::vector<std::string> expected = {
|
|
".",
|
|
"/",
|
|
"/",
|
|
"/usr",
|
|
"/",
|
|
"//tmp",
|
|
".",
|
|
".",
|
|
".",
|
|
".",
|
|
};
|
|
|
|
std::vector<std::string> results;
|
|
|
|
for (const auto &path : paths)
|
|
results.push_back(utils::dirname(path));
|
|
|
|
if (results != expected) {
|
|
cerr << "utils::dirname() tests failed" << endl;
|
|
|
|
cerr << "expected: " << endl;
|
|
for (const auto &path : expected)
|
|
cerr << "\t" << path << endl;
|
|
|
|
cerr << "results: " << endl;
|
|
for (const auto &path : results)
|
|
cerr << "\t" << path << endl;
|
|
|
|
return TestFail;
|
|
}
|
|
|
|
return TestPass;
|
|
}
|
|
|
|
int testEnumerate()
|
|
{
|
|
std::vector<unsigned int> integers{ 1, 2, 3, 4, 5 };
|
|
unsigned int i = 0;
|
|
|
|
for (auto [index, value] : utils::enumerate(integers)) {
|
|
if (index != i || value != i + 1) {
|
|
cerr << "utils::enumerate(<vector>) test failed: i=" << i
|
|
<< ", index=" << index << ", value=" << value
|
|
<< std::endl;
|
|
return TestFail;
|
|
}
|
|
|
|
/* Verify that we can modify the value. */
|
|
--value;
|
|
++i;
|
|
}
|
|
|
|
if (integers != std::vector<unsigned int>{ 0, 1, 2, 3, 4 }) {
|
|
cerr << "Failed to modify container in enumerated range loop" << endl;
|
|
return TestFail;
|
|
}
|
|
|
|
Span<const unsigned int> span{ integers };
|
|
i = 0;
|
|
|
|
for (auto [index, value] : utils::enumerate(span)) {
|
|
if (index != i || value != i) {
|
|
cerr << "utils::enumerate(<span>) test failed: i=" << i
|
|
<< ", index=" << index << ", value=" << value
|
|
<< std::endl;
|
|
return TestFail;
|
|
}
|
|
|
|
++i;
|
|
}
|
|
|
|
const unsigned int array[] = { 0, 2, 4, 6, 8 };
|
|
i = 0;
|
|
|
|
for (auto [index, value] : utils::enumerate(array)) {
|
|
if (index != i || value != i * 2) {
|
|
cerr << "utils::enumerate(<array>) test failed: i=" << i
|
|
<< ", index=" << index << ", value=" << value
|
|
<< std::endl;
|
|
return TestFail;
|
|
}
|
|
|
|
++i;
|
|
}
|
|
|
|
return TestPass;
|
|
}
|
|
|
|
int testDuration()
|
|
{
|
|
std::ostringstream os;
|
|
utils::Duration exposure;
|
|
double ratio;
|
|
|
|
exposure = 25ms + 25ms;
|
|
if (exposure.get<std::micro>() != 50000.0) {
|
|
cerr << "utils::Duration failed to return microsecond count";
|
|
return TestFail;
|
|
}
|
|
|
|
exposure = 1.0s / 4;
|
|
if (exposure != 250ms) {
|
|
cerr << "utils::Duration failed scalar divide test";
|
|
return TestFail;
|
|
}
|
|
|
|
exposure = 5000.5us;
|
|
if (!exposure) {
|
|
cerr << "utils::Duration failed boolean test";
|
|
return TestFail;
|
|
}
|
|
|
|
os << exposure;
|
|
if (os.str() != "5000.50us") {
|
|
cerr << "utils::Duration operator << failed";
|
|
return TestFail;
|
|
}
|
|
|
|
exposure = 100ms;
|
|
ratio = exposure / 25ms;
|
|
if (ratio != 4.0) {
|
|
cerr << "utils::Duration failed ratio test";
|
|
return TestFail;
|
|
}
|
|
|
|
return TestPass;
|
|
}
|
|
|
|
int run()
|
|
{
|
|
/* utils::hex() test. */
|
|
std::ostringstream os;
|
|
std::string ref;
|
|
|
|
os << utils::hex(static_cast<int32_t>(0x42)) << " ";
|
|
ref += "0x00000042 ";
|
|
os << utils::hex(static_cast<uint32_t>(0x42)) << " ";
|
|
ref += "0x00000042 ";
|
|
os << utils::hex(static_cast<int64_t>(0x42)) << " ";
|
|
ref += "0x0000000000000042 ";
|
|
os << utils::hex(static_cast<uint64_t>(0x42)) << " ";
|
|
ref += "0x0000000000000042 ";
|
|
os << utils::hex(static_cast<int32_t>(0x42), 4) << " ";
|
|
ref += "0x0042 ";
|
|
os << utils::hex(static_cast<uint32_t>(0x42), 1) << " ";
|
|
ref += "0x42 ";
|
|
os << utils::hex(static_cast<int64_t>(0x42), 4) << " ";
|
|
ref += "0x0042 ";
|
|
os << utils::hex(static_cast<uint64_t>(0x42), 1) << " ";
|
|
ref += "0x42 ";
|
|
|
|
std::string s = os.str();
|
|
if (s != ref) {
|
|
cerr << "utils::hex() test failed, expected '" << ref
|
|
<< "', got '" << s << "'";
|
|
return TestFail;
|
|
}
|
|
|
|
/* utils::join() and utils::split() test. */
|
|
std::vector<std::string> elements = {
|
|
"/bin",
|
|
"/usr/bin",
|
|
"",
|
|
"",
|
|
};
|
|
|
|
std::string path;
|
|
for (const auto &element : elements)
|
|
path += (path.empty() ? "" : ":") + element;
|
|
|
|
if (path != utils::join(elements, ":")) {
|
|
cerr << "utils::join() test failed" << endl;
|
|
return TestFail;
|
|
}
|
|
|
|
std::vector<std::string> dirs;
|
|
|
|
for (const auto &dir : utils::split(path, ":"))
|
|
dirs.push_back(dir);
|
|
|
|
if (dirs != elements) {
|
|
cerr << "utils::split() test failed" << endl;
|
|
return TestFail;
|
|
}
|
|
|
|
const auto &split = utils::split(path, ":");
|
|
dirs = std::vector<std::string>{ split.begin(), split.end() };
|
|
|
|
if (dirs != elements) {
|
|
cerr << "utils::split() LegacyInputIterator test failed" << endl;
|
|
return TestFail;
|
|
}
|
|
|
|
/* utils::join() with conversion function test. */
|
|
std::vector<Size> sizes = { { 0, 0 }, { 100, 100 } };
|
|
s = utils::join(sizes, "/", [](const Size &size) {
|
|
return size.toString();
|
|
});
|
|
|
|
if (s != "0x0/100x100") {
|
|
cerr << "utils::join() with conversion test failed" << endl;
|
|
return TestFail;
|
|
}
|
|
|
|
/* utils::dirname() tests. */
|
|
if (TestPass != testDirname())
|
|
return TestFail;
|
|
|
|
|
|
/* utils::map_keys() test. */
|
|
const std::map<std::string, unsigned int> map{
|
|
{ "zero", 0 },
|
|
{ "one", 1 },
|
|
{ "two", 2 },
|
|
};
|
|
std::vector<std::string> expectedKeys{
|
|
"zero",
|
|
"one",
|
|
"two",
|
|
};
|
|
|
|
std::sort(expectedKeys.begin(), expectedKeys.end());
|
|
|
|
const std::vector<std::string> keys = utils::map_keys(map);
|
|
if (keys != expectedKeys) {
|
|
cerr << "utils::map_keys() test failed" << endl;
|
|
return TestFail;
|
|
}
|
|
|
|
/* utils::alignUp() and utils::alignDown() tests. */
|
|
if (utils::alignDown(6, 3) != 6 || utils::alignDown(7, 3) != 6) {
|
|
cerr << "utils::alignDown test failed" << endl;
|
|
return TestFail;
|
|
}
|
|
|
|
if (utils::alignUp(6, 3) != 6 || utils::alignUp(7, 3) != 9) {
|
|
cerr << "utils::alignUp test failed" << endl;
|
|
return TestFail;
|
|
}
|
|
|
|
/* utils::enumerate() test. */
|
|
if (testEnumerate() != TestPass)
|
|
return TestFail;
|
|
|
|
/* utils::Duration test. */
|
|
if (testDuration() != TestPass)
|
|
return TestFail;
|
|
|
|
return TestPass;
|
|
}
|
|
};
|
|
|
|
TEST_REGISTER(UtilsTest)
|