From 577e33e04bc65d38471e6cb05b3297e6afe850ca Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 28 Sep 2020 17:37:19 +0200 Subject: 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(+) create mode 100644 tests/flatpak-info create mode 100644 tests/services/meson.build create mode 100644 tests/services/org.freedesktop.portal.Tracker.service.in create mode 100644 tests/test-bus.conf.in 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 08d16da17..8c16b40b4 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 @@ + + + + session + + unix:tmpdir=./ + + @abs_top_builddir@/tests/services/ + + + + + + + + + + + + -- cgit v1.2.1