summaryrefslogtreecommitdiff
path: root/src/lc-compliance/main.cpp
diff options
context:
space:
mode:
authorNiklas Söderlund <niklas.soderlund@ragnatech.se>2021-01-27 01:23:51 +0100
committerNiklas Söderlund <niklas.soderlund@ragnatech.se>2021-04-12 10:48:56 +0200
commit02bc1108578e8b8eb68fa7d9ae3eeea558723931 (patch)
tree42e99d5d3cfa45b25651e0175b44400823efdfe2 /src/lc-compliance/main.cpp
parent43ab65df8dd2fd6ef3336fdb1f56909661de2475 (diff)
lc-compliance: Add a libcamera compliance tool
Add a compliance tool to ease testing of cameras. In contrast to the unit-tests under test/ that aims to test the internal components of libcamera the compliance tool aims to test application use-cases and to some extent the public API. This change adds the boilerplate code of a simple framework for the creation of tests. The tests aim both to demonstrate the tool and to catch real problems. The tests added are: - Test that if one queues exactly N requests to a camera exactly N requests are eventually completed. - Test that a configured camera can be started and stopped multiple times in an attempt to exercise cleanup code paths otherwise not often tested with 'cam' for example. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Tested-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Diffstat (limited to 'src/lc-compliance/main.cpp')
-rw-r--r--src/lc-compliance/main.cpp148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/lc-compliance/main.cpp b/src/lc-compliance/main.cpp
new file mode 100644
index 00000000..54cee54a
--- /dev/null
+++ b/src/lc-compliance/main.cpp
@@ -0,0 +1,148 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2020, Google Inc.
+ *
+ * main.cpp - lc-compliance - The libcamera compliance tool
+ */
+
+#include <iomanip>
+#include <iostream>
+#include <string.h>
+
+#include <libcamera/libcamera.h>
+
+#include "../cam/options.h"
+#include "tests.h"
+
+using namespace libcamera;
+
+enum {
+ OptCamera = 'c',
+ OptHelp = 'h',
+};
+
+class Harness
+{
+public:
+ Harness(const OptionsParser::Options &options);
+ ~Harness();
+
+ int exec();
+
+private:
+ int init();
+ void listCameras();
+
+ OptionsParser::Options options_;
+ std::unique_ptr<CameraManager> cm_;
+ std::shared_ptr<Camera> camera_;
+};
+
+Harness::Harness(const OptionsParser::Options &options)
+ : options_(options)
+{
+ cm_ = std::make_unique<CameraManager>();
+}
+
+Harness::~Harness()
+{
+ if (camera_) {
+ camera_->release();
+ camera_.reset();
+ }
+
+ cm_->stop();
+}
+
+int Harness::exec()
+{
+ int ret = init();
+ if (ret)
+ return ret;
+
+ std::vector<Results> results;
+
+ results.push_back(testSingleStream(camera_));
+
+ for (const Results &result : results) {
+ ret = result.summary();
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+int Harness::init()
+{
+ int ret = cm_->start();
+ if (ret) {
+ std::cout << "Failed to start camera manager: "
+ << strerror(-ret) << std::endl;
+ return ret;
+ }
+
+ if (!options_.isSet(OptCamera)) {
+ std::cout << "No camera specified, available cameras:" << std::endl;
+ listCameras();
+ return -ENODEV;
+ }
+
+ const std::string &cameraId = options_[OptCamera];
+ camera_ = cm_->get(cameraId);
+ if (!camera_) {
+ std::cout << "Camera " << cameraId << " not found, available cameras:" << std::endl;
+ listCameras();
+ return -ENODEV;
+ }
+
+ if (camera_->acquire()) {
+ std::cout << "Failed to acquire camera" << std::endl;
+ return -EINVAL;
+ }
+
+ std::cout << "Using camera " << cameraId << std::endl;
+
+ return 0;
+}
+
+void Harness::listCameras()
+{
+ for (const std::shared_ptr<Camera> &cam : cm_->cameras())
+ std::cout << "- " << cam.get()->id() << std::endl;
+}
+
+static int parseOptions(int argc, char **argv, OptionsParser::Options *options)
+{
+ OptionsParser parser;
+ parser.addOption(OptCamera, OptionString,
+ "Specify which camera to operate on, by id", "camera",
+ ArgumentRequired, "camera");
+ parser.addOption(OptHelp, OptionNone, "Display this help message",
+ "help");
+
+ *options = parser.parse(argc, argv);
+ if (!options->valid())
+ return -EINVAL;
+
+ if (options->isSet(OptHelp)) {
+ parser.usage();
+ return -EINTR;
+ }
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ OptionsParser::Options options;
+ int ret = parseOptions(argc, argv, &options);
+ if (ret == -EINTR)
+ return EXIT_SUCCESS;
+ if (ret < 0)
+ return EXIT_FAILURE;
+
+ Harness harness(options);
+
+ return harness.exec() ? EXIT_FAILURE : EXIT_SUCCESS;
+}