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

Open
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

tomli380576
Copy link
Contributor

@tomli380576 tomli380576 commented Oct 31, 2024

Description

This PR implements a V4L2 compliance test parser in checkbox support for test cases to validate that the ioctl requests they need to use are actually supported.

Requires #1566

Resolved issues

Documentation

Test cases can from checkbox_support.parsers.v4l2_compliance import parse_v4l2_compliance and call the function for a device, such as parse_v4l2_compliance('/dev/video0')

Tests

Unit tests

Copy link

codecov bot commented Oct 31, 2024

Codecov Report

Attention: Patch coverage is 86.36364% with 6 lines in your changes missing coverage. Please review.

Project coverage is 48.04%. Comparing base (7b5dd02) to head (a684219).
Report is 48 commits behind head on main.

Files with missing lines Patch % Lines
...upport/checkbox_support/parsers/v4l2_compliance.py 86.36% 5 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1569      +/-   ##
==========================================
+ Coverage   48.00%   48.04%   +0.04%     
==========================================
  Files         371      371              
  Lines       39833    39877      +44     
  Branches     6730     6739       +9     
==========================================
+ Hits        19121    19159      +38     
- Misses      19994    20000       +6     
  Partials      718      718              
Flag Coverage Δ
checkbox-support 60.93% <86.36%> (+0.21%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@tomli380576 tomli380576 marked this pull request as ready for review November 14, 2024 06:00
@fernando79513 fernando79513 self-assigned this Nov 18, 2024
@pieqq pieqq assigned Hook25 and unassigned fernando79513 Nov 29, 2024
Copy link
Collaborator

@Hook25 Hook25 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job here, sorry it took me a while to review it. Consider my comments below, the only one that is blocking is the one about pkg_resource, because soon it will go away, and when it does I will have to patch half of checkbox to add the workaroud I suggested.

Comment on lines +146 to +150
lines = [] # type: list[str]
for line in out.stdout.splitlines():
clean_line = line.strip()
if clean_line != "":
lines.append(clean_line)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
lines = [] # type: list[str]
for line in out.stdout.splitlines():
clean_line = line.strip()
if clean_line != "":
lines.append(clean_line)
lines = [line.strip() for line in out.stdout.splitlines() if line.strip()]

Comment on lines 157 to 170
summary = {}
if match_output:
summary = {
"device_name": match_output.group(1),
"total": int(match_output.group(2)),
"succeeded": int(match_output.group(3)),
"failed": int(match_output.group(4)),
"warnings": int(match_output.group(5)),
}

assert summary != {}, (
"There's no summary line in v4l2-compliance's output. "
"Output might be corrupted."
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, never hide the output if you can, especially when it fails an expectation

Suggested change
summary = {}
if match_output:
summary = {
"device_name": match_output.group(1),
"total": int(match_output.group(2)),
"succeeded": int(match_output.group(3)),
"failed": int(match_output.group(4)),
"warnings": int(match_output.group(5)),
}
assert summary != {}, (
"There's no summary line in v4l2-compliance's output. "
"Output might be corrupted."
)
if not match_output:
raise SystemExit(
"There's no summary line in v4l2-compliance's output. "
"Output might be corrupted. Last line is: \n {}".format(lines[-1])
)
summary = {
"device_name": match_output.group(1),
"total": int(match_output.group(2)),
"succeeded": int(match_output.group(3)),
"failed": int(match_output.group(4)),
"warnings": int(match_output.group(5)),
}

Comment on lines 178 to 194
for line in lines:
if line.endswith(": OK"):
name, is_ioctl_name = get_test_name_from_line(line)
if is_ioctl_name:
# ignore unknown test names, just don't append
for ioctl_name in TEST_NAME_TO_IOCTL_MAP.get(name, []):
details["succeeded"].append(ioctl_name)
elif line.endswith(": OK (Not Supported)"):
name, is_ioctl_name = get_test_name_from_line(line)
if is_ioctl_name:
for ioctl_name in TEST_NAME_TO_IOCTL_MAP.get(name, []):
details["not_supported"].append(ioctl_name)
elif line.endswith(": FAIL"):
name, is_ioctl_name = get_test_name_from_line(line)
if is_ioctl_name:
for ioctl_name in TEST_NAME_TO_IOCTL_MAP.get(name, []):
details["failed"].append(ioctl_name)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

slightly easier to read imo

Suggested change
for line in lines:
if line.endswith(": OK"):
name, is_ioctl_name = get_test_name_from_line(line)
if is_ioctl_name:
# ignore unknown test names, just don't append
for ioctl_name in TEST_NAME_TO_IOCTL_MAP.get(name, []):
details["succeeded"].append(ioctl_name)
elif line.endswith(": OK (Not Supported)"):
name, is_ioctl_name = get_test_name_from_line(line)
if is_ioctl_name:
for ioctl_name in TEST_NAME_TO_IOCTL_MAP.get(name, []):
details["not_supported"].append(ioctl_name)
elif line.endswith(": FAIL"):
name, is_ioctl_name = get_test_name_from_line(line)
if is_ioctl_name:
for ioctl_name in TEST_NAME_TO_IOCTL_MAP.get(name, []):
details["failed"].append(ioctl_name)
for line in lines:
if line.endswith(": OK"):
result = "succeeded"
elif line.endswith(": OK (Not Supported)"):
result = "not_supported"
elif line.endswith(": FAIL"):
result = "failed"
else:
continue
name, is_ioctl_name = get_test_name_from_line(line)
if is_ioctl_name:
# ignore unknown test names, just don't append
for ioctl_name in TEST_NAME_TO_IOCTL_MAP.get(name, []):
details[result].append(ioctl_name)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohh that's a lot cleaner ty

Comment on lines 5 to 12
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()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this point pkg_resources is very deprecated, lets avoid it if possible

Suggested change
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()
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 = resources.files("checkbox_support")
file_ref = ref.joinpath(resource_path)
with file_ref.open('r') as f:
return f.read()
except ImportError:
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()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see, I used pkg_resource because I saw another parser test using that to get the test input files. (Also does this mean we are moving towards python 3.9? :D)

],
"VIDIOC_G/S_AUDIO": ["VIDIOC_G_AUDIO", "VIDIOC_S_AUDIO"],
"VIDIOC_G/S_MODULATOR": ["VIDIOC_G_MODULATOR", "VIDIOC_S_MODULATOR"],
"VIDIOC_G/S_FREQUENCY": ["VIDIOC_G_FREQUENCY", "VIDIOC_S_FREQUENCY"],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this one is duplicated

Suggested change
"VIDIOC_G/S_FREQUENCY": ["VIDIOC_G_FREQUENCY", "VIDIOC_S_FREQUENCY"],

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the catch!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants