From 1c80dd2b08f4bd4f3187909f78b3d1801764e553 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Sat, 24 Jan 2026 15:57:27 +0100 Subject: [PATCH 1/7] Move all license comments to SPDX-License-Identifier --- dbusmock/__init__.py | 6 +----- dbusmock/__main__.py | 6 +----- dbusmock/mockobject.py | 6 +----- dbusmock/pytest_fixtures.py | 6 +----- dbusmock/templates/__init__.py | 6 +----- dbusmock/templates/bluez5-obex.py | 6 +----- dbusmock/templates/bluez5.py | 6 +----- dbusmock/templates/gnome_screensaver.py | 6 +----- dbusmock/templates/gsd_rfkill.py | 6 +----- dbusmock/templates/logind.py | 6 +----- dbusmock/templates/low_memory_monitor.py | 6 +----- dbusmock/templates/modemmanager.py | 6 +----- dbusmock/templates/networkmanager.py | 6 +----- dbusmock/templates/notification_daemon.py | 6 +----- dbusmock/templates/ofono.py | 6 +----- dbusmock/templates/polkitd.py | 6 +----- dbusmock/templates/power_profiles_daemon.py | 6 +----- dbusmock/templates/systemd.py | 6 +----- dbusmock/templates/timedated.py | 6 +----- dbusmock/templates/upower.py | 6 +----- dbusmock/templates/upower_power_profiles_daemon.py | 6 +----- dbusmock/templates/urfkill.py | 6 +----- dbusmock/testcase.py | 6 +----- tests/test_api.py | 6 +----- tests/test_api_pytest.py | 6 +----- tests/test_bluez5.py | 6 +----- tests/test_cli.py | 6 +----- tests/test_code.py | 6 +----- tests/test_gnome_screensaver.py | 6 +----- tests/test_gsd_rfkill.py | 6 +----- tests/test_logind.py | 6 +----- tests/test_low_memory_monitor.py | 6 +----- tests/test_modemmanager.py | 6 +----- tests/test_networkmanager.py | 6 +----- tests/test_notification_daemon.py | 6 +----- tests/test_ofono.py | 6 +----- tests/test_polkitd.py | 6 +----- tests/test_power_profiles_daemon.py | 6 +----- tests/test_systemd.py | 6 +----- tests/test_timedated.py | 6 +----- tests/test_upower.py | 6 +----- tests/test_urfkill.py | 6 +----- 42 files changed, 42 insertions(+), 210 deletions(-) diff --git a/dbusmock/__init__.py b/dbusmock/__init__.py index ee5bc8af..3ec4b001 100644 --- a/dbusmock/__init__.py +++ b/dbusmock/__init__.py @@ -1,10 +1,6 @@ """Mock D-Bus objects for test suites.""" -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later from dbusmock.mockobject import MOCK_IFACE, OBJECT_MANAGER_IFACE, DBusMockObject, get_object, get_objects from dbusmock.testcase import BusType, DBusTestCase, PrivateDBus, SpawnedMock diff --git a/dbusmock/__main__.py b/dbusmock/__main__.py index a21c78f9..8c04c5a5 100644 --- a/dbusmock/__main__.py +++ b/dbusmock/__main__.py @@ -1,10 +1,6 @@ """Main entry point for running mock server.""" -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Martin Pitt" __copyright__ = """ diff --git a/dbusmock/mockobject.py b/dbusmock/mockobject.py index 14f40a44..1a66cde2 100644 --- a/dbusmock/mockobject.py +++ b/dbusmock/mockobject.py @@ -1,10 +1,6 @@ """Mock D-Bus objects for test suites.""" -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Martin Pitt" __copyright__ = """ diff --git a/dbusmock/pytest_fixtures.py b/dbusmock/pytest_fixtures.py index d3e70a43..a6c508f8 100644 --- a/dbusmock/pytest_fixtures.py +++ b/dbusmock/pytest_fixtures.py @@ -1,10 +1,6 @@ """pytest fixtures for DBusMock""" -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Martin Pitt" __copyright__ = "(c) 2023 Martin Pitt " diff --git a/dbusmock/templates/__init__.py b/dbusmock/templates/__init__.py index ea9212dd..159cbae7 100644 --- a/dbusmock/templates/__init__.py +++ b/dbusmock/templates/__init__.py @@ -1,7 +1,3 @@ """Mock templates for common D-Bus services""" -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later diff --git a/dbusmock/templates/bluez5-obex.py b/dbusmock/templates/bluez5-obex.py index d6192ecf..e14c70f7 100644 --- a/dbusmock/templates/bluez5-obex.py +++ b/dbusmock/templates/bluez5-obex.py @@ -7,11 +7,7 @@ This supports BlueZ 5 only. """ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Philip Withnall" __copyright__ = """ diff --git a/dbusmock/templates/bluez5.py b/dbusmock/templates/bluez5.py index a1ef46d3..c27ce6a0 100644 --- a/dbusmock/templates/bluez5.py +++ b/dbusmock/templates/bluez5.py @@ -7,11 +7,7 @@ This supports BlueZ 5 only. """ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Philip Withnall" __copyright__ = """ diff --git a/dbusmock/templates/gnome_screensaver.py b/dbusmock/templates/gnome_screensaver.py index 143df57f..772f19ab 100644 --- a/dbusmock/templates/gnome_screensaver.py +++ b/dbusmock/templates/gnome_screensaver.py @@ -4,11 +4,7 @@ org.gnome.ScreenSaver object. """ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Bastien Nocera" __copyright__ = """ diff --git a/dbusmock/templates/gsd_rfkill.py b/dbusmock/templates/gsd_rfkill.py index a4cea27e..588f14de 100644 --- a/dbusmock/templates/gsd_rfkill.py +++ b/dbusmock/templates/gsd_rfkill.py @@ -5,11 +5,7 @@ "parameters". """ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Guido Günther" __copyright__ = "2024 The Phosh Developers" diff --git a/dbusmock/templates/logind.py b/dbusmock/templates/logind.py index 6440c3a3..37929870 100644 --- a/dbusmock/templates/logind.py +++ b/dbusmock/templates/logind.py @@ -5,11 +5,7 @@ like "CanSuspend" or the return value of Inhibit() in "parameters". """ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Martin Pitt" __copyright__ = """ diff --git a/dbusmock/templates/low_memory_monitor.py b/dbusmock/templates/low_memory_monitor.py index c29e5e93..081fd852 100644 --- a/dbusmock/templates/low_memory_monitor.py +++ b/dbusmock/templates/low_memory_monitor.py @@ -6,11 +6,7 @@ This provides only the 2.0 D-Bus API of low-memory-monitor. """ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Bastien Nocera" __copyright__ = """ diff --git a/dbusmock/templates/modemmanager.py b/dbusmock/templates/modemmanager.py index c363c2aa..e4754b77 100644 --- a/dbusmock/templates/modemmanager.py +++ b/dbusmock/templates/modemmanager.py @@ -5,11 +5,7 @@ such as DaemonVersion in "parameters". """ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Guido Günther" __copyright__ = "2024 The Phosh Developers" diff --git a/dbusmock/templates/networkmanager.py b/dbusmock/templates/networkmanager.py index f9dab3e4..318e4aa0 100644 --- a/dbusmock/templates/networkmanager.py +++ b/dbusmock/templates/networkmanager.py @@ -6,11 +6,7 @@ "parameters". """ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Iftikhar Ahmad" __copyright__ = """ diff --git a/dbusmock/templates/notification_daemon.py b/dbusmock/templates/notification_daemon.py index 7ac602c4..fa106d4d 100644 --- a/dbusmock/templates/notification_daemon.py +++ b/dbusmock/templates/notification_daemon.py @@ -5,11 +5,7 @@ "parameters". """ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Martin Pitt" __copyright__ = """ diff --git a/dbusmock/templates/ofono.py b/dbusmock/templates/ofono.py index c88cd28e..074102aa 100644 --- a/dbusmock/templates/ofono.py +++ b/dbusmock/templates/ofono.py @@ -1,10 +1,6 @@ """ofonod D-Bus mock template""" -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Martin Pitt" __copyright__ = """ diff --git a/dbusmock/templates/polkitd.py b/dbusmock/templates/polkitd.py index c8c65754..7e50748c 100644 --- a/dbusmock/templates/polkitd.py +++ b/dbusmock/templates/polkitd.py @@ -6,11 +6,7 @@ which actions are allowed. """ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Martin Pitt" __copyright__ = """ diff --git a/dbusmock/templates/power_profiles_daemon.py b/dbusmock/templates/power_profiles_daemon.py index 5986cdbc..df54b5eb 100644 --- a/dbusmock/templates/power_profiles_daemon.py +++ b/dbusmock/templates/power_profiles_daemon.py @@ -8,11 +8,7 @@ bus name/object path, it is provided in upower_power_profiles_daemon.py """ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Bastien Nocera" __copyright__ = """ diff --git a/dbusmock/templates/systemd.py b/dbusmock/templates/systemd.py index f1fe5085..6c4f6392 100644 --- a/dbusmock/templates/systemd.py +++ b/dbusmock/templates/systemd.py @@ -1,10 +1,6 @@ """systemd mock template""" -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Jonas Ådahl" __copyright__ = """ diff --git a/dbusmock/templates/timedated.py b/dbusmock/templates/timedated.py index 65209748..24d667eb 100644 --- a/dbusmock/templates/timedated.py +++ b/dbusmock/templates/timedated.py @@ -5,11 +5,7 @@ "Timezone" or "NTP" in "parameters". """ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Iain Lane" __copyright__ = """ diff --git a/dbusmock/templates/upower.py b/dbusmock/templates/upower.py index 3d649e6d..6958edd0 100644 --- a/dbusmock/templates/upower.py +++ b/dbusmock/templates/upower.py @@ -8,11 +8,7 @@ This provides the 1.0 D-Bus API of upower. """ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Martin Pitt" __copyright__ = """ diff --git a/dbusmock/templates/upower_power_profiles_daemon.py b/dbusmock/templates/upower_power_profiles_daemon.py index 2c945eb0..25f0ba44 100644 --- a/dbusmock/templates/upower_power_profiles_daemon.py +++ b/dbusmock/templates/upower_power_profiles_daemon.py @@ -6,11 +6,7 @@ This provides the D-Bus API as of version 0.20. """ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Bastien Nocera" __copyright__ = """ diff --git a/dbusmock/templates/urfkill.py b/dbusmock/templates/urfkill.py index 75669615..3dce2b2a 100644 --- a/dbusmock/templates/urfkill.py +++ b/dbusmock/templates/urfkill.py @@ -5,11 +5,7 @@ such as urfkill in "parameters". """ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Jussi Pakkanen" __copyright__ = """ diff --git a/dbusmock/testcase.py b/dbusmock/testcase.py index 97a73e72..ed926897 100644 --- a/dbusmock/testcase.py +++ b/dbusmock/testcase.py @@ -1,10 +1,6 @@ """unittest.TestCase convenience methods for DBusMocks""" -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Martin Pitt" __copyright__ = """ diff --git a/tests/test_api.py b/tests/test_api.py index 334d99a1..edb27972 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1,8 +1,4 @@ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Martin Pitt" __copyright__ = """ diff --git a/tests/test_api_pytest.py b/tests/test_api_pytest.py index d232470f..854814f9 100644 --- a/tests/test_api_pytest.py +++ b/tests/test_api_pytest.py @@ -1,8 +1,4 @@ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Martin Pitt" __copyright__ = """ diff --git a/tests/test_bluez5.py b/tests/test_bluez5.py index 17c13599..da28e78a 100644 --- a/tests/test_bluez5.py +++ b/tests/test_bluez5.py @@ -1,8 +1,4 @@ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Philip Withnall" __copyright__ = """ diff --git a/tests/test_cli.py b/tests/test_cli.py index eaabef8e..5b99bd88 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,8 +1,4 @@ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Martin Pitt" __copyright__ = """ diff --git a/tests/test_code.py b/tests/test_code.py index c5ccace6..a1a801a3 100644 --- a/tests/test_code.py +++ b/tests/test_code.py @@ -1,8 +1,4 @@ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Martin Pitt" __copyright__ = """ diff --git a/tests/test_gnome_screensaver.py b/tests/test_gnome_screensaver.py index 62d7e72a..6c5ebe74 100644 --- a/tests/test_gnome_screensaver.py +++ b/tests/test_gnome_screensaver.py @@ -1,8 +1,4 @@ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Martin Pitt" __copyright__ = """ diff --git a/tests/test_gsd_rfkill.py b/tests/test_gsd_rfkill.py index 3c07173a..994b7fb1 100644 --- a/tests/test_gsd_rfkill.py +++ b/tests/test_gsd_rfkill.py @@ -1,8 +1,4 @@ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Guido Günther" __copyright__ = "2024 The Phosh Developers" diff --git a/tests/test_logind.py b/tests/test_logind.py index 8ca2b666..302c38cf 100644 --- a/tests/test_logind.py +++ b/tests/test_logind.py @@ -1,8 +1,4 @@ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Martin Pitt" __copyright__ = """ diff --git a/tests/test_low_memory_monitor.py b/tests/test_low_memory_monitor.py index 980ddbe4..ee610bfa 100644 --- a/tests/test_low_memory_monitor.py +++ b/tests/test_low_memory_monitor.py @@ -1,8 +1,4 @@ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Bastien Nocera" __copyright__ = """ diff --git a/tests/test_modemmanager.py b/tests/test_modemmanager.py index 8b3ee207..89ed5352 100644 --- a/tests/test_modemmanager.py +++ b/tests/test_modemmanager.py @@ -1,8 +1,4 @@ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Guido Günther" __copyright__ = """ diff --git a/tests/test_networkmanager.py b/tests/test_networkmanager.py index 40a73847..784362c9 100644 --- a/tests/test_networkmanager.py +++ b/tests/test_networkmanager.py @@ -1,8 +1,4 @@ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Iftikhar Ahmad" __copyright__ = """ diff --git a/tests/test_notification_daemon.py b/tests/test_notification_daemon.py index edbd425f..6aae4a3a 100644 --- a/tests/test_notification_daemon.py +++ b/tests/test_notification_daemon.py @@ -1,8 +1,4 @@ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Martin Pitt" __copyright__ = """ diff --git a/tests/test_ofono.py b/tests/test_ofono.py index ac30cb8b..474d53e8 100644 --- a/tests/test_ofono.py +++ b/tests/test_ofono.py @@ -1,8 +1,4 @@ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Martin Pitt" __copyright__ = """ diff --git a/tests/test_polkitd.py b/tests/test_polkitd.py index 2f14abc4..ca48140d 100644 --- a/tests/test_polkitd.py +++ b/tests/test_polkitd.py @@ -1,8 +1,4 @@ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Martin Pitt" __copyright__ = """ diff --git a/tests/test_power_profiles_daemon.py b/tests/test_power_profiles_daemon.py index 23a383f9..31c54825 100644 --- a/tests/test_power_profiles_daemon.py +++ b/tests/test_power_profiles_daemon.py @@ -1,8 +1,4 @@ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Bastien Nocera" __copyright__ = """ diff --git a/tests/test_systemd.py b/tests/test_systemd.py index 6ee0ab21..9a486d04 100644 --- a/tests/test_systemd.py +++ b/tests/test_systemd.py @@ -1,8 +1,4 @@ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Jonas Ådahl" __copyright__ = """ diff --git a/tests/test_timedated.py b/tests/test_timedated.py index e05cd944..e99131ea 100644 --- a/tests/test_timedated.py +++ b/tests/test_timedated.py @@ -1,8 +1,4 @@ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Iain Lane" __copyright__ = """ diff --git a/tests/test_upower.py b/tests/test_upower.py index 24abd8ca..da40042c 100644 --- a/tests/test_upower.py +++ b/tests/test_upower.py @@ -1,8 +1,4 @@ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Martin Pitt" __copyright__ = """ diff --git a/tests/test_urfkill.py b/tests/test_urfkill.py index fe2d125e..4c2a573d 100644 --- a/tests/test_urfkill.py +++ b/tests/test_urfkill.py @@ -1,8 +1,4 @@ -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) any -# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text -# of the license. +# SPDX-License-Identifier: LGPL-3.0-or-later __author__ = "Jussi Pakkanen" __copyright__ = """ From c1037076ab492e45b350aed3e7454be1d5320638 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Sat, 24 Jan 2026 09:17:23 +0100 Subject: [PATCH 2/7] tests: Factorize repeated spawn_server_template() --- tests/test_logind.py | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/tests/test_logind.py b/tests/test_logind.py index 302c38cf..0e3f70a2 100644 --- a/tests/test_logind.py +++ b/tests/test_logind.py @@ -3,7 +3,7 @@ __author__ = "Martin Pitt" __copyright__ = """ (c) 2013 Canonical Ltd. -(c) 2017 - 2022 Martin Pitt +(c) 2017 - 2025 Martin Pitt """ import re @@ -37,16 +37,12 @@ def setUpClass(cls): cls.version = re.search(r"(\d+)", out.splitlines()[0]).group(1) def setUp(self): - self.p_mock = None - - def tearDown(self): - if self.p_mock: - self.p_mock.stdout.close() - self.p_mock.terminate() - self.p_mock.wait() + (self.p_mock, self.obj_logind) = self.spawn_server_template("logind", {}, stdout=subprocess.PIPE) + self.addCleanup(self.p_mock.wait) + self.addCleanup(self.p_mock.terminate) + self.addCleanup(self.p_mock.stdout.close) def test_empty(self): - (self.p_mock, _) = self.spawn_server_template("logind", {}, stdout=subprocess.PIPE) cmd = ["loginctl"] if self.version >= "209": cmd.append("--no-legend") @@ -60,9 +56,7 @@ def test_empty(self): self.assertEqual(out, "") def test_session(self): - (self.p_mock, obj_logind) = self.spawn_server_template("logind", {}, stdout=subprocess.PIPE) - - obj_logind.AddSession("c1", "seat0", 500, "joe", True) + self.obj_logind.AddSession("c1", "seat0", 500, "joe", True) out = subprocess.check_output(["loginctl", "list-seats"], text=True) self.assertRegex(out, r"(^|\n)seat0\s+") @@ -108,16 +102,13 @@ def test_session(self): self.assertRegex(out, "LockedHint=yes") def test_properties(self): - (self.p_mock, obj_logind) = self.spawn_server_template("logind", {}, stdout=subprocess.PIPE) - props = obj_logind.GetAll("org.freedesktop.login1.Manager", interface=dbus.PROPERTIES_IFACE) + props = self.obj_logind.GetAll("org.freedesktop.login1.Manager", interface=dbus.PROPERTIES_IFACE) self.assertEqual(props["PreparingForSleep"], False) self.assertEqual(props["IdleSinceHint"], 0) def test_inhibit(self): - (self.p_mock, obj_logind) = self.spawn_server_template("logind", {}, stdout=subprocess.PIPE) - # what, who, why, mode - fd = obj_logind.Inhibit("suspend", "testcode", "purpose", "delay") + fd = self.obj_logind.Inhibit("suspend", "testcode", "purpose", "delay") # Our inhibitor is held out = subprocess.check_output(["systemd-inhibit"], text=True) From 906524ae4935ce48a34336453b3830ff60216b55 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Sat, 24 Jan 2026 16:29:13 +0100 Subject: [PATCH 3/7] tests: Replace tearDown() with addCleanup() --- tests/test_api.py | 8 ++------ tests/test_bluez5.py | 18 +++++++++--------- tests/test_cli.py | 18 +++++------------- tests/test_gnome_screensaver.py | 8 +++----- tests/test_gsd_rfkill.py | 8 +++----- tests/test_low_memory_monitor.py | 8 +++----- tests/test_modemmanager.py | 11 +++-------- tests/test_networkmanager.py | 8 +++----- tests/test_notification_daemon.py | 8 +++----- tests/test_ofono.py | 3 +++ tests/test_polkitd.py | 8 +++----- tests/test_power_profiles_daemon.py | 8 +++----- tests/test_systemd.py | 19 ++++--------------- tests/test_timedated.py | 9 +++------ tests/test_upower.py | 8 +++----- tests/test_urfkill.py | 8 +++----- 16 files changed, 56 insertions(+), 102 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index edb27972..b3ca8438 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -45,6 +45,8 @@ def setUp(self): self.p_mock = self.spawn_server( "org.freedesktop.Test", "/", "org.freedesktop.Test.Main", stdout=self.mock_log ) + self.addCleanup(self.p_mock.wait) + self.addCleanup(self.p_mock.terminate) self.obj_test = self.dbus_con.get_object("org.freedesktop.Test", "/") self.dbus_test = dbus.Interface(self.obj_test, "org.freedesktop.Test.Main") @@ -54,12 +56,6 @@ def setUp(self): def assertLog(self, regex): self.assertRegex(Path(self.mock_log.name).read_bytes(), regex) - def tearDown(self): - if self.p_mock.stdout: - self.p_mock.stdout.close() - self.p_mock.terminate() - self.p_mock.wait() - def test_noarg_noret(self): """no arguments, no return value""" diff --git a/tests/test_bluez5.py b/tests/test_bluez5.py index da28e78a..4bcc36c8 100644 --- a/tests/test_bluez5.py +++ b/tests/test_bluez5.py @@ -95,6 +95,9 @@ def setUpClass(cls): cls.start_system_bus() cls.dbus_con = cls.get_dbus(True) (cls.p_mock, cls.obj_bluez) = cls.spawn_server_template("bluez5", {}, stdout=subprocess.PIPE) + cls.addClassCleanup(cls.p_mock.wait) + cls.addClassCleanup(cls.p_mock.terminate) + cls.addClassCleanup(cls.p_mock.stdout.close) out = _run_bluetoothctl("version") version = next(line.split(" ")[-1] for line in out if line.startswith("Version")) @@ -577,22 +580,19 @@ def setUpClass(cls): def setUp(self): # bluetoothd (self.p_mock, self.obj_bluez) = self.spawn_server_template("bluez5", {}, stdout=subprocess.PIPE) + self.addCleanup(self.p_mock.wait) + self.addCleanup(self.p_mock.terminate) + self.addCleanup(self.p_mock.stdout.close) self.dbusmock_bluez = dbus.Interface(self.obj_bluez, "org.bluez.Mock") # obexd (self.p_mock_obex, self.obj_obex) = self.spawn_server_template("bluez5-obex", {}, stdout=subprocess.PIPE) + self.addCleanup(self.p_mock_obex.wait) + self.addCleanup(self.p_mock_obex.terminate) + self.addCleanup(self.p_mock_obex.stdout.close) self.dbusmock = dbus.Interface(self.obj_obex, dbusmock.MOCK_IFACE) self.dbusmock_obex = dbus.Interface(self.obj_obex, "org.bluez.obex.Mock") - def tearDown(self): - self.p_mock.stdout.close() - self.p_mock.terminate() - self.p_mock.wait() - - self.p_mock_obex.stdout.close() - self.p_mock_obex.terminate() - self.p_mock_obex.wait() - def test_everything(self): # Set up an adapter and device. adapter_name = "hci0" diff --git a/tests/test_cli.py b/tests/test_cli.py index 5b99bd88..746eca83 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -27,6 +27,8 @@ class TestCLI(dbusmock.DBusTestCase): """Test running dbusmock from the command line""" + p_mock = None + @classmethod def setUpClass(cls): cls.start_system_bus() @@ -34,24 +36,14 @@ def setUpClass(cls): cls.system_con = cls.get_dbus(True) cls.session_con = cls.get_dbus() - def setUp(self): - self.p_mock = None - - def tearDown(self): - if self.p_mock: - if self.p_mock.stdout: - self.p_mock.stdout.close() - if self.p_mock.stderr: - self.p_mock.stdout.close() - self.p_mock.terminate() - self.p_mock.wait() - self.p_mock = None - def start_mock(self, args, wait_name, wait_path, wait_system=False): # pylint: disable=consider-using-with self.p_mock = subprocess.Popen( [sys.executable, "-m", "dbusmock", *args], stdout=subprocess.PIPE, universal_newlines=True ) + self.addCleanup(self.p_mock.wait) + self.addCleanup(self.p_mock.terminate) + self.addCleanup(self.p_mock.stdout.close) self.wait_for_bus_object(wait_name, wait_path, wait_system) def start_mock_process(self, args): diff --git a/tests/test_gnome_screensaver.py b/tests/test_gnome_screensaver.py index 6c5ebe74..e54e101d 100644 --- a/tests/test_gnome_screensaver.py +++ b/tests/test_gnome_screensaver.py @@ -25,15 +25,13 @@ def setUpClass(cls): def setUp(self): (self.p_mock, self.obj_ss) = self.spawn_server_template("gnome_screensaver", {}, stdout=subprocess.PIPE) + self.addCleanup(self.p_mock.wait) + self.addCleanup(self.p_mock.terminate) + self.addCleanup(self.p_mock.stdout.close) # set log to nonblocking flags = fcntl.fcntl(self.p_mock.stdout, fcntl.F_GETFL) fcntl.fcntl(self.p_mock.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK) - def tearDown(self): - self.p_mock.stdout.close() - self.p_mock.terminate() - self.p_mock.wait() - def test_default_state(self): """Not locked by default""" diff --git a/tests/test_gsd_rfkill.py b/tests/test_gsd_rfkill.py index 994b7fb1..875c44d4 100644 --- a/tests/test_gsd_rfkill.py +++ b/tests/test_gsd_rfkill.py @@ -24,15 +24,13 @@ def setUpClass(cls): def setUp(self): (self.p_mock, self.p_obj) = self.spawn_server_template("gsd_rfkill", {}, stdout=subprocess.PIPE) + self.addCleanup(self.p_mock.wait) + self.addCleanup(self.p_mock.terminate) + self.addCleanup(self.p_mock.stdout.close) # set log to nonblocking flags = fcntl.fcntl(self.p_mock.stdout, fcntl.F_GETFL) fcntl.fcntl(self.p_mock.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK) - def tearDown(self): - self.p_mock.stdout.close() - self.p_mock.terminate() - self.p_mock.wait() - def test_mainobject(self): propiface = dbus.Interface(self.p_obj, dbus.PROPERTIES_IFACE) diff --git a/tests/test_low_memory_monitor.py b/tests/test_low_memory_monitor.py index ee610bfa..91df9f1e 100644 --- a/tests/test_low_memory_monitor.py +++ b/tests/test_low_memory_monitor.py @@ -30,17 +30,15 @@ def setUpClass(cls): def setUp(self): (self.p_mock, self.obj_lmm) = self.spawn_server_template("low_memory_monitor", {}, stdout=subprocess.PIPE) + self.addCleanup(self.p_mock.wait) + self.addCleanup(self.p_mock.terminate) + self.addCleanup(self.p_mock.stdout.close) # set log to nonblocking flags = fcntl.fcntl(self.p_mock.stdout, fcntl.F_GETFL) fcntl.fcntl(self.p_mock.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK) self.last_warning = -1 self.dbusmock = dbus.Interface(self.obj_lmm, dbusmock.MOCK_IFACE) - def tearDown(self): - self.p_mock.stdout.close() - self.p_mock.terminate() - self.p_mock.wait() - def test_low_memory_warning_signal(self): """LowMemoryWarning signal""" diff --git a/tests/test_modemmanager.py b/tests/test_modemmanager.py index 89ed5352..dc5d03b8 100644 --- a/tests/test_modemmanager.py +++ b/tests/test_modemmanager.py @@ -38,14 +38,9 @@ def setUpClass(cls): def setUp(self): super().setUp() (self.p_mock, self.p_obj) = self.spawn_server_template("modemmanager", {}, stdout=subprocess.PIPE) - - def tearDown(self): - if self.p_mock: - self.p_mock.stdout.close() - self.p_mock.terminate() - self.p_mock.wait() - - super().tearDown() + self.addCleanup(self.p_mock.wait) + self.addCleanup(self.p_mock.terminate) + self.addCleanup(self.p_mock.stdout.close) def get_property(self, name): return self.p_obj.Get(self.dbus_interface, name, dbus_interface=dbus.PROPERTIES_IFACE) diff --git a/tests/test_networkmanager.py b/tests/test_networkmanager.py index 784362c9..d8472fd3 100644 --- a/tests/test_networkmanager.py +++ b/tests/test_networkmanager.py @@ -66,14 +66,12 @@ def setUp(self): (self.p_mock, self.obj_networkmanager) = self.spawn_server_template( "networkmanager", {"NetworkingEnabled": True, "WwanEnabled": False}, stdout=subprocess.PIPE ) + self.addCleanup(self.p_mock.wait) + self.addCleanup(self.p_mock.terminate) + self.addCleanup(self.p_mock.stdout.close) self.dbusmock = dbus.Interface(self.obj_networkmanager, dbusmock.MOCK_IFACE) self.settings = dbus.Interface(self.dbus_con.get_object(MANAGER_IFACE, SETTINGS_OBJ), SETTINGS_IFACE) - def tearDown(self): - self.p_mock.stdout.close() - self.p_mock.terminate() - self.p_mock.wait() - def read_general(self): return subprocess.check_output(["nmcli", "--nocheck", "general"], env=self.lang_env, text=True) diff --git a/tests/test_notification_daemon.py b/tests/test_notification_daemon.py index 6aae4a3a..ac95ecad 100644 --- a/tests/test_notification_daemon.py +++ b/tests/test_notification_daemon.py @@ -35,15 +35,13 @@ def setUpClass(cls): def setUp(self): (self.p_mock, self.obj_daemon) = self.spawn_server_template("notification_daemon", {}, stdout=subprocess.PIPE) + self.addCleanup(self.p_mock.wait) + self.addCleanup(self.p_mock.terminate) + self.addCleanup(self.p_mock.stdout.close) # set log to nonblocking flags = fcntl.fcntl(self.p_mock.stdout, fcntl.F_GETFL) fcntl.fcntl(self.p_mock.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK) - def tearDown(self): - self.p_mock.stdout.close() - self.p_mock.terminate() - self.p_mock.wait() - def test_no_options(self): """notify-send with no options""" diff --git a/tests/test_ofono.py b/tests/test_ofono.py index 474d53e8..2bfaedc7 100644 --- a/tests/test_ofono.py +++ b/tests/test_ofono.py @@ -30,6 +30,9 @@ def setUpClass(cls): cls.start_system_bus() cls.dbus_con = cls.get_dbus(True) (cls.p_mock, cls.obj_ofono) = cls.spawn_server_template("ofono", {}, stdout=subprocess.PIPE) + cls.addClassCleanup(cls.p_mock.wait) + cls.addClassCleanup(cls.p_mock.terminate) + cls.addClassCleanup(cls.p_mock.stdout.close) def setUp(self): self.obj_ofono.Reset() diff --git a/tests/test_polkitd.py b/tests/test_polkitd.py index ca48140d..5b679921 100644 --- a/tests/test_polkitd.py +++ b/tests/test_polkitd.py @@ -31,13 +31,11 @@ def setUpClass(cls): def setUp(self): (self.p_mock, self.obj_polkitd) = self.spawn_server_template("polkitd", {}, stdout=subprocess.PIPE) + self.addCleanup(self.p_mock.wait) + self.addCleanup(self.p_mock.terminate) + self.addCleanup(self.p_mock.stdout.close) self.dbusmock = dbus.Interface(self.obj_polkitd, dbusmock.MOCK_IFACE) - def tearDown(self): - self.p_mock.stdout.close() - self.p_mock.terminate() - self.p_mock.wait() - def test_default(self): self.check_action("org.freedesktop.test.frobnicate", False) diff --git a/tests/test_power_profiles_daemon.py b/tests/test_power_profiles_daemon.py index 31c54825..974ee410 100644 --- a/tests/test_power_profiles_daemon.py +++ b/tests/test_power_profiles_daemon.py @@ -47,16 +47,14 @@ def setUp(self): template = "upower_power_profiles_daemon" (self.p_mock, self.obj_ppd) = self.spawn_server_template(template, {}, stdout=subprocess.PIPE) + self.addCleanup(self.p_mock.wait) + self.addCleanup(self.p_mock.terminate) + self.addCleanup(self.p_mock.stdout.close) # set log to nonblocking flags = fcntl.fcntl(self.p_mock.stdout, fcntl.F_GETFL) fcntl.fcntl(self.p_mock.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK) self.dbusmock = dbus.Interface(self.obj_ppd, dbusmock.MOCK_IFACE) - def tearDown(self): - self.p_mock.stdout.close() - self.p_mock.terminate() - self.p_mock.wait() - def test_list_profiles(self): """List Profiles and check active profile""" diff --git a/tests/test_systemd.py b/tests/test_systemd.py index 9a486d04..5bcc8b0c 100644 --- a/tests/test_systemd.py +++ b/tests/test_systemd.py @@ -29,15 +29,6 @@ def setUpClass(cls): cls.session_bus = cls.get_dbus(False) cls.system_bus = cls.get_dbus(True) - def setUp(self): - self.p_mock = None - - def tearDown(self): - if self.p_mock: - self.p_mock.stdout.close() - self.p_mock.terminate() - self.p_mock.wait() - def _assert_unit_property(self, unit_obj, name, expect): value = unit_obj.Get("org.freedesktop.systemd1.Unit", name) self.assertEqual(str(value), expect) @@ -45,7 +36,10 @@ def _assert_unit_property(self, unit_obj, name, expect): def _test_base(self, bus, system_bus=True): dummy_service = "dummy-dbusmock.service" - (self.p_mock, obj_systemd) = self.spawn_server_template("systemd", {}, subprocess.PIPE, system_bus=system_bus) + (p_mock, obj_systemd) = self.spawn_server_template("systemd", {}, subprocess.PIPE, system_bus=system_bus) + self.addCleanup(p_mock.wait) + self.addCleanup(p_mock.terminate) + self.addCleanup(p_mock.stdout.close) systemd_mock = dbus.Interface(obj_systemd, dbusmock.MOCK_IFACE) systemd_mock.AddMockUnit(dummy_service) @@ -88,11 +82,6 @@ def wait_for_job(path): wait_for_job(job_path) self._assert_unit_property(unit_obj, "ActiveState", "inactive") - self.p_mock.stdout.close() - self.p_mock.terminate() - self.p_mock.wait() - self.p_mock = None - def test_user(self): self._test_base(self.session_bus, system_bus=False) diff --git a/tests/test_timedated.py b/tests/test_timedated.py index e99131ea..00facd84 100644 --- a/tests/test_timedated.py +++ b/tests/test_timedated.py @@ -32,14 +32,11 @@ def setUpClass(cls): def setUp(self): (self.p_mock, _) = self.spawn_server_template("timedated", {}, stdout=subprocess.PIPE) + self.addCleanup(self.p_mock.wait) + self.addCleanup(self.p_mock.terminate) + self.addCleanup(self.p_mock.stdout.close) self.obj_timedated = self.dbus_con.get_object("org.freedesktop.timedate1", "/org/freedesktop/timedate1") - def tearDown(self): - if self.p_mock: - self.p_mock.stdout.close() - self.p_mock.terminate() - self.p_mock.wait() - def run_timedatectl(self): return subprocess.check_output(["timedatectl"], text=True) diff --git a/tests/test_upower.py b/tests/test_upower.py index da40042c..5b20c8ea 100644 --- a/tests/test_upower.py +++ b/tests/test_upower.py @@ -45,16 +45,14 @@ def setUp(self): }, stdout=subprocess.PIPE, ) + self.addCleanup(self.p_mock.wait) + self.addCleanup(self.p_mock.terminate) + self.addCleanup(self.p_mock.stdout.close) # set log to nonblocking flags = fcntl.fcntl(self.p_mock.stdout, fcntl.F_GETFL) fcntl.fcntl(self.p_mock.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK) self.dbusmock = dbus.Interface(self.obj_upower, dbusmock.MOCK_IFACE) - def tearDown(self): - self.p_mock.stdout.close() - self.p_mock.terminate() - self.p_mock.wait() - def test_no_devices(self): out = subprocess.check_output(["upower", "--dump"], text=True) self.assertIn("/DisplayDevice\n", out) diff --git a/tests/test_urfkill.py b/tests/test_urfkill.py index 4c2a573d..fdbf3ffd 100644 --- a/tests/test_urfkill.py +++ b/tests/test_urfkill.py @@ -34,16 +34,14 @@ def setUpClass(cls): def setUp(self): (self.p_mock, self.obj_urfkill) = self.spawn_server_template("urfkill", {}, stdout=subprocess.PIPE) + self.addCleanup(self.p_mock.wait) + self.addCleanup(self.p_mock.terminate) + self.addCleanup(self.p_mock.stdout.close) # set log to nonblocking flags = fcntl.fcntl(self.p_mock.stdout, fcntl.F_GETFL) fcntl.fcntl(self.p_mock.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK) self.dbusmock = dbus.Interface(self.obj_urfkill, dbusmock.MOCK_IFACE) - def tearDown(self): - self.p_mock.stdout.close() - self.p_mock.terminate() - self.p_mock.wait() - def test_mainobject(self): (remote_object, iface) = _get_urfkill_objects() self.assertFalse(iface.IsFlightMode()) From aa5af6da048673c5b8b39cfe6c678acc0a4db6eb Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Sat, 24 Jan 2026 16:09:29 +0100 Subject: [PATCH 4/7] polkitd: Add RegisterAuthenticationAgentWithOptions This is what systemd calls these days. --- dbusmock/templates/polkitd.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dbusmock/templates/polkitd.py b/dbusmock/templates/polkitd.py index 7e50748c..2bd8b582 100644 --- a/dbusmock/templates/polkitd.py +++ b/dbusmock/templates/polkitd.py @@ -67,6 +67,11 @@ def RegisterAuthenticationAgent(_self, _subject, _locale, _object_path): pass +@dbus.service.method(MAIN_IFACE, in_signature="(sa{sv})ssa{sv}") +def RegisterAuthenticationAgentWithOptions(_self, _subject, _locale, _object_path, _options): + pass + + @dbus.service.method(MOCK_IFACE, in_signature="b", out_signature="") def AllowUnknown(self, default): """Control whether unknown actions are allowed From 44653b797466890a35a1b9ddf59989b9f12652cf Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Sat, 24 Jan 2026 16:10:21 +0100 Subject: [PATCH 5/7] logind: Add SetWallMessage `systemctl suspend` and friends call this. Add a test case. --- dbusmock/templates/logind.py | 1 + tests/test_logind.py | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/dbusmock/templates/logind.py b/dbusmock/templates/logind.py index 37929870..22def4d2 100644 --- a/dbusmock/templates/logind.py +++ b/dbusmock/templates/logind.py @@ -58,6 +58,7 @@ def load(mock, parameters): ("GetUser", "u", "o", 'ret = "/org/freedesktop/login1/user/" + args[0]'), ("KillUser", "us", "", ""), ("TerminateUser", "u", "", ""), + ("SetWallMessage", "sb", "", ""), ], ) diff --git a/tests/test_logind.py b/tests/test_logind.py index 0e3f70a2..5be9001b 100644 --- a/tests/test_logind.py +++ b/tests/test_logind.py @@ -6,6 +6,8 @@ (c) 2017 - 2025 Martin Pitt """ +import fcntl +import os import re import shutil import subprocess @@ -42,6 +44,9 @@ def setUp(self): self.addCleanup(self.p_mock.terminate) self.addCleanup(self.p_mock.stdout.close) + flags = fcntl.fcntl(self.p_mock.stdout, fcntl.F_GETFL) + fcntl.fcntl(self.p_mock.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK) + def test_empty(self): cmd = ["loginctl"] if self.version >= "209": @@ -123,6 +128,17 @@ def test_inhibit(self): out = subprocess.check_output(["systemd-inhibit"], text=True) self.assertRegex(out, "No inhibitors|0 inhibitors listed") + def test_suspend(self): + (p_mock_polkit, _obj_polkitd) = self.spawn_server_template("polkitd", {}, stdout=subprocess.DEVNULL) + self.addCleanup(p_mock_polkit.wait) + self.addCleanup(p_mock_polkit.terminate) + + subprocess.check_call(["systemctl", "suspend"]) + + log = self.p_mock.stdout.read().decode() + self.assertIn('SetWallMessage "" True', log) + self.assertIn("Suspend True", log) + if __name__ == "__main__": # avoid writing to stderr From 3c62a3bc75491a38d73c9c1ec712ec420bb92be9 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Sun, 25 Jan 2026 10:14:25 +0100 Subject: [PATCH 6/7] README: Update outaded and broken examples - The Suspend() functionality moved from UPower to systemd-logind ages ago. Move the examples to that. - Make the examples actually work unmodified by addig a `busctl` call as a placeholder for what your tested program would do. - Move from tearDown() to addCleanup(), which is is the modern style. - Rewrite the pytest example to use the current API. Fixes #236 --- README.md | 190 +++++++++++++++++++++++++++--------------------------- 1 file changed, 96 insertions(+), 94 deletions(-) diff --git a/README.md b/README.md index 2bdb4851..7bd15d40 100644 --- a/README.md +++ b/README.md @@ -11,20 +11,20 @@ D-Bus services such as upower, systemd, logind, gnome-session or others, and it is hard (or impossible without root privileges) to set the state of the real services to what you expect in your tests. -Suppose you want to write tests for gnome-settings-daemon's power -plugin, or another program that talks to upower. You want to verify that -after the configured idle time the program suspends the machine. So your -program calls `org.freedesktop.UPower.Suspend()` on the system D-Bus. - -Now, your test suite should not really talk to the actual system D-Bus -and the real upower; a `make check` that suspends your machine will not -be considered very friendly by most people, and if you want to run this -in continuous integration test servers or package build environments, -chances are that your process does not have the privilege to suspend, or -there is no system bus or upower to begin with. Likewise, there is no -way for an user process to forcefully set the system/seat idle flag in -logind, so your tests cannot set up the expected test environment on the -real daemon. +Suppose you want to write tests for a desktop environment's power management: +You want to verify that after the configured idle time the program suspends the +machine. So your program calls `org.freedesktop.login1.Manager.Suspend()` on +the system D-Bus. + +Now, your test suite should not really talk to the actual system D-Bus and +the real systemd; a `make check` that suspends your machine will not be +considered very friendly by most people, and if you want to run this in +continuous integration test servers or package build environments, chances +are that your process does not have the privilege to suspend, or there is +no system bus or running systemd to begin with. Likewise, there is no way +for an user process to forcefully set the system/seat idle flag in logind, +so your tests cannot set up the expected test environment on the real +daemon. That's where mock objects come into play: They look like the real API (or at least the parts that you actually need), but they do not actually @@ -47,11 +47,12 @@ convenience D-Bus launch API that way. ## Simple example using Python's unittest -Picking up the above example about mocking upower's `Suspend()` method, -this is how you would set up a mock upower in your test case: +Picking up the above example about mocking systemd-logind's `Suspend()` +method, this is how you would set up a mock logind in your test case: ```python import subprocess +import unittest import dbus @@ -65,29 +66,32 @@ class TestMyProgram(dbusmock.DBusTestCase): cls.dbus_con = cls.get_dbus(system_bus=True) def setUp(self): - self.p_mock = self.spawn_server('org.freedesktop.UPower', - '/org/freedesktop/UPower', - 'org.freedesktop.UPower', + self.p_mock = self.spawn_server('org.freedesktop.login1', + '/org/freedesktop/login1', + 'org.freedesktop.login1.Manager', system_bus=True, stdout=subprocess.PIPE) + self.addCleanup(self.p_mock.wait) + self.addCleanup(self.p_mock.terminate) + self.addCleanup(self.p_mock.stdout.close) - # Get a proxy for the UPower object's Mock interface - self.dbus_upower_mock = dbus.Interface(self.dbus_con.get_object( - 'org.freedesktop.UPower', '/org/freedesktop/UPower'), + # Get a proxy for the logind object's Mock interface + self.dbus_logind_mock = dbus.Interface(self.dbus_con.get_object( + 'org.freedesktop.login1', '/org/freedesktop/login1'), dbusmock.MOCK_IFACE) - self.dbus_upower_mock.AddMethod('', 'Suspend', '', '', '') - - def tearDown(self): - self.p_mock.stdout.close() - self.p_mock.terminate() - self.p_mock.wait() + self.dbus_logind_mock.AddMethod('', 'Suspend', 'b', '', '') def test_suspend_on_idle(self): # run your program in a way that should trigger one suspend call + # represented here as direct D-Bus call + subprocess.check_call( + ["busctl", "call", "org.freedesktop.login1", + "/org/freedesktop/login1", "org.freedesktop.login1.Manager", + "Suspend", "b", "false"]) # now check the log that we got one Suspend() call - self.assertRegex(self.p_mock.stdout.readline(), b'^[0-9.]+ Suspend$') + self.assertRegex(self.p_mock.stdout.readline(), b'^[0-9.]+ Suspend False$') ``` Let's walk through: @@ -103,7 +107,7 @@ Let's walk through: instead of `setUp()` is enough. - `setUp()` spawns the mock D-Bus server process for an initial - `/org/freedesktop/UPower` object with an `org.freedesktop.UPower` + `/org/freedesktop/login1` object with an `org.freedesktop.login1` D-Bus interface on the system bus. We capture its stdout to be able to verify that methods were called. @@ -113,18 +117,21 @@ Let's walk through: stdout). It takes no input arguments, returns nothing, and does not run any custom code. - - `tearDown()` stops our mock D-Bus server again. We do this so that - each test case has a fresh and clean upower instance, but of - course you can also set up everything in `setUpClass()` if tests + We use `addCleanup()` to register cleanup handlers that will + stop our mock D-Bus server after each test. This ensures each + test case has a fresh and clean logind mock instance. Of course + you can also set up everything in `setUpClass()` if tests do not interfere with each other on setting up the mock. - `test_suspend_on_idle()` is the actual test case. It needs to run - your program in a way that should trigger one suspend call. Your - program will try to call `Suspend()`, but as that's now being - served by our mock instead of upower, there will not be any actual - machine suspend. Our mock process will log the method call - together with a time stamp; you can use the latter for doing - timing related tests, but we just ignore it here. + your program in a way that should trigger one suspend call. For this + example this is represented by doing just a direct D-Bus call using + `busctl`. + + That `Suspend()` call is now being served by our mock instead of the real + logind, there will not be any actual machine suspend. Our mock process + will log the method call together with a time stamp; you can use the + latter for doing timing related tests, but we just ignore it here. ## Simple example using pytest @@ -132,73 +139,68 @@ The same functionality as above but instead using the pytest fixture provided by this package. ```python +# Enable dbusmock's pytest fixtures (can also go in conftest.py) +pytest_plugins = "dbusmock.pytest_fixtures" + import subprocess import dbus -import pytest import dbusmock -@pytest.fixture -def upower_mock(dbusmock_system): - p_mock = dbusmock_system.spawn_server( - 'org.freedesktop.UPower', - '/org/freedesktop/UPower', - 'org.freedesktop.UPower', - system_bus=True, - stdout=subprocess.PIPE) - - # Get a proxy for the UPower object's Mock interface - dbus_upower_mock = dbus.Interface(dbusmock_system.get_dbus(True).get_object( - 'org.freedesktop.UPower', - '/org/freedesktop/UPower' - ), dbusmock.MOCK_IFACE) - dbus_upower_mock.AddMethod('', 'Suspend', '', '', '') - - yield p_mock - - p_mock.stdout.close() - p_mock.terminate() - p_mock.wait() - - -def test_suspend_on_idle(upower_mock): - # run your program in a way that should trigger one suspend call - - # now check the log that we got one Suspend() call - assert upower_mock.stdout.readline() == b'^[0-9.]+ Suspend$' +def test_suspend_on_idle(dbusmock_system): + # Spawn the mock D-Bus server for logind on the system bus + with dbusmock.SpawnedMock.spawn_for_name( + 'org.freedesktop.login1', + '/org/freedesktop/login1', + 'org.freedesktop.login1.Manager', + dbusmock.BusType.SYSTEM, + stdout=subprocess.PIPE) as p_mock: + + # Get a proxy for the logind object's Mock interface + obj_logind = p_mock.obj + obj_logind.AddMethod('', 'Suspend', 'b', '', '', interface_name=dbusmock.MOCK_IFACE) + + # Run your program in a way that should trigger one suspend call + # represented here as direct D-Bus call + subprocess.check_call( + ["busctl", "call", "org.freedesktop.login1", + "/org/freedesktop/login1", "org.freedesktop.login1.Manager", + "Suspend", "b", "false"]) + + # Check the log that we got one Suspend() call + assert b'Suspend False\n' in p_mock.stdout.readline() ``` Let's walk through: +- We enable dbusmock's pytest fixtures with `pytest_plugins = "dbusmock.pytest_fixtures"`. + This makes fixtures like `dbusmock_system` and `dbusmock_session` available to your + tests. In a real project, you would typically put this line in your `conftest.py` + instead of in each test file. + - We import the `dbusmock_system` fixture from dbusmock which provides us - with a system bus started for our test case wherever the - `dbusmock_system` argument is used by a test case and/or a pytest - fixture. - -- The `upower_mock` fixture spawns the mock D-Bus server process for an initial - `/org/freedesktop/UPower` object with an `org.freedesktop.UPower` - D-Bus interface on the system bus. We capture its stdout to be - able to verify that methods were called. - - We then call `org.freedesktop.DBus.Mock.AddMethod()` to add a - `Suspend()` method to our new object to the default D-Bus - interface. This will not do anything (except log its call to - stdout). It takes no input arguments, returns nothing, and does - not run any custom code. - - This mock server process is yielded to the test function that uses - the `upower_mock` fixture - once the test is complete the process is - terminated again. - -- `test_suspend_on_idle()` is the actual test case. It needs to run - your program in a way that should trigger one suspend call. Your - program will try to call `Suspend()`, but as that's now being - served by our mock instead of upower, there will not be any actual - machine suspend. Our mock process will log the method call - together with a time stamp; you can use the latter for doing - timing related tests, but we just ignore it here. + with a system bus started for our test case. Even though we don't use it + directly in this simple example, it ensures the test environment is set up. + +- `test_suspend_on_idle()` is the actual test. It uses + `SpawnedMock.spawn_for_name()` to spawn the mock D-Bus server process for + `/org/freedesktop/login1` object with `org.freedesktop.login1.Manager` + interface. We capture its stdout to verify that methods were called. + + We then call `org.freedesktop.DBus.Mock.AddMethod()` to add a `Suspend()` + method to our new logind mock object to the default D-Bus interface. This + will not do anything (except log its call to stdout). It takes one boolean + input argument, returns nothing, and does not run any custom code. + + Exactly like in the unittest example above, we then run our program in a way that + should trigger one suspend call. For this example this is again represented + by doing just a direct D-Bus call using `busctl`. The log of the call gets + asserted. + + The context manager automatically terminates the mock server process after + the test completes. ## Simple example from shell From a46410891758e9e224950e7cc2e6b740c07f140f Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Sun, 25 Jan 2026 11:22:09 +0100 Subject: [PATCH 7/7] test: Check the examples in README.md This extracts the examples into temporary files and runs them through pytest. Let's make sure that these don't break again in the future! --- tests/test_readme_examples.py | 42 +++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 tests/test_readme_examples.py diff --git a/tests/test_readme_examples.py b/tests/test_readme_examples.py new file mode 100644 index 00000000..7d0e0425 --- /dev/null +++ b/tests/test_readme_examples.py @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later + +"""Test that code examples in README.md actually work""" + +# pylint does not understand pytest fixtures.. +# pylint: disable=redefined-outer-name + +__author__ = "Martin Pitt" +__copyright__ = """ +(c) 2026 Martin Pitt +""" + +import re +import subprocess +import sys +from pathlib import Path + +import pytest + + +@pytest.fixture(scope="module") +def readme_blocks(): + """Extract Python code blocks from README.md""" + readme_path = Path(__file__).parent.parent / "README.md" + return re.findall(r"```python\n(.*?)\n```", readme_path.read_text(), re.DOTALL) + + +def test_examples_exist(readme_blocks): + """Verify that we found some Python code blocks""" + assert len(readme_blocks) > 0 + + +def test_readme_examples(readme_blocks, tmp_path): + """Test all README examples by running them through pytest""" + for i, code_block in enumerate(readme_blocks): + test_file = tmp_path / f"test_readme_example_{i}.py" + test_file.write_text(code_block) + + subprocess.run( + [sys.executable, "-m", "pytest", str(test_file), "-v"], + check=True, + )