[2/4] apps: lc-compliance: Test for mandatory controls
diff mbox series

Message ID 20240320101652.12873-3-jacopo.mondi@ideasonboard.com
State New
Headers show
Series
  • apps: lc-compliance: Properties and multi-stream tests
Related show

Commit Message

Jacopo Mondi March 20, 2024, 10:16 a.m. UTC
Test for mandatory controls and properties to be supported by
a Camera.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
---
 src/apps/lc-compliance/meson.build            |  1 +
 .../lc-compliance/tests/controls_test.cpp     | 98 +++++++++++++++++++
 2 files changed, 99 insertions(+)
 create mode 100644 src/apps/lc-compliance/tests/controls_test.cpp

Comments

Paul Elder May 7, 2025, 2:57 p.m. UTC | #1
On Wed, Mar 20, 2024 at 11:16:49AM +0100, Jacopo Mondi wrote:
> Test for mandatory controls and properties to be supported by
> a Camera.
> 
> Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>

Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>

> ---
>  src/apps/lc-compliance/meson.build            |  1 +
>  .../lc-compliance/tests/controls_test.cpp     | 98 +++++++++++++++++++
>  2 files changed, 99 insertions(+)
>  create mode 100644 src/apps/lc-compliance/tests/controls_test.cpp
> 
> diff --git a/src/apps/lc-compliance/meson.build b/src/apps/lc-compliance/meson.build
> index b1f605f3392a..09f068628d53 100644
> --- a/src/apps/lc-compliance/meson.build
> +++ b/src/apps/lc-compliance/meson.build
> @@ -16,6 +16,7 @@ lc_compliance_sources = files([
>      'helpers/capture.cpp',
>      'main.cpp',
>      'tests/capture_test.cpp',
> +    'tests/controls_test.cpp'
>  ])
>  
>  lc_compliance_includes = ([
> diff --git a/src/apps/lc-compliance/tests/controls_test.cpp b/src/apps/lc-compliance/tests/controls_test.cpp
> new file mode 100644
> index 000000000000..ff594fbe672a
> --- /dev/null
> +++ b/src/apps/lc-compliance/tests/controls_test.cpp
> @@ -0,0 +1,98 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2023, Ideas On Board Oy
> + *
> + * controls_test.cpp - Test controls and properties
> + */
> +
> +#include <array>
> +#include <iostream>
> +
> +#include <libcamera/control_ids.h>
> +#include <libcamera/controls.h>
> +#include <libcamera/property_ids.h>
> +
> +#include <gtest/gtest.h>
> +
> +#include "environment.h"
> +
> +using namespace libcamera;
> +
> +std::array<const ControlIdMap *, 2> controlMaps = {
> +	&controls::controls,
> +	&properties::properties,
> +};
> +
> +class ControlTest : public testing::TestWithParam<const ControlIdMap *>
> +{
> +public:
> +	static std::string nameParameters(const testing::TestParamInfo<ControlTest::ParamType> &info);
> +
> +protected:
> +	void SetUp() override;
> +	void TearDown() override;
> +
> +	std::shared_ptr<Camera> camera_;
> +};
> +
> +void ControlTest::SetUp()
> +{
> +	Environment *env = Environment::get();
> +
> +	camera_ = env->cm()->get(env->cameraId());
> +
> +	ASSERT_EQ(camera_->acquire(), 0);
> +}
> +
> +void ControlTest::TearDown()
> +{
> +	if (!camera_)
> +		return;
> +
> +	camera_->release();
> +	camera_.reset();
> +}
> +
> +std::string ControlTest::nameParameters(const testing::TestParamInfo<ControlTest::ParamType> &info)
> +{
> +	const ControlIdMap *idMap = info.param;
> +	if (idMap == &controls::controls)
> +		return "controls";
> +	else if (idMap == &properties::properties)
> +		return "properties";
> +
> +	return "vendor";
> +}
> +
> +/* Test that mandatory controls and properties are supported by a camera. */
> +TEST_P(ControlTest, RequiredControls)
> +{
> +	auto controlMap = GetParam();
> +
> +	for (const auto &[id, ctrl] : *controlMap) {
> +		if (!ctrl->required())
> +			continue;
> +
> +		if (controlMap == &controls::controls) {
> +			const auto it = camera_->controls().find(ctrl);
> +
> +			if (it == camera_->controls().end())
> +				FAIL() << "Mandatory control \"" << ctrl->name()
> +				       << "\" not supported" << std::endl;
> +		} else if (controlMap == &properties::properties) {
> +			bool found = camera_->properties().contains(id);
> +
> +			if (!found)
> +				FAIL() << "Mandatory property \"" << ctrl->name()
> +				       << "\" not supported" << std::endl;
> +		}
> +	}
> +}
> +
> +/*
> + * Use a Value-Parametrized Test case so that vendors can easily test vendor
> + * control lists by expanding 'controlMaps'.
> + */
> +INSTANTIATE_TEST_SUITE_P(ControlsTest, ControlTest,
> +			 testing::ValuesIn(controlMaps),
> +			 ControlTest::nameParameters);
> -- 
> 2.44.0
>

Patch
diff mbox series

diff --git a/src/apps/lc-compliance/meson.build b/src/apps/lc-compliance/meson.build
index b1f605f3392a..09f068628d53 100644
--- a/src/apps/lc-compliance/meson.build
+++ b/src/apps/lc-compliance/meson.build
@@ -16,6 +16,7 @@  lc_compliance_sources = files([
     'helpers/capture.cpp',
     'main.cpp',
     'tests/capture_test.cpp',
+    'tests/controls_test.cpp'
 ])
 
 lc_compliance_includes = ([
diff --git a/src/apps/lc-compliance/tests/controls_test.cpp b/src/apps/lc-compliance/tests/controls_test.cpp
new file mode 100644
index 000000000000..ff594fbe672a
--- /dev/null
+++ b/src/apps/lc-compliance/tests/controls_test.cpp
@@ -0,0 +1,98 @@ 
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2023, Ideas On Board Oy
+ *
+ * controls_test.cpp - Test controls and properties
+ */
+
+#include <array>
+#include <iostream>
+
+#include <libcamera/control_ids.h>
+#include <libcamera/controls.h>
+#include <libcamera/property_ids.h>
+
+#include <gtest/gtest.h>
+
+#include "environment.h"
+
+using namespace libcamera;
+
+std::array<const ControlIdMap *, 2> controlMaps = {
+	&controls::controls,
+	&properties::properties,
+};
+
+class ControlTest : public testing::TestWithParam<const ControlIdMap *>
+{
+public:
+	static std::string nameParameters(const testing::TestParamInfo<ControlTest::ParamType> &info);
+
+protected:
+	void SetUp() override;
+	void TearDown() override;
+
+	std::shared_ptr<Camera> camera_;
+};
+
+void ControlTest::SetUp()
+{
+	Environment *env = Environment::get();
+
+	camera_ = env->cm()->get(env->cameraId());
+
+	ASSERT_EQ(camera_->acquire(), 0);
+}
+
+void ControlTest::TearDown()
+{
+	if (!camera_)
+		return;
+
+	camera_->release();
+	camera_.reset();
+}
+
+std::string ControlTest::nameParameters(const testing::TestParamInfo<ControlTest::ParamType> &info)
+{
+	const ControlIdMap *idMap = info.param;
+	if (idMap == &controls::controls)
+		return "controls";
+	else if (idMap == &properties::properties)
+		return "properties";
+
+	return "vendor";
+}
+
+/* Test that mandatory controls and properties are supported by a camera. */
+TEST_P(ControlTest, RequiredControls)
+{
+	auto controlMap = GetParam();
+
+	for (const auto &[id, ctrl] : *controlMap) {
+		if (!ctrl->required())
+			continue;
+
+		if (controlMap == &controls::controls) {
+			const auto it = camera_->controls().find(ctrl);
+
+			if (it == camera_->controls().end())
+				FAIL() << "Mandatory control \"" << ctrl->name()
+				       << "\" not supported" << std::endl;
+		} else if (controlMap == &properties::properties) {
+			bool found = camera_->properties().contains(id);
+
+			if (!found)
+				FAIL() << "Mandatory property \"" << ctrl->name()
+				       << "\" not supported" << std::endl;
+		}
+	}
+}
+
+/*
+ * Use a Value-Parametrized Test case so that vendors can easily test vendor
+ * control lists by expanding 'controlMaps'.
+ */
+INSTANTIATE_TEST_SUITE_P(ControlsTest, ControlTest,
+			 testing::ValuesIn(controlMaps),
+			 ControlTest::nameParameters);