Revert "tests: Simplify capture of driver behaviour for regression tests"
This reverts commit 0dcb4be4d3
.
This commit is contained in:
parent
0dcb4be4d3
commit
e22497d51b
3 changed files with 47 additions and 149 deletions
|
@ -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.
|
||||||
|
|
|
@ -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")
|
|
|
@ -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 = [
|
||||||
|
|
Loading…
Reference in a new issue