1#!/usr/bin/env python3 2# 3# This file is formatted with Python Black 4# 5# Run with pytest 6 7from pathlib import Path 8 9import configparser 10import os 11import pytest 12import re 13 14# see the IDs from 15# https://github.com/torvalds/linux/blob/master/drivers/hid/hid-ids.h#L772 16# https://github.com/torvalds/linux/blob/master/drivers/hid/hid-logitech-dj.c#L1826 17logitech_receivers = [ 18 0xC50C, # USB_DEVICE_ID_S510_RECEIVER 19 0xC517, # USB_DEVICE_ID_S510_RECEIVER_2 20 0xC512, # USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 21 0xC513, # USB_DEVICE_ID_MX3000_RECEIVER 22 0xC51B, # USB_DEVICE_ID_LOGITECH_27MHZ_MOUSE_RECEIVER 23 0xC52B, # USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER 24 0xC52F, # USB_DEVICE_ID_LOGITECH_NANO_RECEIVER 25 0xC532, # USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2 26 0xC534, # USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2 27 0xC539, # USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1 28 0xC53F, # USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1 29 0xC53A, # USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 30 0xC545, # Bolt receiver, not listed in the kernel (yet) 31 0xC547, # Bolt receiver, not listed in the kernel (yet) 32 0xC548, # Bolt receiver, not listed in the kernel (yet) 33] 34 35 36def quirksdir(): 37 return Path(os.getenv("MESON_SOURCE_ROOT") or ".") / "quirks" 38 39 40def pytest_generate_tests(metafunc): 41 # for any function that takes a "quirksfile" argument return the path to 42 # a quirks file 43 if "quirksfile" in metafunc.fixturenames: 44 metafunc.parametrize("quirksfile", [f for f in quirksdir().glob("*.quirks")]) 45 46 47def test_matches_are_valid(quirksfile): 48 quirks = configparser.ConfigParser(strict=True) 49 # Don't convert to lowercase 50 quirks.optionxform = lambda option: option # type: ignore 51 quirks.read(quirksfile) 52 53 for name, section in filter(lambda n: n != "DEFAULT", quirks.items()): 54 bus = section.get("MatchBus") 55 if bus is not None: 56 assert bus in ("ps2", "usb", "bluetooth", "i2c", "spi") 57 58 vid = section.get("MatchVendor") 59 if vid is not None: 60 assert re.match( 61 "0x[0-9A-F]{4}", vid 62 ), f"{quirksfile}: {name}: {vid} must be uppercase hex (0xAB12)" 63 64 pid = section.get("MatchProduct") 65 if pid is not None: 66 assert re.match( 67 "0x[0-9A-F]{4}", pid 68 ), f"{quirksfile}: {name}: {pid} must be uppercase hex (0xAB12)" 69 70 71def test_match_product_is_not_a_logitech_receiver(quirksfile): 72 quirks = configparser.ConfigParser(strict=True) 73 # Don't convert to lowercase 74 quirks.optionxform = lambda option: option # type: ignore 75 quirks.read(quirksfile) 76 77 for name, section in filter(lambda n: n != "DEFAULT", quirks.items()): 78 vid = int(section.get("MatchVendor", "0x0"), 16) 79 if vid == 0x046D: 80 pid = int(section.get("MatchProduct", "0x0"), 16) 81 assert ( 82 pid not in logitech_receivers 83 ), f"{quirksfile}: {name}: applies to a Logitech Receiver" 84 85 86def main(): 87 args = [__file__] 88 try: 89 import xdist # noqa 90 91 ncores = os.environ.get("FDO_CI_CONCURRENT", "auto") 92 args += ["-n", ncores] 93 except ImportError: 94 pass 95 96 return pytest.main(args) 97 98 99if __name__ == "__main__": 100 raise SystemExit(main()) 101