1#!/bin/env python3
2# SPDX-License-Identifier: GPL-2.0
3# -*- coding: utf-8 -*-
4#
5# Copyright (c) 2017 Benjamin Tissoires <benjamin.tissoires@gmail.com>
6# Copyright (c) 2017 Red Hat, Inc.
7
8import platform
9import pytest
10import re
11import resource
12import subprocess
13from .base import HIDTestUdevRule
14from pathlib import Path
15
16
17# See the comment in HIDTestUdevRule, this doesn't set up but it will clean
18# up once the last test exited.
19@pytest.fixture(autouse=True, scope="session")
20def udev_rules_session_setup():
21    with HIDTestUdevRule.instance():
22        yield
23
24
25@pytest.fixture(autouse=True, scope="session")
26def setup_rlimit():
27    resource.setrlimit(resource.RLIMIT_CORE, (0, 0))
28
29
30@pytest.fixture(autouse=True, scope="session")
31def start_udevd(pytestconfig):
32    if pytestconfig.getoption("udevd"):
33        import subprocess
34
35        with subprocess.Popen("/usr/lib/systemd/systemd-udevd") as proc:
36            yield
37            proc.kill()
38    else:
39        yield
40
41
42def pytest_configure(config):
43    config.addinivalue_line(
44        "markers",
45        "skip_if_uhdev(condition, message): mark test to skip if the condition on the uhdev device is met",
46    )
47
48
49# Generate the list of modules and modaliases
50# for the tests that need to be parametrized with those
51def pytest_generate_tests(metafunc):
52    if "usbVidPid" in metafunc.fixturenames:
53        modules = (
54            Path("/lib/modules/")
55            / platform.uname().release
56            / "kernel"
57            / "drivers"
58            / "hid"
59        )
60
61        modalias_re = re.compile(r"alias:\s+hid:b0003g.*v([0-9a-fA-F]+)p([0-9a-fA-F]+)")
62
63        params = []
64        ids = []
65        for module in modules.glob("*.ko"):
66            p = subprocess.run(
67                ["modinfo", module], capture_output=True, check=True, encoding="utf-8"
68            )
69            for line in p.stdout.split("\n"):
70                m = modalias_re.match(line)
71                if m is not None:
72                    vid, pid = m.groups()
73                    vid = int(vid, 16)
74                    pid = int(pid, 16)
75                    params.append([module.name.replace(".ko", ""), vid, pid])
76                    ids.append(f"{module.name} {vid:04x}:{pid:04x}")
77        metafunc.parametrize("usbVidPid", params, ids=ids)
78
79
80def pytest_addoption(parser):
81    parser.addoption("--udevd", action="store_true", default=False)
82