[libcamera-devel] [PATCH v4 6/6] tests: Introduce hotplug hot-unplug unit test
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Fri Jun 12 13:42:04 CEST 2020
Hi Umang,
Thank you for the patch.
On Thu, Jun 11, 2020 at 05:16:08PM +0000, Umang Jain wrote:
> This test checks the code-paths for camera's hotplugged and
> unplugged support. It is based on bind/unbind of a UVC device
> from sysfs. Hence, this test requires root permissions to run
> and should have at least one already bound UVC device present
> in the system.
>
> Signed-off-by: Umang Jain <email at uajain.com>
> ---
> test/hotplug-cameras.cpp | 124 +++++++++++++++++++++++++++++++++++++++
> test/meson.build | 1 +
> 2 files changed, 125 insertions(+)
> create mode 100644 test/hotplug-cameras.cpp
>
> diff --git a/test/hotplug-cameras.cpp b/test/hotplug-cameras.cpp
> new file mode 100644
> index 0000000..07500fc
> --- /dev/null
> +++ b/test/hotplug-cameras.cpp
> @@ -0,0 +1,124 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2020, Umang Jain <email at uajain.com>
> + *
> + * hotplug-cameras.cpp - Test cameraAdded/cameraRemoved signals in CameraManager
> + */
> +
> +#include <dirent.h>
> +#include <fstream>
> +#include <iostream>
> +#include <string.h>
> +#include <unistd.h>
> +
> +#include <libcamera/camera.h>
> +#include <libcamera/camera_manager.h>
> +#include <libcamera/event_dispatcher.h>
> +#include <libcamera/timer.h>
> +
> +#include "libcamera/internal/file.h"
> +#include "libcamera/internal/thread.h"
> +
> +#include "test.h"
> +
> +using namespace libcamera;
> +
> +class HotplugTest : public Test
> +{
> +protected:
> + void cameraAddedHandler(std::shared_ptr<Camera> cam)
> + {
> + cameraAdded_ = true;
> + }
> +
> + void cameraRemovedHandler(std::shared_ptr<Camera> cam)
> + {
> + cameraRemoved_ = true;
> + }
> +
> + int init()
> + {
> + if (!File::exists("/sys/module/uvcvideo")) {
> + std::cout << "uvcvideo driver is not loaded, skipping" << std::endl;
> + return TestSkip;
> + }
> +
> + if (geteuid() != 0) {
> + std::cout << "This test requires root permissions, skipping" << std::endl;
> + return TestSkip;
> + }
> +
> + cm_ = new CameraManager();
> + if (cm_->start()) {
> + std::cout << "Failed to start camera manager" << std::endl;
> + return TestFail;
> + }
> +
> + cameraAdded_ = false;
> + cameraRemoved_ = false;
> +
> + cm_->cameraAdded.connect(this, &HotplugTest::cameraAddedHandler);
> + cm_->cameraRemoved.connect(this, &HotplugTest::cameraRemovedHandler);
> +
> + return 0;
> + }
> +
> + int run()
> + {
> + DIR *dir;
> + struct dirent *dirent;
> + std::string uvcDeviceDir;
> +
> + dir = opendir(uvcDriverDir_.c_str());
> + /* Find a UVC device directory, which we can bind/unbind. */
> + while ((dirent = readdir(dir)) != nullptr) {
> + if (!File::exists(uvcDriverDir_ + dirent->d_name + "/video4linux"))
> + continue;
> +
> + uvcDeviceDir = dirent->d_name;
> + break;
> + }
> + closedir(dir);
> +
> + /* If no UVC device found, skip the test. */
> + if (uvcDeviceDir.empty())
> + return TestSkip;
> +
> + /* Unbind a camera and process events. */
> + std::ofstream(uvcDriverDir_ + "unbind", std::ios::binary)
> + << uvcDeviceDir;
> + Timer timer;
> + timer.start(1000);
> + while (timer.isRunning() && !cameraRemoved_)
> + Thread::current()->eventDispatcher()->processEvents();
> + if (!cameraRemoved_)
std::cout << "Camera unplug not detected" << std::endl;
> + return TestFail;
> +
> + /* Bind the camera again and process events. */
> + std::ofstream(uvcDriverDir_ + "bind", std::ios::binary)
> + << uvcDeviceDir;
> + timer.start(1000);
> + while (timer.isRunning() && !cameraAdded_)
> + Thread::current()->eventDispatcher()->processEvents();
> + if (!cameraAdded_)
std::cout << "Camera plug not detected" << std::endl;
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> + return TestFail;
> +
> + return TestPass;
> + }
> +
> + void cleanup()
> + {
> + cm_->stop();
> + delete cm_;
> + }
> +
> +private:
> + CameraManager *cm_;
> + static const std::string uvcDriverDir_;
> + bool cameraRemoved_;
> + bool cameraAdded_;
> +};
> +
> +const std::string HotplugTest::uvcDriverDir_ = "/sys/bus/usb/drivers/uvcvideo/";
> +
> +TEST_REGISTER(HotplugTest)
> diff --git a/test/meson.build b/test/meson.build
> index bd7da14..a868813 100644
> --- a/test/meson.build
> +++ b/test/meson.build
> @@ -30,6 +30,7 @@ internal_tests = [
> ['event-thread', 'event-thread.cpp'],
> ['file', 'file.cpp'],
> ['file-descriptor', 'file-descriptor.cpp'],
> + ['hotplug-cameras', 'hotplug-cameras.cpp'],
> ['message', 'message.cpp'],
> ['object', 'object.cpp'],
> ['object-invoke', 'object-invoke.cpp'],
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list