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