tools/replay: check the recorded udev properties against the local properties

Where a device is replayed locally for testing, its udev properties should
match the recorded properties. Otherwise the testing results will not be
reliable.

The exception here is the device group which we currently don't set for
emulated devices and even if we did, it may intentionally differ anyway.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2020-09-09 10:50:42 +10:00
parent f86d6a6e5a
commit 5ebd7bd1f0

View file

@ -33,6 +33,7 @@ from pathlib import Path
try:
import libevdev
import yaml
import pyudev
except ModuleNotFoundError as e:
print('Error: {}'.format(e), file=sys.stderr)
print('One or more python modules are missing. Please install those '
@ -60,6 +61,41 @@ def fetch(yaml, key):
raise YamlException('Failed to get \'{}\' from recording.'.format(key))
def check_udev_properties(yaml_data, uinput):
'''
Compare the properties our new uinput device has with the ones from the
recording and ring the alarm bell if one of them is off.
'''
yaml_udev_section = fetch(yaml_data, 'udev')
yaml_udev_props = fetch(yaml_udev_section, 'properties')
yaml_props = {k: v for (k, v) in [prop.split('=', maxsplit=1) for prop in yaml_udev_props]}
try:
# We don't assign this one to virtual devices
del yaml_props['LIBINPUT_DEVICE_GROUP']
except KeyError:
pass
# give udev some time to catch up
time.sleep(0.2)
context = pyudev.Context()
udev_device = pyudev.Devices.from_device_file(context, uinput.devnode)
for name, value in udev_device.properties.items():
if name in yaml_props:
if yaml_props[name] != value:
error(f'Warning: udev property mismatch: recording has {name}={yaml_props[name]}, device has {name}={value}')
del yaml_props[name]
else:
# The list of properties we add to the recording, see libinput-record.c
prefixes = ("ID_INPUT", "LIBINPUT", "EVDEV_ABS", "MOUSE_DPI", "POINTINGSTICK_")
for prefix in prefixes:
if name.startswith(prefix):
error(f'Warning: unexpected property: {name}={value}')
# the ones we found above were removed from the dict
for name, value in yaml_props.items():
error(f'Warning: device is missing recorded udev property: {name}={value}')
def create(device):
evdev = fetch(device, 'evdev')
@ -95,6 +131,9 @@ def create(device):
d.enable(libevdev.propbit(prop))
uinput = d.create_uinput_device()
check_udev_properties(device, uinput)
return uinput