162306a36Sopenharmony_ci#!/bin/env python3
262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0
362306a36Sopenharmony_ci# -*- coding: utf-8 -*-
462306a36Sopenharmony_ci#
562306a36Sopenharmony_ci# Copyright (c) 2017 Benjamin Tissoires <benjamin.tissoires@gmail.com>
662306a36Sopenharmony_ci# Copyright (c) 2017 Red Hat, Inc.
762306a36Sopenharmony_ci
862306a36Sopenharmony_ciimport platform
962306a36Sopenharmony_ciimport pytest
1062306a36Sopenharmony_ciimport re
1162306a36Sopenharmony_ciimport resource
1262306a36Sopenharmony_ciimport subprocess
1362306a36Sopenharmony_cifrom .base import HIDTestUdevRule
1462306a36Sopenharmony_cifrom pathlib import Path
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci# See the comment in HIDTestUdevRule, this doesn't set up but it will clean
1862306a36Sopenharmony_ci# up once the last test exited.
1962306a36Sopenharmony_ci@pytest.fixture(autouse=True, scope="session")
2062306a36Sopenharmony_cidef udev_rules_session_setup():
2162306a36Sopenharmony_ci    with HIDTestUdevRule.instance():
2262306a36Sopenharmony_ci        yield
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci@pytest.fixture(autouse=True, scope="session")
2662306a36Sopenharmony_cidef setup_rlimit():
2762306a36Sopenharmony_ci    resource.setrlimit(resource.RLIMIT_CORE, (0, 0))
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci@pytest.fixture(autouse=True, scope="session")
3162306a36Sopenharmony_cidef start_udevd(pytestconfig):
3262306a36Sopenharmony_ci    if pytestconfig.getoption("udevd"):
3362306a36Sopenharmony_ci        import subprocess
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci        with subprocess.Popen("/usr/lib/systemd/systemd-udevd") as proc:
3662306a36Sopenharmony_ci            yield
3762306a36Sopenharmony_ci            proc.kill()
3862306a36Sopenharmony_ci    else:
3962306a36Sopenharmony_ci        yield
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_cidef pytest_configure(config):
4362306a36Sopenharmony_ci    config.addinivalue_line(
4462306a36Sopenharmony_ci        "markers",
4562306a36Sopenharmony_ci        "skip_if_uhdev(condition, message): mark test to skip if the condition on the uhdev device is met",
4662306a36Sopenharmony_ci    )
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci# Generate the list of modules and modaliases
5062306a36Sopenharmony_ci# for the tests that need to be parametrized with those
5162306a36Sopenharmony_cidef pytest_generate_tests(metafunc):
5262306a36Sopenharmony_ci    if "usbVidPid" in metafunc.fixturenames:
5362306a36Sopenharmony_ci        modules = (
5462306a36Sopenharmony_ci            Path("/lib/modules/")
5562306a36Sopenharmony_ci            / platform.uname().release
5662306a36Sopenharmony_ci            / "kernel"
5762306a36Sopenharmony_ci            / "drivers"
5862306a36Sopenharmony_ci            / "hid"
5962306a36Sopenharmony_ci        )
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci        modalias_re = re.compile(r"alias:\s+hid:b0003g.*v([0-9a-fA-F]+)p([0-9a-fA-F]+)")
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci        params = []
6462306a36Sopenharmony_ci        ids = []
6562306a36Sopenharmony_ci        for module in modules.glob("*.ko"):
6662306a36Sopenharmony_ci            p = subprocess.run(
6762306a36Sopenharmony_ci                ["modinfo", module], capture_output=True, check=True, encoding="utf-8"
6862306a36Sopenharmony_ci            )
6962306a36Sopenharmony_ci            for line in p.stdout.split("\n"):
7062306a36Sopenharmony_ci                m = modalias_re.match(line)
7162306a36Sopenharmony_ci                if m is not None:
7262306a36Sopenharmony_ci                    vid, pid = m.groups()
7362306a36Sopenharmony_ci                    vid = int(vid, 16)
7462306a36Sopenharmony_ci                    pid = int(pid, 16)
7562306a36Sopenharmony_ci                    params.append([module.name.replace(".ko", ""), vid, pid])
7662306a36Sopenharmony_ci                    ids.append(f"{module.name} {vid:04x}:{pid:04x}")
7762306a36Sopenharmony_ci        metafunc.parametrize("usbVidPid", params, ids=ids)
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_cidef pytest_addoption(parser):
8162306a36Sopenharmony_ci    parser.addoption("--udevd", action="store_true", default=False)
82