[tracker-miners/sam/functional-tests-shared: 10/15] functional-tests: Use the trackertestutils module from tracker.git



commit 180ec75cc9b641882c7e93bde0d42e064b26ee14
Author: Sam Thursfield <sam afuera me uk>
Date:   Wed Aug 21 22:37:53 2019 +0100

    functional-tests: Use the trackertestutils module from tracker.git
    
    There is a lot of test framework code duplicated between
    tracker-miners.git and tracker.git. This has been a problem since
    tracker-miners.git was split out from tracker.git.
    
    Now, the majority of the test framework lives in tracker.git and
    is installed as a private Python library, which is used by the
    tests in this repository.

 meson.build                                        |   2 +
 .../functional-tests/common/utils/configuration.py |  63 +-
 tests/functional-tests/common/utils/dconf.py       |  80 ---
 tests/functional-tests/common/utils/extractor.py   |   3 +
 tests/functional-tests/common/utils/helpers.py     | 672 ---------------------
 tests/functional-tests/common/utils/html.py        |  63 --
 tests/functional-tests/common/utils/mainloop.py    |  58 --
 tests/functional-tests/common/utils/storetest.py   |  43 --
 tests/functional-tests/common/utils/system.py      | 129 +++-
 tests/functional-tests/configuration.json.in       |   2 -
 tests/functional-tests/meson.build                 |   2 +-
 11 files changed, 133 insertions(+), 984 deletions(-)
---
diff --git a/meson.build b/meson.build
index 683c16813..102b14d83 100644
--- a/meson.build
+++ b/meson.build
@@ -38,6 +38,7 @@ if get_option('tracker_core') == 'system'
   tracker_uninstalled_domain_rule = join_paths 
(tracker_sparql.get_pkgconfig_variable('domain_ontologies_dir'), 'default.rule')
   tracker_uninstalled_nepomuk_ontologies_dir = 
join_paths(tracker_sparql.get_pkgconfig_variable('ontologies_dir'), 'nepomuk')
   tracker_uninstalled_stop_words_dir = join_paths(tracker_sparql.get_pkgconfig_variable('datadir'), 
'tracker', 'stop-words')
+  tracker_uninstalled_testutils_dir = join_paths(tracker_sparql.get_pkgconfig_variable('libdir', 
'tracker-2.0', 'trackertestutils'))
 else
   tracker_subproject = subproject('tracker',
     default_options: [
@@ -55,6 +56,7 @@ else
   tracker_uninstalled_domain_rule = tracker_subproject.get_variable('tracker_uninstalled_domain_rule')
   tracker_uninstalled_nepomuk_ontologies_dir = 
tracker_subproject.get_variable('tracker_uninstalled_nepomuk_ontologies_dir')
   tracker_uninstalled_stop_words_dir = tracker_subproject.get_variable('tracker_uninstalled_stop_words_dir')
+  tracker_uninstalled_testutils_dir = tracker_subproject.get_variable('tracker_uninstalled_testutils_dir')
 
   tracker_common_enums_header = tracker_subproject.get_variable('tracker_common_enums_header')
   tracker_gsettings_schemas = tracker_subproject.get_variable('tracker_gsettings_schemas')
diff --git a/tests/functional-tests/common/utils/configuration.py 
b/tests/functional-tests/common/utils/configuration.py
index 2ee408ead..0d3c5078f 100644
--- a/tests/functional-tests/common/utils/configuration.py
+++ b/tests/functional-tests/common/utils/configuration.py
@@ -18,7 +18,6 @@
 # 02110-1301, USA.
 #
 
-"Constants describing Tracker D-Bus services"
 
 import errno
 import json
@@ -36,60 +35,16 @@ if 'TRACKER_FUNCTIONAL_TEST_CONFIG' not in os.environ:
 with open(os.environ['TRACKER_FUNCTIONAL_TEST_CONFIG']) as f:
     config = json.load(f)
 
-TRACKER_BUSNAME = 'org.freedesktop.Tracker1'
-TRACKER_OBJ_PATH = '/org/freedesktop/Tracker1/Resources'
-RESOURCES_IFACE = "org.freedesktop.Tracker1.Resources"
-
-MINERFS_BUSNAME = "org.freedesktop.Tracker1.Miner.Files"
-MINERFS_OBJ_PATH = "/org/freedesktop/Tracker1/Miner/Files"
-MINER_IFACE = "org.freedesktop.Tracker1.Miner"
-MINERFS_INDEX_OBJ_PATH = "/org/freedesktop/Tracker1/Miner/Files/Index"
-MINER_INDEX_IFACE = "org.freedesktop.Tracker1.Miner.Files.Index"
-
-TRACKER_BACKUP_OBJ_PATH = "/org/freedesktop/Tracker1/Backup"
-BACKUP_IFACE = "org.freedesktop.Tracker1.Backup"
-
-TRACKER_STATS_OBJ_PATH = "/org/freedesktop/Tracker1/Statistics"
-STATS_IFACE = "org.freedesktop.Tracker1.Statistics"
-
-TRACKER_STATUS_OBJ_PATH = "/org/freedesktop/Tracker1/Status"
-STATUS_IFACE = "org.freedesktop.Tracker1.Status"
-
-TRACKER_EXTRACT_BUSNAME = "org.freedesktop.Tracker1.Miner.Extract"
-TRACKER_EXTRACT_OBJ_PATH = "/org/freedesktop/Tracker1/Miner/Extract"
-
-WRITEBACK_BUSNAME = "org.freedesktop.Tracker1.Writeback"
-
 
 DCONF_MINER_SCHEMA = "org.freedesktop.Tracker.Miner.Files"
 
-# Autoconf substitutes paths in the configuration.json file without
-# expanding variables, so we need to manually insert these.
-
-
-def expandvars(variable):
-    # Note: the order matters!
-    result = variable
-    for var, value in [("${datarootdir}", RAW_DATAROOT_DIR),
-                       ("${exec_prefix}", RAW_EXEC_PREFIX),
-                       ("${prefix}", PREFIX),
-                       ("@top_builddir@", TOP_BUILDDIR)]:
-        result = result.replace(var, value)
-
-    return result
-
-
-PREFIX = config['PREFIX']
-RAW_EXEC_PREFIX = config['RAW_EXEC_PREFIX']
-RAW_DATAROOT_DIR = config['RAW_DATAROOT_DIR']
 TOP_BUILDDIR = os.environ['TRACKER_FUNCTIONAL_TEST_BUILD_DIR']
+DATADIR = config['RAW_DATAROOT_DIR']
 
-TRACKER_EXTRACT_PATH = os.path.normpath(expandvars(config['TRACKER_EXTRACT_PATH']))
-TRACKER_MINER_FS_PATH = os.path.normpath(expandvars(config['TRACKER_MINER_FS_PATH']))
-TRACKER_STORE_PATH = os.path.normpath(expandvars(config['TRACKER_STORE_PATH']))
-TRACKER_WRITEBACK_PATH = os.path.normpath(expandvars(config['TRACKER_WRITEBACK_PATH']))
-
-DATADIR = os.path.normpath(expandvars(config['RAW_DATAROOT_DIR']))
+TRACKER_EXTRACT_PATH = config['TRACKER_EXTRACT_PATH']
+TRACKER_MINER_FS_PATH = config['TRACKER_MINER_FS_PATH']
+TRACKER_STORE_PATH = config['TRACKER_STORE_PATH']
+TRACKER_WRITEBACK_PATH = config['TRACKER_WRITEBACK_PATH']
 
 
 # This path is used for test data for tests which expect filesystem monitoring
@@ -110,13 +65,7 @@ if _TEST_MONITORED_TMP_DIR.startswith('/tmp'):
 
 def create_monitored_test_dir():
     '''Returns a unique tmpdir which supports filesystem monitor events.'''
-    try:
-        os.makedirs(_TEST_MONITORED_TMP_DIR)
-    except OSError as e:
-        if e.errno == errno.EEXIST:
-            pass
-        else:
-            raise
+    os.makedirs(_TEST_MONITORED_TMP_DIR, exist_ok=True)
     return tempfile.mkdtemp(dir=_TEST_MONITORED_TMP_DIR)
 
 
diff --git a/tests/functional-tests/common/utils/extractor.py 
b/tests/functional-tests/common/utils/extractor.py
index 5a66c6117..cf85c3f4b 100644
--- a/tests/functional-tests/common/utils/extractor.py
+++ b/tests/functional-tests/common/utils/extractor.py
@@ -91,6 +91,9 @@ class TrackerExtractTestCase(ut.TestCase):
         if not isinstance(d, dict):
             self.fail("Expected dict, got %s" % d)
         if key not in d:
+            import pdb
+            pdb.set_trace()
+
             standardMsg = "Missing: %s" % (key)
             self.fail(self._formatMessage(msg, standardMsg))
         else:
diff --git a/tests/functional-tests/common/utils/system.py b/tests/functional-tests/common/utils/system.py
index e6c190b2e..8c980fb48 100644
--- a/tests/functional-tests/common/utils/system.py
+++ b/tests/functional-tests/common/utils/system.py
@@ -4,10 +4,12 @@ import os
 import shutil
 import tempfile
 
+from gi.repository import Gio
 from gi.repository import GLib
 
-from common.utils.dconf import DConfClient
-from common.utils import helpers
+import trackertestutils.dconf
+import trackertestutils.helpers
+from . import configuration as cfg
 
 TEST_ENV_VARS = {"LC_COLLATE": "en_GB.utf8"}
 
@@ -16,10 +18,121 @@ REASONABLE_TIMEOUT = 5
 log = logging.getLogger(__name__)
 
 
+class WakeupCycleTimeoutException(RuntimeError):
+    pass
+
+
 class UnableToBootException (Exception):
     pass
 
 
+class MinerFsHelper (trackertestutils.helpers.Helper):
+
+    MINERFS_BUSNAME = "org.freedesktop.Tracker1.Miner.Files"
+    MINERFS_OBJ_PATH = "/org/freedesktop/Tracker1/Miner/Files"
+    MINER_IFACE = "org.freedesktop.Tracker1.Miner"
+    MINERFS_INDEX_OBJ_PATH = "/org/freedesktop/Tracker1/Miner/Files/Index"
+    MINER_INDEX_IFACE = "org.freedesktop.Tracker1.Miner.Files.Index"
+
+    def __init__(self, process_path):
+        trackertestutils.helpers.Helper.__init__(self, "tracker-miner-fs", self.MINERFS_BUSNAME, 
process_path)
+        self._progress_handler_id = 0
+        self._wakeup_count = 0
+        self._previous_status = None
+        self._target_wakeup_count = None
+
+    def start(self):
+        trackertestutils.helpers.Helper.start(self, ['--initial-sleep=0'])
+
+        self.miner_fs = Gio.DBusProxy.new_sync(
+            self.bus, Gio.DBusProxyFlags.DO_NOT_AUTO_START, None,
+            self.MINERFS_BUSNAME, self.MINERFS_OBJ_PATH, self.MINER_IFACE)
+        self.index = Gio.DBusProxy.new_sync(
+            self.bus, Gio.DBusProxyFlags.DO_NOT_AUTO_START, None,
+            self.MINERFS_BUSNAME, self.MINERFS_INDEX_OBJ_PATH, self.MINER_INDEX_IFACE)
+
+        def signal_handler(proxy, sender_name, signal_name, parameters):
+            if signal_name == 'Progress':
+                self._progress_cb(*parameters.unpack())
+
+        self._progress_handler_id = self.miner_fs.connect('g-signal', signal_handler)
+
+    def stop(self):
+        trackertestutils.helpers.Helper.stop(self)
+
+        if self._progress_handler_id != 0:
+            self.miner_fs.disconnect(self._progress_handler_id)
+
+    def _progress_cb(self, status, progress, remaining_time):
+        if self._previous_status is None:
+            self._previous_status = status
+        if self._previous_status != 'Idle' and status == 'Idle':
+            self._wakeup_count += 1
+
+        if self._target_wakeup_count is not None and self._wakeup_count >= self._target_wakeup_count:
+            self.loop.quit()
+
+    def wakeup_count(self):
+        """Return the number of wakeup-to-idle cycles the miner-fs completed."""
+        return self._wakeup_count
+
+    def await_wakeup_count(self, target_wakeup_count, timeout=REASONABLE_TIMEOUT):
+        """Block until the miner has completed N wakeup-and-idle cycles.
+
+        This function is for use by miner-fs tests that should trigger an
+        operation in the miner, but which do not cause a new resource to be
+        inserted. These tests can instead wait for the status to change from
+        Idle to Processing... and then back to Idle.
+
+        The miner may change its status any number of times, but you can use
+        this function reliably as follows:
+
+            wakeup_count = miner_fs.wakeup_count()
+            # Trigger a miner-fs operation somehow ...
+            miner_fs.await_wakeup_count(wakeup_count + 1)
+            # The miner has probably finished processing the operation now.
+
+        If the timeout is reached before enough wakeup cycles complete, an
+        exception will be raised.
+
+        """
+
+        assert self._target_wakeup_count is None
+
+        if self._wakeup_count >= target_wakeup_count:
+            log.debug("miner-fs wakeup count is at %s (target is %s). No need to wait", self._wakeup_count, 
target_wakeup_count)
+        else:
+            def _timeout_cb():
+                raise WakeupCycleTimeoutException()
+            timeout_id = GLib.timeout_add_seconds(timeout, _timeout_cb)
+
+            log.debug("Waiting for miner-fs wakeup count of %s (currently %s)", target_wakeup_count, 
self._wakeup_count)
+            self._target_wakeup_count = target_wakeup_count
+            self.loop.run_checked()
+
+            self._target_wakeup_count = None
+            GLib.source_remove(timeout_id)
+
+    def index_file(self, uri):
+        return self.index.IndexFile('(s)', uri)
+
+
+class ExtractorHelper (trackertestutils.helpers.Helper):
+
+    BUSNAME = "org.freedesktop.Tracker1.Miner.Extract"
+
+    def __init__(self, process_path):
+        trackertestutils.helpers.Helper.__init__(self, "tracker-extract", self.BUSNAME, process_path)
+
+
+class WritebackHelper (trackertestutils.helpers.Helper):
+
+    BUSNAME = "org.freedesktop.Tracker1.Writeback"
+
+    def __init__(self, process_path):
+        trackertestutils.helpers.Helper.__init__(self, "tracker-writeback", self.BUSNAME, process_path)
+
+
 class TrackerSystemAbstraction (object):
     def __init__(self, settings=None, ontodir=None):
         self._basedir = None
@@ -72,7 +185,7 @@ class TrackerSystemAbstraction (object):
 
     def _apply_settings(self, settings):
         for schema_name, contents in settings.items():
-            dconf = DConfClient(schema_name)
+            dconf = trackertestutils.dconf.DConfClient(schema_name)
             dconf.reset()
             for key, value in contents.items():
                 dconf.write(key, value)
@@ -84,7 +197,7 @@ class TrackerSystemAbstraction (object):
         """
         self.set_up_environment(confdir, ontodir)
 
-        self.store = helpers.StoreHelper()
+        self.store = trackertestutils.helpers.StoreHelper(cfg.TRACKER_STORE_PATH)
         self.store.start()
 
     def tracker_store_start(self):
@@ -135,19 +248,19 @@ class TrackerSystemAbstraction (object):
         self.set_up_environment(confdir, None)
 
         # Start also the store. DBus autoactivation ignores the env variables.
-        self.store = helpers.StoreHelper()
+        self.store = trackertestutils.helpers.StoreHelper(cfg.TRACKER_STORE_PATH)
         self.store.start()
 
-        self.extractor = helpers.ExtractorHelper()
+        self.extractor = ExtractorHelper(cfg.TRACKER_EXTRACT_PATH)
         self.extractor.start()
 
-        self.miner_fs = helpers.MinerFsHelper()
+        self.miner_fs = MinerFsHelper(cfg.TRACKER_MINER_FS_PATH)
         self.miner_fs.start()
 
     def tracker_writeback_testing_start(self, confdir=None):
         # Start the miner-fs (and store) and then the writeback process
         self.tracker_miner_fs_testing_start(confdir)
-        self.writeback = helpers.WritebackHelper()
+        self.writeback = WritebackHelper(cfg.TRACKER_WRITEBACK_PATH)
         self.writeback.start()
 
     def tracker_all_testing_start(self, confdir=None):
diff --git a/tests/functional-tests/configuration.json.in b/tests/functional-tests/configuration.json.in
index ff8b0b58e..0c04cfc54 100644
--- a/tests/functional-tests/configuration.json.in
+++ b/tests/functional-tests/configuration.json.in
@@ -1,6 +1,4 @@
 {
-    "PREFIX": "@prefix@",
-    "RAW_EXEC_PREFIX": "@exec_prefix@",
     "RAW_DATAROOT_DIR": "@datarootdir@",
     "TRACKER_EXTRACT_PATH": "@FUNCTIONAL_TESTS_TRACKER_EXTRACT_PATH@",
     "TRACKER_MINER_FS_PATH": "@FUNCTIONAL_TESTS_TRACKER_MINER_FS_PATH@",
diff --git a/tests/functional-tests/meson.build b/tests/functional-tests/meson.build
index d3c4bd3ce..c71690f46 100644
--- a/tests/functional-tests/meson.build
+++ b/tests/functional-tests/meson.build
@@ -74,7 +74,7 @@ tracker_extractors_dir = join_paths(meson.current_build_dir(), '..', '..', 'src'
 test_env = environment()
 test_env.set('DCONF_PROFILE', dconf_profile_full_path)
 test_env.set('GSETTINGS_SCHEMA_DIR', tracker_miners_uninstalled_gsettings_schema_dir)
-
+test_env.prepend('PYTHONPATH', tracker_uninstalled_testutils_dir)
 test_env.set('TRACKER_DB_ONTOLOGIES_DIR', tracker_uninstalled_nepomuk_ontologies_dir)
 test_env.set('TRACKER_EXTRACTORS_DIR', tracker_extractors_dir)
 test_env.set('TRACKER_EXTRACTOR_RULES_DIR', tracker_uninstalled_extract_rules_dir)


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