Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement V4L2 compliance parser (New) #1569

Merged
merged 22 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
bdb1ff2
feat: initial impl of v4l2-compliance test parser
tomli380576 Sep 26, 2024
676c3c7
fix: spelling
tomli380576 Sep 26, 2024
4005f47
fix: naming
tomli380576 Oct 2, 2024
e895b72
style: rename
tomli380576 Oct 3, 2024
3142e16
feat: add test name to ioctl map
tomli380576 Oct 29, 2024
08874c3
fix: raise an error if the device can't be opened
tomli380576 Oct 29, 2024
cf4718c
fix: remove main
tomli380576 Oct 31, 2024
c001bcb
test: add unit tests for v4l2 compliance parser
tomli380576 Oct 31, 2024
72beae0
fix: remove assertion in parser because v4l-utils is not a build depe…
tomli380576 Oct 31, 2024
b65b2a6
fix: extra error message check
tomli380576 Nov 14, 2024
59f7015
fix: show bad input in assertions, remove extra line in dict
tomli380576 Dec 4, 2024
d6bc8a5
fix: apply Max's workaround for pkg_resource
tomli380576 Dec 4, 2024
4f82a6b
style: formatting
tomli380576 Dec 4, 2024
c00d6fe
fix: 3.8 doesn't have importlib.resources.files
tomli380576 Dec 4, 2024
bfedca0
fix: remove the color flag as it doesn't exist on 16 & 18
tomli380576 Dec 4, 2024
a684219
fix: device name doesn't always appear in the last line
tomli380576 Dec 4, 2024
75a31df
fix: make regex more flexible
tomli380576 Dec 5, 2024
ee1e523
test: add more test cases from different ubuntu versions
tomli380576 Dec 5, 2024
7ba1f66
fix: spelling
tomli380576 Dec 5, 2024
f747727
fix: apply Max's suggestion
tomli380576 Dec 6, 2024
c9d2a78
fix: simplify the name parsing steps
tomli380576 Dec 6, 2024
1005470
style: formatting
tomli380576 Dec 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import subprocess as sp
from checkbox_support.parsers.v4l2_compliance import parse_v4l2_compliance
import unittest as ut
from unittest.mock import patch, MagicMock

try:
# new in python 3.9
from importlib.resources import files

def read_file_as_str(name: str):
resource_path = "parsers/tests/v4l2_compliance_data/{}.txt".format(
name
)
ref = files("checkbox_support")
file_ref = ref.joinpath(resource_path)
with file_ref.open("r") as f:
return f.read()

except ImportError:
# 3.5 fallback
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("22_04_success")
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(
"22_04_expected_fail_1"
).splitlines()
for ioctl_request in expected_failures:
self.assertIn(ioctl_request.strip(), detail["failed"])
self.assertEqual(len(expected_failures), len(detail["failed"]))

@patch("subprocess.run")
def test_happy_path_24_04(self, mock_run: MagicMock):
ok_input = read_file_as_str("24_04_success")
mock_run.return_value = sp.CompletedProcess(
[], 1, stdout=ok_input, stderr=""
)
summary, detail = parse_v4l2_compliance()
self.assertDictEqual(
{
"device_name": "v4l2 loopback device /dev/video0",
"total": 46,
"succeeded": 41,
"failed": 5,
"warnings": 6,
},
summary,
)
expected_failures = read_file_as_str(
"24_04_expected_fail_1"
).splitlines()
for ioctl_request in expected_failures:
self.assertIn(ioctl_request.strip(), detail["failed"])
self.assertEqual(len(expected_failures), len(detail["failed"]))

@patch("subprocess.run")
def test_happy_path_18_04(self, mock_run: MagicMock):
ok_input = read_file_as_str("18_04_success")
mock_run.return_value = sp.CompletedProcess(
[], 1, stdout=ok_input, stderr=""
)
summary, detail = parse_v4l2_compliance()
self.assertDictEqual(
{
"device_name": "device /dev/video0",
"total": 43,
"succeeded": 38,
"failed": 5,
"warnings": 1,
},
summary,
)
expected_failures = read_file_as_str(
"18_04_expected_fail_1"
).splitlines()
for ioctl_request in expected_failures:
self.assertIn(ioctl_request.strip(), detail["failed"])
self.assertEqual(len(expected_failures), len(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)

@patch("subprocess.run")
def test_unopenable_device(self, mock_run: MagicMock):
err_messages = [
# 16.04 18.04: found this message in VMs
# without camera USB pass through
"Failed to open device /dev/video0: No such file or directory"
# 20.04: found this msg in VMs without camera pass through
# 22.04, 24.04: found this message if we disable camera in BIOS
"Cannot open device /dev/video0, exiting."
]
for err_msg in err_messages:
mock_run.return_value = sp.CompletedProcess(
[], 1, stdout="", stderr=err_msg
)
self.assertRaises(FileNotFoundError, parse_v4l2_compliance)


if __name__ == "__main__":
ut.main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
VIDIOC_QUERY_EXT_CTRL
VIDIOC_QUERYMENU
VIDIOC_S_CTRL
VIDIOC_G_CTRL
VIDIOC_REQBUFS
VIDIOC_CREATE_BUFS
VIDIOC_QUERYBUF
VIDIOC_G_EXT_CTRLS
VIDIOC_S_EXT_CTRLS
VIDIOC_TRY_EXT_CTRLS
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
v4l2-compliance SHA : not available

Driver Info:
Driver name : uvcvideo
Card type : Integrated_Webcam_HD: Integrate
Bus info : usb-0000:02:00.0-7
Driver version: 5.4.233
Capabilities : 0x84A00001
Video Capture
Metadata Capture
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x04200001
Video Capture
Streaming
Extended Pix Format

Compliance test for device /dev/video0 (not using libv4l2):

Required ioctls:
test VIDIOC_QUERYCAP: OK

Allow for multiple opens:
test second video 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)

Test input 0:

Control ioctls:
fail: v4l2-test-controls.cpp(214): missing control class for class 00980000
fail: v4l2-test-controls.cpp(251): missing control class for class 009a0000
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: FAIL
test VIDIOC_QUERYCTRL: OK
fail: v4l2-test-controls.cpp(437): s_ctrl returned an error (84)
test VIDIOC_G/S_CTRL: FAIL
fail: v4l2-test-controls.cpp(675): s_ext_ctrls returned an error (84)
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: 14 Private Controls: 0

Format ioctls:
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(887): Could not set fmt2
test VIDIOC_S_FMT: OK
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
fail: v4l2-test-formats.cpp(1374): doioctl(node, VIDIOC_CROPCAP, &cap) != EINVAL
fail: v4l2-test-formats.cpp(1396): testLegacyCrop(node)
test Cropping: FAIL
test Composing: OK (Not Supported)
test Scaling: OK (Not Supported)

Codec ioctls:
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:
fail: v4l2-test-buffers.cpp(533): check_0(reqbufs.reserved, sizeof(reqbufs.reserved))
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: FAIL
test VIDIOC_EXPBUF: OK

Test input 0:


Total: 43, Succeeded: 38, Failed: 5, Warnings: 1
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
VIDIOC_ENUM_FMT
VIDIOC_ENUM_FRAMESIZES
VIDIOC_ENUM_FRAMEINTERVALS
VIDIOC_G_PARM
VIDIOC_S_PARM
VIDIOC_G_FMT
VIDIOC_REQBUFS
VIDIOC_CREATE_BUFS
VIDIOC_QUERYBUF
Loading
Loading