testing grab retries and capability modification

This commit is contained in:
sezanzeb 2020-11-19 11:30:01 +01:00
parent 46eafc48da
commit 6def1dcc54
3 changed files with 95 additions and 54 deletions

View File

@ -75,8 +75,9 @@ def _modify_capabilities(device):
# to act like the device. # to act like the device.
capabilities = device.capabilities(absinfo=False) capabilities = device.capabilities(absinfo=False)
# However, make sure that it supports all keycodes, not just some # However, make sure that it supports all keycodes, not just some
# random ones. That's why I avoid from_device for this # random ones, because the mapping could contain anything.
capabilities[evdev.ecodes.EV_KEY] = evdev.ecodes.keys.keys() # That's why I avoid from_device for this
capabilities[evdev.ecodes.EV_KEY] = list(evdev.ecodes.keys.keys())
# just like what python-evdev does in from_device # just like what python-evdev does in from_device
if evdev.ecodes.EV_SYN in capabilities: if evdev.ecodes.EV_SYN in capabilities:

View File

@ -24,6 +24,9 @@
import sys import sys
import unittest import unittest
import evdev
from keymapper.logger import update_verbosity from keymapper.logger import update_verbosity
@ -31,51 +34,6 @@ tmp = '/tmp/key-mapper-test'
uinput_write_history = [] uinput_write_history = []
pending_events = {} pending_events = {}
def get_events():
"""Get all events written by the injector."""
return uinput_write_history
def push_event(device, event):
"""Emit a fake event for a device.
Parameters
----------
device : string
For example 'device 1'
event : Event
"""
if pending_events.get(device) is None:
pending_events[device] = []
pending_events[device].append(event)
class Event:
"""Event to put into the injector for tests."""
def __init__(self, type, code, value):
"""
Paramaters
----------
type : int
one of evdev.ecodes.EV_*
code : int
keyboard event code as known to linux. E.g. 2 for the '1' button
value : int
1 for down, 0 for up, 2 for hold
"""
self.type = type
self.code = code
self.value = value
def patch_paths():
from keymapper import paths
paths.CONFIG = '/tmp/key-mapper-test/'
def patch_evdev():
import evdev
# key-mapper is only interested in devices that have EV_KEY, add some # key-mapper is only interested in devices that have EV_KEY, add some
# random other stuff to test that they are ignored. # random other stuff to test that they are ignored.
fixtures = { fixtures = {
@ -124,6 +82,50 @@ def patch_evdev():
}, },
} }
def get_events():
"""Get all events written by the injector."""
return uinput_write_history
def push_event(device, event):
"""Emit a fake event for a device.
Parameters
----------
device : string
For example 'device 1'
event : Event
"""
if pending_events.get(device) is None:
pending_events[device] = []
pending_events[device].append(event)
class Event:
"""Event to put into the injector for tests."""
def __init__(self, type, code, value):
"""
Paramaters
----------
type : int
one of evdev.ecodes.EV_*
code : int
keyboard event code as known to linux. E.g. 2 for the '1' button
value : int
1 for down, 0 for up, 2 for hold
"""
self.type = type
self.code = code
self.value = value
def patch_paths():
from keymapper import paths
paths.CONFIG = '/tmp/key-mapper-test/'
def patch_evdev():
def list_devices(): def list_devices():
return fixtures.keys() return fixtures.keys()

View File

@ -23,23 +23,61 @@ import unittest
import evdev import evdev
from keymapper.injector import _start_injecting_worker, \ from keymapper.injector import _start_injecting_worker, _grab, \
is_numlock_on, toggle_numlock, ensure_numlock is_numlock_on, toggle_numlock, ensure_numlock, _modify_capabilities
from keymapper.getdevices import get_devices from keymapper.getdevices import get_devices
from keymapper.state import custom_mapping, system_mapping from keymapper.state import custom_mapping, system_mapping
from test import uinput_write_history, Event, pending_events from test import uinput_write_history, Event, pending_events, fixtures
class TestInjector(unittest.TestCase): class TestInjector(unittest.TestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
cls.injector = None cls.injector = None
cls.grab = evdev.InputDevice.grab
def setUp(self):
self.failed = 0
def grab_fail_twice(_):
if self.failed < 2:
self.failed += 1
raise OSError()
evdev.InputDevice.grab = grab_fail_twice
def tearDown(self): def tearDown(self):
if self.injector is not None: if self.injector is not None:
self.injector.stop_injecting() self.injector.stop_injecting()
self.injector = None self.injector = None
evdev.InputDevice.grab = self.grab
def test_modify_capabilities(self):
class FakeDevice:
def capabilities(self, absinfo=True):
assert absinfo is False
return {
evdev.ecodes.EV_SYN: [1, 2, 3],
evdev.ecodes.EV_FF: [1, 2, 3]
}
capabilities = _modify_capabilities(FakeDevice())
self.assertIn(evdev.ecodes.EV_KEY, capabilities)
self.assertIsInstance(capabilities[evdev.ecodes.EV_KEY], list)
self.assertIsInstance(capabilities[evdev.ecodes.EV_KEY][0], int)
self.assertNotIn(evdev.ecodes.EV_SYN, capabilities)
self.assertNotIn(evdev.ecodes.EV_FF, capabilities)
def test_grab(self):
# path is from the fixtures
path = '/dev/input/event11'
device = _grab(path)
self.assertEqual(self.failed, 2)
# success on the third try
device.name = fixtures[path]['name']
def test_numlock(self): def test_numlock(self):
before = is_numlock_on() before = is_numlock_on()