test_quirks_files.py 3.5 KB

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