tests: Add umockdev based testing
Initially only the vfs5011 driver is tested. Please note that these tests will be unreliable before umockdev 0.13.2. See also https://github.com/martinpitt/umockdev/pull/92
This commit is contained in:
parent
e372311afe
commit
538038867b
8 changed files with 329 additions and 2 deletions
|
@ -7,7 +7,7 @@ stages:
|
|||
variables:
|
||||
DEPENDENCIES: libgusb-devel glib2-devel nss-devel pixman-devel systemd meson gtk-doc
|
||||
gcc gcc-c++ glibc-devel libX11-devel libXv-devel gtk3-devel flatpak-builder
|
||||
gobject-introspection-devel python3-cairo python3-gobject
|
||||
gobject-introspection-devel python3-cairo python3-gobject umockdev
|
||||
BUNDLE: "org.freedesktop.libfprint.Demo.flatpak"
|
||||
LAST_ABI_BREAK: "056ea541ddc97f5806cffbd99a12dc87e4da3546"
|
||||
|
||||
|
@ -44,7 +44,7 @@ test:
|
|||
stage: test
|
||||
script:
|
||||
- dnf update -y --nogpgcheck && dnf install -y --nogpgcheck $DEPENDENCIES
|
||||
- meson -Ddrivers=virtual_image . _build
|
||||
- meson -Ddrivers=all . _build
|
||||
- ninja -C _build
|
||||
- meson test -C _build --verbose --no-stdsplit
|
||||
|
||||
|
|
21
tests/README-umockdev
Normal file
21
tests/README-umockdev
Normal file
|
@ -0,0 +1,21 @@
|
|||
To create a new umockdev test, you should:
|
||||
|
||||
1. Decide on what to test, the easiest case is just using the existing
|
||||
capture test case.
|
||||
2. Find the USB device you are testing with lsusb, e.g.:
|
||||
Bus 001 Device 005: ID 138a:0090 Validity Sensors, Inc. VFS7500 Touch Fingerprint Sensor
|
||||
This means we need to record USB device /dev/bus/usb/001/005
|
||||
3. Run "umockdev-record /dev/bus/usb/001/005 >device"
|
||||
This records the information about device, it should be placed into test/DRIVER/device
|
||||
4. Run the test, for a capture test this would be:
|
||||
umockdev-record -i /dev/bus/usb/001/005=capture.ioctl -- ./capture.py capture.png
|
||||
This will create a capture.ioctl and capture.png file.
|
||||
5. Place all files into the driver subdirectory test/DRIVER,
|
||||
i.e. device, capture.ioctl, capture.png
|
||||
6. Add glue to meson.build
|
||||
7. Test whether everything works as expected
|
||||
|
||||
Please note, there is no need to use a real finger print in this case. If
|
||||
you would like to avoid submitting your own fingerprint then please just
|
||||
use e.g. the side of your finger, arm, or anything else that will produce
|
||||
an image with the device.
|
46
tests/capture.py
Executable file
46
tests/capture.py
Executable file
|
@ -0,0 +1,46 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import gi
|
||||
gi.require_version('FPrint', '2.0')
|
||||
from gi.repository import FPrint, GLib
|
||||
import cairo
|
||||
import sys
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
print("Please specify exactly one argument, the output location for the capture image")
|
||||
sys.exit(1)
|
||||
|
||||
ctx = GLib.main_context_default()
|
||||
|
||||
c = FPrint.Context()
|
||||
c.enumerate()
|
||||
devices = c.get_devices()
|
||||
|
||||
d = devices[0]
|
||||
|
||||
d.open_sync()
|
||||
|
||||
img = d.capture_sync(True)
|
||||
|
||||
d.close_sync()
|
||||
|
||||
width = img.get_width()
|
||||
height = img.get_height()
|
||||
|
||||
c_img = cairo.ImageSurface(cairo.FORMAT_RGB24, width, height)
|
||||
|
||||
c_rowstride = c_img.get_stride()
|
||||
|
||||
buf = img.get_data()
|
||||
c_buf = c_img.get_data()
|
||||
|
||||
for x in range(width):
|
||||
for y in range(height):
|
||||
c_buf[y * c_rowstride + x * 4 + 0] = buf[y * width + x]
|
||||
c_buf[y * c_rowstride + x * 4 + 1] = buf[y * width + x]
|
||||
c_buf[y * c_rowstride + x * 4 + 2] = buf[y * width + x]
|
||||
# Byte 4 is don't care
|
||||
|
||||
c_img.mark_dirty()
|
||||
c_img.write_to_png(sys.argv[1])
|
||||
|
|
@ -15,3 +15,11 @@ if 'virtual_image' in drivers
|
|||
)
|
||||
endif
|
||||
|
||||
if 'vfs5011' in drivers
|
||||
test(
|
||||
'vfs5011',
|
||||
find_program('umockdev-test.py'),
|
||||
args: join_paths(meson.current_source_dir(), 'vfs5011'),
|
||||
env: envs,
|
||||
)
|
||||
endif
|
||||
|
|
65
tests/umockdev-test.py
Executable file
65
tests/umockdev-test.py
Executable file
|
@ -0,0 +1,65 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
import os.path
|
||||
import shutil
|
||||
import tempfile
|
||||
import subprocess
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
print("You need to specify exactly one argument, the directory with test data")
|
||||
|
||||
edir = os.path.dirname(sys.argv[0])
|
||||
ddir = sys.argv[1]
|
||||
|
||||
tmpdir = tempfile.mkdtemp(prefix='libfprint-umockdev-test-')
|
||||
|
||||
assert os.path.isdir(ddir)
|
||||
assert os.path.isfile(os.path.join(ddir, "device"))
|
||||
|
||||
def cmp_pngs(png_a, png_b):
|
||||
print("Comparing PNGs %s and %s" % (png_a, png_b))
|
||||
import cairo
|
||||
img_a = cairo.ImageSurface.create_from_png(png_a)
|
||||
img_b = cairo.ImageSurface.create_from_png(png_b)
|
||||
|
||||
assert img_a.get_format() == cairo.FORMAT_RGB24
|
||||
assert img_b.get_format() == cairo.FORMAT_RGB24
|
||||
assert img_a.get_width() == img_b.get_width()
|
||||
assert img_a.get_height() == img_b.get_height()
|
||||
assert img_a.get_stride () == img_b.get_stride()
|
||||
|
||||
data_a = img_a.get_data()
|
||||
data_b = img_b.get_data()
|
||||
stride = img_a.get_stride()
|
||||
|
||||
for x in range(img_a.get_width()):
|
||||
for y in range(img_a.get_height()):
|
||||
assert(data_a[y * stride + x * 4] == data_b[y * stride + x * 4])
|
||||
|
||||
def capture():
|
||||
ioctl = os.path.join(ddir, "capture.ioctl")
|
||||
device = os.path.join(ddir, "device")
|
||||
dev = open(ioctl).readline().strip()
|
||||
assert dev.startswith('@DEV ')
|
||||
dev = dev[5:]
|
||||
|
||||
subprocess.check_call(['umockdev-run', '-d', device,
|
||||
'-i', "%s=%s" % (dev, ioctl),
|
||||
'--',
|
||||
'%s' % os.path.join(edir, "capture.py"),
|
||||
'%s' % os.path.join(tmpdir, "capture.png")])
|
||||
|
||||
assert os.path.isfile(os.path.join(tmpdir, "capture.png"))
|
||||
if os.path.isfile(os.path.join(ddir, "capture.png")):
|
||||
# Compare the images, they need to be identical
|
||||
cmp_pngs(os.path.join(tmpdir, "capture.png"), os.path.join(ddir, "capture.png"))
|
||||
|
||||
try:
|
||||
if os.path.exists(os.path.join(ddir, "capture.ioctl")):
|
||||
capture()
|
||||
|
||||
finally:
|
||||
shutil.rmtree(tmpdir)
|
||||
|
107
tests/vfs5011/capture.ioctl
Normal file
107
tests/vfs5011/capture.ioctl
Normal file
File diff suppressed because one or more lines are too long
BIN
tests/vfs5011/capture.png
Normal file
BIN
tests/vfs5011/capture.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
80
tests/vfs5011/device
Normal file
80
tests/vfs5011/device
Normal file
|
@ -0,0 +1,80 @@
|
|||
P: /devices/pci0000:00/0000:00:14.0/usb2/2-6
|
||||
N: bus/usb/002/017=12011001FF11FF088A13170078000000010109022E00010100A0320904000004FF00000007050102400000070581024000000705820240000007058303080004
|
||||
E: DEVNAME=/dev/bus/usb/002/017
|
||||
E: DEVTYPE=usb_device
|
||||
E: DRIVER=usb
|
||||
E: PRODUCT=138a/17/78
|
||||
E: TYPE=255/17/255
|
||||
E: BUSNUM=002
|
||||
E: DEVNUM=017
|
||||
E: MAJOR=189
|
||||
E: MINOR=144
|
||||
E: SUBSYSTEM=usb
|
||||
E: ID_VENDOR=138a
|
||||
E: ID_VENDOR_ENC=138a
|
||||
E: ID_VENDOR_ID=138a
|
||||
E: ID_MODEL=0017
|
||||
E: ID_MODEL_ENC=0017
|
||||
E: ID_MODEL_ID=0017
|
||||
E: ID_REVISION=0078
|
||||
E: ID_SERIAL=138a_0017_6c3b5712a6c0
|
||||
E: ID_SERIAL_SHORT=6c3b5712a6c0
|
||||
E: ID_BUS=usb
|
||||
E: ID_USB_INTERFACES=:ff0000:
|
||||
E: ID_VENDOR_FROM_DATABASE=Validity Sensors, Inc.
|
||||
E: ID_MODEL_FROM_DATABASE=VFS 5011 fingerprint sensor
|
||||
A: authorized=1
|
||||
A: avoid_reset_quirk=0
|
||||
A: bConfigurationValue=1
|
||||
A: bDeviceClass=ff
|
||||
A: bDeviceProtocol=ff
|
||||
A: bDeviceSubClass=11
|
||||
A: bMaxPacketSize0=8
|
||||
A: bMaxPower=100mA
|
||||
A: bNumConfigurations=1
|
||||
A: bNumInterfaces= 1
|
||||
A: bcdDevice=0078
|
||||
A: bmAttributes=a0
|
||||
A: busnum=2
|
||||
A: configuration=
|
||||
H: descriptors=12011001FF11FF088A13170078000000010109022E00010100A0320904000004FF00000007050102400000070581024000000705820240000007058303080004
|
||||
A: dev=189:144
|
||||
A: devnum=17
|
||||
A: devpath=6
|
||||
L: driver=../../../../../bus/usb/drivers/usb
|
||||
A: idProduct=0017
|
||||
A: idVendor=138a
|
||||
A: ltm_capable=no
|
||||
A: maxchild=0
|
||||
L: port=../2-0:1.0/usb2-port6
|
||||
A: power/active_duration=624952
|
||||
A: power/async=enabled
|
||||
A: power/autosuspend=2
|
||||
A: power/autosuspend_delay_ms=2000
|
||||
A: power/connected_duration=624952
|
||||
A: power/control=on
|
||||
A: power/level=on
|
||||
A: power/persist=1
|
||||
A: power/runtime_active_kids=0
|
||||
A: power/runtime_active_time=624676
|
||||
A: power/runtime_enabled=forbidden
|
||||
A: power/runtime_status=active
|
||||
A: power/runtime_suspended_time=0
|
||||
A: power/runtime_usage=1
|
||||
A: power/wakeup=disabled
|
||||
A: power/wakeup_abort_count=
|
||||
A: power/wakeup_active=
|
||||
A: power/wakeup_active_count=
|
||||
A: power/wakeup_count=
|
||||
A: power/wakeup_expire_count=
|
||||
A: power/wakeup_last_time_ms=
|
||||
A: power/wakeup_max_time_ms=
|
||||
A: power/wakeup_total_time_ms=
|
||||
A: quirks=0x0
|
||||
A: removable=fixed
|
||||
A: rx_lanes=1
|
||||
A: serial=6c3b5712a6c0
|
||||
A: speed=12
|
||||
A: tx_lanes=1
|
||||
A: urbnum=7
|
||||
A: version= 1.10
|
Loading…
Reference in a new issue