From da66a9dba5ea5b8007d999b8a00dd197e8c36e63 Mon Sep 17 00:00:00 2001 From: Zhongning Li <60045212+tomli380576@users.noreply.github.com> Date: Thu, 31 Oct 2024 12:22:39 +0100 Subject: [PATCH] test: add unit tests for v4l2 compliance parser --- .../parsers/tests/test_v4l2_compliance.py | 49 ++++++++ .../v4l2_compliance_data/clean_input_1.txt | 112 ++++++++++++++++++ .../output_failed_ioctls_1.txt | 8 ++ .../parsers/v4l2_compliance.py | 7 +- 4 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 checkbox-support/checkbox_support/parsers/tests/test_v4l2_compliance.py create mode 100644 checkbox-support/checkbox_support/parsers/tests/v4l2_compliance_data/clean_input_1.txt create mode 100644 checkbox-support/checkbox_support/parsers/tests/v4l2_compliance_data/output_failed_ioctls_1.txt diff --git a/checkbox-support/checkbox_support/parsers/tests/test_v4l2_compliance.py b/checkbox-support/checkbox_support/parsers/tests/test_v4l2_compliance.py new file mode 100644 index 000000000..6c1788482 --- /dev/null +++ b/checkbox-support/checkbox_support/parsers/tests/test_v4l2_compliance.py @@ -0,0 +1,49 @@ +import subprocess as sp +from checkbox_support.parsers.v4l2_compliance import parse_v4l2_compliance +import unittest as ut +from unittest.mock import patch, MagicMock +from pkg_resources import resource_filename + + +def read_file_as_str(name: str): + resource = "parsers/tests/v4l2_compliance_data/{}.txt".format(name) + filename = resource_filename("checkbox_support", resource) + with open(filename) as f: + return f.read() + + +class TestV4L2ComplianceParser(ut.TestCase): + + @patch("subprocess.run") + def test_happy_path(self, mock_run: MagicMock): + ok_input = read_file_as_str("clean_input_1") + mock_run.return_value = sp.CompletedProcess( + [], 1, stdout=ok_input, stderr="" + ) + summary, detail = parse_v4l2_compliance() + self.assertDictEqual( + { + "device_name": "uvcvideo device /dev/video0", + "total": 46, + "succeeded": 43, + "failed": 3, + "warnings": 1, + }, + summary, + ) + expected_failures = read_file_as_str("output_failed_ioctls_1") + for ioctl_request in expected_failures.splitlines(): + self.assertIn(ioctl_request.strip(), detail["failed"]) + + @patch("subprocess.run") + def test_unparsable(self, mock_run: MagicMock): + bad_input = "askdjhasjkdhlakbbeqmnwbeqmvykudsuchab,b1231" + mock_run.return_value = sp.CompletedProcess( + [], 1, stdout=bad_input, stderr="" + ) + + self.assertRaises(AssertionError, parse_v4l2_compliance) + + +if __name__ == "__main__": + ut.main() diff --git a/checkbox-support/checkbox_support/parsers/tests/v4l2_compliance_data/clean_input_1.txt b/checkbox-support/checkbox_support/parsers/tests/v4l2_compliance_data/clean_input_1.txt new file mode 100644 index 000000000..ad683e7d8 --- /dev/null +++ b/checkbox-support/checkbox_support/parsers/tests/v4l2_compliance_data/clean_input_1.txt @@ -0,0 +1,112 @@ +v4l2-compliance 1.22.1, 64 bits, 64-bit time_t + +Compliance test for uvcvideo device /dev/video0: + +Driver Info: + Driver name : uvcvideo + Card type : Integrated_Webcam_HD: Integrate + Bus info : usb-0000:00:14.0-9 + Driver version : 6.8.12 + Capabilities : 0x84a00001 + Video Capture + Metadata Capture + Streaming + Extended Pix Format + Device Capabilities + Device Caps : 0x04200001 + Video Capture + Streaming + Extended Pix Format +Media Driver Info: + Driver name : uvcvideo + Model : Integrated_Webcam_HD: Integrate + Serial : 200901010001 + Bus info : usb-0000:00:14.0-9 + Media version : 6.8.12 + Hardware revision: 0x00009628 (38440) + Driver version : 6.8.12 +Interface Info: + ID : 0x03000002 + Type : V4L Video +Entity Info: + ID : 0x00000001 (1) + Name : Integrated_Webcam_HD: Integrate + Function : V4L2 I/O + Flags : default + Pad 0x01000007 : 0: Sink + Link 0x02000013: from remote pad 0x100000a of entity 'Extension 4' (Video Pixel Formatter): Data, Enabled, Immutable + +Required ioctls: + test MC information (see 'Media Driver Info' above): OK + test VIDIOC_QUERYCAP: OK + test invalid ioctls: OK + +Allow for multiple opens: + test second /dev/video0 open: OK + test VIDIOC_QUERYCAP: OK + test VIDIOC_G/S_PRIORITY: OK + test for unlimited opens: OK + +Debug ioctls: + test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported) + test VIDIOC_LOG_STATUS: OK (Not Supported) + +Input ioctls: + test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported) + test VIDIOC_G/S_FREQUENCY: OK (Not Supported) + test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported) + test VIDIOC_ENUMAUDIO: OK (Not Supported) + test VIDIOC_G/S/ENUMINPUT: OK + test VIDIOC_G/S_AUDIO: OK (Not Supported) + Inputs: 1 Audio Inputs: 0 Tuners: 0 + +Output ioctls: + test VIDIOC_G/S_MODULATOR: OK (Not Supported) + test VIDIOC_G/S_FREQUENCY: OK (Not Supported) + test VIDIOC_ENUMAUDOUT: OK (Not Supported) + test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported) + test VIDIOC_G/S_AUDOUT: OK (Not Supported) + Outputs: 0 Audio Outputs: 0 Modulators: 0 + +Input/Output configuration ioctls: + test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported) + test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported) + test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported) + test VIDIOC_G/S_EDID: OK (Not Supported) + +Control ioctls (Input 0): + test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK + test VIDIOC_QUERYCTRL: OK + fail: v4l2-test-controls.cpp(489): s_ctrl returned an error (13) + test VIDIOC_G/S_CTRL: FAIL + fail: v4l2-test-controls.cpp(736): s_ext_ctrls returned an error (13) + test VIDIOC_G/S/TRY_EXT_CTRLS: FAIL + test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK + test VIDIOC_G/S_JPEGCOMP: OK (Not Supported) + Standard Controls: 16 Private Controls: 0 + +Format ioctls (Input 0): + test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK + test VIDIOC_G/S_PARM: OK + test VIDIOC_G_FBUF: OK (Not Supported) + test VIDIOC_G_FMT: OK + test VIDIOC_TRY_FMT: OK + warn: v4l2-test-formats.cpp(1036): Could not set fmt2 + test VIDIOC_S_FMT: OK + test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported) + test Cropping: OK (Not Supported) + test Composing: OK (Not Supported) + test Scaling: OK (Not Supported) + +Codec ioctls (Input 0): + test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported) + test VIDIOC_G_ENC_INDEX: OK (Not Supported) + test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported) + +Buffer ioctls (Input 0): + fail: v4l2-test-buffers.cpp(703): check_0(crbufs.reserved, sizeof(crbufs.reserved)) + test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: FAIL + test VIDIOC_EXPBUF: OK + test Requests: OK (Not Supported) + +Total for uvcvideo device /dev/video0: 46, Succeeded: 43, Failed: 3, Warnings: 1 \ No newline at end of file diff --git a/checkbox-support/checkbox_support/parsers/tests/v4l2_compliance_data/output_failed_ioctls_1.txt b/checkbox-support/checkbox_support/parsers/tests/v4l2_compliance_data/output_failed_ioctls_1.txt new file mode 100644 index 000000000..e5b485eeb --- /dev/null +++ b/checkbox-support/checkbox_support/parsers/tests/v4l2_compliance_data/output_failed_ioctls_1.txt @@ -0,0 +1,8 @@ +VIDIOC_REQBUFS +VIDIOC_CREATE_BUFS +VIDIOC_QUERYBUF +VIDIOC_G_EXT_CTRLS +VIDIOC_S_EXT_CTRLS +VIDIOC_TRY_EXT_CTRLS +VIDIOC_G_CTRL +VIDIOC_S_CTRL \ No newline at end of file diff --git a/checkbox-support/checkbox_support/parsers/v4l2_compliance.py b/checkbox-support/checkbox_support/parsers/v4l2_compliance.py index d5bbd3e1e..6ecce217c 100755 --- a/checkbox-support/checkbox_support/parsers/v4l2_compliance.py +++ b/checkbox-support/checkbox_support/parsers/v4l2_compliance.py @@ -164,6 +164,11 @@ def parse_v4l2_compliance( "warnings": int(match_output.group(5)), } + assert summary != {}, ( + "There's no summary line in v4l2-compliance's output. " + "Output might be corrupted." + ) + details = { "succeeded": [], "failed": [], @@ -188,4 +193,4 @@ def parse_v4l2_compliance( for ioctl_name in TEST_NAME_TO_IOCTL_MAP.get(name, []): details["failed"].append(ioctl_name) - return summary, details \ No newline at end of file + return summary, details