[{"id":10996,"web_url":"https://patchwork.libcamera.org/comment/10996/","msgid":"<20200629231424.GF21452@pendragon.ideasonboard.com>","date":"2020-06-29T23:14:24","subject":"Re: [libcamera-devel] [PATCH v3] tests: v4l2_compat: Add test for\n\tv4l2_compat","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Paul,\n\nThank you for the patch.\n\nOn Tue, Jun 30, 2020 at 12:15:29AM +0900, Paul Elder wrote:\n> Test the V4L2 compatibility layer by running v4l2-compliance -s on every\n> /dev/video* device.\n> \n> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>\n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> \n> ---\n> Changes in v3:\n> - use argparse\n> - add argument to test all cameras, and test only one camera per driver\n>   by default\n> - print the devices that we're testing and if each succeeded or failed\n> \n> Note that as of v2, the tests will fail if the tester has a camera\n> supported by libcamera that has unsupported formats, since they will\n> cause a floating point exception. So I don't think this should be merged\n> until that is fixed, otherwise we might get nasty test failures in\n> bisection.\n\nIs this fixed by the PixelFormatInfo series you've just sent, or are we\nstill missing something ?\n\n> Changes in v2:\n> - change all strings to single-quote\n> - simplify meson.build\n> - get path to v4l2-compat.so from cli arg, rather than running custom find()\n>   - remove find_file()\n> - extend test timeout to 60 seconds (from default of 30)\n> - don't run v4l2-compliance subprocesses in shell\n> - check if v4l2-compliance runs are killed by signal (eg. the known\n>   SIGABRT due to floating point exception)\n> - move the check to see if libcamera supports the camera to v4l2-ctl\n>   instead of v4l2-compliance (in v1 we only checked if the pipeline was\n>   supported with v4l2-ctl)\n> ---\n>  test/meson.build                     |   1 +\n>  test/v4l2_compat/meson.build         |  10 ++\n>  test/v4l2_compat/v4l2_compat_test.py | 143 +++++++++++++++++++++++++++\n>  3 files changed, 154 insertions(+)\n>  create mode 100644 test/v4l2_compat/meson.build\n>  create mode 100755 test/v4l2_compat/v4l2_compat_test.py\n> \n> diff --git a/test/meson.build b/test/meson.build\n> index 7808a26..f41d6e7 100644\n> --- a/test/meson.build\n> +++ b/test/meson.build\n> @@ -12,6 +12,7 @@ subdir('pipeline')\n>  subdir('process')\n>  subdir('serialization')\n>  subdir('stream')\n> +subdir('v4l2_compat')\n>  subdir('v4l2_subdevice')\n>  subdir('v4l2_videodevice')\n>  \n> diff --git a/test/v4l2_compat/meson.build b/test/v4l2_compat/meson.build\n> new file mode 100644\n> index 0000000..5b29de7\n> --- /dev/null\n> +++ b/test/v4l2_compat/meson.build\n> @@ -0,0 +1,10 @@\n> +# SPDX-License-Identifier: CC0-1.0\n> +\n> +if is_variable('v4l2_compat')\n> +    v4l2_compat_test = files('v4l2_compat_test.py')\n> +\n> +    test('v4l2_compat_test', v4l2_compat_test,\n> +         args : v4l2_compat,\n> +         suite : 'v4l2_compat',\n> +         timeout : 60)\n> +endif\n> diff --git a/test/v4l2_compat/v4l2_compat_test.py b/test/v4l2_compat/v4l2_compat_test.py\n> new file mode 100755\n> index 0000000..fd76647\n> --- /dev/null\n> +++ b/test/v4l2_compat/v4l2_compat_test.py\n> @@ -0,0 +1,143 @@\n> +#!/usr/bin/env python3\n> +# SPDX-License-Identifier: GPL-2.0-or-later\n> +# Copyright (C) 2020, Google Inc.\n> +#\n> +# Author: Paul Elder <paul.elder@ideasonboard.com>\n> +#\n> +# v4l2_compat_test.py - Test the V4L2 compatibility layer\n> +\n> +import argparse\n> +import glob\n> +import os\n> +import re\n> +import shutil\n> +import signal\n> +import subprocess\n> +import sys\n> +\n> +TestPass = 0\n> +TestFail = -1\n> +TestSkip = 77\n> +\n> +\n> +supported_pipelines = [\n> +    'uvcvideo',\n> +    'vimc',\n> +]\n> +\n> +\n> +def grep(exp, arr):\n> +    return [s for s in arr if re.search(exp, s)]\n> +\n> +\n> +def run_with_stdout(*args, env={}):\n> +    try:\n> +        with open(os.devnull, 'w') as devnull:\n> +            output = subprocess.check_output(args, env=env, stderr=devnull)\n> +        ret = 0\n> +    except subprocess.CalledProcessError as err:\n> +        output = err.output\n> +        ret = err.returncode\n> +    return ret, output.decode('utf-8').split('\\n')\n> +\n> +\n> +def extract_result(result):\n> +    res = result.split(', ')\n> +    ret = {}\n> +    ret['total']     = int(res[0].split(': ')[-1])\n> +    ret['succeeded'] = int(res[1].split(': ')[-1])\n> +    ret['failed']    = int(res[2].split(': ')[-1])\n> +    ret['warnings']  = int(res[3].split(': ')[-1])\n> +    ret['device']    = res[0].split()[4].strip(':')\n> +    ret['driver']    = res[0].split()[2]\n> +    return ret\n> +\n> +\n> +def print_output_arr(output_arr):\n> +    print('\\n'.join(output_arr))\n> +\n> +\n> +def test_v4l2_compliance(v4l2_compliance, v4l2_compat, device, base_driver):\n> +    ret, output = run_with_stdout(v4l2_compliance, '-s', '-d', device, env={'LD_PRELOAD': v4l2_compat})\n> +    if ret < 0:\n> +        print_output_arr(output)\n> +        print(f'Test for {device} terminated due to signal {signal.Signals(-ret).name}')\n> +        return TestFail\n> +\n> +    result = extract_result(output[-2])\n> +    if result['failed'] == 0:\n> +        return TestPass\n> +\n> +    # vimc will fail s_fmt because it only supports framesizes that are\n> +    # multiples of 3\n> +    if base_driver == 'vimc' and result['failed'] == 1:\n> +        failures = grep('fail', output)\n> +        if re.search('S_FMT cannot handle an invalid format', failures[0]) is None:\n> +            print_output_arr(output)\n> +            return TestFail\n> +        return TestPass\n> +\n> +    print_output_arr(output)\n> +    return TestFail\n> +\n> +\n> +def main(argv):\n> +    parser = argparse.ArgumentParser()\n> +    parser.add_argument('-a', '--all', action='store_true',\n> +                        help='Test all available cameras')\n> +    parser.add_argument('v4l2_compat', type=str,\n> +                        help='Path to v4l2-compat.so')\n> +    args = parser.parse_args(argv[1:])\n> +\n> +    v4l2_compat = args.v4l2_compat\n> +\n> +    v4l2_compliance = shutil.which('v4l2-compliance')\n> +    if v4l2_compliance is None:\n> +        print('v4l2-compliance is not available')\n> +        return TestSkip\n> +\n> +    v4l2_ctl = shutil.which('v4l2-ctl')\n> +    if v4l2_ctl is None:\n> +        print('v4l2-ctl is not available')\n> +        return TestSkip\n> +\n> +    dev_nodes = glob.glob('/dev/video*')\n> +    if len(dev_nodes) == 0:\n> +        print('no video nodes available to test with')\n> +        return TestSkip\n> +\n> +    failed = []\n> +    drivers_tested = {driver : False for driver in supported_pipelines}\n\n    drivers_tested = {}\n\n> +    for device in dev_nodes:\n> +        _, out = run_with_stdout(v4l2_ctl, '-D', '-d', device, env={'LD_PRELOAD': v4l2_compat})\n> +        driver = grep('Driver name', out)[0].split(':')[-1].strip()\n> +        if driver != \"libcamera\":\n> +            continue\n> +\n> +        _, out = run_with_stdout(v4l2_ctl, '-D', '-d', device)\n> +        driver = grep('Driver name', out)[0].split(':')[-1].strip()\n> +        if driver not in supported_pipelines:\n> +            continue\n> +\n> +        if (not args.all) and drivers_tested[driver]:\n\n        if not args.all and driver in drivers_tested:\n\n> +            continue\n> +\n> +        print(f'Testing {device} with {driver} driver...', end=' ')\n\nMaybe\n\n        print(f'Testing {device} with {driver} driver... ', end='')\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> +        ret = test_v4l2_compliance(v4l2_compliance, v4l2_compat, device, driver)\n> +        if ret == TestFail:\n> +            failed.append(device)\n> +            print('failed')\n> +        else:\n> +            print('success')\n> +        drivers_tested[driver] = True\n> +\n> +    if len(failed) > 0:\n> +        print(f'Failed {len(failed)} tests:')\n> +        for device in failed:\n> +            print(f'- {device}')\n> +\n> +    return TestPass if not failed else TestFail\n> +\n> +\n> +if __name__ == '__main__':\n> +    sys.exit(main(sys.argv))","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id B8A00BFFE2\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 29 Jun 2020 23:14:31 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3F997609DF;\n\tTue, 30 Jun 2020 01:14:31 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D49E6603B5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 30 Jun 2020 01:14:29 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-216-236.bb.dnainternet.fi\n\t[81.175.216.236])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id D62A4299;\n\tTue, 30 Jun 2020 01:14:28 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"aATA3xJx\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1593472469;\n\tbh=Mpuz72ZkJ0GpP35Gj8jKd3KW0Ee+ulmjxEhaVvu9yxY=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=aATA3xJxqoUInyJNzx8UnIHVPu1oHhiVWxrKe2l7vKYW0l09xpElZQl/GhMs5+JNN\n\tZ0AeQlQRvIbDf2V8mU1PNO4rnr2oY66hDiAHRcNqurEQBNO3Twxt/FcJxL4jyJqqGu\n\tsrT8+MfZs0vwgaAzuigxS6M3QAyNNW4ruHC7sAwQ=","Date":"Tue, 30 Jun 2020 02:14:24 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Paul Elder <paul.elder@ideasonboard.com>","Message-ID":"<20200629231424.GF21452@pendragon.ideasonboard.com>","References":"<20200629151529.217022-1-paul.elder@ideasonboard.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20200629151529.217022-1-paul.elder@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v3] tests: v4l2_compat: Add test for\n\tv4l2_compat","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":10997,"web_url":"https://patchwork.libcamera.org/comment/10997/","msgid":"<20200630045947.GA198306@pyrite.rasen.tech>","date":"2020-06-30T04:59:47","subject":"Re: [libcamera-devel] [PATCH v3] tests: v4l2_compat: Add test for\n\tv4l2_compat","submitter":{"id":17,"url":"https://patchwork.libcamera.org/api/people/17/","name":"Paul Elder","email":"paul.elder@ideasonboard.com"},"content":"Hi Laurent,\n\nThank you for the review.\n\nOn Tue, Jun 30, 2020 at 02:14:24AM +0300, Laurent Pinchart wrote:\n> Hi Paul,\n> \n> Thank you for the patch.\n> \n> On Tue, Jun 30, 2020 at 12:15:29AM +0900, Paul Elder wrote:\n> > Test the V4L2 compatibility layer by running v4l2-compliance -s on every\n> > /dev/video* device.\n> > \n> > Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>\n> > Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > \n> > ---\n> > Changes in v3:\n> > - use argparse\n> > - add argument to test all cameras, and test only one camera per driver\n> >   by default\n> > - print the devices that we're testing and if each succeeded or failed\n> > \n> > Note that as of v2, the tests will fail if the tester has a camera\n> > supported by libcamera that has unsupported formats, since they will\n> > cause a floating point exception. So I don't think this should be merged\n> > until that is fixed, otherwise we might get nasty test failures in\n> > bisection.\n> \n> Is this fixed by the PixelFormatInfo series you've just sent, or are we\n> still missing something ?\n\nUhh I think we might still be missing something. The PixelFormatInfo\nseries that I sent allows v4l2-compat to use all the formats supported\nby libcamera in the PixelFormatInfo list, but I'm pretty sure\nunsupported formats can still get through and cause FPE. The only way to\nreally test it is with the vivid pipeline handler, though; I'm pretty\nsure all the pipeline handlers that we support have all their formats in\nthat list, in which case it wouldn't cause a problem. Is it possible\nthat uvc cameras might declare formats that aren't in that list, and\nlibcamera would let it through?\n\n> > Changes in v2:\n> > - change all strings to single-quote\n> > - simplify meson.build\n> > - get path to v4l2-compat.so from cli arg, rather than running custom find()\n> >   - remove find_file()\n> > - extend test timeout to 60 seconds (from default of 30)\n> > - don't run v4l2-compliance subprocesses in shell\n> > - check if v4l2-compliance runs are killed by signal (eg. the known\n> >   SIGABRT due to floating point exception)\n> > - move the check to see if libcamera supports the camera to v4l2-ctl\n> >   instead of v4l2-compliance (in v1 we only checked if the pipeline was\n> >   supported with v4l2-ctl)\n> > ---\n> >  test/meson.build                     |   1 +\n> >  test/v4l2_compat/meson.build         |  10 ++\n> >  test/v4l2_compat/v4l2_compat_test.py | 143 +++++++++++++++++++++++++++\n> >  3 files changed, 154 insertions(+)\n> >  create mode 100644 test/v4l2_compat/meson.build\n> >  create mode 100755 test/v4l2_compat/v4l2_compat_test.py\n> > \n> > diff --git a/test/meson.build b/test/meson.build\n> > index 7808a26..f41d6e7 100644\n> > --- a/test/meson.build\n> > +++ b/test/meson.build\n> > @@ -12,6 +12,7 @@ subdir('pipeline')\n> >  subdir('process')\n> >  subdir('serialization')\n> >  subdir('stream')\n> > +subdir('v4l2_compat')\n> >  subdir('v4l2_subdevice')\n> >  subdir('v4l2_videodevice')\n> >  \n> > diff --git a/test/v4l2_compat/meson.build b/test/v4l2_compat/meson.build\n> > new file mode 100644\n> > index 0000000..5b29de7\n> > --- /dev/null\n> > +++ b/test/v4l2_compat/meson.build\n> > @@ -0,0 +1,10 @@\n> > +# SPDX-License-Identifier: CC0-1.0\n> > +\n> > +if is_variable('v4l2_compat')\n> > +    v4l2_compat_test = files('v4l2_compat_test.py')\n> > +\n> > +    test('v4l2_compat_test', v4l2_compat_test,\n> > +         args : v4l2_compat,\n> > +         suite : 'v4l2_compat',\n> > +         timeout : 60)\n> > +endif\n> > diff --git a/test/v4l2_compat/v4l2_compat_test.py b/test/v4l2_compat/v4l2_compat_test.py\n> > new file mode 100755\n> > index 0000000..fd76647\n> > --- /dev/null\n> > +++ b/test/v4l2_compat/v4l2_compat_test.py\n> > @@ -0,0 +1,143 @@\n> > +#!/usr/bin/env python3\n> > +# SPDX-License-Identifier: GPL-2.0-or-later\n> > +# Copyright (C) 2020, Google Inc.\n> > +#\n> > +# Author: Paul Elder <paul.elder@ideasonboard.com>\n> > +#\n> > +# v4l2_compat_test.py - Test the V4L2 compatibility layer\n> > +\n> > +import argparse\n> > +import glob\n> > +import os\n> > +import re\n> > +import shutil\n> > +import signal\n> > +import subprocess\n> > +import sys\n> > +\n> > +TestPass = 0\n> > +TestFail = -1\n> > +TestSkip = 77\n> > +\n> > +\n> > +supported_pipelines = [\n> > +    'uvcvideo',\n> > +    'vimc',\n> > +]\n> > +\n> > +\n> > +def grep(exp, arr):\n> > +    return [s for s in arr if re.search(exp, s)]\n> > +\n> > +\n> > +def run_with_stdout(*args, env={}):\n> > +    try:\n> > +        with open(os.devnull, 'w') as devnull:\n> > +            output = subprocess.check_output(args, env=env, stderr=devnull)\n> > +        ret = 0\n> > +    except subprocess.CalledProcessError as err:\n> > +        output = err.output\n> > +        ret = err.returncode\n> > +    return ret, output.decode('utf-8').split('\\n')\n> > +\n> > +\n> > +def extract_result(result):\n> > +    res = result.split(', ')\n> > +    ret = {}\n> > +    ret['total']     = int(res[0].split(': ')[-1])\n> > +    ret['succeeded'] = int(res[1].split(': ')[-1])\n> > +    ret['failed']    = int(res[2].split(': ')[-1])\n> > +    ret['warnings']  = int(res[3].split(': ')[-1])\n> > +    ret['device']    = res[0].split()[4].strip(':')\n> > +    ret['driver']    = res[0].split()[2]\n> > +    return ret\n> > +\n> > +\n> > +def print_output_arr(output_arr):\n> > +    print('\\n'.join(output_arr))\n> > +\n> > +\n> > +def test_v4l2_compliance(v4l2_compliance, v4l2_compat, device, base_driver):\n> > +    ret, output = run_with_stdout(v4l2_compliance, '-s', '-d', device, env={'LD_PRELOAD': v4l2_compat})\n> > +    if ret < 0:\n> > +        print_output_arr(output)\n> > +        print(f'Test for {device} terminated due to signal {signal.Signals(-ret).name}')\n> > +        return TestFail\n> > +\n> > +    result = extract_result(output[-2])\n> > +    if result['failed'] == 0:\n> > +        return TestPass\n> > +\n> > +    # vimc will fail s_fmt because it only supports framesizes that are\n> > +    # multiples of 3\n> > +    if base_driver == 'vimc' and result['failed'] == 1:\n> > +        failures = grep('fail', output)\n> > +        if re.search('S_FMT cannot handle an invalid format', failures[0]) is None:\n> > +            print_output_arr(output)\n> > +            return TestFail\n> > +        return TestPass\n> > +\n> > +    print_output_arr(output)\n> > +    return TestFail\n> > +\n> > +\n> > +def main(argv):\n> > +    parser = argparse.ArgumentParser()\n> > +    parser.add_argument('-a', '--all', action='store_true',\n> > +                        help='Test all available cameras')\n> > +    parser.add_argument('v4l2_compat', type=str,\n> > +                        help='Path to v4l2-compat.so')\n> > +    args = parser.parse_args(argv[1:])\n> > +\n> > +    v4l2_compat = args.v4l2_compat\n> > +\n> > +    v4l2_compliance = shutil.which('v4l2-compliance')\n> > +    if v4l2_compliance is None:\n> > +        print('v4l2-compliance is not available')\n> > +        return TestSkip\n> > +\n> > +    v4l2_ctl = shutil.which('v4l2-ctl')\n> > +    if v4l2_ctl is None:\n> > +        print('v4l2-ctl is not available')\n> > +        return TestSkip\n> > +\n> > +    dev_nodes = glob.glob('/dev/video*')\n> > +    if len(dev_nodes) == 0:\n> > +        print('no video nodes available to test with')\n> > +        return TestSkip\n> > +\n> > +    failed = []\n> > +    drivers_tested = {driver : False for driver in supported_pipelines}\n> \n>     drivers_tested = {}\n> \n> > +    for device in dev_nodes:\n> > +        _, out = run_with_stdout(v4l2_ctl, '-D', '-d', device, env={'LD_PRELOAD': v4l2_compat})\n> > +        driver = grep('Driver name', out)[0].split(':')[-1].strip()\n> > +        if driver != \"libcamera\":\n> > +            continue\n> > +\n> > +        _, out = run_with_stdout(v4l2_ctl, '-D', '-d', device)\n> > +        driver = grep('Driver name', out)[0].split(':')[-1].strip()\n> > +        if driver not in supported_pipelines:\n> > +            continue\n> > +\n> > +        if (not args.all) and drivers_tested[driver]:\n> \n>         if not args.all and driver in drivers_tested:\n\nAh yes, pythonicism.\n\n> > +            continue\n> > +\n> > +        print(f'Testing {device} with {driver} driver...', end=' ')\n> \n> Maybe\n> \n>         print(f'Testing {device} with {driver} driver... ', end='')\n\nYeah.\n\n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> \n> > +        ret = test_v4l2_compliance(v4l2_compliance, v4l2_compat, device, driver)\n> > +        if ret == TestFail:\n> > +            failed.append(device)\n> > +            print('failed')\n> > +        else:\n> > +            print('success')\n> > +        drivers_tested[driver] = True\n> > +\n> > +    if len(failed) > 0:\n> > +        print(f'Failed {len(failed)} tests:')\n> > +        for device in failed:\n> > +            print(f'- {device}')\n> > +\n> > +    return TestPass if not failed else TestFail\n> > +\n> > +\n> > +if __name__ == '__main__':\n> > +    sys.exit(main(sys.argv))\n\n\nThanks,\n\nPaul","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 22130BF415\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 30 Jun 2020 04:59:57 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 93FA660C56;\n\tTue, 30 Jun 2020 06:59:56 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 6C781603AE\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 30 Jun 2020 06:59:55 +0200 (CEST)","from pyrite.rasen.tech (unknown\n\t[IPv6:2400:4051:61:600:2c71:1b79:d06d:5032])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id C89CC29F;\n\tTue, 30 Jun 2020 06:59:53 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"fPsRoTcl\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1593493195;\n\tbh=dOOnszZa3VsXvshZsR1o2iDOwK2pQJnun5x2Rm2gfCc=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=fPsRoTclOSn2JlmUqQL2Hz8XWFzFXe86/QptHvgsOG309tc2eA0ofbCGWiwaqZaoL\n\tbfS22AOZKkFG2+iM5sRM0SpddX5IjQfwPXGRTICY0on/74EIvhVnt8FVIL6lD9ut+A\n\tC+IWmPoS/clSMpQRwV0dW3lah+91c2dDZdYqloEo=","Date":"Tue, 30 Jun 2020 13:59:47 +0900","From":"Paul Elder <paul.elder@ideasonboard.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<20200630045947.GA198306@pyrite.rasen.tech>","References":"<20200629151529.217022-1-paul.elder@ideasonboard.com>\n\t<20200629231424.GF21452@pendragon.ideasonboard.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20200629231424.GF21452@pendragon.ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v3] tests: v4l2_compat: Add test for\n\tv4l2_compat","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]