camera_V4L2: Move unittests pass logic from python to cc
media_v4l2_unittest.cc and camera_V4L2.py both have some logic to decide
that test cases in unittest should pass or not.
Move all logic to media_v4l2_unittest.cc to control it easily.
BUG=b:36662557
TEST=test_that -b ${BOARD} ${IP} camera_V4L2
Change-Id: If1766bdc2c9b82d2ee7f21c41092649d3c43eb92
Reviewed-on: https://chromium-review.googlesource.com/477735
Commit-Ready: Heng-ruey Hsu <henryhsu@google.com>
Tested-by: Heng-ruey Hsu <henryhsu@google.com>
Reviewed-by: Heng-ruey Hsu <henryhsu@google.com>
diff --git a/client/site_tests/camera_V4L2/camera_V4L2.py b/client/site_tests/camera_V4L2/camera_V4L2.py
index a7b66cb..c47f0cc 100644
--- a/client/site_tests/camera_V4L2/camera_V4L2.py
+++ b/client/site_tests/camera_V4L2/camera_V4L2.py
@@ -69,75 +69,12 @@
if not self.v4l2_devices:
raise error.TestFail("No V4L2 devices found!")
- def unittest_passed(self, testname, stdout):
- return re.search(r"OK \] V4L2DeviceTest\." + testname, stdout)
-
def run_v4l2_unittests(self, device):
self.executable = os.path.join(self.bindir, "media_v4l2_unittest")
cmd = "%s --device=%s" % (self.executable, device)
logging.info("Running %s" % cmd)
stdout = utils.system_output(cmd, retain_output=True)
- # Check the result of unittests.
- # We had exercise all the optional ioctls in unittest which maybe
- # optional by V4L2 Specification. Therefore we need to check those
- # tests that we thought are mandatory.
- # 1. Multiple open should be supported for panel application.
- if not self.unittest_passed("MultipleOpen", stdout):
- raise error.TestError(device + " does not support multiple open!")
-
- # 2. Need to make sure this is really support or just driver error.
- if not self.unittest_passed("MultipleInit", stdout):
- raise error.TestError(device + " does support multiple init!")
-
- # 3. EnumInput and EnumStandard is optional.
-
- # 4. EnumControl is mandatory.
- if not self.unittest_passed("EnumControl", stdout):
- raise error.TestError(device + " does support enum controls!")
- pattern = re.compile(r"Control (\w+) is enabled\((\d+)-(\d+):(\d+)\)")
- control_info = pattern.findall(stdout)
- self.supported_controls = [x[0] for x in control_info]
- logging.info("Supported Controls: %s\n" % self.supported_controls)
-
- # TODO(jiesun): what is required?
- mandatory_controls = [
- "Brightness",
- "Contrast",
- "Saturation",
- "Hue",
- "Gamma"]
- for control in mandatory_controls:
- if self.assert_mandatory_controls and \
- control not in self.supported_controls:
- raise error.TestError(device + " does not support " + control)
-
- # 5. SetControl is mandatory.
- if not self.unittest_passed("SetControl", stdout):
- raise error.TestError(device + " does not support set controls!")
-
- # 6. 7. Set/GetCrop are both optional.
-
- # 8. ProbeCaps is mandatory.
- if not self.unittest_passed("ProbeCaps", stdout):
- raise error.TestError(device + " does not support probe caps!")
-
- if not re.search(r"support video capture interface.>>>", stdout):
- raise error.TestFail(device + " does not support video capture!")
-
- # 9. EnumFormats is always mandatory.
- if not self.unittest_passed("EnumFormats", stdout):
- raise error.TestError(device + " does not support enum formats!")
-
- pattern = re.compile(r"supported format #\d+: .* \((....)\)")
- format_info = pattern.findall(stdout)
- # Remove duplicated pixel formats from list.
- self.supported_formats = list(set(format_info))
- logging.info("Supported pixel format: %s\n", self.supported_formats)
-
- # 10. Get/SetParam for framerate is optional.
- # 11. EnumFrameSize is optional.
-
def run_v4l2_capture_test(self, device):
options = ["--device=%s" % device]
options += ["--usb-info=%s" % self.usb_info]
diff --git a/client/site_tests/camera_V4L2/src/media_v4l2_unittest.cc b/client/site_tests/camera_V4L2/src/media_v4l2_unittest.cc
index cfbdff3..be95473 100644
--- a/client/site_tests/camera_V4L2/src/media_v4l2_unittest.cc
+++ b/client/site_tests/camera_V4L2/src/media_v4l2_unittest.cc
@@ -8,7 +8,7 @@
#include "media_v4l2_device.h"
-void ExerciseControl(V4L2Device* v4l2_dev, uint32_t id, const char* control) {
+bool ExerciseControl(V4L2Device* v4l2_dev, uint32_t id, const char* control) {
v4l2_queryctrl query_ctrl;
if (v4l2_dev->QueryControl(id, &query_ctrl)) {
if (!v4l2_dev->SetControl(id, query_ctrl.maximum))
@@ -19,7 +19,9 @@
printf("[Warning] Can not set %s to default value\n", control);
} else {
printf("[Warning] Can not query control name :%s\n", control);
+ return false;
}
+ return true;
}
void TestMultipleOpen(const char* dev_name) {
@@ -27,6 +29,7 @@
V4L2Device v4l2_dev2(dev_name, 4);
if (!v4l2_dev1.OpenDevice()) {
printf("[Error] Can not open device '%s' for the first time\n", dev_name);
+ exit(EXIT_FAILURE);
}
if (!v4l2_dev2.OpenDevice()) {
printf("[Error] Can not open device '%s' for the second time\n", dev_name);
@@ -42,13 +45,16 @@
V4L2Device v4l2_dev2(dev_name, 4);
if (!v4l2_dev1.OpenDevice()) {
printf("[Error] Can not open device '%s' for the first time\n", dev_name);
+ exit(EXIT_FAILURE);
}
if (!v4l2_dev2.OpenDevice()) {
printf("[Error] Can not open device '%s' for the second time\n", dev_name);
+ exit(EXIT_FAILURE);
}
if (!v4l2_dev1.InitDevice(io, 640, 480, V4L2_PIX_FMT_YUYV, 30)) {
printf("[Error] Can not init device '%s' for the first time\n", dev_name);
+ exit(EXIT_FAILURE);
}
// multiple streaming request should fail.
@@ -64,10 +70,12 @@
printf("[OK ] V4L2DeviceTest.MultipleInit\n");
}
+// EnumInput and EnumStandard are optional.
void TestEnumInputAndStandard(const char* dev_name) {
V4L2Device v4l2_dev1(dev_name, 4);
if (!v4l2_dev1.OpenDevice()) {
printf("[Error] Can not open device '%s'\n", dev_name);
+ exit(EXIT_FAILURE);
}
v4l2_dev1.EnumInput();
v4l2_dev1.EnumStandard();
@@ -79,6 +87,7 @@
V4L2Device v4l2_dev(dev_name, 4);
if (!v4l2_dev.OpenDevice()) {
printf("[Error] Can not open device '%s'\n", dev_name);
+ exit(EXIT_FAILURE);
}
v4l2_dev.EnumControl();
v4l2_dev.CloseDevice();
@@ -89,22 +98,33 @@
V4L2Device v4l2_dev(dev_name, 4);
if (!v4l2_dev.OpenDevice()) {
printf("[Error] Can not open device '%s'\n", dev_name);
+ exit(EXIT_FAILURE);
}
- ExerciseControl(&v4l2_dev, V4L2_CID_BRIGHTNESS, "brightness");
- ExerciseControl(&v4l2_dev, V4L2_CID_CONTRAST, "contrast");
- ExerciseControl(&v4l2_dev, V4L2_CID_SATURATION, "saturation");
- ExerciseControl(&v4l2_dev, V4L2_CID_GAMMA, "gamma");
- ExerciseControl(&v4l2_dev, V4L2_CID_HUE, "hue");
+ // Test mandatory controls.
+ if (!ExerciseControl(&v4l2_dev, V4L2_CID_BRIGHTNESS, "brightness"))
+ exit(EXIT_FAILURE);
+ if (!ExerciseControl(&v4l2_dev, V4L2_CID_CONTRAST, "contrast"))
+ exit(EXIT_FAILURE);
+ if (!ExerciseControl(&v4l2_dev, V4L2_CID_SATURATION, "saturation"))
+ exit(EXIT_FAILURE);
+ if (!ExerciseControl(&v4l2_dev, V4L2_CID_GAMMA, "gamma"))
+ exit(EXIT_FAILURE);
+ if (!ExerciseControl(&v4l2_dev, V4L2_CID_HUE, "hue"))
+ exit(EXIT_FAILURE);
+
+ // Test optional controls.
ExerciseControl(&v4l2_dev, V4L2_CID_GAIN, "gain");
ExerciseControl(&v4l2_dev, V4L2_CID_SHARPNESS, "sharpness");
v4l2_dev.CloseDevice();
printf("[OK ] V4L2DeviceTest.SetControl\n");
}
+// SetCrop is optional.
void TestSetCrop(const char* dev_name) {
V4L2Device v4l2_dev(dev_name, 4);
if (!v4l2_dev.OpenDevice()) {
printf("[Error] Can not open device '%s'\n", dev_name);
+ exit(EXIT_FAILURE);
}
v4l2_cropcap cropcap;
memset(&cropcap, 0, sizeof(cropcap));
@@ -119,10 +139,12 @@
printf("[OK ] V4L2DeviceTest.SetCrop\n");
}
+// GetCrop is optional.
void TestGetCrop(const char* dev_name) {
V4L2Device v4l2_dev(dev_name, 4);
if (!v4l2_dev.OpenDevice()) {
printf("[Error] Can not open device '%s'\n", dev_name);
+ exit(EXIT_FAILURE);
}
v4l2_crop crop;
memset(&crop, 0, sizeof(crop));
@@ -136,10 +158,17 @@
V4L2Device v4l2_dev(dev_name, 4);
if (!v4l2_dev.OpenDevice()) {
printf("[Error] Can not open device '%s'\n", dev_name);
+ exit(EXIT_FAILURE);
}
v4l2_capability caps;
if (!v4l2_dev.ProbeCaps(&caps, true)) {
printf("[Error] Can not probe caps on device '%s'\n", dev_name);
+ exit(EXIT_FAILURE);
+ }
+ if (!(caps.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
+ printf("<<< Info: %s does not support video capture interface.>>>\n",
+ dev_name);
+ exit(EXIT_FAILURE);
}
v4l2_dev.CloseDevice();
printf("[OK ] V4L2DeviceTest.ProbeCaps\n");
@@ -149,8 +178,12 @@
V4L2Device v4l2_dev(dev_name, 4);
if (!v4l2_dev.OpenDevice()) {
printf("[Error] Can not open device '%s'\n", dev_name);
+ exit(EXIT_FAILURE);
}
- v4l2_dev.EnumFormat(NULL);
+ if (!v4l2_dev.EnumFormat(NULL)) {
+ printf("[Error] Can not enumerate format on device '%s'\n", dev_name);
+ exit(EXIT_FAILURE);
+ }
v4l2_dev.CloseDevice();
printf("[OK ] V4L2DeviceTest.EnumFormats\n");
}
@@ -159,9 +192,13 @@
V4L2Device v4l2_dev(dev_name, 4);
if (!v4l2_dev.OpenDevice()) {
printf("[Error] Can not open device '%s'\n", dev_name);
+ exit(EXIT_FAILURE);
}
uint32_t format_count = 0;
- v4l2_dev.EnumFormat(&format_count);
+ if (!v4l2_dev.EnumFormat(&format_count)) {
+ printf("[Error] Can not enumerate format on device '%s'\n", dev_name);
+ exit(EXIT_FAILURE);
+ }
for (uint32_t i = 0; i < format_count; ++i) {
uint32_t pixfmt;
if (!v4l2_dev.GetPixelFormat(i, &pixfmt)) {
@@ -170,6 +207,7 @@
}
if (!v4l2_dev.EnumFrameSize(pixfmt, NULL)) {
printf("[Warning] Enumerate frame size error on device '%s'\n", dev_name);
+ exit(EXIT_FAILURE);
};
}
v4l2_dev.CloseDevice();
@@ -183,7 +221,10 @@
exit(EXIT_FAILURE);
}
uint32_t format_count = 0;
- v4l2_dev.EnumFormat(&format_count);
+ if (!v4l2_dev.EnumFormat(&format_count)) {
+ printf("[Error] Can not enumerate format on device '%s'\n", dev_name);
+ exit(EXIT_FAILURE);
+ }
for (uint32_t i = 0; i < format_count; ++i) {
uint32_t pixfmt;
if (!v4l2_dev.GetPixelFormat(i, &pixfmt)) {
@@ -217,6 +258,7 @@
V4L2Device v4l2_dev(dev_name, 4);
if (!v4l2_dev.OpenDevice()) {
printf("[Error] Can not open device '%s'\n", dev_name);
+ exit(EXIT_FAILURE);
}
v4l2_streamparm param;
if (!v4l2_dev.GetParam(¶m)) {
@@ -229,6 +271,8 @@
printf("[Error] Can not set stream param on device '%s'\n", dev_name);
exit(EXIT_FAILURE);
}
+ } else {
+ printf("[Info] %s does not support TIMEPERFRAME.\n", dev_name);
}
v4l2_dev.CloseDevice();
@@ -238,22 +282,18 @@
static void PrintUsage() {
printf("Usage: media_v4l2_unittest [options]\n\n"
"Options:\n"
- "--device=DEVICE_NAME Video device name [/dev/video]\n"
"--help Print usage\n"
- "--buffer-io=mmap Use memory mapped buffers\n"
- "--buffer-io=userp Use application allocated buffers\n");
+ "--device=DEVICE_NAME Video device name [/dev/video]\n");
}
-static const char short_options[] = "d:?b";
+static const char short_options[] = "?d:";
static const struct option long_options[] = {
- { "device", required_argument, NULL, 'd' },
- { "help", no_argument, NULL, '?' },
- { "buffer-io", required_argument, NULL, 'b' },
+ { "help", no_argument, NULL, '?' },
+ { "device", required_argument, NULL, 'd' },
};
int main(int argc, char** argv) {
- std::string dev_name = "/dev/video", io_name;
- V4L2Device::IOMethod io = V4L2Device::IO_METHOD_MMAP;
+ std::string dev_name = "/dev/video";
// Parse the command line.
for (;;) {
@@ -264,23 +304,12 @@
switch (c) {
case 0: // getopt_long() flag.
break;
- case 'd':
- // Initialize default v4l2 device name.
- dev_name = strdup(optarg);
- break;
case '?':
PrintUsage();
exit (EXIT_SUCCESS);
- case 'b':
- io_name = strdup(optarg);
- if (io_name == "mmap") {
- io = V4L2Device::IO_METHOD_MMAP;
- } else if (io_name == "userp") {
- io = V4L2Device::IO_METHOD_USERPTR;
- } else {
- PrintUsage();
- exit(EXIT_FAILURE);
- }
+ case 'd':
+ // Initialize default v4l2 device name.
+ dev_name = strdup(optarg);
break;
default:
PrintUsage();
@@ -289,7 +318,8 @@
}
TestMultipleOpen(dev_name.c_str());
- TestMultipleInit(dev_name.c_str(), io);
+ TestMultipleInit(dev_name.c_str(), V4L2Device::IO_METHOD_MMAP);
+ TestMultipleInit(dev_name.c_str(), V4L2Device::IO_METHOD_USERPTR);
TestEnumInputAndStandard(dev_name.c_str());
TestEnumControl(dev_name.c_str());
TestSetControl(dev_name.c_str());