Message ID | 20200611171528.9381-7-email@uajain.com |
---|---|
State | Superseded |
Headers | show |
Series |
|
Related | show |
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@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@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@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'],
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@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_) + 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_) + 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'],
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> --- test/hotplug-cameras.cpp | 124 +++++++++++++++++++++++++++++++++++++++ test/meson.build | 1 + 2 files changed, 125 insertions(+) create mode 100644 test/hotplug-cameras.cpp