From 84ad104499d9efc0253dae1a60ee070ed375ad95 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 20 Oct 2022 00:44:55 +0300 Subject: Move test applications to src/apps/ The cam and qcam test application share code, currently through a crude hack that references the cam source files directly from the qcam meson.build file. To prepare for the introduction of hosting that code in a static library, move all applications to src/apps/. Signed-off-by: Laurent Pinchart Reviewed-by: Paul Elder Reviewed-by: Kieran Bingham --- src/lc-compliance/capture_test.cpp | 128 ----------------------- src/lc-compliance/environment.cpp | 22 ---- src/lc-compliance/environment.h | 27 ----- src/lc-compliance/main.cpp | 193 ----------------------------------- src/lc-compliance/meson.build | 31 ------ src/lc-compliance/simple_capture.cpp | 191 ---------------------------------- src/lc-compliance/simple_capture.h | 65 ------------ 7 files changed, 657 deletions(-) delete mode 100644 src/lc-compliance/capture_test.cpp delete mode 100644 src/lc-compliance/environment.cpp delete mode 100644 src/lc-compliance/environment.h delete mode 100644 src/lc-compliance/main.cpp delete mode 100644 src/lc-compliance/meson.build delete mode 100644 src/lc-compliance/simple_capture.cpp delete mode 100644 src/lc-compliance/simple_capture.h (limited to 'src/lc-compliance') diff --git a/src/lc-compliance/capture_test.cpp b/src/lc-compliance/capture_test.cpp deleted file mode 100644 index 52578207..00000000 --- a/src/lc-compliance/capture_test.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2020, Google Inc. - * Copyright (C) 2021, Collabora Ltd. - * - * capture_test.cpp - Test camera capture - */ - -#include - -#include - -#include "environment.h" -#include "simple_capture.h" - -using namespace libcamera; - -const std::vector NUMREQUESTS = { 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 }; -const std::vector ROLES = { Raw, StillCapture, VideoRecording, Viewfinder }; - -class SingleStream : public testing::TestWithParam> -{ -public: - static std::string nameParameters(const testing::TestParamInfo &info); - -protected: - void SetUp() override; - void TearDown() override; - - std::shared_ptr camera_; -}; - -/* - * We use gtest's SetUp() and TearDown() instead of constructor and destructor - * in order to be able to assert on them. - */ -void SingleStream::SetUp() -{ - Environment *env = Environment::get(); - - camera_ = env->cm()->get(env->cameraId()); - - ASSERT_EQ(camera_->acquire(), 0); -} - -void SingleStream::TearDown() -{ - if (!camera_) - return; - - camera_->release(); - camera_.reset(); -} - -std::string SingleStream::nameParameters(const testing::TestParamInfo &info) -{ - std::map rolesMap = { { Raw, "Raw" }, - { StillCapture, "StillCapture" }, - { VideoRecording, "VideoRecording" }, - { Viewfinder, "Viewfinder" } }; - - std::string roleName = rolesMap[std::get<0>(info.param)]; - std::string numRequestsName = std::to_string(std::get<1>(info.param)); - - return roleName + "_" + numRequestsName; -} - -/* - * Test single capture cycles - * - * Makes sure the camera completes the exact number of requests queued. Example - * failure is a camera that completes less requests than the number of requests - * queued. - */ -TEST_P(SingleStream, Capture) -{ - auto [role, numRequests] = GetParam(); - - SimpleCaptureBalanced capture(camera_); - - capture.configure(role); - - capture.capture(numRequests); -} - -/* - * Test multiple start/stop cycles - * - * Makes sure the camera supports multiple start/stop cycles. Example failure is - * a camera that does not clean up correctly in its error path but is only - * tested by single-capture applications. - */ -TEST_P(SingleStream, CaptureStartStop) -{ - auto [role, numRequests] = GetParam(); - unsigned int numRepeats = 3; - - SimpleCaptureBalanced capture(camera_); - - capture.configure(role); - - for (unsigned int starts = 0; starts < numRepeats; starts++) - capture.capture(numRequests); -} - -/* - * Test unbalanced stop - * - * Makes sure the camera supports a stop with requests queued. Example failure - * is a camera that does not handle cancelation of buffers coming back from the - * video device while stopping. - */ -TEST_P(SingleStream, UnbalancedStop) -{ - auto [role, numRequests] = GetParam(); - - SimpleCaptureUnbalanced capture(camera_); - - capture.configure(role); - - capture.capture(numRequests); -} - -INSTANTIATE_TEST_SUITE_P(CaptureTests, - SingleStream, - testing::Combine(testing::ValuesIn(ROLES), - testing::ValuesIn(NUMREQUESTS)), - SingleStream::nameParameters); diff --git a/src/lc-compliance/environment.cpp b/src/lc-compliance/environment.cpp deleted file mode 100644 index 5eb3775f..00000000 --- a/src/lc-compliance/environment.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2021, Collabora Ltd. - * - * environment.cpp - Common environment for tests - */ - -#include "environment.h" - -using namespace libcamera; - -Environment *Environment::get() -{ - static Environment instance; - return &instance; -} - -void Environment::setup(CameraManager *cm, std::string cameraId) -{ - cm_ = cm; - cameraId_ = cameraId; -} diff --git a/src/lc-compliance/environment.h b/src/lc-compliance/environment.h deleted file mode 100644 index 0debbcce..00000000 --- a/src/lc-compliance/environment.h +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2021, Collabora Ltd. - * - * environment.h - Common environment for tests - */ - -#pragma once - -#include - -class Environment -{ -public: - static Environment *get(); - - void setup(libcamera::CameraManager *cm, std::string cameraId); - - const std::string &cameraId() const { return cameraId_; } - libcamera::CameraManager *cm() const { return cm_; } - -private: - Environment() = default; - - std::string cameraId_; - libcamera::CameraManager *cm_; -}; diff --git a/src/lc-compliance/main.cpp b/src/lc-compliance/main.cpp deleted file mode 100644 index 7eb52ae4..00000000 --- a/src/lc-compliance/main.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2020, Google Inc. - * Copyright (C) 2021, Collabora Ltd. - * - * main.cpp - lc-compliance - The libcamera compliance tool - */ - -#include -#include -#include - -#include - -#include - -#include "environment.h" -#include "../cam/options.h" - -using namespace libcamera; - -enum { - OptCamera = 'c', - OptList = 'l', - OptFilter = 'f', - OptHelp = 'h', -}; - -/* - * Make asserts act like exceptions, otherwise they only fail (or skip) the - * current function. From gtest documentation: - * https://google.github.io/googletest/advanced.html#asserting-on-subroutines-with-an-exception - */ -class ThrowListener : public testing::EmptyTestEventListener -{ - void OnTestPartResult(const testing::TestPartResult &result) override - { - if (result.type() == testing::TestPartResult::kFatalFailure || - result.type() == testing::TestPartResult::kSkip) - throw testing::AssertionException(result); - } -}; - -static void listCameras(CameraManager *cm) -{ - for (const std::shared_ptr &cam : cm->cameras()) - std::cout << "- " << cam.get()->id() << std::endl; -} - -static int initCamera(CameraManager *cm, OptionsParser::Options options) -{ - std::shared_ptr camera; - - 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(cm); - 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(cm); - return -ENODEV; - } - - Environment::get()->setup(cm, cameraId); - - std::cout << "Using camera " << cameraId << std::endl; - - return 0; -} - -static int initGtestParameters(char *arg0, OptionsParser::Options options) -{ - const std::map gtestFlags = { { "list", "--gtest_list_tests" }, - { "filter", "--gtest_filter" } }; - - int argc = 0; - std::string filterParam; - - /* - * +2 to have space for both the 0th argument that is needed but not - * used and the null at the end. - */ - char **argv = new char *[(gtestFlags.size() + 2)]; - if (!argv) - return -ENOMEM; - - argv[0] = arg0; - argc++; - - if (options.isSet(OptList)) { - argv[argc] = const_cast(gtestFlags.at("list").c_str()); - argc++; - } - - if (options.isSet(OptFilter)) { - /* - * The filter flag needs to be passed as a single parameter, in - * the format --gtest_filter=filterStr - */ - filterParam = gtestFlags.at("filter") + "=" + - static_cast(options[OptFilter]); - - argv[argc] = const_cast(filterParam.c_str()); - argc++; - } - - argv[argc] = nullptr; - - ::testing::InitGoogleTest(&argc, argv); - - delete[] argv; - - return 0; -} - -static int initGtest(char *arg0, OptionsParser::Options options) -{ - int ret = initGtestParameters(arg0, options); - if (ret) - return ret; - - testing::UnitTest::GetInstance()->listeners().Append(new ThrowListener); - - return 0; -} - -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(OptList, OptionNone, "List all tests and exit", "list"); - parser.addOption(OptFilter, OptionString, - "Specify which tests to run", "filter", - ArgumentRequired, "filter"); - 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(); - std::cerr << "Further options from Googletest can be passed as environment variables" - << std::endl; - 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; - - std::unique_ptr cm = std::make_unique(); - - /* No need to initialize the camera if we'll just list tests */ - if (!options.isSet(OptList)) { - ret = initCamera(cm.get(), options); - if (ret) - return ret; - } - - ret = initGtest(argv[0], options); - if (ret) - return ret; - - ret = RUN_ALL_TESTS(); - - if (!options.isSet(OptList)) - cm->stop(); - - return ret; -} diff --git a/src/lc-compliance/meson.build b/src/lc-compliance/meson.build deleted file mode 100644 index 8b57474b..00000000 --- a/src/lc-compliance/meson.build +++ /dev/null @@ -1,31 +0,0 @@ -# SPDX-License-Identifier: CC0-1.0 - -libevent = dependency('libevent_pthreads', required : get_option('lc-compliance')) -libgtest = dependency('gtest', required : get_option('lc-compliance'), - fallback : ['gtest', 'gtest_dep']) - -if not (libevent.found() and libgtest.found()) - lc_compliance_enabled = false - subdir_done() -endif - -lc_compliance_enabled = true - -lc_compliance_sources = files([ - '../cam/event_loop.cpp', - '../cam/options.cpp', - 'environment.cpp', - 'main.cpp', - 'simple_capture.cpp', - 'capture_test.cpp', -]) - -lc_compliance = executable('lc-compliance', lc_compliance_sources, - cpp_args : [ '-fexceptions' ], - dependencies : [ - libatomic, - libcamera_public, - libevent, - libgtest, - ], - install : true) diff --git a/src/lc-compliance/simple_capture.cpp b/src/lc-compliance/simple_capture.cpp deleted file mode 100644 index ab5cb35c..00000000 --- a/src/lc-compliance/simple_capture.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2020-2021, Google Inc. - * - * simple_capture.cpp - Simple capture helper - */ - -#include - -#include "simple_capture.h" - -using namespace libcamera; - -SimpleCapture::SimpleCapture(std::shared_ptr camera) - : loop_(nullptr), camera_(camera), - allocator_(std::make_unique(camera)) -{ -} - -SimpleCapture::~SimpleCapture() -{ - stop(); -} - -void SimpleCapture::configure(StreamRole role) -{ - config_ = camera_->generateConfiguration({ role }); - - if (!config_) { - std::cout << "Role not supported by camera" << std::endl; - GTEST_SKIP(); - } - - if (config_->validate() != CameraConfiguration::Valid) { - config_.reset(); - FAIL() << "Configuration not valid"; - } - - if (camera_->configure(config_.get())) { - config_.reset(); - FAIL() << "Failed to configure camera"; - } -} - -void SimpleCapture::start() -{ - Stream *stream = config_->at(0).stream(); - int count = allocator_->allocate(stream); - - ASSERT_GE(count, 0) << "Failed to allocate buffers"; - EXPECT_EQ(count, config_->at(0).bufferCount) << "Allocated less buffers than expected"; - - camera_->requestCompleted.connect(this, &SimpleCapture::requestComplete); - - ASSERT_EQ(camera_->start(), 0) << "Failed to start camera"; -} - -void SimpleCapture::stop() -{ - if (!config_ || !allocator_->allocated()) - return; - - camera_->stop(); - - camera_->requestCompleted.disconnect(this); - - Stream *stream = config_->at(0).stream(); - allocator_->free(stream); -} - -/* SimpleCaptureBalanced */ - -SimpleCaptureBalanced::SimpleCaptureBalanced(std::shared_ptr camera) - : SimpleCapture(camera) -{ -} - -void SimpleCaptureBalanced::capture(unsigned int numRequests) -{ - start(); - - Stream *stream = config_->at(0).stream(); - const std::vector> &buffers = allocator_->buffers(stream); - - /* No point in testing less requests then the camera depth. */ - if (buffers.size() > numRequests) { - std::cout << "Camera needs " + std::to_string(buffers.size()) - + " requests, can't test only " - + std::to_string(numRequests) << std::endl; - GTEST_SKIP(); - } - - queueCount_ = 0; - captureCount_ = 0; - captureLimit_ = numRequests; - - /* Queue the recommended number of reqeuests. */ - std::vector> requests; - for (const std::unique_ptr &buffer : buffers) { - std::unique_ptr request = camera_->createRequest(); - ASSERT_TRUE(request) << "Can't create request"; - - ASSERT_EQ(request->addBuffer(stream, buffer.get()), 0) << "Can't set buffer for request"; - - ASSERT_EQ(queueRequest(request.get()), 0) << "Failed to queue request"; - - requests.push_back(std::move(request)); - } - - /* Run capture session. */ - loop_ = new EventLoop(); - loop_->exec(); - stop(); - delete loop_; - - ASSERT_EQ(captureCount_, captureLimit_); -} - -int SimpleCaptureBalanced::queueRequest(Request *request) -{ - queueCount_++; - if (queueCount_ > captureLimit_) - return 0; - - return camera_->queueRequest(request); -} - -void SimpleCaptureBalanced::requestComplete(Request *request) -{ - captureCount_++; - if (captureCount_ >= captureLimit_) { - loop_->exit(0); - return; - } - - request->reuse(Request::ReuseBuffers); - if (queueRequest(request)) - loop_->exit(-EINVAL); -} - -/* SimpleCaptureUnbalanced */ - -SimpleCaptureUnbalanced::SimpleCaptureUnbalanced(std::shared_ptr camera) - : SimpleCapture(camera) -{ -} - -void SimpleCaptureUnbalanced::capture(unsigned int numRequests) -{ - start(); - - Stream *stream = config_->at(0).stream(); - const std::vector> &buffers = allocator_->buffers(stream); - - captureCount_ = 0; - captureLimit_ = numRequests; - - /* Queue the recommended number of reqeuests. */ - std::vector> requests; - for (const std::unique_ptr &buffer : buffers) { - std::unique_ptr request = camera_->createRequest(); - ASSERT_TRUE(request) << "Can't create request"; - - ASSERT_EQ(request->addBuffer(stream, buffer.get()), 0) << "Can't set buffer for request"; - - ASSERT_EQ(camera_->queueRequest(request.get()), 0) << "Failed to queue request"; - - requests.push_back(std::move(request)); - } - - /* Run capture session. */ - loop_ = new EventLoop(); - int status = loop_->exec(); - stop(); - delete loop_; - - ASSERT_EQ(status, 0); -} - -void SimpleCaptureUnbalanced::requestComplete(Request *request) -{ - captureCount_++; - if (captureCount_ >= captureLimit_) { - loop_->exit(0); - return; - } - - request->reuse(Request::ReuseBuffers); - if (camera_->queueRequest(request)) - loop_->exit(-EINVAL); -} diff --git a/src/lc-compliance/simple_capture.h b/src/lc-compliance/simple_capture.h deleted file mode 100644 index 9d31f7cb..00000000 --- a/src/lc-compliance/simple_capture.h +++ /dev/null @@ -1,65 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2020-2021, Google Inc. - * - * simple_capture.h - Simple capture helper - */ - -#pragma once - -#include - -#include - -#include "../cam/event_loop.h" - -class SimpleCapture -{ -public: - void configure(libcamera::StreamRole role); - -protected: - SimpleCapture(std::shared_ptr camera); - virtual ~SimpleCapture(); - - void start(); - void stop(); - - virtual void requestComplete(libcamera::Request *request) = 0; - - EventLoop *loop_; - - std::shared_ptr camera_; - std::unique_ptr allocator_; - std::unique_ptr config_; -}; - -class SimpleCaptureBalanced : public SimpleCapture -{ -public: - SimpleCaptureBalanced(std::shared_ptr camera); - - void capture(unsigned int numRequests); - -private: - int queueRequest(libcamera::Request *request); - void requestComplete(libcamera::Request *request) override; - - unsigned int queueCount_; - unsigned int captureCount_; - unsigned int captureLimit_; -}; - -class SimpleCaptureUnbalanced : public SimpleCapture -{ -public: - SimpleCaptureUnbalanced(std::shared_ptr camera); - - void capture(unsigned int numRequests); - -private: - void requestComplete(libcamera::Request *request) override; - - unsigned int captureCount_; - unsigned int captureLimit_; -}; -- cgit v1.2.1