| 
									
										
										
										
											2021-08-10 10:58:53 +02:00
										 |  |  | #!/usr/bin/python3 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # 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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-07 00:42:14 +01:00
										 |  |  | __author__ = "Bastien Nocera" | 
					
						
							|  |  |  | __email__ = "hadess@hadess.net" | 
					
						
							|  |  |  | __copyright__ = "(c) 2019, 2021 Red Hat Inc." | 
					
						
							|  |  |  | __license__ = "LGPL 3+" | 
					
						
							| 
									
										
										
										
											2021-08-10 10:58:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import unittest | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | import subprocess | 
					
						
							|  |  |  | import fcntl | 
					
						
							|  |  |  | import os | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import taptestrunner | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | try: | 
					
						
							|  |  |  |     # Do all non-standard imports here so we can skip the tests if any | 
					
						
							|  |  |  |     # needed packages are not available. | 
					
						
							|  |  |  |     import dbus | 
					
						
							|  |  |  |     import dbus.mainloop.glib | 
					
						
							|  |  |  |     import dbusmock | 
					
						
							|  |  |  |     from gi.repository import GLib | 
					
						
							|  |  |  |     from gi.repository import Gio | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class TestPowerProfileMonitor(dbusmock.DBusTestCase): | 
					
						
							| 
									
										
										
										
											2025-02-07 00:42:14 +01:00
										 |  |  |         """Test GPowerProfileMonitorDBus""" | 
					
						
							| 
									
										
										
										
											2021-08-10 10:58:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         @classmethod | 
					
						
							|  |  |  |         def setUpClass(klass): | 
					
						
							|  |  |  |             klass.start_system_bus() | 
					
						
							|  |  |  |             klass.dbus_con = klass.get_dbus(True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def setUp(self): | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 Gio.PowerProfileMonitor | 
					
						
							|  |  |  |             except AttributeError: | 
					
						
							| 
									
										
										
										
											2025-02-07 00:42:14 +01:00
										 |  |  |                 raise unittest.SkipTest( | 
					
						
							|  |  |  |                     "Power Profile Monitor not in " | 
					
						
							|  |  |  |                     "introspection data. Requires " | 
					
						
							|  |  |  |                     "GObject-Introspection ≥ 1.63.2" | 
					
						
							|  |  |  |                 )  # FIXME version | 
					
						
							| 
									
										
										
										
											2021-08-10 10:58:53 +02:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 (self.p_mock, self.obj_ppd) = self.spawn_server_template( | 
					
						
							| 
									
										
										
										
											2025-02-07 00:47:34 +01:00
										 |  |  |                     "upower_power_profiles_daemon", {}, stdout=subprocess.PIPE | 
					
						
							| 
									
										
										
										
											2025-02-07 00:42:14 +01:00
										 |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2021-08-10 10:58:53 +02:00
										 |  |  |             except ModuleNotFoundError: | 
					
						
							| 
									
										
										
										
											2025-02-07 00:42:14 +01:00
										 |  |  |                 raise unittest.SkipTest( | 
					
						
							|  |  |  |                     "power-profiles-daemon dbusmock template not " | 
					
						
							| 
									
										
										
										
											2025-02-07 00:47:34 +01:00
										 |  |  |                     "found. Requires dbusmock > 0.31.1." | 
					
						
							| 
									
										
										
										
											2025-02-07 00:42:14 +01:00
										 |  |  |                 )  # FIXME version | 
					
						
							| 
									
										
										
										
											2021-08-10 10:58:53 +02:00
										 |  |  |             # 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.power_saver_enabled = False | 
					
						
							|  |  |  |             self.dbus_props = dbus.Interface(self.obj_ppd, dbus.PROPERTIES_IFACE) | 
					
						
							|  |  |  |             self.power_profile_monitor = Gio.PowerProfileMonitor.dup_default() | 
					
						
							| 
									
										
										
										
											2025-02-07 00:42:14 +01:00
										 |  |  |             assert "GPowerProfileMonitorDBus" in str(self.power_profile_monitor) | 
					
						
							|  |  |  |             self.power_profile_monitor.connect( | 
					
						
							|  |  |  |                 "notify::power-saver-enabled", self.power_saver_enabled_cb | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2021-08-10 10:58:53 +02:00
										 |  |  |             self.mainloop = GLib.MainLoop() | 
					
						
							|  |  |  |             self.main_context = self.mainloop.get_context() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def tearDown(self): | 
					
						
							|  |  |  |             self.p_mock.terminate() | 
					
						
							|  |  |  |             self.p_mock.wait() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-22 13:56:05 +00:00
										 |  |  |         def assertEventually(self, condition, message=None, timeout=5): | 
					
						
							| 
									
										
										
										
											2025-02-07 00:42:14 +01:00
										 |  |  |             """Assert that condition function eventually returns True.
 | 
					
						
							| 
									
										
										
										
											2021-08-10 10:58:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-22 13:56:05 +00:00
										 |  |  |             Timeout is in seconds, defaulting to 5 seconds. message is | 
					
						
							| 
									
										
										
										
											2021-08-10 10:58:53 +02:00
										 |  |  |             printed on failure. | 
					
						
							| 
									
										
										
										
											2025-02-07 00:42:14 +01:00
										 |  |  |             """
 | 
					
						
							| 
									
										
										
										
											2024-01-22 13:56:05 +00:00
										 |  |  |             if not message: | 
					
						
							| 
									
										
										
										
											2025-02-07 00:42:14 +01:00
										 |  |  |                 message = "timed out waiting for " + str(condition) | 
					
						
							| 
									
										
										
										
											2024-01-22 13:56:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             def timed_out_cb(message): | 
					
						
							|  |  |  |                 self.fail(message) | 
					
						
							|  |  |  |                 return GLib.SOURCE_REMOVE | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             timeout_source = GLib.timeout_source_new_seconds(timeout) | 
					
						
							|  |  |  |             timeout_source.set_callback(timed_out_cb, message) | 
					
						
							|  |  |  |             timeout_source.attach(self.main_context) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             while not condition(): | 
					
						
							|  |  |  |                 self.main_context.iteration(True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             timeout_source.destroy() | 
					
						
							| 
									
										
										
										
											2021-08-10 10:58:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def power_saver_enabled_cb(self, spec, data): | 
					
						
							| 
									
										
										
										
											2025-02-07 00:42:14 +01:00
										 |  |  |             self.power_saver_enabled = ( | 
					
						
							|  |  |  |                 self.power_profile_monitor.get_power_saver_enabled() | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2021-08-10 10:58:53 +02:00
										 |  |  |             self.main_context.wakeup() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def test_power_profile_power_saver_enabled(self): | 
					
						
							| 
									
										
										
										
											2025-02-07 00:42:14 +01:00
										 |  |  |             """power-saver-enabled property""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             self.assertEqual( | 
					
						
							|  |  |  |                 self.power_profile_monitor.get_power_saver_enabled(), False | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             self.dbus_props.Set( | 
					
						
							| 
									
										
										
										
											2025-02-07 00:47:34 +01:00
										 |  |  |                 "org.freedesktop.UPower.PowerProfiles", | 
					
						
							| 
									
										
										
										
											2025-02-07 00:42:14 +01:00
										 |  |  |                 "ActiveProfile", | 
					
						
							|  |  |  |                 dbus.String("power-saver", variant_level=1), | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             self.assertEventually( | 
					
						
							|  |  |  |                 lambda: self.power_saver_enabled == True, | 
					
						
							|  |  |  |                 "power-saver didn't become enabled", | 
					
						
							|  |  |  |                 1, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             self.dbus_props.Set( | 
					
						
							| 
									
										
										
										
											2025-02-07 00:47:34 +01:00
										 |  |  |                 "org.freedesktop.UPower.PowerProfiles", | 
					
						
							| 
									
										
										
										
											2025-02-07 00:42:14 +01:00
										 |  |  |                 "ActiveProfile", | 
					
						
							|  |  |  |                 dbus.String("balanced", variant_level=1), | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             self.assertEventually( | 
					
						
							|  |  |  |                 lambda: self.power_saver_enabled == False, | 
					
						
							|  |  |  |                 "power-saver didn't become disabled", | 
					
						
							|  |  |  |                 1, | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2021-08-10 10:58:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | except ImportError as e: | 
					
						
							| 
									
										
										
										
											2025-02-07 00:42:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-10 10:58:53 +02:00
										 |  |  |     @unittest.skip("Cannot import %s" % e.name) | 
					
						
							|  |  |  |     class TestPowerProfileMonitor(unittest.TestCase): | 
					
						
							|  |  |  |         def test_power_profile_power_saver_enabled(self): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-07 00:42:14 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | if __name__ == "__main__": | 
					
						
							| 
									
										
										
										
											2021-08-10 10:58:53 +02:00
										 |  |  |     unittest.main(testRunner=taptestrunner.TAPTestRunner()) |