[tracker/sam/umockdev: 3/3] WIP: Add support for testing power management with umockdev



commit 5047c5c9da79f2708f622fbb489302d60c37e6ab
Author: Sam Thursfield <sam afuera me uk>
Date:   Thu May 21 12:42:24 2020 +0200

    WIP: Add support for testing power management with umockdev

 utils/trackertestutils/dbusdaemon.py | 32 ++++++++++++++++++++++++++++++++
 utils/trackertestutils/helpers.py    |  2 +-
 utils/trackertestutils/sandbox.py    | 33 +++++++++++++++++++++++++++++++++
 3 files changed, 66 insertions(+), 1 deletion(-)
---
diff --git a/utils/trackertestutils/dbusdaemon.py b/utils/trackertestutils/dbusdaemon.py
index e55c03595..24011bcbb 100644
--- a/utils/trackertestutils/dbusdaemon.py
+++ b/utils/trackertestutils/dbusdaemon.py
@@ -26,6 +26,10 @@ import signal
 import subprocess
 import threading
 
+from . import mainloop
+
+DEFAULT_TIMEOUT = 10
+
 log = logging.getLogger(__name__)
 dbus_stderr_log = logging.getLogger(__name__ + '.stderr')
 dbus_stdout_log = logging.getLogger(__name__ + '.stdout')
@@ -35,6 +39,31 @@ class DaemonNotStartedError(Exception):
     pass
 
 
+def await_bus_name(conn, bus_name, timeout=DEFAULT_TIMEOUT):
+    """Blocks until 'bus_name' has an owner."""
+
+    log.info("Blocking until name %s has owner", bus_name)
+    loop = mainloop.MainLoop()
+
+    def name_appeared_cb(connection, name, name_owner):
+        log.info("Name %s appeared (owned by %s)", name, name_owner)
+        loop.quit()
+
+    def timeout_cb():
+        log.info("Timeout fired after %s seconds", timeout)
+        raise AwaitTimeoutException(
+            f"Timeout awaiting bus name '{bus_name}'")
+
+    watch_id = Gio.bus_watch_name_on_connection(
+        conn, bus_name, Gio.BusNameWatcherFlags.NONE, name_appeared_cb, None)
+    timeout_id = GLib.timeout_add_seconds(timeout, timeout_cb)
+
+    loop.run_checked()
+
+    Gio.bus_unwatch_name(watch_id)
+    GLib.source_remove(timeout_id)
+
+
 class DBusDaemon:
     """The private D-Bus instance that provides the sandbox's session bus."""
 
@@ -199,3 +228,6 @@ class DBusDaemon:
                 return None
             else:
                 raise
+
+    def await_bus_name(self, bus_name, timeout=DEFAULT_TIMEOUT):
+        await_bus_name(self.get_connection(), bus_name, timeout)
diff --git a/utils/trackertestutils/helpers.py b/utils/trackertestutils/helpers.py
index c1795b974..91086618f 100644
--- a/utils/trackertestutils/helpers.py
+++ b/utils/trackertestutils/helpers.py
@@ -17,5 +17,5 @@
 
 # FIXME: Compatibility module due to recent API breaks.
 # Remove this before 3.0.
-from .sandbox import TrackerSandbox
+from .sandbox import TrackerSandbox as TrackerDBusSandbox
 from .storehelper import StoreHelper
diff --git a/utils/trackertestutils/sandbox.py b/utils/trackertestutils/sandbox.py
index e9fd85363..bf18ccf78 100644
--- a/utils/trackertestutils/sandbox.py
+++ b/utils/trackertestutils/sandbox.py
@@ -27,8 +27,10 @@ import atexit
 import logging
 import os
 import signal
+import subprocess
 
 from . import dbusdaemon
+from . import devices
 from . import psutil_mini as psutil
 
 log = logging.getLogger(__name__)
@@ -58,6 +60,7 @@ class TrackerSandbox:
         self.extra_env = extra_env or {}
 
         self.daemon = dbusdaemon.DBusDaemon()
+        self.umockdev_testbed = None
 
     def start(self, new_session=False):
         env = os.environ
@@ -84,6 +87,22 @@ class TrackerSandbox:
         log.debug("Added environment variables: %s", self.extra_env)
         self.daemon.start(self.dbus_daemon_config_file, env=env, new_session=new_session)
 
+    def start_upowerd(self, testbed):
+        """Start the upower daemon.
+
+        Needed only for tests that use mock power devices.
+
+        """
+        # FIXME: -> start_system_daemon ()
+        # FIXME: We could use auto activation here ?
+        env = os.environ.copy()
+        env['DBUS_SYSTEM_BUS_ADDRESS'] = self.daemon.get_address()
+        env['UMOCKDEV_DIR'] = testbed.get_root_dir()
+        # FIXME: need to capture the logs  - maybe factor pipe_to_log out from
+        # dbusdaemon.py
+        self.upower = subprocess.Popen([devices.upowerd_path(), '--verbose'], env=env)
+        self.daemon.await_bus_name('org.freedesktop.UPower')
+
     def stop(self):
         tracker_processes = []
 
@@ -128,4 +147,18 @@ class TrackerSandbox:
             log.info("Couldn't find a process owning %s.", busname)
 
     def get_connection(self):
+        """Return a Gio.BusConnection to the sandbox's private D-Bus daemon."""
         return self.daemon.get_connection()
+
+    def get_umockdev_testbed(self):
+        """Returns the UMockDev.TestBed used to control mock hardware devices.
+
+        Raises `devices.UMockDevNotFound` if the umockdev library is not
+        available. You can use `devices.HAVE_UMOCKDEV` to check before calling.
+
+        The `devices` module provides helpers for use with this object.
+
+        """
+        if not self.umockdev_testbed:
+            self.umockdev_testbed = devices.create_testbed()
+        return self.umockdev_testbed


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