# Path: tests/_constants.py
# def _UDEV_TEST(version, node=None):  # pylint: disable=invalid-name
#     fmt_str = "%s: udev version must be at least %s, is %s"
#     return pytest.mark.skipif(
#         _UDEV_VERSION < version, reason=fmt_str % (node, version, _UDEV_VERSION)
#     )
# 
# Path: tests/utils/udev.py
# class DeviceDatabase(collections.abc.Iterable, collections.abc.Sized):
#     """
#     The udev device database.
# 
#     Takes a snapshot of the udev device database when it is initialized.
#     Consequently, some :class:`DeviceData` objects in the database may
#     not exist when the database is iterated over.
# 
#     This class is an iterable over :class:`DeviceData` objects that contain the
#     data associated with each device stored in the udev database.
#     """
# 
#     _db = None
# 
#     @classmethod
#     def db(cls, renew=False):  # pylint: disable=invalid-name
#         """
#         Get a database object.
# 
#         :param bool renew: if renew is True, get a new object
#         :returns: a database object
#         :rtype: :class:`DeviceDatabase`
#         """
#         if cls._db is None or renew:
#             udevadm = UDevAdm.adm()
#             if udevadm:
#                 cls._db = DeviceDatabase(udevadm)
#         return cls._db
# 
#     def __init__(self, udevadm):
#         self._udevadm = udevadm
#         self._devices = set(self._udevadm.query_devices())
# 
#     def __iter__(self):
#         return (
#             d for d in (DeviceData(d, self._udevadm) for d in self._devices) if d.exists
#         )
# 
#     def __len__(self):
#         return sum(1 for _ in self)
# 
#     def find_device_data(self, device_path):
#         """
#         Find device data for the device designated by ``device_path``.
# 
#         ``device_path`` is a string containing the device path.
# 
#         Return a :class:`DeviceData` object containing the data for the given
#         device, or ``None`` if the device was not found.
#         """
#         data = DeviceData(device_path, self._udevadm)
#         return data if data.exists and data in self else None


import random
import pytest
    import mock
from contextlib import contextmanager
from datetime import datetime, timedelta
from select import select
from tests._constants import _UDEV_TEST
from tests.utils.udev import DeviceDatabase
from pyudev import Devices, Monitor, MonitorObserver
    from unittest import mock
        spec = lambda m, s, t: None
        libudev = monitor._libudev
        with mock.patch.object(libudev, funcname, autospec=spec) as match:
            funcname = "udev_monitor_filter_update"
            spec = lambda m: None
            with mock.patch.object(libudev, funcname, autospec=spec) as update:
                monitor.filter_by("input")
                match.assert_called_once_with(monitor, b"input", None)
                update.assert_called_once_with(monitor)

    def test_filter_by_subsystem_dev_type(self, monitor):
        monitor.filter_by("input", b"usb_interface")
        monitor.filter_by("input", "usb_interface")

    def test_filter_by_subsystem_dev_type_mock(self, monitor):
        funcname = "udev_monitor_filter_add_match_subsystem_devtype"
        spec = lambda m, s, t: None
        libudev = monitor._libudev
        with mock.patch.object(libudev, funcname, autospec=spec) as match:
            funcname = "udev_monitor_filter_update"
            spec = lambda m: None
            with mock.patch.object(libudev, funcname, autospec=spec) as update:
                monitor.filter_by("input", "usb_interface")
                match.assert_called_once_with(monitor, b"input", b"usb_interface")
                update.assert_called_once_with(monitor)

    @_UDEV_TEST(154, "test_filter_by_tag")
    def test_filter_by_tag(self, monitor):
        monitor.filter_by_tag("spam")


# Path: tests/_constants.py
# def _UDEV_TEST(version, node=None):  # pylint: disable=invalid-name
#     fmt_str = "%s: udev version must be at least %s, is %s"
#     return pytest.mark.skipif(
#         _UDEV_VERSION < version, reason=fmt_str % (node, version, _UDEV_VERSION)
#     )
# 
# Path: tests/utils/udev.py
# class DeviceDatabase(collections.abc.Iterable, collections.abc.Sized):
#     """
#     The udev device database.
# 
#     Takes a snapshot of the udev device database when it is initialized.
#     Consequently, some :class:`DeviceData` objects in the database may
#     not exist when the database is iterated over.
# 
#     This class is an iterable over :class:`DeviceData` objects that contain the
#     data associated with each device stored in the udev database.
#     """
# 
#     _db = None
# 
#     @classmethod
#     def db(cls, renew=False):  # pylint: disable=invalid-name
#         """
#         Get a database object.
# 
#         :param bool renew: if renew is True, get a new object
#         :returns: a database object
#         :rtype: :class:`DeviceDatabase`
#         """
#         if cls._db is None or renew:
#             udevadm = UDevAdm.adm()
#             if udevadm:
#                 cls._db = DeviceDatabase(udevadm)
#         return cls._db
# 
#     def __init__(self, udevadm):
#         self._udevadm = udevadm
#         self._devices = set(self._udevadm.query_devices())
# 
#     def __iter__(self):
#         return (
#             d for d in (DeviceData(d, self._udevadm) for d in self._devices) if d.exists
#         )
# 
#     def __len__(self):
#         return sum(1 for _ in self)
# 
#     def find_device_data(self, device_path):
#         """
#         Find device data for the device designated by ``device_path``.
# 
#         ``device_path`` is a string containing the device path.
# 
#         Return a :class:`DeviceData` object containing the data for the given
#         device, or ``None`` if the device was not found.
#         """
#         data = DeviceData(device_path, self._udevadm)
#         return data if data.exists and data in self else None


# Path: tests/test_monitor.py
import random
import pytest
    import mock
from contextlib import contextmanager
from datetime import datetime, timedelta
from select import select
from tests._constants import _UDEV_TEST
from tests.utils.udev import DeviceDatabase
from pyudev import Devices, Monitor, MonitorObserver
    from unittest import mock

        spec = lambda m, s, t: None
        libudev = monitor._libudev
        with mock.patch.object(libudev, funcname, autospec=spec) as match:
            funcname = "udev_monitor_filter_update"
            spec = lambda m: None
            with mock.patch.object(libudev, funcname, autospec=spec) as update:
                monitor.filter_by("input")
                match.assert_called_once_with(monitor, b"input", None)
                update.assert_called_once_with(monitor)

    def test_filter_by_subsystem_dev_type(self, monitor):
        monitor.filter_by("input", b"usb_interface")
        monitor.filter_by("input", "usb_interface")

    def test_filter_by_subsystem_dev_type_mock(self, monitor):
        funcname = "udev_monitor_filter_add_match_subsystem_devtype"
        spec = lambda m, s, t: None
        libudev = monitor._libudev
        with mock.patch.object(libudev, funcname, autospec=spec) as match:
            funcname = "udev_monitor_filter_update"
            spec = lambda m: None
            with mock.patch.object(libudev, funcname, autospec=spec) as update:
                monitor.filter_by("input", "usb_interface")
                match.assert_called_once_with(monitor, b"input", b"usb_interface")
                update.assert_called_once_with(monitor)

    @_UDEV_TEST(154, "test_filter_by_tag")
    def test_filter_by_tag(self, monitor):
        monitor.filter_by_tag("spam")


    @_UDEV_TEST(154, "test_filter_by_tag")