diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 14:51:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 14:51:55 +0000 |
commit | 86b7f1a83d7db9c912f32b29c32e1124c0a6454d (patch) | |
tree | 42a7ff7c6885e99e0669d07b104df11b2bf387b6 /tests/gsdtestcase.py | |
parent | Initial commit. (diff) | |
download | gnome-settings-daemon-upstream.tar.xz gnome-settings-daemon-upstream.zip |
Adding upstream version 3.38.2.upstream/3.38.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/gsdtestcase.py')
-rw-r--r-- | tests/gsdtestcase.py | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/tests/gsdtestcase.py b/tests/gsdtestcase.py new file mode 100644 index 0000000..28068f6 --- /dev/null +++ b/tests/gsdtestcase.py @@ -0,0 +1,216 @@ +'''GNOME settings daemon test base class''' + +__author__ = 'Martin Pitt <martin.pitt@ubuntu.com>' +__copyright__ = '(C) 2013 Canonical Ltd.' +__license__ = 'GPL v2 or later' + +import subprocess +import time +import os +import os.path +import tempfile +import fcntl +import shutil +import sys +from glob import glob + +from gi.repository import GLib + +try: + import dbusmock +except ImportError: + sys.stderr.write('You need python-dbusmock (http://pypi.python.org/pypi/python-dbusmock) for this test suite.\n') + sys.exit(1) + +from x11session import X11SessionTestCase + +try: + from gi.repository import Gio +except ImportError: + sys.stderr.write('You need pygobject and the Gio GIR for this test suite.\n') + sys.exit(0) + +if subprocess.call(['which', 'gnome-session'], stdout=subprocess.PIPE) != 0: + sys.stderr.write('You need gnome-session for this test suite.\n') + sys.exit(0) + + +top_builddir = os.environ.get('TOP_BUILDDIR', + os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +def set_nonblock(fd): + '''Set a file object to non-blocking''' + + flags = fcntl.fcntl(fd, fcntl.F_GETFL) + fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK) + + +class GSDTestCase(X11SessionTestCase): + '''Base class for settings daemon tests + + This redirects the XDG directories to temporary directories, and runs local + session and system D-BUSes with a minimal GNOME session and a mock + notification daemon. It also provides common functionality for plugin + tests. + ''' + @classmethod + def setUpClass(klass): + os.environ['GIO_USE_VFS'] = 'local' + os.environ['GVFS_DISABLE_FUSE'] = '1' + # we do some string checks, disable translations + os.environ['LC_MESSAGES'] = 'C' + klass.workdir = tempfile.mkdtemp(prefix='gsd-plugin-test') + + # Prevent applications from accessing an outside session manager + os.environ['SESSION_MANAGER'] = '' + + # Signal to mutter and gnome-session that we are using X11 + os.environ['XDG_SESSION_TYPE'] = 'x11' + + # tell dconf and friends to use our config/runtime directories + os.environ['XDG_CONFIG_HOME'] = os.path.join(klass.workdir, 'config') + os.environ['XDG_DATA_HOME'] = os.path.join(klass.workdir, 'data') + os.environ['XDG_RUNTIME_DIR'] = os.path.join(klass.workdir, 'runtime') + + # Copy gschema file into XDG_DATA_HOME + gschema_dir = os.path.join(os.environ['XDG_DATA_HOME'], 'glib-2.0', 'schemas') + os.makedirs(gschema_dir) + shutil.copy(os.path.join(top_builddir, 'data', 'gschemas.compiled'), gschema_dir) + + # work around https://bugzilla.gnome.org/show_bug.cgi?id=689136 + os.makedirs(os.path.join(os.environ['XDG_CONFIG_HOME'], 'dconf')) + os.makedirs(os.environ['XDG_RUNTIME_DIR'], mode=0o700) + + # Starts Xvfb and dbus busses + X11SessionTestCase.setUpClass() + + klass.system_bus_con = klass.get_dbus(True) + klass.session_bus_con = klass.get_dbus(False) + + # we never want to cause notifications on the actual GUI + klass.p_notify = klass.spawn_server_template( + 'notification_daemon', {}, stdout=subprocess.PIPE)[0] + set_nonblock(klass.p_notify.stdout) + + klass.start_session() + klass.start_monitor() + + klass.settings_session = Gio.Settings(schema_id='org.gnome.desktop.session') + + @classmethod + def tearDownClass(klass): + klass.p_notify.terminate() + klass.p_notify.wait() + klass.stop_monitor() + X11SessionTestCase.tearDownClass() + shutil.rmtree(klass.workdir) + + def run(self, result=None): + '''Show log files on failed tests + + If the environment variable $SHELL_ON_FAIL is set, this runs bash in + the work directory; exit the shell to continue the tests. Otherwise it + shows all log files. + ''' + if result: + orig_err_fail = len(result.errors) + len(result.failures) + super(GSDTestCase, self).run(result) + if result and len(result.errors) + len(result.failures) > orig_err_fail: + if 'SHELL_ON_FAIL' in os.environ: + subprocess.call(['bash', '-i'], cwd=self.workdir) + else: + for log_file in glob(os.path.join(self.workdir, '*.log')): + with open(log_file) as f: + print('\n----- %s -----\n%s\n------\n' + % (log_file, f.read())) + + @classmethod + def start_session(klass): + '''Start minimal GNOME session''' + + # create dummy session type and component + d = os.path.join(klass.workdir, 'config', 'gnome-session', 'sessions') + if not os.path.isdir(d): + os.makedirs(d) + shutil.copy(os.path.join(os.path.dirname(__file__), 'dummy.session'), d) + + d = os.path.join(klass.workdir, 'data', 'applications') + if not os.path.isdir(d): + os.makedirs(d) + shutil.copy(os.path.join(os.path.dirname(__file__), 'dummyapp.desktop'), d) + + @classmethod + def start_monitor(klass): + '''Start dbus-monitor''' + + # You can rename the log file to *.log if you want to see it on test + # case failures + klass.monitor_log = open(os.path.join(klass.workdir, 'dbus-monitor.out'), 'wb', buffering=0) + klass.monitor = subprocess.Popen(['dbus-monitor', '--monitor'], + stdout=klass.monitor_log, + stderr=subprocess.STDOUT) + + @classmethod + def stop_monitor(klass): + '''Stop dbus-monitor''' + + assert klass.monitor + klass.monitor.terminate() + klass.monitor.wait() + + klass.monitor_log.flush() + klass.monitor_log.close() + + def start_logind(self, parameters=None): + '''start mock logind''' + + if parameters is None: + parameters = {} + self.logind, self.logind_obj = self.spawn_server_template('logind', + parameters, + stdout=subprocess.PIPE) + + # Monkey patch SuspendThenHibernate functions in for dbusmock <= 0.17.2 + # This should be removed once we can depend on dbusmock 0.17.3 + self.logind_obj.AddMethod('org.freedesktop.login1.Manager', 'SuspendThenHibernate', 'b', '', '') + self.logind_obj.AddMethod('org.freedesktop.login1.Manager', 'CanSuspendThenHibernate', '', 's', 'ret = "%s"' % parameters.get('CanSuspendThenHibernate', 'yes')) + + self.logind_obj.AddMethod('org.freedesktop.login1.Session', 'SetBrightness', 'ssu', '', '') + + # set log to nonblocking + set_nonblock(self.logind.stdout) + + def stop_logind(self): + '''stop mock logind''' + + self.logind.terminate() + self.logind.wait() + + def start_mutter(klass): + ''' start mutter ''' + + os.environ['MUTTER_DEBUG_RESET_IDLETIME']='1' + klass.mutter_log = open(os.path.join(klass.workdir, 'mutter.log'), 'wb', buffering=0) + # See https://gitlab.gnome.org/GNOME/mutter/merge_requests/15 + klass.mutter = subprocess.Popen(['mutter', '--x11'], + stdout=klass.mutter_log, + stderr=subprocess.STDOUT) + + def stop_mutter(klass): + '''stop mutter''' + + assert klass.monitor + klass.mutter.terminate() + klass.mutter.wait() + + klass.mutter_log.flush() + klass.mutter_log.close() + + @classmethod + def reset_idle_timer(klass): + '''trigger activity to reset idle timer''' + + obj_mutter_idlemonitor = klass.session_bus_con.get_object( + 'org.gnome.Mutter.IdleMonitor', '/org/gnome/Mutter/IdleMonitor/Core') + + obj_mutter_idlemonitor.ResetIdletime(dbus_interface='org.gnome.Mutter.IdleMonitor') |