Revert "tests: Simplify capture of driver behaviour for regression tests"

This reverts commit 0dcb4be4d3.
This commit is contained in:
Bastien Nocera 2021-09-06 17:34:15 +02:00
parent 0dcb4be4d3
commit e22497d51b
3 changed files with 47 additions and 149 deletions

View file

@ -15,23 +15,57 @@ script, capture it and store the capture to `custom.pcapng`.
----------------------- -----------------------
A new 'capture' test is created by means of `capture.py` script: A new 'capture' test is created by means of `capture.py` script:
1. Make sure that libfprint is built with support for the device driver 1. Create (if needed) a directory for the driver under `tests`
that you want to capture a test case for. directory:
2. From the build directory, run tests/create-driver-test.py as root. Note `mkdir DRIVER`
that if you're capturing data for a driver which already has a test case
but the hardware is slightly different, you might want to pass a variant
name as a command-line options, for example:
```sh
$ sudo tests/create-driver-test.py version2
```
3. If the capture is not successful, run the tool again to start another capture. Note that the name must be the exact name of the libfprint driver,
or the exact name of the driver followed by a `-` and a unique identifier
of your choosing.
4. Add driver test name to `drivers_tests` in the `meson.build`, as instructed, 2. Prepare your execution environment.
and change the ownership of the just-created test directory in the source.
5. Check whether `meson test` passes with this new test. In the next step a working and up to date libfprint is needed. This can be
achieved by installing it into your system. Alternatively, you can set
the following environment variables to run a local build:
- `export LD_PRELOAD=<meson-build-dir>/libfprint/libfprint-2.so`
- `export GI_TYPELIB_PATH=<meson-build-dir>/libfprint`
Also, sometimes the driver must be adapted to the emulated environment
(mainly if it uses random numbers, see `synaptics.c` for an example).
Set the following environment variable to enable this adaptation:
- `export FP_DEVICE_EMULATION=1`
Run the next steps in the same terminal.
3. Find the real USB fingerprint device with `lsusb`, e.g.:
`Bus 001 Device 005: ID 138a:0090 Validity Sensors, Inc. VFS7500 Touch Fingerprint Sensor`
The following USB device is used in the example above:
`/dev/bus/usb/001/005`.
For the following commands, it is assumed that the user that's
running the commands has full access to the device node, whether
by running the commands as `root`, or changing the permissions for
that device node.
4. Record information about this device:
`umockdev-record /dev/bus/usb/001/005 > DRIVER/device`
5. Record interaction of `capture.py` (or other test) with the device. To do
so, start wireshark and record `usbmonX` (where X is the bus number). Then
run the test script:
`python3 ./capture.py DRIVER/capture.png`
Save the wireshark recording as `capture.pcapng`. The command will create
`capture.png`.
6. Add driver's name to `drivers_tests` in the `meson.build`.
7. Check whether everything works as expected.
**Note.** To avoid submitting a real fingerprint, the side of finger, **Note.** To avoid submitting a real fingerprint, the side of finger,
arm, or anything else producing an image with the device can be used. arm, or anything else producing an image with the device can be used.

View file

@ -1,127 +0,0 @@
#!/usr/bin/python3
BUILDDIR='@BUILDDIR@'
SRCDIR='@SRCDIR@'
import os
import sys
library_path = BUILDDIR + '/libfprint/'
# Relaunch ourselves with a changed environment so
# that we're loading the development version of libfprint
if 'LD_LIBRARY_PATH' not in os.environ or not library_path in os.environ['LD_LIBRARY_PATH']:
os.environ['LD_LIBRARY_PATH'] = library_path
os.environ['GI_TYPELIB_PATH'] = '/home/hadess/.cache/jhbuild/build/libfprint/libfprint/'
os.environ['FP_DEVICE_EMULATION'] = '1'
try:
os.execv(sys.argv[0], sys.argv)
except Exception as e:
print('Could not run script with new library path')
sys.exit(1)
import gi
gi.require_version('FPrint', '2.0')
from gi.repository import FPrint
gi.require_version('GUsb', '1.0')
from gi.repository import GUsb
import re
import shutil
import subprocess
import tempfile
import time
def print_usage():
print(f'Usage: {sys.argv[0]} [test-variant-name]')
print('A test variant name is optional, and must be all lower case letters, or dashes, with no spaces')
print(f'The captured data will be stored in {BUILDDIR}/tests/[driver name]-[test variant name]')
if len(sys.argv) > 2:
print_usage()
sys.exit(1)
test_variant = None
if len(sys.argv) == 2:
valid_re = re.compile('[a-z-]*')
test_variant = sys.argv[1]
if (not valid_re.match(test_variant) or
test_variant.startswith('-') or
test_variant.endswith('-')):
print(f'Invalid variant name {test_variant}\n')
print_usage()
sys.exit(1)
# Check that running as root
if os.geteuid() != 0:
print(f'{sys.argv[0]} is expected to be run as root')
sys.exit(1)
# Check that tshark is available
if not shutil.which('tshark'):
print("The 'tshark' WireShark command-line tool must be installed to capture USB traffic")
sys.exit(1)
# Find the fingerprint reader
ctx = FPrint.Context()
ctx.enumerate()
devices = ctx.get_devices()
if len(devices) == 0:
print('Could not find a supported fingerprint reader')
sys.exit(1)
elif len(devices) > 1:
print('Capture requires a single fingerprint reader to be plugged in')
sys.exit(1)
driver_name = devices[0].get_driver()
test_name = driver_name
if test_variant:
test_name = driver_name + '-' + test_variant
usb_device = devices[0].get_property('fpi-usb-device')
bus_num = usb_device.get_bus()
device_num = usb_device.get_address()
print(f'### Detected USB device /dev/bus/usb/{bus_num:03d}/{device_num:03d}')
# Make directory
test_dir = SRCDIR + '/tests/' + test_name
os.makedirs(test_dir, mode=0o775, exist_ok=True)
# Capture device info
args = ['umockdev-record', f'/dev/bus/usb/{bus_num:03d}/{device_num:03d}']
device_out = open(test_dir + '/device', 'w')
process = subprocess.Popen(args, stdout=device_out)
process.wait()
# Run capture
# https://osqa-ask.wireshark.org/questions/53919/how-can-i-precisely-specify-a-usb-device-to-capture-with-tshark/
print(f'### Starting USB capture on usbmon{bus_num}')
unfiltered_cap_path = os.path.join(tempfile.gettempdir(), 'capture-unfiltered.pcapng')
args = ['tshark', '-i', f'usbmon{bus_num}', '-w', unfiltered_cap_path]
traffic_cap = subprocess.Popen(args)
# Wait 1 sec to settle
time.sleep(1)
print('### Capturing fingerprint, please swipe or press your finger on the reader')
with subprocess.Popen(['python3', SRCDIR + '/tests/capture.py', test_dir + '/capture.png']) as capture_process:
capture_process.wait()
if capture_process.returncode != 0:
print('Failed to capture fingerprint')
traffic_cap.kill()
sys.exit(1)
traffic_cap.kill()
# Filter the capture
print(f'\n### Saving USB capture as test case {test_name}')
args = ['tshark', '-r', unfiltered_cap_path, '-Y', f'usb.bus_id == {bus_num} and usb.device_address == {device_num}',
'-w', test_dir + '/capture.pcapng']
with subprocess.Popen(args, stderr=subprocess.DEVNULL) as filter_process:
filter_process.wait()
print(f"\nDone! Don't forget to add {test_name} to tests/meson.build")

View file

@ -37,15 +37,6 @@ drivers_tests = [
'egis0570', 'egis0570',
] ]
if get_option('introspection')
conf = configuration_data()
conf.set('SRCDIR', meson.project_source_root())
conf.set('BUILDDIR', meson.project_build_root())
configure_file(configuration: conf,
input: 'create-driver-test.py.in',
output: 'create-driver-test.py')
endif
if get_option('introspection') if get_option('introspection')
envs.prepend('GI_TYPELIB_PATH', join_paths(meson.build_root(), 'libfprint')) envs.prepend('GI_TYPELIB_PATH', join_paths(meson.build_root(), 'libfprint'))
virtual_devices_tests = [ virtual_devices_tests = [