From b5284e5cccc3ae2898462b05cf89c917f022dd56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Sat, 11 Dec 2021 11:41:53 +0100 Subject: [PATCH] tests/dbus-runner: Add methods needed for taking control of a session This is needed if one wants to run the test suite parts that need KMS or evdev access in a virtual machine. However, only initiate these methods if the meta-dbus-runner.py program was launched with --kvm, as it's only suitable for using while running as root in a virtual machine. Part-of: --- src/tests/meta-dbus-runner.py | 66 +++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/src/tests/meta-dbus-runner.py b/src/tests/meta-dbus-runner.py index 69daa0af2..79f6a0790 100755 --- a/src/tests/meta-dbus-runner.py +++ b/src/tests/meta-dbus-runner.py @@ -6,6 +6,7 @@ import os import fcntl import subprocess import getpass +import argparse from collections import OrderedDict from dbusmock import DBusTestCase from dbus.mainloop.glib import DBusGMainLoop @@ -28,7 +29,7 @@ def get_subprocess_stdout(): class MutterDBusTestCase(DBusTestCase): @classmethod - def setUpClass(klass): + def setUpClass(klass, enable_kvm): klass.mocks = OrderedDict() print('Starting D-Bus daemons (session & system)...', file=sys.stderr) @@ -40,13 +41,12 @@ class MutterDBusTestCase(DBusTestCase): (klass.mocks_manager, klass.mock_obj) = klass.start_from_local_template( 'meta-mocks-manager', {'templates-dir': get_templates_dir()}) - logind = klass.start_from_template('logind') klass.start_from_local_template('localed') klass.system_bus_con = klass.get_dbus(system_bus=True) klass.session_bus_con = klass.get_dbus(system_bus=False) - klass.add_logind_session(logind) + klass.init_logind(enable_kvm) if klass.session_bus_con.name_has_owner('org.gnome.Mutter.DisplayConfig'): raise Exception( @@ -105,13 +105,55 @@ class MutterDBusTestCase(DBusTestCase): return mocks @classmethod - def add_logind_session(klass, logind): + def init_logind_kvm(klass, session_path): + session_obj = klass.system_bus_con.get_object('org.freedesktop.login1', session_path) + session_obj.AddMethod('org.freedesktop.login1.Session', + 'TakeDevice', + 'uu', 'hb', +''' +import re + +major = args[0] +minor = args[1] + +sysfs_uevent_path = '/sys/dev/char/{}:{}/uevent'.format(major, minor) +sysfs_uevent = open(sysfs_uevent_path, 'r') +devname = None +for line in sysfs_uevent.readlines(): + match = re.match('DEVNAME=(.*)', line) + if match: + devname = match[1] + break +sysfs_uevent.close() +if not devname: + raise dbus.exceptions.DBusException(f'Device file {major}:{minor} doesn\\\'t exist', + major=major, minor=minor) +fd = os.open('/dev/' + devname, os.O_RDWR | os.O_CLOEXEC) +unix_fd = dbus.types.UnixFd(fd) +os.close(fd) +ret = (unix_fd, False) +''') + session_obj.AddMethods('org.freedesktop.login1.Session', [ + ('ReleaseDevice', 'uu', '', ''), + ('TakeControl', 'b', '', ''), + ]) + + @classmethod + def init_logind(klass, enable_kvm): + logind = klass.start_from_template('logind') + [p_mock, obj] = logind + mock_iface = 'org.freedesktop.DBus.Mock' obj.AddSeat('seat0', dbus_interface=mock_iface) - obj.AddSession('dummy', 'seat0', - dbus.types.UInt32(os.getuid()), getpass.getuser(), - True, dbus_interface=mock_iface) + session_path = obj.AddSession('dummy', 'seat0', + dbus.types.UInt32(os.getuid()), + getpass.getuser(), + True, + dbus_interface=mock_iface) + + if enable_kvm: + klass.init_logind_kvm(session_path) def wrap_call(self, args): env = {} @@ -130,11 +172,15 @@ class MutterDBusTestCase(DBusTestCase): if __name__ == '__main__': - MutterDBusTestCase.setUpClass() + parser = argparse.ArgumentParser() + parser.add_argument('--kvm', action='store_true', default=False) + (args, rest) = parser.parse_known_args(sys.argv) + + MutterDBusTestCase.setUpClass(args.kvm) test_case = MutterDBusTestCase() - test_case.assertGreater(len(sys.argv), 1) + test_case.assertGreater(len(rest), 1) try: print('Running test case...', file=sys.stderr) - test_case.wrap_call(sys.argv[1:]) + test_case.wrap_call(rest[1:]) finally: MutterDBusTestCase.tearDownClass()