tests: Add dbusmock template for fprintd daemon

This commit is contained in:
Bastien Nocera
2020-01-17 14:47:13 +01:00
parent cd3ed2e450
commit 0a42b90390
2 changed files with 321 additions and 0 deletions

320
tests/dbusmock/fprintd.py Normal file
View File

@ -0,0 +1,320 @@
# -*- coding: utf-8 -*-
'''fprintd mock template
This creates the expected methods and properties of the
net.reactivated.Fprint.Manager object (/net/reactivated/Fprint/Manager)
but no devices.
'''
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option) any
# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text
# of the license.
__author__ = 'Bastien Nocera'
__email__ = 'hadess@hadess.net'
__copyright__ = '(c) 2020 Red Hat Inc.'
__license__ = 'LGPL 3+'
import dbus
from dbusmock import MOCK_IFACE, mockobject
BUS_NAME = 'net.reactivated.Fprint'
MAIN_OBJ = '/net/reactivated/Fprint/Manager'
SYSTEM_BUS = True
IS_OBJECT_MANAGER = False
MAIN_IFACE = 'net.reactivated.Fprint.Manager'
MANAGER_MOCK_IFACE = 'net.reactivated.Fprint.Manager.Mock'
DEVICE_IFACE = 'net.reactivated.Fprint.Device'
DEVICE_MOCK_IFACE = 'net.reactivated.Fprint.Device.Mock'
VALID_FINGER_NAMES = [
'left-thumb',
'left-index-finger',
'left-middle-finger',
'left-ring-finger',
'left-little-finger',
'right-thumb',
'right-index-finger',
'right-middle-finger',
'right-ring-finger',
'right-little-finger'
]
VALID_VERIFY_STATUS = [
'verify-no-match',
'verify-match',
'verify-retry-scan',
'verify-swipe-too-short',
'verify-finger-not-centered',
'verify-remove-and-retry',
'verify-disconnected',
'verify-unknown-error'
]
VALID_ENROLL_STATUS = [
'enroll-completed',
'enroll-failed',
'enroll-stage-passed',
'enroll-retry-scan',
'enroll-swipe-too-short',
'enroll-finger-not-centered',
'enroll-remove-and-retry',
'enroll-data-full',
'enroll-disconnected',
'enroll-unknown-error'
]
# Ever incrementing device ID
last_id = 0
def load(mock, parameters):
fprintd = mockobject.objects[MAIN_OBJ]
mock.last_device_id = 0
fprintd.fingers = {}
@dbus.service.method(MAIN_IFACE,
in_signature='', out_signature='ao')
def GetDevices(self):
return [(k) for k in mockobject.objects.keys() if "/Device/" in k]
@dbus.service.method(MAIN_IFACE,
in_signature='', out_signature='o')
def GetDefaultDevice(self):
devices = self.GetDevices()
if len(devices) < 1:
raise dbus.exceptions.DBusException(
'No devices available',
name='net.reactivated.Fprint.Error.NoSuchDevice')
return devices[0]
@dbus.service.method(MANAGER_MOCK_IFACE,
in_signature='sis', out_signature='s')
def AddDevice(self, device_name, num_enroll_stages, scan_type):
'''Convenience method to add a fingerprint reader device
You have to specify a device name, the number of enrollment
stages it would use (> 0) and the scan type, as a string
(either 'press' or 'swipe')
'''
if scan_type not in ['swipe', 'press']:
raise dbus.exceptions.DBusException(
'Invalid scan_type \'%s\'.' % scan_type,
name='org.freedesktop.DBus.Error.InvalidArgs')
if num_enroll_stages <= 0:
raise dbus.exceptions.DBusException(
'Invalid num_enroll_stages \'%s\'.' % num_enroll_stages,
name='org.freedesktop.DBus.Error.InvalidArgs')
self.last_device_id += 1
path = '/net/reactivated/Fprint/Device/%d' % last_id
device_properties = {
'name': dbus.String(device_name, variant_level=1),
'num-enroll-stages': dbus.UInt32(num_enroll_stages, variant_level=1),
'scan-type': scan_type
}
self.AddObject(path,
DEVICE_IFACE,
# Properties
device_properties,
# Methods
[
('ListEnrolledFingers', 's', 'as', ListEnrolledFingers),
('DeleteEnrolledFingers', 's', '', DeleteEnrolledFingers),
('DeleteEnrolledFingers2', '', '', DeleteEnrolledFingers2),
('Claim', 's', '', Claim),
('Release', '', '', Release),
('VerifyStart', 's', '', VerifyStart),
('VerifyStop', '', '', VerifyStop),
('EnrollStart', 's', '', EnrollStart),
('EnrollStop', '', '', EnrollStop)
])
device = mockobject.objects[path]
device.fingers = {}
device.claimed_user = None
device.action = None
return path
@dbus.service.method(DEVICE_IFACE,
in_signature='s', out_signature='as')
def ListEnrolledFingers(device, user):
if user in device.fingers:
return device.fingers[user]
raise dbus.exceptions.DBusException(
'No enrolled prints in device %s for user %s' % (device.path, user),
name='net.reactivated.Fprint.Error.NoEnrolledPrints')
@dbus.service.method(DEVICE_IFACE,
in_signature='s', out_signature='')
def DeleteEnrolledFingers(device, user):
device.fingers[user] = []
@dbus.service.method(DEVICE_IFACE,
in_signature='', out_signature='')
def DeleteEnrolledFingers2(device):
if not device.claimed_user:
raise dbus.exceptions.DBusException(
'Device was not claimed before use',
name='net.reactivated.Fprint.Error.ClaimDevice')
device.fingers[device.claimed_user] = []
@dbus.service.method(DEVICE_IFACE,
in_signature='s', out_signature='')
def Claim(device, user):
if device.claimed_user:
raise dbus.exceptions.DBusException(
'Device already in use by %s' % device.claimed_user,
name='net.reactivated.Fprint.Error.AlreadyInUse')
device.claimed_user = user
@dbus.service.method(DEVICE_IFACE,
in_signature='', out_signature='')
def Release(device):
if not device.claimed_user:
raise dbus.exceptions.DBusException(
'Device was not claimed before use',
name='net.reactivated.Fprint.Error.ClaimDevice')
device.claimed_user = None
def can_verify_finger(device, finger_name):
# We should already have checked that there are enrolled fingers
if finger_name == 'any':
return True
if finger_name in device.fingers[device.claimed_user]:
return True
return False
@dbus.service.method(DEVICE_IFACE,
in_signature='s', out_signature='')
def VerifyStart(device, finger_name):
if not device.claimed_user:
raise dbus.exceptions.DBusException(
'Device was not claimed before use',
name='net.reactivated.Fprint.Error.ClaimDevice')
if device.claimed_user not in device.fingers:
raise dbus.exceptions.DBusException(
'No enrolled prints for user \'%s\'' % device.claimed_user,
name='net.reactivated.Fprint.Error.NoEnrolledPrints')
if not finger_name:
raise dbus.exceptions.DBusException(
'Invalid empty finger_name.',
name='org.freedesktop.DBus.Error.InvalidArgs')
if not can_verify_finger(device, finger_name):
raise dbus.exceptions.DBusException(
'Finger \'%s\' not enrolled.' % finger_name,
name='org.freedesktop.DBus.Error.Internal')
if device.action:
raise dbus.exceptions.DBusException(
'Action \'%s\' already in progress' % device.action,
name='net.reactivated.Fprint.Error.AlreadyInUse')
device.action = 'verify'
if finger_name == 'any':
finger_name = device.fingers[device.claimed_user][0]
device.EmitSignal(DEVICE_IFACE, 'VerifyFingerSelected', 's', [
finger_name
])
@dbus.service.method(DEVICE_MOCK_IFACE,
in_signature='sb', out_signature='')
def EmitVerifyStatus(device, result, done):
if (not device.action) or (device.action != 'verify'):
raise dbus.exceptions.DBusException(
'Cannot send verify statuses when not verifying',
name='org.freedesktop.DBus.Error.InvalidArgs')
if result not in VALID_VERIFY_STATUS:
raise dbus.exceptions.DBusException(
'Unknown verify status \'%s\'' % result,
name='org.freedesktop.DBus.Error.InvalidArgs')
device.EmitSignal(DEVICE_IFACE, 'VerifyStatus', 'sb', [
result,
done
])
@dbus.service.method(DEVICE_IFACE,
in_signature='', out_signature='')
def VerifyStop(device):
if device.action != 'verify':
raise dbus.exceptions.DBusException(
'No verification to stop',
name='net.reactivated.Fprint.Error.NoActionInProgress')
device.action = None
@dbus.service.method(DEVICE_IFACE,
in_signature='s', out_signature='')
def EnrollStart(device, finger_name):
if finger_name not in VALID_FINGER_NAMES:
raise dbus.exceptions.DBusException(
'Invalid finger name \'%s\'' % finger_name,
name='net.reactivated.Fprint.Error.InvalidFingername')
if not device.claimed_user:
raise dbus.exceptions.DBusException(
'Device was not claimed before use',
name='net.reactivated.Fprint.Error.ClaimDevice')
if device.action:
raise dbus.exceptions.DBusException(
'Action \'%s\' already in progress' % device.action,
name='net.reactivated.Fprint.Error.AlreadyInUse')
device.action = 'enroll'
@dbus.service.method(DEVICE_MOCK_IFACE,
in_signature='sb', out_signature='')
def EmitEnrollStatus(device, result, done):
if (not device.action) or (device.action != 'enroll'):
raise dbus.exceptions.DBusException(
'Cannot send enroll statuses when not enrolling',
name='org.freedesktop.DBus.Error.InvalidArgs')
if result not in VALID_ENROLL_STATUS:
raise dbus.exceptions.DBusException(
'Unknown enroll status \'%s\'' % result,
name='org.freedesktop.DBus.Error.InvalidArgs')
device.EmitSignal(DEVICE_IFACE, 'EnrollStatus', 'sb', [
result,
done
])
# FIXME save enrolled finger?
@dbus.service.method(DEVICE_IFACE,
in_signature='', out_signature='')
def EnrollStop(device):
if device.action != 'enroll':
raise dbus.exceptions.DBusException(
'No enrollment to stop',
name='net.reactivated.Fprint.Error.NoActionInProgress')
device.action = None
@dbus.service.method(DEVICE_MOCK_IFACE,
in_signature='sas', out_signature='')
def SetEnrolledFingers(device, user, fingers):
'''Convenience method to set the list of enrolled fingers.
The device_path is the return value from AddDevice(), and the
array of fingers must only contain valid finger names.
Returns nothing.
'''
if len(fingers) < 1:
raise dbus.exceptions.DBusException(
'Fingers array must not be empty',
name='org.freedesktop.DBus.Error.InvalidArgs')
for k in fingers:
if k not in VALID_FINGER_NAMES:
raise dbus.exceptions.DBusException(
'Invalid finger name \'%s\'' % k,
name='org.freedesktop.DBus.Error.InvalidArgs')
device.fingers[user] = fingers