summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/camera-sensor.cpp7
-rw-r--r--test/geometry.cpp14
-rw-r--r--test/ipa/libipa/interpolator.cpp54
-rw-r--r--test/ipa/libipa/meson.build15
-rw-r--r--test/ipa/meson.build1
-rw-r--r--test/py/meson.build14
-rwxr-xr-xtest/py/unittests.py2
-rw-r--r--test/serialization/generated_serializer/generated_serializer_test.cpp1
-rw-r--r--test/v4l2_videodevice/v4l2_videodevice_test.cpp5
-rw-r--r--test/v4l2_videodevice/v4l2_videodevice_test.h2
-rw-r--r--test/yaml-parser.cpp52
11 files changed, 153 insertions, 14 deletions
diff --git a/test/camera-sensor.cpp b/test/camera-sensor.cpp
index 1d402c43..869c7889 100644
--- a/test/camera-sensor.cpp
+++ b/test/camera-sensor.cpp
@@ -52,8 +52,8 @@ protected:
return TestFail;
}
- sensor_ = new CameraSensor(entity);
- if (sensor_->init() < 0) {
+ sensor_ = CameraSensorFactoryBase::create(entity);
+ if (!sensor_) {
cerr << "Unable to initialise camera sensor" << endl;
return TestFail;
}
@@ -118,13 +118,12 @@ protected:
void cleanup()
{
- delete sensor_;
}
private:
std::unique_ptr<DeviceEnumerator> enumerator_;
std::shared_ptr<MediaDevice> media_;
- CameraSensor *sensor_;
+ std::unique_ptr<CameraSensor> sensor_;
CameraLens *lens_;
};
diff --git a/test/geometry.cpp b/test/geometry.cpp
index 64169206..5760fa3c 100644
--- a/test/geometry.cpp
+++ b/test/geometry.cpp
@@ -481,6 +481,20 @@ protected:
return TestFail;
}
+ Point topLeft(3, 3);
+ Point bottomRight(30, 30);
+ Point topRight(30, 3);
+ Point bottomLeft(3, 30);
+ Rectangle rect1(topLeft, bottomRight);
+ Rectangle rect2(topRight, bottomLeft);
+ Rectangle rect3(bottomRight, topLeft);
+ Rectangle rect4(bottomLeft, topRight);
+
+ if (rect1 != rect2 || rect1 != rect3 || rect1 != rect4) {
+ cout << "Point-to-point construction failed" << endl;
+ return TestFail;
+ }
+
return TestPass;
}
};
diff --git a/test/ipa/libipa/interpolator.cpp b/test/ipa/libipa/interpolator.cpp
new file mode 100644
index 00000000..6abb7760
--- /dev/null
+++ b/test/ipa/libipa/interpolator.cpp
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2024, Ideas on Board Oy
+ *
+ * Interpolator tests
+ */
+
+#include "../src/ipa/libipa/interpolator.h"
+
+#include <cmath>
+#include <iostream>
+#include <map>
+#include <stdint.h>
+#include <stdio.h>
+
+#include "test.h"
+
+using namespace std;
+using namespace libcamera;
+using namespace ipa;
+
+#define ASSERT_EQ(a, b) \
+ if ((a) != (b)) { \
+ printf(#a " != " #b "\n"); \
+ return TestFail; \
+ }
+
+class InterpolatorTest : public Test
+{
+protected:
+ int run()
+ {
+ Interpolator<int> interpolator;
+ interpolator.setData({ { 10, 100 }, { 20, 200 }, { 30, 300 } });
+
+ ASSERT_EQ(interpolator.getInterpolated(0), 100);
+ ASSERT_EQ(interpolator.getInterpolated(10), 100);
+ ASSERT_EQ(interpolator.getInterpolated(20), 200);
+ ASSERT_EQ(interpolator.getInterpolated(25), 250);
+ ASSERT_EQ(interpolator.getInterpolated(30), 300);
+ ASSERT_EQ(interpolator.getInterpolated(40), 300);
+
+ interpolator.setQuantization(10);
+ unsigned int q = 0;
+ ASSERT_EQ(interpolator.getInterpolated(25, &q), 300);
+ ASSERT_EQ(q, 30);
+ ASSERT_EQ(interpolator.getInterpolated(24, &q), 200);
+ ASSERT_EQ(q, 20);
+
+ return TestPass;
+ }
+};
+
+TEST_REGISTER(InterpolatorTest)
diff --git a/test/ipa/libipa/meson.build b/test/ipa/libipa/meson.build
new file mode 100644
index 00000000..4d2427db
--- /dev/null
+++ b/test/ipa/libipa/meson.build
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: CC0-1.0
+
+libipa_test = [
+ {'name': 'interpolator', 'sources': ['interpolator.cpp']},
+]
+
+foreach test : libipa_test
+ exe = executable(test['name'], test['sources'],
+ dependencies : [libcamera_private, libipa_dep],
+ link_with : [test_libraries],
+ include_directories : [test_includes_internal,
+ '../../../src/ipa/libipa/'])
+
+ test(test['name'], exe, suite : 'ipa')
+endforeach
diff --git a/test/ipa/meson.build b/test/ipa/meson.build
index e9871aba..63820de5 100644
--- a/test/ipa/meson.build
+++ b/test/ipa/meson.build
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: CC0-1.0
+subdir('libipa')
subdir('rkisp1')
ipa_test = [
diff --git a/test/py/meson.build b/test/py/meson.build
index 0b679d31..b922e857 100644
--- a/test/py/meson.build
+++ b/test/py/meson.build
@@ -13,15 +13,25 @@ if asan_runtime_missing
subdir_done()
endif
+py_env = environment()
+
pymod = import('python')
py3 = pymod.find_installation('python3')
pypathdir = meson.project_build_root() / 'src' / 'py'
-py_env = ['PYTHONPATH=' + pypathdir]
+py_env.append('PYTHONPATH', pypathdir)
if asan_enabled
+ py_env.append('LD_PRELOAD', asan_runtime)
+
+ # Preload the C++ standard library to work around a bug in ASan when
+ # dynamically loading C++ .so modules.
+ stdlib = run_command(cxx, '-print-file-name=' + cxx_stdlib + '.so',
+ check : true).stdout().strip()
+ py_env.append('LD_PRELOAD', stdlib)
+
# Disable leak detection as the Python interpreter is full of leaks.
- py_env += ['LD_PRELOAD=' + asan_runtime, 'ASAN_OPTIONS=detect_leaks=0']
+ py_env.append('ASAN_OPTIONS', 'detect_leaks=0')
endif
test('pyunittests',
diff --git a/test/py/unittests.py b/test/py/unittests.py
index 1caea98e..8cb850d4 100755
--- a/test/py/unittests.py
+++ b/test/py/unittests.py
@@ -66,7 +66,7 @@ class SimpleTestMethods(BaseTestCase):
libcam.log_set_level('Camera', 'FATAL')
with self.assertRaises(RuntimeError):
cam.acquire()
- libcam.log_set_level('Camera', 'ERROR')
+ libcam.log_set_level('Camera', 'INFO')
cam.release()
diff --git a/test/serialization/generated_serializer/generated_serializer_test.cpp b/test/serialization/generated_serializer/generated_serializer_test.cpp
index 4b11d67f..dd696885 100644
--- a/test/serialization/generated_serializer/generated_serializer_test.cpp
+++ b/test/serialization/generated_serializer/generated_serializer_test.cpp
@@ -6,6 +6,7 @@
*/
#include <algorithm>
+#include <iostream>
#include <tuple>
#include <vector>
diff --git a/test/v4l2_videodevice/v4l2_videodevice_test.cpp b/test/v4l2_videodevice/v4l2_videodevice_test.cpp
index 1113cf5b..9fbd24cc 100644
--- a/test/v4l2_videodevice/v4l2_videodevice_test.cpp
+++ b/test/v4l2_videodevice/v4l2_videodevice_test.cpp
@@ -64,8 +64,8 @@ int V4L2VideoDeviceTest::init()
format.size.height = 480;
if (driver_ == "vimc") {
- sensor_ = new CameraSensor(media_->getEntityByName("Sensor A"));
- if (sensor_->init())
+ sensor_ = CameraSensorFactoryBase::create(media_->getEntityByName("Sensor A"));
+ if (!sensor_)
return TestFail;
debayer_ = new V4L2Subdevice(media_->getEntityByName("Debayer A"));
@@ -98,6 +98,5 @@ void V4L2VideoDeviceTest::cleanup()
capture_->close();
delete debayer_;
- delete sensor_;
delete capture_;
}
diff --git a/test/v4l2_videodevice/v4l2_videodevice_test.h b/test/v4l2_videodevice/v4l2_videodevice_test.h
index b5871ce6..7c9003ec 100644
--- a/test/v4l2_videodevice/v4l2_videodevice_test.h
+++ b/test/v4l2_videodevice/v4l2_videodevice_test.h
@@ -36,7 +36,7 @@ protected:
std::string entity_;
std::unique_ptr<libcamera::DeviceEnumerator> enumerator_;
std::shared_ptr<libcamera::MediaDevice> media_;
- libcamera::CameraSensor *sensor_;
+ std::unique_ptr<libcamera::CameraSensor> sensor_;
libcamera::V4L2Subdevice *debayer_;
libcamera::V4L2VideoDevice *capture_;
std::vector<std::unique_ptr<libcamera::FrameBuffer>> buffers_;
diff --git a/test/yaml-parser.cpp b/test/yaml-parser.cpp
index 81c82983..1b22c87b 100644
--- a/test/yaml-parser.cpp
+++ b/test/yaml-parser.cpp
@@ -34,10 +34,12 @@ static const string testYaml =
"list:\n"
" - James\n"
" - Mary\n"
+ " - \n"
"dictionary:\n"
" a: 1\n"
" c: 3\n"
" b: 2\n"
+ " empty:\n"
"level1:\n"
" level2:\n"
" - [1, 2]\n"
@@ -430,9 +432,10 @@ protected:
if (testObjectType(listObj, "list", Type::List) != TestPass)
return TestFail;
- static constexpr std::array<const char *, 2> listValues{
+ static constexpr std::array<const char *, 3> listValues{
"James",
"Mary",
+ "",
};
if (listObj.size() != listValues.size()) {
@@ -465,16 +468,23 @@ protected:
i++;
}
+ /* Ensure that empty objects get parsed as empty strings. */
+ if (!listObj[2].isValue()) {
+ cerr << "Empty object is not a value" << std::endl;
+ return TestFail;
+ }
+
/* Test dictionary object */
auto &dictObj = (*root)["dictionary"];
if (testObjectType(dictObj, "dictionary", Type::Dictionary) != TestPass)
return TestFail;
- static constexpr std::array<std::pair<const char *, int>, 3> dictValues{ {
+ static constexpr std::array<std::pair<const char *, int>, 4> dictValues{ {
{ "a", 1 },
{ "c", 3 },
{ "b", 2 },
+ { "empty", -100 },
} };
size_t dictSize = dictValues.size();
@@ -505,7 +515,7 @@ protected:
return TestFail;
}
- if (elem.get<int32_t>(0) != item.second) {
+ if (elem.get<int32_t>(-100) != item.second) {
std::cerr << "Dictionary element " << i << " has wrong value"
<< std::endl;
return TestFail;
@@ -514,6 +524,42 @@ protected:
i++;
}
+ /* Ensure that empty objects get parsed as empty strings. */
+ if (!dictObj["empty"].isValue()) {
+ cerr << "Empty object is not of type value" << std::endl;
+ return TestFail;
+ }
+
+ /* Ensure that keys without values are added to a dict. */
+ if (!dictObj.contains("empty")) {
+ cerr << "Empty element is missing in dict" << std::endl;
+ return TestFail;
+ }
+
+ /* Test access to nonexistent member. */
+ if (dictObj["nonexistent"].get<std::string>("default") != "default") {
+ cerr << "Accessing nonexistent dict entry fails to return default" << std::endl;
+ return TestFail;
+ }
+
+ /* Test nonexistent object has value type empty. */
+ if (!dictObj["nonexistent"].isEmpty()) {
+ cerr << "Accessing nonexistent object returns non-empty object" << std::endl;
+ return TestFail;
+ }
+
+ /* Test explicit cast to bool on an empty object returns true. */
+ if (!!dictObj["empty"] != true) {
+ cerr << "Casting empty entry to bool returns false" << std::endl;
+ return TestFail;
+ }
+
+ /* Test explicit cast to bool on nonexistent object returns false. */
+ if (!!dictObj["nonexistent"] != false) {
+ cerr << "Casting nonexistent dict entry to bool returns true" << std::endl;
+ return TestFail;
+ }
+
/* Make sure utils::map_keys() works on the adapter. */
(void)utils::map_keys(dictObj.asDict());