diff --git a/tests/README.md b/tests/README.md index 14b4893..20fdf9f 100644 --- a/tests/README.md +++ b/tests/README.md @@ -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: -1. Make sure that libfprint is built with support for the device driver - that you want to capture a test case for. +1. Create (if needed) a directory for the driver under `tests` + directory: -2. From the build directory, run tests/create-driver-test.py as root. Note - 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 -``` + `mkdir DRIVER` -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, - and change the ownership of the just-created test directory in the source. +2. Prepare your execution environment. -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=/libfprint/libfprint-2.so` + - `export GI_TYPELIB_PATH=/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, arm, or anything else producing an image with the device can be used. diff --git a/tests/create-driver-test.py.in b/tests/create-driver-test.py.in deleted file mode 100755 index 92419f5..0000000 --- a/tests/create-driver-test.py.in +++ /dev/null @@ -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") diff --git a/tests/meson.build b/tests/meson.build index bb19e10..5ad3d59 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -37,15 +37,6 @@ drivers_tests = [ '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') envs.prepend('GI_TYPELIB_PATH', join_paths(meson.build_root(), 'libfprint')) virtual_devices_tests = [