[tracker/wip/carlosg/more-tests: 8/12] tests: Add functional test infrastructure for portal tests




commit 57b19bb37dfbde5c2b6285fed946dcd939a5b622
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon Sep 28 17:37:19 2020 +0200

    tests: Add functional test infrastructure for portal tests
    
    Add a base test class that runs the portal and an arbitrary set of endpoints
    in a DBus sandbox, so that different combinations of permissions can be tested.

 tests/flatpak-info                                 |   1 +
 tests/functional-tests/configuration.json.in       |   2 +
 tests/functional-tests/configuration.py            |   2 +
 tests/functional-tests/fixtures.py                 | 115 +++++++++++++++++++++
 tests/functional-tests/meson.build                 |   2 +
 tests/meson.build                                  |   6 ++
 tests/services/meson.build                         |   8 ++
 .../org.freedesktop.portal.Tracker.service.in      |   5 +
 tests/test-bus.conf.in                             |  21 ++++
 9 files changed, 162 insertions(+)
---
diff --git a/tests/flatpak-info b/tests/flatpak-info
new file mode 100644
index 000000000..4af14d3f4
--- /dev/null
+++ b/tests/flatpak-info
@@ -0,0 +1 @@
+[Policy Tracker3]
diff --git a/tests/functional-tests/configuration.json.in b/tests/functional-tests/configuration.json.in
index 6ec1d72e1..ecbea53ca 100644
--- a/tests/functional-tests/configuration.json.in
+++ b/tests/functional-tests/configuration.json.in
@@ -1,5 +1,7 @@
 {
     "TEST_CLI_DIR": "@TEST_CLI_DIR@",
     "TEST_ONTOLOGIES_DIR": "@TEST_ONTOLOGIES_DIR@",
+    "TEST_DBUS_DAEMON_CONFIG_FILE": "@TEST_DBUS_DAEMON_CONFIG_FILE@",
+    "TEST_PORTAL_FLATPAK_INFO": "@TEST_PORTAL_FLATPAK_INFO@",
     "TRACKER_VERSION": "@TRACKER_VERSION@"
 }
diff --git a/tests/functional-tests/configuration.py b/tests/functional-tests/configuration.py
index a9bc7ccc9..cb1bc9a2b 100644
--- a/tests/functional-tests/configuration.py
+++ b/tests/functional-tests/configuration.py
@@ -38,6 +38,8 @@ if 'TRACKER_FUNCTIONAL_TEST_CONFIG' not in os.environ:
 with open(os.environ['TRACKER_FUNCTIONAL_TEST_CONFIG']) as f:
     config = json.load(f)
 
+TEST_DBUS_DAEMON_CONFIG_FILE = config['TEST_DBUS_DAEMON_CONFIG_FILE']
+TEST_PORTAL_FLATPAK_INFO = config['TEST_PORTAL_FLATPAK_INFO']
 
 def cli_dir():
     return config['TEST_CLI_DIR']
diff --git a/tests/functional-tests/fixtures.py b/tests/functional-tests/fixtures.py
index c99fc0bbe..cf2ad9811 100644
--- a/tests/functional-tests/fixtures.py
+++ b/tests/functional-tests/fixtures.py
@@ -32,6 +32,7 @@ import logging
 import os
 import pathlib
 import multiprocessing
+import threading
 import shutil
 import subprocess
 import sys
@@ -148,6 +149,120 @@ class TrackerSparqlBusTest (ut.TestCase):
         shutil.rmtree(self.tmpdir, ignore_errors=True)
 
 
+class TrackerPortalTest(ut.TestCase):
+    @classmethod
+    def database_process_fn(self, service_name, in_queue, out_queue, dbus_address):
+        # This runs in a separate process and provides a clean Tracker database
+        # exported over D-Bus to the main test process.
+
+        log.info("Started database thread")
+
+        bus = Gio.DBusConnection.new_for_address_sync(
+            dbus_address,
+            Gio.DBusConnectionFlags.AUTHENTICATION_CLIENT |
+            Gio.DBusConnectionFlags.MESSAGE_BUS_CONNECTION, None, None)
+
+        conn = Tracker.SparqlConnection.new(
+            Tracker.SparqlConnectionFlags.NONE,
+            None,
+            Gio.File.new_for_path(cfg.ontologies_dir()),
+            None)
+
+        endpoint = Tracker.EndpointDBus.new(conn, bus, None, None)
+
+        bus.call_sync(
+            'org.freedesktop.DBus',
+            '/org/freedesktop/DBus',
+            'org.freedesktop.DBus',
+            'RequestName',
+            GLib.Variant('(su)', (service_name, 0x4)),
+            None, 0, -1, None)
+
+        loop = GLib.MainLoop.new(None, False)
+
+        def pop_update(message_queue):
+            try:
+                sparql = message_queue.get_nowait()
+                if sparql is None:
+                    loop.quit()
+                conn.update(sparql, None)
+                out_queue.put(None)
+            except Exception:
+                pass
+            return GLib.SOURCE_CONTINUE
+
+        GLib.timeout_add (50, pop_update, in_queue)
+        out_queue.put(None)
+        loop.run()
+
+        bus.close(None)
+
+    def setUp(self):
+        extra_env = {}
+        extra_env['TRACKER_TEST_PORTAL_FLATPAK_INFO'] = cfg.TEST_PORTAL_FLATPAK_INFO
+
+        self.message_queues = {}
+        self.connections = {}
+        self.sandbox = trackertestutils.helpers.TrackerDBusSandbox(
+            session_bus_config_file=cfg.TEST_DBUS_DAEMON_CONFIG_FILE, extra_env=extra_env)
+
+        self.sandbox.start()
+
+        self.bus = self.sandbox.get_session_bus_connection()
+        self.dbus_address = self.sandbox.get_session_bus_address()
+
+        try:
+            log.info("Starting portal")
+            self._portal_proxy = Gio.DBusProxy.new_sync(
+                self.bus,
+                Gio.DBusProxyFlags.NONE, None,
+                'org.freedesktop.portal.Tracker',
+                '/org/freedesktop/portal/Tracker',
+                'org.freedesktop.portal.Tracker',
+                None)
+
+        except Exception:
+            self.sandbox.stop()
+            raise
+
+    def tearDown(self):
+        for service in self.message_queues:
+            self.stop_service(service)
+        self.sandbox.stop()
+
+    def start_service(self, service_name):
+        in_queue = multiprocessing.Queue()
+        out_queue = multiprocessing.Queue()
+        thread = threading.Thread(
+            target=self.database_process_fn,
+            args=(service_name, out_queue, in_queue, self.dbus_address))
+        thread.start()
+        in_queue.get()
+        self.message_queues[service_name] = [ in_queue, out_queue ]
+
+    def stop_service(self, service_name):
+        queues = self.message_queues[service_name]
+        if queues is not None:
+            queues[1].put(None)
+
+    def update(self, service_name, sparql):
+        if sparql is not None:
+            # Updates go through the message queue, bypassing the sandbox
+            queues = self.message_queues[service_name]
+            if queues is not None:
+                queues[1].put(sparql)
+                queues[0].get()
+
+    def query(self, service_name, sparql):
+        if service_name not in self.connections:
+            conn = Tracker.SparqlConnection.bus_new(service_name, None, self.bus)
+            store = trackertestutils.helpers.StoreHelper(conn)
+            self.connections[service_name] = store
+        else:
+            store = self.connections[service_name]
+
+        return store.query(sparql)
+
 
 class CliError(Exception):
     pass
diff --git a/tests/functional-tests/meson.build b/tests/functional-tests/meson.build
index 89b78756d..b9efebb6c 100644
--- a/tests/functional-tests/meson.build
+++ b/tests/functional-tests/meson.build
@@ -6,6 +6,8 @@ config_json_full_path = join_paths(meson.current_build_dir(), 'configuration.jso
 
 testconf.set('TEST_CLI_DIR', tracker_uninstalled_cli_dir)
 testconf.set('TEST_ONTOLOGIES_DIR', tracker_uninstalled_nepomuk_ontologies_dir)
+testconf.set('TEST_DBUS_DAEMON_CONFIG_FILE', build_root / 'tests' / 'test-bus.conf')
+testconf.set('TEST_PORTAL_FLATPAK_INFO', source_root / 'tests' / 'flatpak-info')
 testconf.set('TRACKER_VERSION', meson.project_version())
 
 config_json = configure_file(
diff --git a/tests/meson.build b/tests/meson.build
index e0647d9f2..562204efe 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -1,5 +1,10 @@
 tests = []
 
+test_bus_conf_file = configure_file(
+  input: 'test-bus.conf.in',
+  output: 'test-bus.conf',
+  configuration: conf)
+
 subdir('common')
 
 subdir('gvdb')
@@ -8,6 +13,7 @@ subdir('libtracker-data')
 subdir('libtracker-fts')
 subdir('libtracker-sparql')
 subdir('functional-tests')
+subdir('services')
 
 foreach t: tests
   test_name = t.get('name')
diff --git a/tests/services/meson.build b/tests/services/meson.build
new file mode 100644
index 000000000..623ec5243
--- /dev/null
+++ b/tests/services/meson.build
@@ -0,0 +1,8 @@
+# This directory contains service files used by dbus-daemon to automatically
+# activate the daemons as needed. These files are used when running Tracker
+# from the build tree.
+
+tracker_test_xdg_portal_service_file = configure_file(
+    input: 'org.freedesktop.portal.Tracker.service.in',
+    output: 'org.freedesktop.portal.Tracker.service',
+    configuration: conf)
diff --git a/tests/services/org.freedesktop.portal.Tracker.service.in 
b/tests/services/org.freedesktop.portal.Tracker.service.in
new file mode 100644
index 000000000..b7aab5796
--- /dev/null
+++ b/tests/services/org.freedesktop.portal.Tracker.service.in
@@ -0,0 +1,5 @@
+[D-BUS Service]
+Name=org.freedesktop.portal.Tracker
+Exec=@abs_top_builddir@/src/portal/tracker-xdg-portal-3
+SystemdService=tracker-xdg-portal-3.service
+
diff --git a/tests/test-bus.conf.in b/tests/test-bus.conf.in
new file mode 100644
index 000000000..2f4b2ef1b
--- /dev/null
+++ b/tests/test-bus.conf.in
@@ -0,0 +1,21 @@
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd";>
+<busconfig>
+  <!-- Our well-known bus type, don't change this -->
+  <type>session</type>
+
+  <listen>unix:tmpdir=./</listen>
+
+  <servicedir>@abs_top_builddir@/tests/services/</servicedir>
+  <standard_session_servicedirs/>
+
+  <policy context="default">
+    <!-- Allow everything to be sent -->
+    <allow send_destination="*"/>
+    <!-- Allow everything to be received -->
+    <allow eavesdrop="true"/>
+    <!-- Allow anyone to own anything -->
+    <allow own="*"/>
+  </policy>
+
+</busconfig>


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