[libcamera-devel] [PATCH] test: CameraManager: Add start/stop tests
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Tue Jul 27 19:58:24 CEST 2021
Hi Kieran,
Thank you for the patch.
On Tue, Jul 27, 2021 at 01:07:54PM +0100, Kieran Bingham wrote:
> Validate the CameraManager can start, stop, and restart successfully, as
> well as highlight that we can not construct a second CameraManager
> without hitting assertions.
>
> Signed-off-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
> ---
> This introduces some basic tests on the lifetime of the CameraManager.
>
> Integration is optional, but I'm posting to higlight the investigations
> I did on this yesterday.
>
> - We can successfully construct, use and destroy a CameraManager
> and then reconstruct a new one and use that too.
>
> - Construction of a CameraManager, with a start()/stop() cycle will
> not function using the same CameraManager if we try to re-start()
> the same instance.
That's not expected, and should be fixed.
> - Construction of two CameraManager instances causes a FATAL assertion
> though somewhat confusingly, it will face a FATAL assertion on the
> second IPAManager construction, before the second CameraManager gets
> to execute its constructor.
This part I'd keep out of the test, as it's an API limitation.
> test/camera-manager.cpp | 106 ++++++++++++++++++++++++++++++++++++++++
> test/meson.build | 1 +
> 2 files changed, 107 insertions(+)
> create mode 100644 test/camera-manager.cpp
>
> diff --git a/test/camera-manager.cpp b/test/camera-manager.cpp
> new file mode 100644
> index 000000000000..9e9c494af21c
> --- /dev/null
> +++ b/test/camera-manager.cpp
> @@ -0,0 +1,106 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2021, Google Inc.
> + *
> + * libcamera Camera Manager API tests
> + */
> +
> +#include <iostream>
> +#include <memory>
> +
> +#include <libcamera/camera.h>
> +#include <libcamera/camera_manager.h>
> +
> +#include "test.h"
> +
> +using namespace libcamera;
> +using namespace std;
> +
> +class CameraManagerTest : public Test
> +{
> +protected:
> + int validate()
> + {
> + std::shared_ptr<Camera> camera;
> +
> + if (cm_->start()) {
> + cerr << "Failed to start camera manager" << endl;
> + return TestFail;
> + }
> +
> + if (cm_->cameras().size() <= 0) {
> + cerr << "No cameras available" << endl;
> + return TestFail;
> + }
> +
> + camera = cm_->cameras()[0];
> + if (!camera) {
> + cerr << "Can not obtain a camera at index 0" << endl;
> + return TestFail;
> + }
> +
> + /* Store the camera id that we get */
> + cameraId_ = camera->id();
> +
> + return TestPass;
> + }
> +
> + int run()
> + {
> + std::string firstCamera;
> +
> + /* Construct and validate the CameraManager */
> + cm_ = new CameraManager();
> + if (validate()) {
> + cerr << "Failed first construction" << endl;
> + return TestFail;
> + }
> +
> + /* Get camera ID stored by validate */
> + firstCamera = cameraId_;
> +
> + /* Now stop everything and reconstruct the CameraManager */
> + cm_->stop();
> + delete cm_;
> +
> + /* Restart and assert we can still get a camera */
> + cm_ = new CameraManager();
> + if (validate()) {
> + cerr << "Failed after re-construction" << endl;
> + return TestFail;
> + }
> +
> + if (firstCamera != cameraId_) {
> + cerr << "Expected to get the same camera after re-construction" << endl;
> + return TestFail;
> + }
There's no guarantee that cameras will be presented in the same order,
we only guarantee camera ID stability. Assuming no camera is plugged or
unplugged while the test is running, which I think is a fair assumption,
but should be documeted in a comment here, you could store all the
camera IDs in a std::set and compare the two sets.
> +
> + /* Test stop and start (without re-create) */
> + cm_->stop();
> +
> + /* validate will call start() */
> + if (validate()) {
> + cerr << "Failed after re-starting CameraManager" << endl;
> + return TestFail;
> + }
> +
> + /*
> + * Creating a second camera manager is not permitted
> + *
> + * This will fail with a FATAL in constructing a second IPA
> + * Manager, even though we also have a FATAL in the
> + * CameraManager construction, but the CameraManager tries
> + * to construct an IPA manager, which fails before the
> + * CameraManager executes any of it's constructor.
> + */
> + //CameraManager *cm2 = new CameraManager();
Ah, you keep it out :-) We could keep it commented out, but I'm not sure
what value it brings. As an out-of-tree patch, to support work on
addressing the assertion in the IPA manager constructor, it's useful,
but I'm not sure I'd merge it.
You're leaking cm_ here. I'd store it in a std::unique_ptr<>.
> +
> + return TestPass;
> + }
> +
> +private:
> + CameraManager *cm_;
> + std::string cameraId_;
> +};
> +
> +TEST_REGISTER(CameraManagerTest)
> diff --git a/test/meson.build b/test/meson.build
> index 2c3e76546fbc..cd23c07e1f16 100644
> --- a/test/meson.build
> +++ b/test/meson.build
> @@ -24,6 +24,7 @@ subdir('v4l2_subdevice')
> subdir('v4l2_videodevice')
>
> public_tests = [
> + ['camera-manager', 'camera-manager.cpp'],
I would have put this in test/camera/
> ['geometry', 'geometry.cpp'],
> ['public-api', 'public-api.cpp'],
> ['signal', 'signal.cpp'],
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list