summaryrefslogtreecommitdiff
path: root/test/v4l2_compat/v4l2_compat_test.py
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2022-12-22 01:04:07 +0200
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2022-12-24 03:29:43 +0200
commit121b5de3295636e618296a018ac0baf1b0732bda (patch)
tree42bc4533a4c0828800295c09fe3e0223f4d782db /test/v4l2_compat/v4l2_compat_test.py
parent9f06cd50cce95ffb5bdcf57b5a162a400212d2c0 (diff)
test: v4l2_compat: Enable test with ASan
When libcamera is compiled with the address sanitizer enabled, the v4l2_compat test generates failures in the link order runtime check, as the host v4l2-ctl and v4l2-compliance tools are not (generally) linked to ASan. For this reason, the test is disabled, which sadly shrinks test coverage. Fix this by loading the ASan runtime using LD_PRELOAD. This needs to be done from within the v4l2_compat_test.py Python script, as the Python interpreter itself leaks memory and would cause test failures if run with ASan. To LD_PRELOAD the ASan runtime, the path to the binary needs to be known. gcc gives us a generic way to get the path, but that doesn't work with clang as the ASan runtime file name depends on the clang version and target architecture. We thus have to keep the v4l2_compat test disabled when ASan is enabled and libcamera is compiled with clang. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Diffstat (limited to 'test/v4l2_compat/v4l2_compat_test.py')
-rwxr-xr-xtest/v4l2_compat/v4l2_compat_test.py18
1 files changed, 13 insertions, 5 deletions
diff --git a/test/v4l2_compat/v4l2_compat_test.py b/test/v4l2_compat/v4l2_compat_test.py
index a77585fc..bd89d496 100755
--- a/test/v4l2_compat/v4l2_compat_test.py
+++ b/test/v4l2_compat/v4l2_compat_test.py
@@ -57,8 +57,8 @@ def extract_result(result):
return ret
-def test_v4l2_compliance(v4l2_compliance, v4l2_compat, device, base_driver):
- ret, output = run_with_stdout(v4l2_compliance, '-s', '-d', device, env={'LD_PRELOAD': v4l2_compat})
+def test_v4l2_compliance(v4l2_compliance, ld_preload, device, base_driver):
+ ret, output = run_with_stdout(v4l2_compliance, '-s', '-d', device, env={'LD_PRELOAD': ld_preload})
if ret < 0:
output.append(f'Test for {device} terminated due to signal {signal.Signals(-ret).name}')
return TestFail, output
@@ -82,13 +82,21 @@ def main(argv):
parser = argparse.ArgumentParser()
parser.add_argument('-a', '--all', action='store_true',
help='Test all available cameras')
+ parser.add_argument('-s', '--sanitizer', type=str,
+ help='Path to the address sanitizer (ASan) runtime')
parser.add_argument('-v', '--verbose', action='store_true',
help='Make the output verbose')
parser.add_argument('v4l2_compat', type=str,
help='Path to v4l2-compat.so')
args = parser.parse_args(argv[1:])
- v4l2_compat = args.v4l2_compat
+ # Compute the LD_PRELOAD value by first loading ASan (if specified) and
+ # then the V4L2 compat layer.
+ ld_preload = []
+ if args.sanitizer:
+ ld_preload.append(args.sanitizer)
+ ld_preload.append(args.v4l2_compat)
+ ld_preload = ':'.join(ld_preload)
v4l2_compliance = shutil.which('v4l2-compliance')
if v4l2_compliance is None:
@@ -118,7 +126,7 @@ def main(argv):
failed = []
drivers_tested = {}
for device in dev_nodes:
- ret, out = run_with_stdout(v4l2_ctl, '-D', '-d', device, env={'LD_PRELOAD': v4l2_compat})
+ ret, out = run_with_stdout(v4l2_ctl, '-D', '-d', device, env={'LD_PRELOAD': ld_preload})
if ret < 0:
failed.append(device)
print(f'v4l2-ctl failed on {device} with v4l2-compat')
@@ -144,7 +152,7 @@ def main(argv):
continue
print(f'Testing {device} with {driver} driver... ', end='')
- ret, msg = test_v4l2_compliance(v4l2_compliance, v4l2_compat, device, driver)
+ ret, msg = test_v4l2_compliance(v4l2_compliance, ld_preload, device, driver)
if ret == TestFail:
failed.append(device)
print('failed')