summaryrefslogtreecommitdiff
path: root/test/media_device
diff options
context:
space:
mode:
authorJacopo Mondi <jacopo@jmondi.org>2018-12-30 00:00:45 +0100
committerJacopo Mondi <jacopo@jmondi.org>2018-12-31 19:01:35 +0100
commitb43f56c46d65cc983936498492a85e7e377c212b (patch)
tree8e7591cb00ab5afee6acfd8658588eda8a2c388a /test/media_device
parent363824662f1246dff09434ae5c1ae63025bc3c22 (diff)
test: Add media device test
Add media device test infrastructure and an intial test that print out the media devices available in the system. Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Diffstat (limited to 'test/media_device')
-rw-r--r--test/media_device/media_device_test.cpp174
-rw-r--r--test/media_device/meson.build5
2 files changed, 179 insertions, 0 deletions
diff --git a/test/media_device/media_device_test.cpp b/test/media_device/media_device_test.cpp
new file mode 100644
index 00000000..c482b2e1
--- /dev/null
+++ b/test/media_device/media_device_test.cpp
@@ -0,0 +1,174 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2018, Google Inc.
+ *
+ * media_device_test.cpp - Tests for the media device class.
+ *
+ * Test library for the media device class.
+ */
+#include <iostream>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "media_device.h"
+
+#include "test.h"
+
+using namespace libcamera;
+using namespace std;
+
+/*
+ * MediaDeviceTest object: runs a sequence of tests on all media
+ * devices found in the system.
+ *
+ * If no accessible media device is found, the test is skipped.
+ */
+class MediaDeviceTest : public Test
+{
+public:
+ MediaDeviceTest() { }
+ ~MediaDeviceTest() { }
+
+protected:
+ int init() { return 0; }
+ int run();
+ void cleanup() { }
+
+private:
+ int testMediaDevice(string devnode);
+
+ void printMediaGraph(const MediaDevice &media, ostream &os);
+ void printLinkFlags(const MediaLink *link, ostream &os);
+ void printNode(const MediaPad *pad, ostream &os);
+};
+
+void MediaDeviceTest::printNode(const MediaPad *pad, ostream &os)
+{
+ const MediaEntity *entity = pad->entity();
+
+ os << "\"" << entity->name() << "\"["
+ << pad->index() << "]";
+}
+
+void MediaDeviceTest::printLinkFlags(const MediaLink *link, ostream &os)
+{
+ unsigned int flags = link->flags();
+
+ os << " [";
+ if (flags) {
+ os << (flags & MEDIA_LNK_FL_ENABLED ? "ENABLED," : "")
+ << (flags & MEDIA_LNK_FL_IMMUTABLE ? "IMMUTABLE" : "");
+ }
+ os << "]\n";
+}
+
+/*
+ * For each entity in the media graph, printout links directed to its sinks
+ * and source pads.
+ */
+void MediaDeviceTest::printMediaGraph(const MediaDevice &media, ostream &os)
+{
+ os << "\n" << media.driver() << " - " << media.devnode() << "\n\n";
+
+ for (auto const &entity : media.entities()) {
+ os << "\"" << entity->name() << "\"\n";
+
+ for (auto const &sink : entity->pads()) {
+ if (!(sink->flags() & MEDIA_PAD_FL_SINK))
+ continue;
+
+ os << " [" << sink->index() << "]" << ": Sink\n";
+ for (auto const &link : sink->links()) {
+ os << "\t";
+ printNode(sink, os);
+ os << " <- ";
+ printNode(link->source(), os);
+ printLinkFlags(link, os);
+ }
+ os << "\n";
+ }
+
+ for (auto const &source : entity->pads()) {
+ if (!(source->flags() & MEDIA_PAD_FL_SOURCE))
+ continue;
+
+ os << " [" << source->index() << "]" << ": Source\n";
+ for (auto const &link : source->links()) {
+ os << "\t";
+ printNode(source, os);
+ os << " -> ";
+ printNode(link->sink(), os);
+ printLinkFlags(link, os);
+ }
+ os << "\n";
+ }
+ }
+
+ os.flush();
+}
+
+/* Test a single media device. */
+int MediaDeviceTest::testMediaDevice(const string devnode)
+{
+ MediaDevice dev(devnode);
+ int ret;
+
+ /* Fuzzy open/close sequence. */
+ ret = dev.open();
+ if (ret)
+ return ret;
+
+ ret = dev.open();
+ if (!ret)
+ return ret;
+
+ dev.close();
+
+ ret = dev.open();
+ if (ret)
+ return ret;
+
+ ret = dev.populate();
+ if (ret)
+ return ret;
+
+ /* Run tests in sequence. */
+ printMediaGraph(dev, cerr);
+ /* TODO: add more tests here. */
+
+ dev.close();
+
+ return 0;
+}
+
+/* Run tests on all media devices. */
+#define MAX_MEDIA_DEV 256
+int MediaDeviceTest::run()
+{
+ const string devnode("/dev/media");
+ unsigned int i;
+ int ret = 77; /* skip test exit code */
+
+ /*
+ * Run the test sequence on all media device found in the
+ * system, if any.
+ */
+ for (i = 0; i < MAX_MEDIA_DEV; i++) {
+ string mediadev = devnode + to_string(i);
+ struct stat pstat = { };
+
+ if (stat(mediadev.c_str(), &pstat))
+ continue;
+
+ ret = testMediaDevice(mediadev);
+ if (ret)
+ return ret;
+
+ }
+
+ return ret;
+}
+
+TEST_REGISTER(MediaDeviceTest);
diff --git a/test/media_device/meson.build b/test/media_device/meson.build
new file mode 100644
index 00000000..b1d21151
--- /dev/null
+++ b/test/media_device/meson.build
@@ -0,0 +1,5 @@
+
+media_device_test = executable('media_device_test', 'media_device_test.cpp',
+ link_with : [libcamera, libtest],
+ include_directories : [libcamera_internal_includes,
+ libtest_includes],)