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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2151>
This commit is contained in:
Jonas Ådahl 2021-12-11 11:41:53 +01:00 committed by Marge Bot
parent 1cc786ffd3
commit b5284e5ccc

View File

@ -6,6 +6,7 @@ import os
import fcntl import fcntl
import subprocess import subprocess
import getpass import getpass
import argparse
from collections import OrderedDict from collections import OrderedDict
from dbusmock import DBusTestCase from dbusmock import DBusTestCase
from dbus.mainloop.glib import DBusGMainLoop from dbus.mainloop.glib import DBusGMainLoop
@ -28,7 +29,7 @@ def get_subprocess_stdout():
class MutterDBusTestCase(DBusTestCase): class MutterDBusTestCase(DBusTestCase):
@classmethod @classmethod
def setUpClass(klass): def setUpClass(klass, enable_kvm):
klass.mocks = OrderedDict() klass.mocks = OrderedDict()
print('Starting D-Bus daemons (session & system)...', file=sys.stderr) 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( (klass.mocks_manager, klass.mock_obj) = klass.start_from_local_template(
'meta-mocks-manager', {'templates-dir': get_templates_dir()}) 'meta-mocks-manager', {'templates-dir': get_templates_dir()})
logind = klass.start_from_template('logind')
klass.start_from_local_template('localed') klass.start_from_local_template('localed')
klass.system_bus_con = klass.get_dbus(system_bus=True) klass.system_bus_con = klass.get_dbus(system_bus=True)
klass.session_bus_con = klass.get_dbus(system_bus=False) 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'): if klass.session_bus_con.name_has_owner('org.gnome.Mutter.DisplayConfig'):
raise Exception( raise Exception(
@ -105,13 +105,55 @@ class MutterDBusTestCase(DBusTestCase):
return mocks return mocks
@classmethod @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 [p_mock, obj] = logind
mock_iface = 'org.freedesktop.DBus.Mock' mock_iface = 'org.freedesktop.DBus.Mock'
obj.AddSeat('seat0', dbus_interface=mock_iface) obj.AddSeat('seat0', dbus_interface=mock_iface)
obj.AddSession('dummy', 'seat0', session_path = obj.AddSession('dummy', 'seat0',
dbus.types.UInt32(os.getuid()), getpass.getuser(), dbus.types.UInt32(os.getuid()),
True, dbus_interface=mock_iface) getpass.getuser(),
True,
dbus_interface=mock_iface)
if enable_kvm:
klass.init_logind_kvm(session_path)
def wrap_call(self, args): def wrap_call(self, args):
env = {} env = {}
@ -130,11 +172,15 @@ class MutterDBusTestCase(DBusTestCase):
if __name__ == '__main__': 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 = MutterDBusTestCase()
test_case.assertGreater(len(sys.argv), 1) test_case.assertGreater(len(rest), 1)
try: try:
print('Running test case...', file=sys.stderr) print('Running test case...', file=sys.stderr)
test_case.wrap_call(sys.argv[1:]) test_case.wrap_call(rest[1:])
finally: finally:
MutterDBusTestCase.tearDownClass() MutterDBusTestCase.tearDownClass()