Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

selftests: hid: import hid-tools hid-gamepad tests

These tests have been developed in the hid-tools[0] tree for a while.
Now that we have a proper selftests/hid kernel entry and that the tests
are more reliable, it is time to directly include those in the kernel
tree.

[0] https://gitlab.freedesktop.org/libevdev/hid-tools

Cc: Candle Sun <candle.sun@unisoc.com>
Cc: Jose Torreguitar <jtguitar@google.com>
Cc: Peter Hutterer <peter.hutterer@who-t.net>
Cc: Roderick Colenbrander <roderick.colenbrander@sony.com>
Cc: Silvan Jegen <s.jegen@gmail.com>
Signed-off-by: Silvan Jegen <s.jegen@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Roderick Colenbrander <roderick.colenbrander@sony.com>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>

+217
+1
tools/testing/selftests/hid/Makefile
··· 6 6 include ../../../scripts/Makefile.include 7 7 8 8 TEST_PROGS := hid-core.sh 9 + TEST_PROGS += hid-gamepad.sh 9 10 10 11 CXX ?= $(CROSS_COMPILE)g++ 11 12
+7
tools/testing/selftests/hid/hid-gamepad.sh
··· 1 + #!/bin/sh 2 + # SPDX-License-Identifier: GPL-2.0 3 + # Runs tests for the HID subsystem 4 + 5 + export TARGET=test_gamepad.py 6 + 7 + bash ./run-hid-tools-tests.sh
+209
tools/testing/selftests/hid/tests/test_gamepad.py
··· 1 + #!/bin/env python3 2 + # SPDX-License-Identifier: GPL-2.0 3 + # -*- coding: utf-8 -*- 4 + # 5 + # Copyright (c) 2019 Benjamin Tissoires <benjamin.tissoires@gmail.com> 6 + # Copyright (c) 2019 Red Hat, Inc. 7 + # 8 + 9 + from . import base 10 + import libevdev 11 + import pytest 12 + 13 + from hidtools.device.base_gamepad import AsusGamepad, SaitekGamepad 14 + 15 + import logging 16 + 17 + logger = logging.getLogger("hidtools.test.gamepad") 18 + 19 + 20 + class BaseTest: 21 + class TestGamepad(base.BaseTestCase.TestUhid): 22 + @pytest.fixture(autouse=True) 23 + def send_initial_state(self): 24 + """send an empty report to initialize the axes""" 25 + uhdev = self.uhdev 26 + 27 + r = uhdev.event() 28 + events = uhdev.next_sync_events() 29 + self.debug_reports(r, uhdev, events) 30 + 31 + def assert_button(self, button): 32 + uhdev = self.uhdev 33 + evdev = uhdev.get_evdev() 34 + syn_event = self.syn_event 35 + 36 + buttons = {} 37 + key = libevdev.evbit(uhdev.buttons_map[button]) 38 + 39 + buttons[button] = True 40 + r = uhdev.event(buttons=buttons) 41 + expected_event = libevdev.InputEvent(key, 1) 42 + events = uhdev.next_sync_events() 43 + self.debug_reports(r, uhdev, events) 44 + self.assertInputEventsIn((syn_event, expected_event), events) 45 + assert evdev.value[key] == 1 46 + 47 + buttons[button] = False 48 + r = uhdev.event(buttons=buttons) 49 + expected_event = libevdev.InputEvent(key, 0) 50 + events = uhdev.next_sync_events() 51 + self.debug_reports(r, uhdev, events) 52 + self.assertInputEventsIn((syn_event, expected_event), events) 53 + assert evdev.value[key] == 0 54 + 55 + def test_buttons(self): 56 + """check for button reliability.""" 57 + uhdev = self.uhdev 58 + 59 + for b in uhdev.buttons: 60 + self.assert_button(b) 61 + 62 + def test_dual_buttons(self): 63 + """check for button reliability when pressing 2 buttons""" 64 + uhdev = self.uhdev 65 + evdev = uhdev.get_evdev() 66 + syn_event = self.syn_event 67 + 68 + # can change intended b1 b2 values 69 + b1 = uhdev.buttons[0] 70 + key1 = libevdev.evbit(uhdev.buttons_map[b1]) 71 + b2 = uhdev.buttons[1] 72 + key2 = libevdev.evbit(uhdev.buttons_map[b2]) 73 + 74 + buttons = {b1: True, b2: True} 75 + r = uhdev.event(buttons=buttons) 76 + expected_event0 = libevdev.InputEvent(key1, 1) 77 + expected_event1 = libevdev.InputEvent(key2, 1) 78 + events = uhdev.next_sync_events() 79 + self.debug_reports(r, uhdev, events) 80 + self.assertInputEventsIn( 81 + (syn_event, expected_event0, expected_event1), events 82 + ) 83 + assert evdev.value[key1] == 1 84 + assert evdev.value[key2] == 1 85 + 86 + buttons = {b1: False, b2: None} 87 + r = uhdev.event(buttons=buttons) 88 + expected_event = libevdev.InputEvent(key1, 0) 89 + events = uhdev.next_sync_events() 90 + self.debug_reports(r, uhdev, events) 91 + self.assertInputEventsIn((syn_event, expected_event), events) 92 + assert evdev.value[key1] == 0 93 + assert evdev.value[key2] == 1 94 + 95 + buttons = {b1: None, b2: False} 96 + r = uhdev.event(buttons=buttons) 97 + expected_event = libevdev.InputEvent(key2, 0) 98 + events = uhdev.next_sync_events() 99 + self.debug_reports(r, uhdev, events) 100 + self.assertInputEventsIn((syn_event, expected_event), events) 101 + assert evdev.value[key1] == 0 102 + assert evdev.value[key2] == 0 103 + 104 + def _get_libevdev_abs_events(self, which): 105 + """Returns which ABS_* evdev axes are expected for the given stick""" 106 + abs_map = self.uhdev.axes_map[which] 107 + 108 + x = abs_map["x"].evdev 109 + y = abs_map["y"].evdev 110 + 111 + assert x 112 + assert y 113 + 114 + return x, y 115 + 116 + def _test_joystick_press(self, which, data): 117 + uhdev = self.uhdev 118 + 119 + libevdev_axes = self._get_libevdev_abs_events(which) 120 + 121 + r = None 122 + if which == "left_stick": 123 + r = uhdev.event(left=data) 124 + else: 125 + r = uhdev.event(right=data) 126 + events = uhdev.next_sync_events() 127 + self.debug_reports(r, uhdev, events) 128 + 129 + for i, d in enumerate(data): 130 + if d is not None and d != 127: 131 + assert libevdev.InputEvent(libevdev_axes[i], d) in events 132 + else: 133 + assert libevdev.InputEvent(libevdev_axes[i]) not in events 134 + 135 + def test_left_joystick_press_left(self): 136 + """check for the left joystick reliability""" 137 + self._test_joystick_press("left_stick", (63, None)) 138 + self._test_joystick_press("left_stick", (0, 127)) 139 + 140 + def test_left_joystick_press_right(self): 141 + """check for the left joystick reliability""" 142 + self._test_joystick_press("left_stick", (191, 127)) 143 + self._test_joystick_press("left_stick", (255, None)) 144 + 145 + def test_left_joystick_press_up(self): 146 + """check for the left joystick reliability""" 147 + self._test_joystick_press("left_stick", (None, 63)) 148 + self._test_joystick_press("left_stick", (127, 0)) 149 + 150 + def test_left_joystick_press_down(self): 151 + """check for the left joystick reliability""" 152 + self._test_joystick_press("left_stick", (127, 191)) 153 + self._test_joystick_press("left_stick", (None, 255)) 154 + 155 + def test_right_joystick_press_left(self): 156 + """check for the right joystick reliability""" 157 + self._test_joystick_press("right_stick", (63, None)) 158 + self._test_joystick_press("right_stick", (0, 127)) 159 + 160 + def test_right_joystick_press_right(self): 161 + """check for the right joystick reliability""" 162 + self._test_joystick_press("right_stick", (191, 127)) 163 + self._test_joystick_press("right_stick", (255, None)) 164 + 165 + def test_right_joystick_press_up(self): 166 + """check for the right joystick reliability""" 167 + self._test_joystick_press("right_stick", (None, 63)) 168 + self._test_joystick_press("right_stick", (127, 0)) 169 + 170 + def test_right_joystick_press_down(self): 171 + """check for the right joystick reliability""" 172 + self._test_joystick_press("right_stick", (127, 191)) 173 + self._test_joystick_press("right_stick", (None, 255)) 174 + 175 + @pytest.mark.skip_if_uhdev( 176 + lambda uhdev: "Hat switch" not in uhdev.fields, 177 + "Device not compatible, missing Hat switch usage", 178 + ) 179 + @pytest.mark.parametrize( 180 + "hat_value,expected_evdev,evdev_value", 181 + [ 182 + (0, "ABS_HAT0Y", -1), 183 + (2, "ABS_HAT0X", 1), 184 + (4, "ABS_HAT0Y", 1), 185 + (6, "ABS_HAT0X", -1), 186 + ], 187 + ) 188 + def test_hat_switch(self, hat_value, expected_evdev, evdev_value): 189 + uhdev = self.uhdev 190 + 191 + r = uhdev.event(hat_switch=hat_value) 192 + events = uhdev.next_sync_events() 193 + self.debug_reports(r, uhdev, events) 194 + assert ( 195 + libevdev.InputEvent( 196 + libevdev.evbit("EV_ABS", expected_evdev), evdev_value 197 + ) 198 + in events 199 + ) 200 + 201 + 202 + class TestSaitekGamepad(BaseTest.TestGamepad): 203 + def create_device(self): 204 + return SaitekGamepad() 205 + 206 + 207 + class TestAsusGamepad(BaseTest.TestGamepad): 208 + def create_device(self): 209 + return AsusGamepad()