dbus/glib testing bulletproofing

pull/1377/head
Chris Caron 2025-07-29 22:25:22 -04:00
parent 90fcc410c8
commit 5cdee8f859
2 changed files with 51 additions and 50 deletions

View File

@ -43,48 +43,47 @@ logging.disable(logging.CRITICAL)
@pytest.fixture @pytest.fixture
def enabled_dbus_environment(mocker): def enabled_dbus_environment(monkeypatch):
"""Fully mocked D-Bus and GI environment with plugin reloaded and """
enabled.""" Fully mocked DBus and GI environment that works in local and CI environments.
"""
# Step 1: Mock DBus Interface # --- Handle dbus (real or fake) ---
interface_mock = mocker.patch("dbus.Interface", spec=True, Notify=Mock()) try:
mocker.patch( import dbus
"dbus.SessionBus", except ImportError:
spec=True, dbus = types.ModuleType("dbus")
**{"get_object.return_value": interface_mock}, dbus.DBusException = type("DBusException", (Exception,), {})
) dbus.Interface = Mock()
dbus.SessionBus = Mock()
# Step 2: Inject valid dbus.mainloop.glib and .qt into sys.modules sys.modules["dbus"] = dbus
fake_loop = Mock(name="FakeMainLoop")
sys.modules["dbus.mainloop.glib"] = types.SimpleNamespace(
DBusGMainLoop=lambda: fake_loop
)
sys.modules["dbus.mainloop.qt"] = types.SimpleNamespace(
DBusQtMainLoop=lambda set_as_default=False: fake_loop
)
# Step 3: Mock GI and GdkPixbuf (also covers image handling) # Inject mainloop support if not already present
if "dbus.mainloop.glib" not in sys.modules:
glib_loop = types.ModuleType("dbus.mainloop.glib")
glib_loop.DBusGMainLoop = lambda: Mock(name="FakeLoop")
sys.modules["dbus.mainloop.glib"] = glib_loop
if "dbus.mainloop" not in sys.modules:
sys.modules["dbus.mainloop"] = types.ModuleType("dbus.mainloop")
# Patch specific attributes always, even if real module is present
monkeypatch.setattr("dbus.Interface", Mock())
monkeypatch.setattr("dbus.SessionBus", Mock())
monkeypatch.setattr("dbus.DBusException", type("DBusException", (Exception,), {}))
# --- Mock GI / GdkPixbuf ---
gi = types.ModuleType("gi") gi = types.ModuleType("gi")
gi.repository = types.ModuleType("gi.repository")
mock_pixbuf = Mock()
mock_image = Mock()
mock_pixbuf.new_from_file.return_value = mock_image
mock_image.get_width.return_value = 100
mock_image.get_height.return_value = 100
mock_image.get_rowstride.return_value = 1
mock_image.get_has_alpha.return_value = 0
mock_image.get_bits_per_sample.return_value = 8
mock_image.get_n_channels.return_value = 1
mock_image.get_pixels.return_value = b""
gi.repository.GdkPixbuf = types.SimpleNamespace(Pixbuf=mock_pixbuf)
gi.require_version = Mock() gi.require_version = Mock()
gi.repository = types.SimpleNamespace(
GdkPixbuf=types.SimpleNamespace(Pixbuf=Mock())
)
sys.modules["gi"] = gi sys.modules["gi"] = gi
sys.modules["gi.repository"] = gi.repository sys.modules["gi.repository"] = gi.repository
# Step 4: Reload plugin after all mocks are in place # --- Reload plugin with controlled env ---
reload_plugin("dbus") reload_plugin("dbus")

View File

@ -41,19 +41,20 @@ logging.disable(logging.CRITICAL)
@pytest.fixture @pytest.fixture
def enabled_glib_environment(mocker): def enabled_glib_environment(monkeypatch):
"""Mocks a working GI/GLib/Gio environment""" """
# Patch GLib.Error and Gio Fully mocked GI/GLib/Gio/GdkPixbuf environment for local and CI.
"""
# Step 1: Fake gi and repository
gi = types.ModuleType("gi") gi = types.ModuleType("gi")
gi.repository = types.SimpleNamespace() gi.require_version = Mock()
fake_variant = Mock(name="Variant")
fake_error = type("GLibError", (Exception,), {})
fake_pixbuf = Mock()
fake_image = Mock()
fake_variant = mocker.MagicMock(name="Variant")
fake_error_type = type("GLibError", (Exception,), {})
fake_pixbuf = mocker.MagicMock(name="Pixbuf")
fake_image = mocker.MagicMock(name="PixbufImage")
fake_pixbuf.new_from_file.return_value = fake_image fake_pixbuf.new_from_file.return_value = fake_image
# Provide fake return values
fake_image.get_width.return_value = 100 fake_image.get_width.return_value = 100
fake_image.get_height.return_value = 100 fake_image.get_height.return_value = 100
fake_image.get_rowstride.return_value = 1 fake_image.get_rowstride.return_value = 1
@ -62,16 +63,17 @@ def enabled_glib_environment(mocker):
fake_image.get_n_channels.return_value = 1 fake_image.get_n_channels.return_value = 1
fake_image.get_pixels.return_value = b"" fake_image.get_pixels.return_value = b""
gi.require_version = Mock() gi.repository = types.SimpleNamespace(
gi.repository.GLib = types.SimpleNamespace( Gio=Mock(),
Error=fake_error_type, Variant=fake_variant) GLib=types.SimpleNamespace(Variant=fake_variant, Error=fake_error),
gi.repository.Gio = mocker.MagicMock(name="Gio") GdkPixbuf=types.SimpleNamespace(Pixbuf=fake_pixbuf),
gi.repository.GdkPixbuf = types.SimpleNamespace( )
Pixbuf=fake_pixbuf)
# Step 2: Inject into sys.modules
sys.modules["gi"] = gi sys.modules["gi"] = gi
sys.modules["gi.repository"] = gi.repository sys.modules["gi.repository"] = gi.repository
# Step 3: Reload plugin with all mocks in place
reload_plugin("glib") reload_plugin("glib")