diff options
author | Umang Jain <email@uajain.com> | 2020-06-16 19:45:39 +0000 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2020-06-17 00:27:59 +0300 |
commit | 8960ef9715cfb38a3b205d7916662f31df5ddd35 (patch) | |
tree | 13356b31aaf1d3ad172b5d8402f7bdc42c9ac06f /test | |
parent | 7055e96ecc9144390a259e4e23be7fb77ca93364 (diff) |
tests: Introduce hotplug hot-unplug unit test
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@uajain.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'test')
-rw-r--r-- | test/hotplug-cameras.cpp | 128 | ||||
-rw-r--r-- | test/meson.build | 1 |
2 files changed, 129 insertions, 0 deletions
diff --git a/test/hotplug-cameras.cpp b/test/hotplug-cameras.cpp new file mode 100644 index 00000000..6a94535f --- /dev/null +++ b/test/hotplug-cameras.cpp @@ -0,0 +1,128 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2020, Umang Jain <email@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; + 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 bd7da147..a8688131 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'], |