[mutter] tests/dbus-runner: Add methods needed for taking control of a session



commit b5284e5cccc3ae2898462b05cf89c917f022dd56
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Sat Dec 11 11:41:53 2021 +0100

    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>

 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 69daa0af21..79f6a07901 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()


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]