1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
# encoding: utf-8
import os
import stat
from select import select
from unittest.mock import patch
import pytest
from pytest import raises, fixture, mark
from evdev import uinput, ecodes, device, UInputError
# -----------------------------------------------------------------------------
uinput_options = {
"name": "test-py-evdev-uinput",
"bustype": ecodes.BUS_USB,
"vendor": 0x1100,
"product": 0x2200,
"version": 0x3300,
}
@fixture
def c():
return uinput_options.copy()
def device_exists(bustype, vendor, product, version):
match = "I: Bus=%04hx Vendor=%04hx Product=%04hx Version=%04hx"
match = match % (bustype, vendor, product, version)
for line in open("/proc/bus/input/devices"):
if line.strip() == match:
return True
return False
# -----------------------------------------------------------------------------
@mark.skip(reason="Requires root")
def test_open(c):
ui = uinput.UInput(**c)
args = (c["bustype"], c["vendor"], c["product"], c["version"])
assert device_exists(*args)
ui.close()
assert not device_exists(*args)
@mark.skip(reason="Requires root")
def test_open_context(c):
args = (c["bustype"], c["vendor"], c["product"], c["version"])
with uinput.UInput(**c):
assert device_exists(*args)
assert not device_exists(*args)
def test_maxnamelen(c):
with raises(uinput.UInputError):
c["name"] = "a" * 150
uinput.UInput(**c)
@mark.skip(reason="Requires root")
def test_enable_events(c):
e = ecodes
c["events"] = {e.EV_KEY: [e.KEY_A, e.KEY_B, e.KEY_C]}
with uinput.UInput(**c) as ui:
cap = ui.capabilities()
assert e.EV_KEY in cap
assert sorted(cap[e.EV_KEY]) == sorted(c["events"][e.EV_KEY])
@mark.skip(reason="Requires root")
def test_abs_values(c):
e = ecodes
c = {
e.EV_KEY: [e.KEY_A, e.KEY_B],
e.EV_ABS: [(e.ABS_X, (0, 0, 255, 0, 0)), (e.ABS_Y, device.AbsInfo(0, 0, 255, 5, 10, 0))],
}
with uinput.UInput(events=c) as ui:
c = ui.capabilities()
abs = device.AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0)
assert c[e.EV_ABS][0] == (0, abs)
abs = device.AbsInfo(value=0, min=0, max=255, fuzz=5, flat=10, resolution=0)
assert c[e.EV_ABS][1] == (1, abs)
c = ui.capabilities(verbose=True)
abs = device.AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0)
assert c[("EV_ABS", 3)][0] == (("ABS_X", 0), abs)
c = ui.capabilities(verbose=False, absinfo=False)
assert c[e.EV_ABS] == list((0, 1))
@mark.skip(reason="Requires root")
def test_write(c):
with uinput.UInput(**c) as ui:
d = ui.device
wrote = False
while True:
r, w, x = select([d], [d], [])
if w and not wrote:
ui.write(ecodes.EV_KEY, ecodes.KEY_P, 1) # KEY_P down
ui.write(ecodes.EV_KEY, ecodes.KEY_P, 1) # KEY_P down
ui.write(ecodes.EV_KEY, ecodes.KEY_P, 0) # KEY_P up
ui.write(ecodes.EV_KEY, ecodes.KEY_A, 1) # KEY_A down
ui.write(ecodes.EV_KEY, ecodes.KEY_A, 2) # KEY_A hold
ui.write(ecodes.EV_KEY, ecodes.KEY_A, 0) # KEY_P up
ui.syn()
wrote = True
if r:
evs = list(d.read())
assert evs[0].code == ecodes.KEY_P and evs[0].value == 1
assert evs[1].code == ecodes.KEY_P and evs[1].value == 0
assert evs[2].code == ecodes.KEY_A and evs[2].value == 1
assert evs[3].code == ecodes.KEY_A and evs[3].value == 2
assert evs[4].code == ecodes.KEY_A and evs[4].value == 0
break
@patch.object(stat, 'S_ISCHR', return_value=False)
def test_not_a_character_device(ischr_mock, c):
with pytest.raises(UInputError, match='not a character device file'):
uinput.UInput(**c)
@patch.object(stat, 'S_ISCHR', return_value=True)
@patch.object(os, 'stat', side_effect=OSError())
def test_not_a_character_device_2(stat_mock, ischr_mock, c):
with pytest.raises(UInputError, match='not a character device file'):
uinput.UInput(**c)
@patch.object(stat, 'S_ISCHR', return_value=True)
@patch.object(os, 'stat', return_value=[])
def test_not_a_character_device_3(stat_mock, ischr_mock, c):
with pytest.raises(UInputError, match='not a character device file'):
uinput.UInput(**c)
|