[nautilus/sam/tracker-3: 62/67] Port to Tracker 3




commit 33ce172ec33d30fa500e790f39202b8f6ef43af9
Author: Sam Thursfield <sam afuera me uk>
Date:   Sat May 2 16:46:28 2020 +0200

    Port to Tracker 3
    
    Mostly the port is straightforward, we connect to tracker-miner-fs
    explicitly over D-Bus instead of the centralized tracker-store daemon
    we connected to previously.
    
    The search-engine-tracker test is now isolated from the user's real
    Tracker index using the `tracker-sandbox` script provided by Tracker,
    and it lets tracker-miner-fs index the test file rather than trying
    to synthesize the expected database contents.
    
    There are more changes in nautilus-tag-manager.c because the
    TrackerNotifier API changed, it no longer queries the URIs for
    us so we need to query these ourselves, and maintain a table
    of ID->URI mappings in addition to the URI->ID mapping that we
    already maintained.

 meson.build                                        |   2 +-
 src/nautilus-batch-rename-utilities.c              |   4 +-
 src/nautilus-global-preferences.c                  |   2 +-
 src/nautilus-search-engine-tracker.c               |  28 ++-
 src/nautilus-tag-manager.c                         | 278 +++++++++++----------
 test/automated/displayless/meson.build             |  29 ++-
 .../test-nautilus-search-engine-tracker.c          | 157 +++++++++---
 7 files changed, 306 insertions(+), 194 deletions(-)
---
diff --git a/meson.build b/meson.build
index 5c1891262..abc3b58ec 100644
--- a/meson.build
+++ b/meson.build
@@ -124,7 +124,7 @@ selinux = []
 if get_option('selinux')
   selinux = dependency('libselinux', version: '>= 2.0')
 endif
-tracker_sparql = dependency('tracker-sparql-2.0')
+tracker_sparql = dependency('tracker-sparql-3.0')
 xml = dependency('libxml-2.0', version: '>= 2.7.8')
 
 ####################
diff --git a/src/nautilus-batch-rename-utilities.c b/src/nautilus-batch-rename-utilities.c
index da0f32113..b31506f5f 100644
--- a/src/nautilus-batch-rename-utilities.c
+++ b/src/nautilus-batch-rename-utilities.c
@@ -63,6 +63,8 @@ enum
     ALBUM_NAME_INDEX,
 } QueryMetadata;
 
+#define TRACKER_MINER_FS_BUSNAME "org.freedesktop.Tracker3.Miner.Files"
+
 static void on_cursor_callback (GObject      *object,
                                 GAsyncResult *result,
                                 gpointer      user_data);
@@ -1117,7 +1119,7 @@ check_metadata_for_selection (NautilusBatchRenameDialog *dialog,
 
     g_string_append (query, "} ORDER BY ASC(nie:contentCreated(?file))");
 
-    connection = tracker_sparql_connection_get (NULL, &error);
+    connection = tracker_sparql_connection_bus_new (TRACKER_MINER_FS_BUSNAME, NULL, NULL, &error);
     if (!connection)
     {
         if (error)
diff --git a/src/nautilus-global-preferences.c b/src/nautilus-global-preferences.c
index 0e7e011b6..685ced48c 100644
--- a/src/nautilus-global-preferences.c
+++ b/src/nautilus-global-preferences.c
@@ -66,5 +66,5 @@ nautilus_global_preferences_init (void)
     gnome_lockdown_preferences = g_settings_new ("org.gnome.desktop.lockdown");
     gnome_background_preferences = g_settings_new ("org.gnome.desktop.background");
     gnome_interface_preferences = g_settings_new ("org.gnome.desktop.interface");
-    tracker_preferences = g_settings_new ("org.freedesktop.Tracker.Miner.Files");
+    tracker_preferences = g_settings_new ("org.freedesktop.Tracker3.Miner.Files");
 }
diff --git a/src/nautilus-search-engine-tracker.c b/src/nautilus-search-engine-tracker.c
index 82876368a..8c44c4892 100644
--- a/src/nautilus-search-engine-tracker.c
+++ b/src/nautilus-search-engine-tracker.c
@@ -55,6 +55,8 @@ enum
     LAST_PROP
 };
 
+#define TRACKER_MINER_FS_BUSNAME "org.freedesktop.Tracker3.Miner.Files"
+
 static void nautilus_search_provider_init (NautilusSearchProviderInterface *iface);
 
 G_DEFINE_TYPE_WITH_CODE (NautilusSearchEngineTracker,
@@ -334,22 +336,22 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
     mimetypes = nautilus_query_get_mime_types (tracker->query);
 
     sparql = g_string_new ("SELECT DISTINCT"
-                           " nie:url(?urn)"
+                           " ?url"
                            " xsd:double(COALESCE(?rank2, ?rank1)) AS ?rank"
-                           " nfo:fileLastModified(?urn)"
-                           " nfo:fileLastAccessed(?urn)");
+                           " nfo:fileLastModified(?file)"
+                           " nfo:fileLastAccessed(?file)");
 
     if (tracker->fts_enabled)
     {
-        g_string_append (sparql, " fts:snippet(?urn)");
+        g_string_append (sparql, " fts:snippet(?content)");
     }
 
     g_string_append (sparql,
                      "\nWHERE {"
-                     "  ?urn a nfo:FileDataObject;"
+                     "  ?file a nfo:FileDataObject;"
                      "  nfo:fileLastModified ?mtime;"
                      "  nfo:fileLastAccessed ?atime;"
-                     "  tracker:available true;"
+                     "  nie:dataSource/tracker:available true;"
                      "  nie:url ?url");
 
     if (mimetypes->len > 0)
@@ -362,15 +364,16 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
         /* Use fts:match only for content search to not lose some filename results due to stop words. */
         g_string_append_printf (sparql,
                                 " {"
-                                " ?urn fts:match '\"nie:plainTextContent\" : \"%s\"*' ."
-                                " BIND(fts:rank(?urn) AS ?rank1) ."
+                                " ?content nie:isStoredAs ?file ."
+                                " ?content fts:match \"%s*\" ."
+                                " BIND(fts:rank(?content) AS ?rank1) ."
                                 " } UNION",
                                 search_text);
     }
 
     g_string_append_printf (sparql,
                             " {"
-                            " ?urn nfo:fileName ?filename ."
+                            " ?file nfo:fileName ?filename ."
                             " FILTER(fn:contains(fn:lower-case(?filename), '%s')) ."
                             " BIND(" FILENAME_RANK " AS ?rank2) ."
                             " }",
@@ -384,7 +387,10 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
     }
     else
     {
-        g_string_append_printf (sparql, "tracker:uri-is-descendant('%s', ?url)", location_uri);
+        /* STRSTARTS is faster than tracker:uri-is-descendant().
+         * See https://gitlab.gnome.org/GNOME/tracker/-/issues/243
+         */
+        g_string_append_printf (sparql, "STRSTARTS(?url, '%s')", location_uri);
     }
 
     date_range = nautilus_query_get_date_range (tracker->query);
@@ -558,7 +564,7 @@ nautilus_search_engine_tracker_init (NautilusSearchEngineTracker *engine)
 
     engine->hits_pending = g_queue_new ();
 
-    engine->connection = tracker_sparql_connection_get (NULL, &error);
+    engine->connection = tracker_sparql_connection_bus_new (TRACKER_MINER_FS_BUSNAME, NULL, NULL, &error);
 
     if (error)
     {
diff --git a/src/nautilus-tag-manager.c b/src/nautilus-tag-manager.c
index a3cf1beaf..68f456cc1 100644
--- a/src/nautilus-tag-manager.c
+++ b/src/nautilus-tag-manager.c
@@ -27,10 +27,14 @@ struct _NautilusTagManager
 {
     GObject object;
 
+    TrackerSparqlConnection *connection;
     TrackerNotifier *notifier;
-    GError *notifier_error;
 
-    GHashTable *starred_files;
+    /* Map of URI -> tracker ID */
+    GHashTable *starred_file_uris;
+    /* Map of tracker ID -> URI */
+    GHashTable *starred_file_ids;
+
     GCancellable *cancellable;
 };
 
@@ -67,30 +71,12 @@ enum
     LAST_SIGNAL
 };
 
+#define TRACKER_MINER_FS_BUSNAME "org.freedesktop.Tracker3.Miner.Files"
+
 #define STARRED_TAG "<urn:gnome:nautilus:starred>"
 
 static guint signals[LAST_SIGNAL];
 
-static const gchar *
-nautilus_tag_manager_file_with_id_changed_url (GHashTable  *hash_table,
-                                               gint64       id,
-                                               const gchar *url)
-{
-    GHashTableIter iter;
-    gpointer key, value;
-
-    g_hash_table_iter_init (&iter, hash_table);
-    while (g_hash_table_iter_next (&iter, &key, &value))
-    {
-        if ((gint64) value == id && g_strcmp0 (url, key) != 0)
-        {
-            return key;
-        }
-    }
-
-    return NULL;
-}
-
 static void
 destroy_insert_task_data (gpointer data)
 {
@@ -134,23 +120,18 @@ add_selection_filter (GList   *selection,
 }
 
 static void
-start_query_or_update (GString             *query,
-                       GAsyncReadyCallback  callback,
-                       gpointer             user_data,
-                       gboolean             is_query,
-                       GCancellable        *cancellable)
+start_query_or_update (TrackerSparqlConnection *connection,
+                       GString                 *query,
+                       GAsyncReadyCallback      callback,
+                       gpointer                 user_data,
+                       gboolean                 is_query,
+                       GCancellable            *cancellable)
 {
     g_autoptr (GError) error = NULL;
-    TrackerSparqlConnection *connection;
 
-    connection = tracker_sparql_connection_get (cancellable, &error);
     if (!connection)
     {
-        if (error)
-        {
-            g_warning ("Error on getting connection: %s", error->message);
-        }
-
+        g_message ("nautilus-tag-manager: No Tracker connection");
         return;
     }
 
@@ -166,13 +147,10 @@ start_query_or_update (GString             *query,
     {
         tracker_sparql_connection_update_async (connection,
                                                 query->str,
-                                                G_PRIORITY_DEFAULT,
                                                 cancellable,
                                                 callback,
                                                 user_data);
     }
-
-    g_object_unref (connection);
 }
 
 static void
@@ -233,7 +211,7 @@ on_update_callback (GObject      *object,
     TrackerSparqlConnection *connection;
     GError *error;
     UpdateData *data;
-    gint64 *id;
+    gint64 *new_id;
     GList *l;
     gchar *uri;
 
@@ -256,17 +234,24 @@ on_update_callback (GObject      *object,
             {
                 if (g_hash_table_contains (data->ids, uri))
                 {
-                    id = g_new0 (gint64, 1);
+                    new_id = g_new0 (gint64, 1);
 
-                    *id = (gint64) g_hash_table_lookup (data->ids, uri);
-                    g_hash_table_insert (data->tag_manager->starred_files,
+                    *new_id = (gint64) g_hash_table_lookup (data->ids, uri);
+                    g_hash_table_insert (data->tag_manager->starred_file_uris,
                                          nautilus_file_get_uri (NAUTILUS_FILE (l->data)),
-                                         id);
+                                         new_id);
+                    g_hash_table_insert (data->tag_manager->starred_file_ids,
+                                         new_id,
+                                         nautilus_file_get_uri (NAUTILUS_FILE (l->data)));
                 }
             }
             else
             {
-                g_hash_table_remove (data->tag_manager->starred_files, uri);
+                new_id = g_hash_table_lookup (data->tag_manager->starred_file_uris, uri);
+                if (new_id) {
+                    g_hash_table_remove (data->tag_manager->starred_file_uris, uri);
+                    g_hash_table_remove (data->tag_manager->starred_file_ids, new_id);
+                }
             }
 
             g_free (uri);
@@ -352,7 +337,7 @@ get_query_status (TrackerSparqlCursor *cursor,
 GList *
 nautilus_tag_manager_get_starred_files (NautilusTagManager *self)
 {
-    return g_hash_table_get_keys (self->starred_files);
+    return g_hash_table_get_keys (self->starred_file_uris);
 }
 
 static void
@@ -383,9 +368,8 @@ on_get_starred_files_cursor_callback (GObject      *object,
     url = tracker_sparql_cursor_get_string (cursor, 0, NULL);
     *id = tracker_sparql_cursor_get_integer (cursor, 1);
 
-    g_hash_table_insert (self->starred_files,
-                         g_strdup (url),
-                         id);
+    g_hash_table_insert (self->starred_file_uris, g_strdup (url), id);
+    g_hash_table_insert (self->starred_file_ids, id, g_strdup (url));
 
     file = nautilus_file_get_by_uri (url);
     changed_files = g_list_prepend (NULL, file);
@@ -428,7 +412,8 @@ nautilus_tag_manager_query_starred_files (NautilusTagManager *self,
     query = g_string_new ("SELECT ?url tracker:id(?urn) "
                           "WHERE { ?urn nie:url ?url ; nao:hasTag " STARRED_TAG "}");
 
-    start_query_or_update (query,
+    start_query_or_update (self->connection,
+                           query,
                            on_get_starred_files_query_callback,
                            self,
                            TRUE,
@@ -484,7 +469,7 @@ gboolean
 nautilus_tag_manager_file_is_starred (NautilusTagManager *self,
                                       const gchar        *file_name)
 {
-    return g_hash_table_contains (self->starred_files, file_name);
+    return g_hash_table_contains (self->starred_file_uris, file_name);
 }
 
 static void
@@ -560,9 +545,9 @@ on_get_file_ids_for_urls_query_callback (GObject      *object,
 }
 
 static void
-nautilus_tag_manager_get_file_ids_for_urls (GObject *object,
-                                            GList   *selection,
-                                            GTask   *task)
+nautilus_tag_manager_get_file_ids_for_urls (NautilusTagManager *self,
+                                            GList              *selection,
+                                            GTask              *task)
 {
     GString *query;
 
@@ -572,7 +557,8 @@ nautilus_tag_manager_get_file_ids_for_urls (GObject *object,
 
     g_string_append (query, "}\n");
 
-    start_query_or_update (query,
+    start_query_or_update (self->connection,
+                           query,
                            on_get_file_ids_for_urls_query_callback,
                            task,
                            TRUE,
@@ -617,7 +603,8 @@ on_star_files_callback (GObject      *object,
      */
     destroy_insert_task_data (data);
 
-    start_query_or_update (query,
+    start_query_or_update (self->connection,
+                           query,
                            on_update_callback,
                            update_data,
                            FALSE,
@@ -651,7 +638,7 @@ nautilus_tag_manager_star_files (NautilusTagManager  *self,
                           data,
                           NULL);
 
-    nautilus_tag_manager_get_file_ids_for_urls (G_OBJECT (self), selection, task);
+    nautilus_tag_manager_get_file_ids_for_urls (self, selection, task);
 }
 
 void
@@ -679,7 +666,8 @@ nautilus_tag_manager_unstar_files (NautilusTagManager  *self,
     update_data->selection = nautilus_file_list_copy (selection);
     update_data->star = FALSE;
 
-    start_query_or_update (query,
+    start_query_or_update (self->connection,
+                           query,
                            on_update_callback,
                            update_data,
                            FALSE,
@@ -690,6 +678,8 @@ nautilus_tag_manager_unstar_files (NautilusTagManager  *self,
 
 static void
 on_tracker_notifier_events (TrackerNotifier *notifier,
+                            gchar           *service,
+                            gchar           *graph,
                             GPtrArray       *events,
                             gpointer         user_data)
 {
@@ -699,13 +689,13 @@ on_tracker_notifier_events (TrackerNotifier *notifier,
     const gchar *location_uri;
     const gchar *new_location_uri;
     GError *error = NULL;
-    TrackerSparqlConnection *connection;
     TrackerSparqlCursor *cursor;
     GString *query;
     gboolean query_has_results;
-    gint64 *id;
+    gboolean is_starred;
+    gint64 id, *new_id;
     GList *changed_files;
-    NautilusFile *file;
+    NautilusFile *changed_file;
 
     self = NAUTILUS_TAG_MANAGER (user_data);
 
@@ -713,52 +703,18 @@ on_tracker_notifier_events (TrackerNotifier *notifier,
     {
         event = g_ptr_array_index (events, i);
 
-        location_uri = tracker_notifier_event_get_location (event);
-
         query = g_string_new ("");
         g_string_append_printf (query,
-                                "SELECT ?url WHERE { ?urn nie:url ?url; nao:hasTag " STARRED_TAG " . FILTER 
(tracker:id(?urn) = %" G_GINT64_FORMAT ")}",
+                                "SELECT ?url EXISTS{ ?urn nao:hasTag " STARRED_TAG "} AS ?starred "
+                                "WHERE { ?urn nie:url ?url . FILTER (tracker:id(?urn) = %" G_GINT64_FORMAT 
")}",
                                 tracker_notifier_event_get_id (event));
 
-        /* check if the file changed it's location and update hash table if so */
-        new_location_uri = nautilus_tag_manager_file_with_id_changed_url (self->starred_files,
-                                                                          tracker_notifier_event_get_id 
(event),
-                                                                          location_uri);
-        if (new_location_uri)
-        {
-            id = g_new0 (gint64, 1);
-            *id = tracker_notifier_event_get_id (event);
-
-            g_hash_table_remove (self->starred_files, new_location_uri);
-            g_hash_table_insert (self->starred_files,
-                                 g_strdup (location_uri),
-                                 id);
-
-            file = nautilus_file_get_by_uri (location_uri);
-            changed_files = g_list_prepend (NULL, file);
-
-            g_signal_emit_by_name (self, "starred-changed", changed_files);
-
-            nautilus_file_list_free (changed_files);
-        }
-
-        connection = tracker_sparql_connection_get (NULL, &error);
-
-        if (!connection)
-        {
-            g_printerr ("Couldn't obtain a direct connection to the Tracker store: %s",
-                        error ? error->message : "unknown error");
-            g_clear_error (&error);
-
-            return;
-        }
-
-        cursor = tracker_sparql_connection_query (connection,
+        cursor = tracker_sparql_connection_query (self->connection,
                                                   query->str,
                                                   NULL,
                                                   &error);
 
-        if (error)
+        if (error || !cursor)
         {
             g_printerr ("Couldn't query the Tracker Store: '%s'", error->message);
 
@@ -767,45 +723,78 @@ on_tracker_notifier_events (TrackerNotifier *notifier,
             return;
         }
 
-        if (cursor)
+        changed_file = NULL;
+
+        id = tracker_notifier_event_get_id (event);
+        location_uri = g_hash_table_lookup (self->starred_file_ids, &id);
+
+        query_has_results = tracker_sparql_cursor_next (cursor, NULL, &error);
+
+        if (!query_has_results)
         {
-            query_has_results = tracker_sparql_cursor_next (cursor, NULL, &error);
+            if (g_hash_table_contains (self->starred_file_ids, &id))
+            {
+                /* The file must have been deleted from the Tracker index. */
+                location_uri = g_hash_table_lookup (self->starred_file_ids, &id);
+
+                changed_file = nautilus_file_get_by_uri (location_uri);
 
-            /* if no results are found, then the file isn't marked as starred.
-             * If needed, update the hashtable.
-             */
-            if (!query_has_results && location_uri && g_hash_table_contains (self->starred_files, 
location_uri))
+                g_hash_table_remove (self->starred_file_ids, &id);
+                g_hash_table_remove (self->starred_file_uris, location_uri);
+            }
+        }
+        else
+        {
+            new_location_uri = tracker_sparql_cursor_get_string (cursor, 0, NULL);
+            is_starred = tracker_sparql_cursor_get_boolean (cursor, 1);
+
+            if (g_hash_table_contains (self->starred_file_ids, &id))
             {
-                g_hash_table_remove (self->starred_files, location_uri);
+                if (is_starred && strcmp (location_uri, new_location_uri) != 0)
+                {
+                    new_id = g_new0 (gint64, 1);
+                    *new_id = id;
 
-                file = nautilus_file_get_by_uri (location_uri);
-                changed_files = g_list_prepend (NULL, file);
+                    /* File URI changed. */
+                    g_hash_table_remove (self->starred_file_uris, location_uri);
 
-                g_signal_emit_by_name (self, "starred-changed", changed_files);
+                    g_hash_table_insert (self->starred_file_ids, &id, g_strdup (new_location_uri));
+                    g_hash_table_insert (self->starred_file_uris, g_strdup (new_location_uri), new_id);
 
-                nautilus_file_list_free (changed_files);
+                    changed_file = nautilus_file_get_by_uri (new_location_uri);
+                }
+                else if (!is_starred)
+                {
+                    /* File is no longer starred */
+                    g_hash_table_remove (self->starred_file_uris, location_uri);
+                    g_hash_table_remove (self->starred_file_ids, &id);
+
+                    changed_file = nautilus_file_get_by_uri (new_location_uri);
+                }
             }
-            else if (query_has_results && location_uri && !g_hash_table_contains (self->starred_files, 
location_uri))
+            else
             {
-                id = g_new0 (gint64, 1);
-                *id = tracker_notifier_event_get_id (event);
+                /* File is newly starred */
+                new_id = g_new0 (gint64, 1);
+                *new_id = id;
 
-                g_hash_table_insert (self->starred_files,
-                                     g_strdup (location_uri),
-                                     id);
+                g_hash_table_insert (self->starred_file_ids, &id, g_strdup (new_location_uri));
+                g_hash_table_insert (self->starred_file_uris, g_strdup (new_location_uri), new_id);
 
-                file = nautilus_file_get_by_uri (location_uri);
-                changed_files = g_list_prepend (NULL, file);
+                changed_file = nautilus_file_get_by_uri (new_location_uri);
+            }
+        }
 
-                g_signal_emit_by_name (self, "starred-changed", changed_files);
+        if (changed_file)
+        {
+            changed_files = g_list_prepend (NULL, changed_file);
 
-                nautilus_file_list_free (changed_files);
-            }
+            g_signal_emit_by_name (self, "starred-changed", changed_files);
 
-            g_object_unref (cursor);
+            nautilus_file_list_free (changed_files);
         }
 
-        g_object_unref (connection);
+        g_object_unref (cursor);
 
         g_string_free (query, TRUE);
     }
@@ -826,8 +815,10 @@ nautilus_tag_manager_finalize (GObject *object)
     }
 
     g_clear_object (&self->notifier);
+    g_clear_object (&self->connection);
 
-    g_hash_table_destroy (self->starred_files);
+    g_hash_table_destroy (self->starred_file_ids);
+    g_hash_table_destroy (self->starred_file_uris);
 
     G_OBJECT_CLASS (nautilus_tag_manager_parent_class)->finalize (object);
 }
@@ -869,30 +860,43 @@ nautilus_tag_manager_get (void)
     return tag_manager;
 }
 
+/* Initialize the tag mananger. */
 void
 nautilus_tag_manager_set_cancellable (NautilusTagManager *self,
                                       GCancellable       *cancellable)
 {
-    nautilus_tag_manager_query_starred_files (self, cancellable);
+    GError *error = NULL;
 
-    self->notifier = tracker_notifier_new (NULL,
-                                           TRACKER_NOTIFIER_FLAG_QUERY_LOCATION,
-                                           cancellable,
-                                           &self->notifier_error);
-    if (self->notifier != NULL)
-    {
-        g_signal_connect (self->notifier,
-                          "events",
-                          G_CALLBACK (on_tracker_notifier_events),
-                          self);
+    self->connection = tracker_sparql_connection_bus_new (
+            TRACKER_MINER_FS_BUSNAME, NULL, NULL, &error);
+
+    if (error) {
+        g_warning ("Unable to initialize tag manager: %s", error->message);
+        g_error_free (error);
+        return;
     }
+
+    self->notifier = tracker_sparql_connection_create_notifier (self->miner_fs);
+
+    nautilus_tag_manager_query_starred_files (self, cancellable);
+
+    g_signal_connect (self->notifier,
+                      "events",
+                      G_CALLBACK (on_tracker_notifier_events),
+                      self);
 }
 
 static void
 nautilus_tag_manager_init (NautilusTagManager *self)
 {
-    self->starred_files = g_hash_table_new_full (g_str_hash,
-                                                 g_str_equal,
-                                                 (GDestroyNotify) g_free,
-                                                 (GDestroyNotify) g_free);
+    self->starred_file_uris = g_hash_table_new_full (g_str_hash,
+                                                     g_str_equal,
+                                                     (GDestroyNotify) g_free,
+                                                     /* values are keys in the other hash table
+                                                      * and are freed there */
+                                                     NULL);
+    self->starred_file_ids = g_hash_table_new_full (g_int_hash,
+                                                    g_int_equal,
+                                                    (GDestroyNotify) g_free,
+                                                    (GDestroyNotify) g_free);
 }
diff --git a/test/automated/displayless/meson.build b/test/automated/displayless/meson.build
index eecc1f406..fccc61b30 100644
--- a/test/automated/displayless/meson.build
+++ b/test/automated/displayless/meson.build
@@ -1,3 +1,7 @@
+trackertestutils = dependency('tracker-testutils-3.0')
+
+tracker_sandbox = find_program(trackertestutils.get_pkgconfig_variable('command'))
+
 tests = [
   ['test-file-utilities-get-common-filename-prefix', [
     'test-file-utilities-get-common-filename-prefix.c'
@@ -23,9 +27,6 @@ tests = [
   ['test-nautilus-search-engine-model', [
     'test-nautilus-search-engine-model.c'
   ]],
-  ['test-nautilus-search-engine-tracker', [
-    'test-nautilus-search-engine-tracker.c'
-  ]],
   ['test-file-operations-copy-files', [
     'test-file-operations-copy-files.c'
   ]],
@@ -34,6 +35,12 @@ tests = [
   ]]
 ]
 
+tracker_tests = [
+  ['test-nautilus-search-engine-tracker', [
+    'test-nautilus-search-engine-tracker.c'
+  ]],
+]
+
 foreach t: tests
   test(
     t[0],
@@ -46,3 +53,19 @@ foreach t: tests
     timeout: 480
   )
 endforeach
+
+# Tests that read and write from the Tracker index are run using 'tracker-sandbox'
+# script to use a temporary instance of tracker-miner-fs instead of the session one.
+foreach t: tracker_tests
+  test(
+    t[0],
+    tracker_sandbox,
+    args: [executable(t[0], t[1], files('test-utilities.c'), dependencies: libnautilus_dep)],
+    env: [
+      test_env,
+      'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir()),
+      'G_TEST_SRCDIR=@0@'.format(meson.current_source_dir())
+    ],
+    timeout: 480
+  )
+endforeach
diff --git a/test/automated/displayless/test-nautilus-search-engine-tracker.c 
b/test/automated/displayless/test-nautilus-search-engine-tracker.c
index 21e86e202..0e5315412 100644
--- a/test/automated/displayless/test-nautilus-search-engine-tracker.c
+++ b/test/automated/displayless/test-nautilus-search-engine-tracker.c
@@ -1,7 +1,107 @@
 #include "test-utilities.h"
 
+/* Time in seconds we allow for Tracker Miners to index the file */
+#define TRACKER_MINERS_AWAIT_TIMEOUT 1000
+
 guint total_hits = 0;
 
+typedef struct
+{
+    GMainLoop *main_loop;
+    gchar *uri;
+    gboolean created;
+} TrackerAwaitFileData;
+
+static TrackerAwaitFileData *
+tracker_await_file_data_new (const char *uri,
+                             GMainLoop  *main_loop)
+{
+    TrackerAwaitFileData *data;
+
+    data = g_slice_new0 (TrackerAwaitFileData);
+    data->uri = g_strdup (uri);
+    data->main_loop = g_main_loop_ref (main_loop);
+
+    return data;
+}
+
+static void
+tracker_await_file_data_free (TrackerAwaitFileData *data)
+{
+    g_free (data->uri);
+    g_main_loop_unref (data->main_loop);
+    g_slice_free (TrackerAwaitFileData, data);
+}
+
+static gboolean timeout_cb (gpointer user_data)
+{
+    TrackerAwaitFileData *data = user_data;
+    g_error ("Timeout waiting for %s to be indexed by Tracker.", data->uri);
+    return FALSE;
+}
+
+static void
+tracker_events_cb (TrackerNotifier *self,
+                   gchar           *service,
+                   gchar           *graph,
+                   GPtrArray       *events,
+                   gpointer         user_data)
+{
+    TrackerAwaitFileData *data = user_data;
+    int i;
+
+    for (i = 0; i < events->len; i++)
+    {
+        TrackerNotifierEvent *event = g_ptr_array_index (events, i);
+
+        if (tracker_notifier_event_get_event_type (event) == TRACKER_NOTIFIER_EVENT_CREATE)
+        {
+            const gchar *urn = tracker_notifier_event_get_urn (event);
+            g_debug ("Got CREATED event for %s", urn);
+            if (strcmp (urn, data->uri) == 0)
+            {
+                data->created = TRUE;
+                g_main_loop_quit (data->main_loop);
+            }
+        }
+    }
+}
+
+/* Create data that the Tracker indexer will find, and wait for the database to be updated. */
+static void
+create_test_data (TrackerSparqlConnection *connection,
+                  const gchar             *indexed_tmpdir)
+{
+    g_autoptr (GFile) test_file = NULL;
+    g_autofree gchar *test_file_path = NULL;
+    g_autoptr (GMainLoop) main_loop = NULL;
+    g_autoptr (GError) error = NULL;
+    g_autoptr (TrackerNotifier) notifier = NULL;
+    TrackerAwaitFileData *await_data;
+    gulong signal_id, timeout_id;
+
+    test_file = g_file_new_build_filename (indexed_tmpdir, "target_file", NULL);
+
+    main_loop = g_main_loop_new (NULL, 0);
+    await_data = tracker_await_file_data_new (g_file_get_uri (test_file), main_loop);
+
+    notifier = tracker_sparql_connection_create_notifier (connection);
+
+    signal_id = g_signal_connect (notifier, "events", G_CALLBACK (tracker_events_cb), await_data);
+    timeout_id = g_timeout_add_seconds (TRACKER_MINERS_AWAIT_TIMEOUT, timeout_cb, await_data);
+
+    g_file_set_contents (g_file_peek_path (test_file), "Please show me in the search results", -1, &error);
+    g_assert_no_error (error);
+
+    g_main_loop_run (main_loop);
+
+    g_assert (await_data->created);
+    g_source_remove (timeout_id);
+    g_clear_signal_handler (&signal_id, notifier);
+
+    tracker_await_file_data_free (await_data);
+}
+
 static void
 hits_added_cb (NautilusSearchEngine *engine,
                GSList               *hits)
@@ -19,21 +119,12 @@ finished_cb (NautilusSearchEngine         *engine,
              NautilusSearchProviderStatus  status,
              gpointer                      user_data)
 {
-    TrackerSparqlConnection *connection;
     g_autofree gchar *sparql_query = NULL;
 
     nautilus_search_provider_stop (NAUTILUS_SEARCH_PROVIDER (engine));
 
     g_print ("\nNautilus search engine tracker finished!\n");
 
-    connection = tracker_sparql_connection_get (NULL, NULL);
-    sparql_query = g_strdup_printf ("DELETE WHERE { <nautilus-test-tracker> ?p ?o }");
-    tracker_sparql_connection_update (connection,
-                                      sparql_query,
-                                      0,
-                                      NULL,
-                                      NULL);
-
     g_main_loop_quit (user_data);
 }
 
@@ -42,14 +133,25 @@ main (int   argc,
       char *argv[])
 {
     g_autoptr (GMainLoop) loop = NULL;
+    g_autoptr (TrackerSparqlConnection) connection = NULL;
     NautilusSearchEngine *engine;
     g_autoptr (NautilusDirectory) directory = NULL;
     g_autoptr (NautilusQuery) query = NULL;
     g_autoptr (GFile) location = NULL;
-    TrackerSparqlConnection *connection;
-    g_autofree gchar *sparql_query = NULL;
+    g_autofree gchar *sparql_update = NULL;
+    g_autoptr (GError) error = NULL;
+    const gchar *indexed_tmpdir;
+
+    indexed_tmpdir = g_getenv ("TRACKER_INDEXED_TMPDIR");
+    if (!indexed_tmpdir)
+    {
+        g_error ("This test must be inside the `tracker-sandbox` script "
+                 "to ensure a private Tracker indexer daemon is used.");
+    }
 
-    connection = tracker_sparql_connection_get (NULL, NULL);
+    connection = tracker_sparql_connection_bus_new ("org.freedesktop.Tracker3.Miner.Files", NULL, NULL, 
&error);
+
+    g_assert_no_error (error);
 
     loop = g_main_loop_new (NULL, FALSE);
 
@@ -60,6 +162,8 @@ main (int   argc,
      */
     nautilus_global_preferences_init ();
 
+    create_test_data (connection, indexed_tmpdir);
+
     engine = nautilus_search_engine_new ();
     g_signal_connect (engine, "hits-added",
                       G_CALLBACK (hits_added_cb), NULL);
@@ -70,37 +174,10 @@ main (int   argc,
     nautilus_query_set_text (query, "target");
     nautilus_search_provider_set_query (NAUTILUS_SEARCH_PROVIDER (engine), query);
 
-    location = g_file_new_for_path (g_get_tmp_dir ());
+    location = g_file_new_for_path (indexed_tmpdir);
     directory = nautilus_directory_get (location);
     nautilus_query_set_location (query, location);
 
-    /* This sparql query with the update call create a virtual file
-     * in tracker, so it sees a file named "target_file" in /tmp.
-     * The file's MIME type is text/plain and the name tracker is
-     * using for search is "target". For the engine tracker to hit,
-     * we also need to set the last time the file was accessed and modified,
-     * which we set to 2001-01-01, at 00:00:01 (the date needs to be a full
-     * ISO 8601 date string) and tracker:available be set to true (in order
-     * for the file to be accessible).
-     */
-
-    sparql_query = g_strdup_printf ("INSERT DATA {\n<nautilus-test-tracker> ");
-    sparql_query = g_strconcat (sparql_query, "a nfo:FileDataObject ;", NULL);
-    sparql_query = g_strconcat (sparql_query, "\na nie:InformationElement ;", NULL);
-    sparql_query = g_strconcat (sparql_query, "\nnie:url 'file:///tmp/target_file';", NULL);
-    sparql_query = g_strconcat (sparql_query, "\nnie:mimeType 'text/plain';", NULL);
-    sparql_query = g_strconcat (sparql_query, "\nnfo:fileName 'target';", NULL);
-    sparql_query = g_strconcat (sparql_query, "\nnfo:fileLastModified '2001-01-01T00:00:01Z';", NULL);
-    sparql_query = g_strconcat (sparql_query, "\nnfo:fileLastAccessed '2001-01-01T00:00:01Z';", NULL);
-    sparql_query = g_strconcat (sparql_query, "\ntracker:available true", NULL);
-    sparql_query = g_strconcat (sparql_query, ".\n}\n", NULL);
-
-    tracker_sparql_connection_update (connection,
-                                      sparql_query,
-                                      0,
-                                      NULL,
-                                      NULL);
-
     nautilus_search_engine_start_by_target (NAUTILUS_SEARCH_PROVIDER (engine),
                                             NAUTILUS_SEARCH_ENGINE_TRACKER_ENGINE);
 


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