File: test_uinput.py

package info (click to toggle)
python-evdev 1.9.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 416 kB
  • sloc: python: 1,388; ansic: 739; makefile: 142; sh: 14
file content (142 lines) | stat: -rw-r--r-- 4,487 bytes parent folder | download
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)