[tracker] tests/libtracker-data: Added unit tests



commit ecaf6226fb8125abf75131db048af9ed5251aad1
Author: Philip Van Hoof <philip codeminded be>
Date:   Tue Mar 23 18:06:34 2010 +0100

    tests/libtracker-data: Added unit tests
    
    For coping with ontology changes and journal replaying (and both combined)

 src/libtracker-data/tracker-data-backup.c          |    4 +-
 src/libtracker-data/tracker-data-backup.h          |    2 +-
 src/libtracker-data/tracker-data-manager.c         |  196 ++++++++--------
 src/libtracker-data/tracker-data-manager.h         |    2 +-
 src/libtracker-data/tracker-data-update.c          |   28 ++-
 src/libtracker-data/tracker-data-update.h          |    3 +
 tests/libtracker-data/backup/backup.ontology       |    4 +-
 .../change/ontologies/99-example.ontology          |   37 +++
 .../change/source/99-example.ontology.v1           |   12 +
 .../change/source/99-example.ontology.v2           |   21 ++
 .../change/source/99-example.ontology.v3           |   29 +++
 .../change/source/99-example.ontology.v4           |   37 +++
 tests/libtracker-data/change/test-1.out            |    1 +
 tests/libtracker-data/change/test-1.rq             |    1 +
 tests/libtracker-data/change/test-2.out            |    1 +
 tests/libtracker-data/change/test-2.rq             |    1 +
 tests/libtracker-data/change/test-3.out            |    1 +
 tests/libtracker-data/change/test-3.rq             |    1 +
 .../change/updates/99-example.queries.v2           |    3 +
 .../change/updates/99-example.queries.v3           |    6 +
 .../change/updates/99-example.queries.v4           |    6 +
 tests/libtracker-data/ontologies/20-dc.ontology    |   19 ++
 tests/libtracker-data/ontologies/31-nao.ontology   |   23 ++
 tests/libtracker-data/tracker-backup-test.c        |  153 +++++++------
 tests/libtracker-data/tracker-ontology-test.c      |  254 ++++++++++++++++----
 tests/libtracker-data/tracker-sparql-test.c        |    4 +-
 tests/libtracker-fts/tracker-fts-test.c            |    4 +-
 27 files changed, 619 insertions(+), 234 deletions(-)
---
diff --git a/src/libtracker-data/tracker-data-backup.c b/src/libtracker-data/tracker-data-backup.c
index 54a8054..9ec4de4 100644
--- a/src/libtracker-data/tracker-data-backup.c
+++ b/src/libtracker-data/tracker-data-backup.c
@@ -127,7 +127,7 @@ tracker_data_backup_restore (GFile *journal,
                              TrackerDataBackupFinished callback,
                              gpointer user_data,
                              GDestroyNotify destroy,
-                             const gchar *test_schema)
+                             const gchar **test_schemas)
 {
 	BackupSaveInfo *info;
 
@@ -164,7 +164,7 @@ tracker_data_backup_restore (GFile *journal,
 
 		tracker_db_journal_shutdown ();
 
-		tracker_data_manager_init (flags, test_schema, &is_first, TRUE);
+		tracker_data_manager_init (flags, test_schemas, &is_first, TRUE);
 
 	} else {
 		g_set_error (&info->error, TRACKER_DATA_BACKUP_ERROR, 0, 
diff --git a/src/libtracker-data/tracker-data-backup.h b/src/libtracker-data/tracker-data-backup.h
index b679192..b64dc64 100644
--- a/src/libtracker-data/tracker-data-backup.h
+++ b/src/libtracker-data/tracker-data-backup.h
@@ -44,7 +44,7 @@ void   tracker_data_backup_restore     (GFile                     *journal,
                                         TrackerDataBackupFinished  callback,
                                         gpointer                   user_data,
                                         GDestroyNotify             destroy,
-                                        const gchar               *test_schema);
+                                        const gchar              **test_schema);
 
 G_END_DECLS
 
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index 73d4235..b10d054 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -72,9 +72,10 @@
 static gchar              *ontologies_dir;
 static gboolean            initialized;
 static gboolean            in_journal_replay;
+static gint                max_service_id = 0;
 
 void
-tracker_data_ontology_load_statement (const gchar *ontology_file,
+tracker_data_ontology_load_statement (const gchar *ontology_path,
                                       gint         subject_id,
                                       const gchar *subject,
                                       const gchar *predicate,
@@ -90,7 +91,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 
 			if (tracker_ontologies_get_class_by_uri (subject) != NULL) {
 				if (!is_new)
-					g_critical ("%s: Duplicate definition of class %s", ontology_file, subject);
+					g_critical ("%s: Duplicate definition of class %s", ontology_path, subject);
 				return;
 			}
 
@@ -116,7 +117,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 
 			if (tracker_ontologies_get_property_by_uri (subject) != NULL) {
 				if (!is_new)
-					g_critical ("%s: Duplicate definition of property %s", ontology_file, subject);
+					g_critical ("%s: Duplicate definition of property %s", ontology_path, subject);
 				return;
 			}
 
@@ -142,7 +143,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 
 			property = tracker_ontologies_get_property_by_uri (subject);
 			if (property == NULL) {
-				g_critical ("%s: Unknown property %s", ontology_file, subject);
+				g_critical ("%s: Unknown property %s", ontology_path, subject);
 				return;
 			}
 
@@ -152,7 +153,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 
 			if (tracker_ontologies_get_namespace_by_uri (subject) != NULL) {
 				if (!is_new)
-					g_critical ("%s: Duplicate definition of namespace %s", ontology_file, subject);
+					g_critical ("%s: Duplicate definition of namespace %s", ontology_path, subject);
 				return;
 			}
 
@@ -167,7 +168,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 
 			if (tracker_ontologies_get_ontology_by_uri (subject) != NULL) {
 				if (!is_new)
-					g_critical ("%s: Duplicate definition of ontology %s", ontology_file, subject);
+					g_critical ("%s: Duplicate definition of ontology %s", ontology_path, subject);
 				return;
 			}
 
@@ -183,7 +184,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 
 		class = tracker_ontologies_get_class_by_uri (subject);
 		if (class == NULL) {
-			g_critical ("%s: Unknown class %s", ontology_file, subject);
+			g_critical ("%s: Unknown class %s", ontology_path, subject);
 			return;
 		}
 
@@ -193,7 +194,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 
 		super_class = tracker_ontologies_get_class_by_uri (object);
 		if (super_class == NULL) {
-			g_critical ("%s: Unknown class %s", ontology_file, object);
+			g_critical ("%s: Unknown class %s", ontology_path, object);
 			return;
 		}
 
@@ -203,7 +204,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 
 		property = tracker_ontologies_get_property_by_uri (subject);
 		if (property == NULL) {
-			g_critical ("%s: Unknown property %s", ontology_file, subject);
+			g_critical ("%s: Unknown property %s", ontology_path, subject);
 			return;
 		}
 
@@ -213,7 +214,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 
 		super_property = tracker_ontologies_get_property_by_uri (object);
 		if (super_property == NULL) {
-			g_critical ("%s: Unknown property %s", ontology_file, object);
+			g_critical ("%s: Unknown property %s", ontology_path, object);
 			return;
 		}
 
@@ -224,7 +225,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 
 		property = tracker_ontologies_get_property_by_uri (subject);
 		if (property == NULL) {
-			g_critical ("%s: Unknown property %s", ontology_file, subject);
+			g_critical ("%s: Unknown property %s", ontology_path, subject);
 			return;
 		}
 
@@ -234,7 +235,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 
 		domain = tracker_ontologies_get_class_by_uri (object);
 		if (domain == NULL) {
-			g_critical ("%s: Unknown class %s", ontology_file, object);
+			g_critical ("%s: Unknown class %s", ontology_path, object);
 			return;
 		}
 
@@ -245,7 +246,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 
 		property = tracker_ontologies_get_property_by_uri (subject);
 		if (property == NULL) {
-			g_critical ("%s: Unknown property %s", ontology_file, subject);
+			g_critical ("%s: Unknown property %s", ontology_path, subject);
 			return;
 		}
 
@@ -255,7 +256,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 
 		range = tracker_ontologies_get_class_by_uri (object);
 		if (range == NULL) {
-			g_critical ("%s: Unknown class %s", ontology_file, object);
+			g_critical ("%s: Unknown class %s", ontology_path, object);
 			return;
 		}
 
@@ -265,7 +266,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 
 		property = tracker_ontologies_get_property_by_uri (subject);
 		if (property == NULL) {
-			g_critical ("%s: Unknown property %s", ontology_file, subject);
+			g_critical ("%s: Unknown property %s", ontology_path, subject);
 			return;
 		}
 
@@ -281,7 +282,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 
 		property = tracker_ontologies_get_property_by_uri (subject);
 		if (property == NULL) {
-			g_critical ("%s: Unknown property %s", ontology_file, subject);
+			g_critical ("%s: Unknown property %s", ontology_path, subject);
 			return;
 		}
 
@@ -297,7 +298,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 
 		property = tracker_ontologies_get_property_by_uri (subject);
 		if (property == NULL) {
-			g_critical ("%s: Unknown property %s", ontology_file, subject);
+			g_critical ("%s: Unknown property %s", ontology_path, subject);
 			return;
 		}
 
@@ -313,7 +314,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 
 		property = tracker_ontologies_get_property_by_uri (subject);
 		if (property == NULL) {
-			g_critical ("%s: Unknown property %s", ontology_file, subject);
+			g_critical ("%s: Unknown property %s", ontology_path, subject);
 			return;
 		}
 
@@ -329,7 +330,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 
 		property = tracker_ontologies_get_property_by_uri (subject);
 		if (property == NULL) {
-			g_critical ("%s: Unknown property %s", ontology_file, subject);
+			g_critical ("%s: Unknown property %s", ontology_path, subject);
 			return;
 		}
 
@@ -345,7 +346,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 
 		property = tracker_ontologies_get_property_by_uri (subject);
 		if (property == NULL) {
-			g_critical ("%s: Unknown property %s", ontology_file, subject);
+			g_critical ("%s: Unknown property %s", ontology_path, subject);
 			return;
 		}
 
@@ -357,7 +358,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 
 		namespace = tracker_ontologies_get_namespace_by_uri (subject);
 		if (namespace == NULL) {
-			g_critical ("%s: Unknown namespace %s", ontology_file, subject);
+			g_critical ("%s: Unknown namespace %s", ontology_path, subject);
 			return;
 		}
 
@@ -371,7 +372,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 
 		ontology = tracker_ontologies_get_ontology_by_uri (subject);
 		if (ontology == NULL) {
-			g_critical ("%s: Unknown ontology %s", ontology_file, subject);
+			g_critical ("%s: Unknown ontology %s", ontology_path, subject);
 			return;
 		}
 
@@ -385,14 +386,14 @@ tracker_data_ontology_load_statement (const gchar *ontology_file,
 }
 
 static void
-load_ontology_file_from_path (const gchar        *ontology_file,
+load_ontology_file_from_path (const gchar        *ontology_path,
                               gint               *max_id,
                               gboolean            is_new)
 {
 	TrackerTurtleReader *reader;
 	GError              *error = NULL;
 
-	reader = tracker_turtle_reader_new (ontology_file, &error);
+	reader = tracker_turtle_reader_new (ontology_path, &error);
 	if (error) {
 		g_critical ("Turtle parse error: %s", error->message);
 		g_error_free (error);
@@ -406,7 +407,7 @@ load_ontology_file_from_path (const gchar        *ontology_file,
 		predicate = tracker_turtle_reader_get_predicate (reader);
 		object = tracker_turtle_reader_get_object (reader);
 
-		tracker_data_ontology_load_statement (ontology_file, 0, subject, predicate, object,
+		tracker_data_ontology_load_statement (ontology_path, 0, subject, predicate, object,
 		                                      max_id, is_new, NULL, NULL);
 	}
 
@@ -420,22 +421,18 @@ load_ontology_file_from_path (const gchar        *ontology_file,
 
 
 static TrackerOntology*
-get_ontology_from_file (const gchar *ontology_file)
+get_ontology_from_path (const gchar *ontology_path)
 {
 	TrackerTurtleReader *reader;
 	GError *error = NULL;
 	GHashTable *ontology_uris;
 	TrackerOntology *ret = NULL;
-	gchar *ontology_path;
-
-	ontology_path = g_build_filename (ontologies_dir, ontology_file, NULL);
 
 	reader = tracker_turtle_reader_new (ontology_path, &error);
 
 	if (error) {
 		g_critical ("Turtle parse error: %s", error->message);
 		g_error_free (error);
-		g_free (ontology_path);
 		return NULL;
 	}
 
@@ -468,8 +465,7 @@ get_ontology_from_file (const gchar *ontology_file)
 
 			ontology = g_hash_table_lookup (ontology_uris, subject);
 			if (ontology == NULL) {
-				g_critical ("%s: Unknown ontology %s", ontology_file, subject);
-				g_free (ontology_path);
+				g_critical ("%s: Unknown ontology %s", ontology_path, subject);
 				return NULL;
 			}
 
@@ -491,24 +487,10 @@ get_ontology_from_file (const gchar *ontology_file)
 		g_error_free (error);
 	}
 
-	g_free (ontology_path);
-
 	return ret;
 }
 
 static void
-load_ontology_file (const gchar               *filename,
-                    gint                      *max_id,
-                    gboolean                   is_new)
-{
-	gchar           *ontology_file;
-
-	ontology_file = g_build_filename (ontologies_dir, filename, NULL);
-	load_ontology_file_from_path (ontology_file, max_id, is_new);
-	g_free (ontology_file);
-}
-
-static void
 load_ontology_from_journal (GHashTable **classes_out,
                             GHashTable **properties_out,
                             GHashTable **id_uri_map_out)
@@ -679,14 +661,15 @@ tracker_data_ontology_process_statement (const gchar *graph,
 }
 
 static void
-load_turtle_file (const gchar* path,
-                  gboolean is_new,
-                  gboolean ignore_nao_last_modified)
+import_ontology_path (const gchar *ontology_path,
+                      gboolean is_new,
+                      gboolean ignore_nao_last_modified)
 {
-	GError *error = NULL;
+	GError          *error = NULL;
+
 	TrackerTurtleReader* reader;
 
-	reader = tracker_turtle_reader_new (path, &error);
+	reader = tracker_turtle_reader_new (ontology_path, &error);
 
 	if (error != NULL) {
 		g_critical ("%s", error->message);
@@ -708,19 +691,6 @@ load_turtle_file (const gchar* path,
 	}
 
 	g_object_unref (reader);
-}
-
-static void
-import_ontology_file (const gchar *filename,
-                      gboolean is_new,
-                      gboolean ignore_nao_last_modified)
-{
-	gchar           *ontology_file;
-	GError          *error = NULL;
-
-	ontology_file = g_build_filename (ontologies_dir, filename, NULL);
-	load_turtle_file (ontology_file, is_new, ignore_nao_last_modified);
-	g_free (ontology_file);
 
 	if (error) {
 		g_critical ("%s", error->message);
@@ -1446,10 +1416,8 @@ get_new_service_id (TrackerDBInterface *iface)
 	/* Don't intermix this thing with tracker_data_update_get_new_service_id,
 	 * if you use this, know what you are doing! */
 
-	static gint         max = 0;
-
-	if (G_LIKELY (max != 0)) {
-		return ++max;
+	if (G_LIKELY (max_service_id != 0)) {
+		return ++max_service_id;
 	}
 
 	iface = tracker_db_manager_get_db_interface ();
@@ -1461,16 +1429,16 @@ get_new_service_id (TrackerDBInterface *iface)
 
 	if (cursor) {
 		tracker_db_cursor_iter_next (cursor);
-		max = MAX (tracker_db_cursor_get_int (cursor, 0), max);
+		max_service_id = MAX (tracker_db_cursor_get_int (cursor, 0), max_service_id);
 		g_object_unref (cursor);
 	}
 
-	return ++max;
+	return ++max_service_id;
 }
 
 gboolean
 tracker_data_manager_init (TrackerDBManagerFlags  flags,
-                           const gchar           *test_schema,
+                           const gchar          **test_schemas,
                            gboolean              *first_time,
                            gboolean               journal_check)
 {
@@ -1483,6 +1451,9 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 	const gchar *env_path;
 	gint max_id = 0;
 
+	tracker_data_update_init ();
+	max_service_id = 0;
+
 	/* First set defaults for return values */
 	if (first_time) {
 		*first_time = FALSE;
@@ -1564,9 +1535,7 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 		g_hash_table_unref (id_uri_map);
 
 	} else if (is_first_time_index) {
-		gchar *test_schema_path = NULL;
-
-		sorted = get_ontologies (test_schema != NULL, ontologies_dir);
+		sorted = get_ontologies (test_schemas != NULL, ontologies_dir);
 
 		/* Truncate journal as it does not even contain a single valid transaction
 		 * or is explicitly ignored (journal_check == FALSE, only for test cases) */
@@ -1575,16 +1544,24 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 		/* load ontology from files into memory (max_id starts at zero: first-time) */
 
 		for (l = sorted; l; l = l->next) {
+			gchar *ontology_path;
 			g_debug ("Loading ontology %s", (char *) l->data);
-			load_ontology_file (l->data, &max_id, FALSE);
+			ontology_path = g_build_filename (ontologies_dir, l->data, NULL);
+			load_ontology_file_from_path (ontology_path, &max_id, FALSE);
+			g_free (ontology_path);
 		}
 
-		if (test_schema) {
-			test_schema_path = g_strconcat (test_schema, ".ontology", NULL);
+		if (test_schemas) {
+			guint p;
+			for (p = 0; test_schemas[p] != NULL; p++) {
+				gchar *test_schema_path;
+				test_schema_path = g_strconcat (test_schemas[p], ".ontology", NULL);
 
-			g_debug ("Loading ontology:'%s' (TEST ONTOLOGY)", test_schema_path);
+				g_debug ("Loading ontology:'%s' (TEST ONTOLOGY)", test_schema_path);
 
-			load_ontology_file_from_path (test_schema_path, &max_id, FALSE);
+				load_ontology_file_from_path (test_schema_path, &max_id, FALSE);
+				g_free (test_schema_path);
+			}
 		}
 
 		tracker_data_begin_db_transaction ();
@@ -1597,12 +1574,20 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 
 		/* store ontology in database */
 		for (l = sorted; l; l = l->next) {
-			import_ontology_file (l->data, FALSE, test_schema != NULL);
+			gchar *ontology_path = g_build_filename (ontologies_dir, l->data, NULL);
+			import_ontology_path (ontology_path, FALSE, !journal_check);
+			g_free (ontology_path);
 		}
 
-		if (test_schema) {
-			load_turtle_file (test_schema_path, FALSE, TRUE);
-			g_free (test_schema_path);
+		if (test_schemas) {
+			guint p;
+			for (p = 0; test_schemas[p] != NULL; p++) {
+				gchar *test_schema_path;
+
+				test_schema_path = g_strconcat (test_schemas[p], ".ontology", NULL);
+				import_ontology_path (test_schema_path, FALSE, TRUE);
+				g_free (test_schema_path);
+			}
 		}
 
 		tracker_db_journal_commit_db_transaction ();
@@ -1625,11 +1610,30 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 		tracker_db_interface_sqlite_fts_init (TRACKER_DB_INTERFACE_SQLITE (iface), FALSE);
 	}
 
-	if (check_ontology && !test_schema) {
+	if (check_ontology) {
 		GList *to_reload = NULL;
+		GList *ontos = NULL;
+		guint p;
 
 		/* Get all the ontology files from ontologies_dir */
-		sorted = get_ontologies (test_schema != NULL, ontologies_dir);
+		sorted = get_ontologies (test_schemas != NULL, ontologies_dir);
+
+		for (l = sorted; l; l = l->next) {
+			gchar *ontology_path;
+			ontology_path = g_build_filename (ontologies_dir, l->data, NULL);
+			ontos = g_list_append (ontos, ontology_path);
+		}
+
+		g_list_foreach (sorted, (GFunc) g_free, NULL);
+		g_list_free (sorted);
+
+		if (test_schemas) {
+			for (p = 0; test_schemas[p] != NULL; p++) {
+				gchar *test_schema_path;
+				test_schema_path = g_strconcat (test_schemas[p], ".ontology", NULL);
+				ontos = g_list_append (ontos, test_schema_path);
+			}
+		}
 
 		/* check ontology against database */
 
@@ -1670,21 +1674,21 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 
 		g_object_unref (cursor);
 
-		for (l = sorted; l; l = l->next) {
+		for (l = ontos; l; l = l->next) {
 			TrackerOntology *ontology;
-			const gchar *ontology_file = l->data;
+			const gchar *ontology_path = l->data;
 			const gchar *ontology_uri;
 			gboolean found;
 			gpointer value;
 
 			/* Parse a TrackerOntology from ontology_file */
-			ontology = get_ontology_from_file (ontology_file);
+			ontology = get_ontology_from_path (ontology_path);
 
 			if (!ontology) {
 				/* TODO: cope with full custom .ontology files: deal with this
 				 * error gracefully. App devs might install wrong ontology files
 				 * and we shouldn't critical() due to this. */
-				g_critical ("Can't get ontology from file: %s", ontology_file);
+				g_critical ("Can't get ontology from file: %s", ontology_path);
 				continue;
 			}
 
@@ -1707,7 +1711,7 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 
 				if (val != last_mod) {
 
-					g_debug ("Ontology file '%s' needs update", ontology_file);
+					g_debug ("Ontology file '%s' needs update", ontology_path);
 
 					if (max_id == 0) {
 						/* In case of first-time, this wont start at zero */
@@ -1717,7 +1721,7 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 					/* load ontology from files into memory, set all new's 
 					 * is_new to TRUE */
 
-					load_ontology_file (ontology_file, &max_id, TRUE);
+					load_ontology_file_from_path (ontology_path, &max_id, TRUE);
 
 					to_reload = g_list_prepend (to_reload, l->data);
 
@@ -1749,9 +1753,9 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 			tracker_data_ontology_import_into_db (TRUE);
 
 			for (l = to_reload; l; l = l->next) {
-				const gchar *ontology_file = l->data;
+				const gchar *ontology_path = l->data;
 				/* store ontology in database */
-				import_ontology_file (ontology_file, TRUE, test_schema != NULL);
+				import_ontology_path (ontology_path, TRUE, !journal_check);
 			}
 			g_list_free (to_reload);
 		}
@@ -1764,8 +1768,8 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 
 		g_hash_table_unref (ontos_table);
 
-		g_list_foreach (sorted, (GFunc) g_free, NULL);
-		g_list_free (sorted);
+		g_list_foreach (ontos, (GFunc) g_free, NULL);
+		g_list_free (ontos);
 	}
 
 	initialized = TRUE;
@@ -1784,7 +1788,9 @@ tracker_data_manager_shutdown (void)
 	/* Make sure we shutdown all other modules we depend on */
 	tracker_db_journal_shutdown ();
 	tracker_db_manager_shutdown ();
+	max_service_id = 0;
 	tracker_ontologies_shutdown ();
+	tracker_data_update_shutdown ();
 
 	initialized = FALSE;
 }
diff --git a/src/libtracker-data/tracker-data-manager.h b/src/libtracker-data/tracker-data-manager.h
index 83d5212..2613164 100644
--- a/src/libtracker-data/tracker-data-manager.h
+++ b/src/libtracker-data/tracker-data-manager.h
@@ -38,7 +38,7 @@ G_BEGIN_DECLS
 #endif
 
 gboolean tracker_data_manager_init                (TrackerDBManagerFlags  flags,
-                                                   const gchar           *test_schema,
+                                                   const gchar          **test_schema,
                                                    gboolean              *first_time,
                                                    gboolean               journal_check);
 void     tracker_data_manager_shutdown            (void);
diff --git a/src/libtracker-data/tracker-data-update.c b/src/libtracker-data/tracker-data-update.c
index dadb88e..b155e5f 100644
--- a/src/libtracker-data/tracker-data-update.c
+++ b/src/libtracker-data/tracker-data-update.c
@@ -149,6 +149,8 @@ static GPtrArray *insert_callbacks = NULL;
 static GPtrArray *delete_callbacks = NULL;
 static GPtrArray *commit_callbacks = NULL;
 static GPtrArray *rollback_callbacks = NULL;
+static gint max_service_id = 0;
+static gint max_modseq = 0;
 
 static gint ensure_resource_id (const gchar *uri, gboolean    *create);
 
@@ -227,10 +229,8 @@ tracker_data_update_get_new_service_id (void)
 	TrackerDBInterface *iface;
 	TrackerDBStatement *stmt;
 
-	static gint         max = 0;
-
-	if (G_LIKELY (max != 0)) {
-		return ++max;
+	if (G_LIKELY (max_service_id != 0)) {
+		return ++max_service_id;
 	}
 
 	iface = tracker_db_manager_get_db_interface ();
@@ -242,11 +242,18 @@ tracker_data_update_get_new_service_id (void)
 
 	if (cursor) {
 		tracker_db_cursor_iter_next (cursor);
-		max = MAX (tracker_db_cursor_get_int (cursor, 0), max);
+		max_service_id = MAX (tracker_db_cursor_get_int (cursor, 0), max_service_id);
 		g_object_unref (cursor);
 	}
 
-	return ++max;
+	return ++max_service_id;
+}
+
+void
+tracker_data_update_shutdown (void)
+{
+	max_service_id = 0;
+	max_modseq = 0;
 }
 
 static gint
@@ -255,10 +262,9 @@ tracker_data_update_get_next_modseq (void)
 	TrackerDBCursor    *cursor;
 	TrackerDBInterface *temp_iface;
 	TrackerDBStatement *stmt;
-	static gint         max = 0;
 
-	if (G_LIKELY (max != 0)) {
-		return ++max;
+	if (G_LIKELY (max_modseq != 0)) {
+		return ++max_modseq;
 	}
 
 	temp_iface = tracker_db_manager_get_db_interface ();
@@ -270,11 +276,11 @@ tracker_data_update_get_next_modseq (void)
 
 	if (cursor) {
 		tracker_db_cursor_iter_next (cursor);
-		max = MAX (tracker_db_cursor_get_int (cursor, 0), max);
+		max_modseq = MAX (tracker_db_cursor_get_int (cursor, 0), max_modseq);
 		g_object_unref (cursor);
 	}
 
-	return ++max;
+	return ++max_modseq;
 }
 
 
diff --git a/src/libtracker-data/tracker-data-update.h b/src/libtracker-data/tracker-data-update.h
index 529d7c1..21f98f2 100644
--- a/src/libtracker-data/tracker-data-update.h
+++ b/src/libtracker-data/tracker-data-update.h
@@ -106,6 +106,9 @@ void     tracker_data_add_commit_statement_callback   (TrackerCommitCallback
 void     tracker_data_add_rollback_statement_callback (TrackerCommitCallback      callback,
                                                        gpointer                   user_data);
 
+void     tracker_data_update_shutdown                 (void);
+#define  tracker_data_update_init                     tracker_data_update_shutdown
+
 G_END_DECLS
 
 #endif /* __LIBTRACKER_DATA_UPDATE_H__ */
diff --git a/tests/libtracker-data/backup/backup.ontology b/tests/libtracker-data/backup/backup.ontology
index f870982..4fb3f9c 100644
--- a/tests/libtracker-data/backup/backup.ontology
+++ b/tests/libtracker-data/backup/backup.ontology
@@ -3,8 +3,10 @@
 @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 @prefix tracker: <http://www.tracker-project.org/ontologies/tracker#> .
 @prefix foo: <http://example.org/ns#> .
+ prefix nao: <http://www.semanticdesktop.org/ontologies/2007/08/15/nao#> .
 
-foo: a tracker:Namespace ;
+foo: a tracker:Namespace, tracker:Ontology ;
+	nao:lastModified "2010-03-23T11:00:04Z" ;
 	tracker:prefix "foo" .
 
 foo:class1 a rdfs:Class .
diff --git a/tests/libtracker-data/change/ontologies/99-example.ontology b/tests/libtracker-data/change/ontologies/99-example.ontology
new file mode 100644
index 0000000..706d77c
--- /dev/null
+++ b/tests/libtracker-data/change/ontologies/99-example.ontology
@@ -0,0 +1,37 @@
+ prefix example: <http://example/> .
+ prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+ prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+ prefix tracker: <http://www.tracker-project.org/ontologies/tracker#> .
+ prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+ prefix nao: <http://www.semanticdesktop.org/ontologies/2007/08/15/nao#> .
+
+example: a tracker:Namespace, tracker:Ontology ;
+	nao:lastModified "2010-03-23T11:00:04Z" ;
+	tracker:prefix "example" .
+
+example:A a rdfs:Class ;
+	rdfs:subClassOf rdfs:Resource .
+
+example:B a rdfs:Class ;
+	rdfs:subClassOf rdfs:Resource .
+
+example:b a rdf:Property ;
+	rdfs:domain example:A ;
+	rdfs:range example:B .
+
+example:i1 a rdf:Property ;
+	rdfs:domain example:A ;
+	rdfs:range xsd:integer .
+
+example:i2 a rdf:Property ;
+	rdfs:domain example:A ;
+	rdfs:range xsd:integer .
+
+example:ib a rdf:Property ;
+	rdfs:domain example:B ;
+	rdfs:range xsd:integer .
+
+example:sb a rdf:Property ;
+	rdfs:domain example:B ;
+	rdfs:range xsd:string .
+
diff --git a/tests/libtracker-data/change/source/99-example.ontology.v1 b/tests/libtracker-data/change/source/99-example.ontology.v1
new file mode 100644
index 0000000..6822e77
--- /dev/null
+++ b/tests/libtracker-data/change/source/99-example.ontology.v1
@@ -0,0 +1,12 @@
+ prefix example: <http://example/> .
+ prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+ prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+ prefix tracker: <http://www.tracker-project.org/ontologies/tracker#> .
+ prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+ prefix nao: <http://www.semanticdesktop.org/ontologies/2007/08/15/nao#> .
+
+example: a tracker:Namespace, tracker:Ontology ;
+	nao:lastModified "2010-03-23T11:00:01Z" ;
+	tracker:prefix "example" .
+
+
diff --git a/tests/libtracker-data/change/source/99-example.ontology.v2 b/tests/libtracker-data/change/source/99-example.ontology.v2
new file mode 100644
index 0000000..fefb68f
--- /dev/null
+++ b/tests/libtracker-data/change/source/99-example.ontology.v2
@@ -0,0 +1,21 @@
+ prefix example: <http://example/> .
+ prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+ prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+ prefix tracker: <http://www.tracker-project.org/ontologies/tracker#> .
+ prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+ prefix nao: <http://www.semanticdesktop.org/ontologies/2007/08/15/nao#> .
+
+example: a tracker:Namespace, tracker:Ontology ;
+	nao:lastModified "2010-03-23T11:00:02Z" ;
+	tracker:prefix "example" .
+
+example:A a rdfs:Class ;
+	rdfs:subClassOf rdfs:Resource .
+
+example:B a rdfs:Class ;
+	rdfs:subClassOf rdfs:Resource .
+
+example:b a rdf:Property ;
+	rdfs:domain example:A ;
+	rdfs:range example:B .
+
diff --git a/tests/libtracker-data/change/source/99-example.ontology.v3 b/tests/libtracker-data/change/source/99-example.ontology.v3
new file mode 100644
index 0000000..a3abb92
--- /dev/null
+++ b/tests/libtracker-data/change/source/99-example.ontology.v3
@@ -0,0 +1,29 @@
+ prefix example: <http://example/> .
+ prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+ prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+ prefix tracker: <http://www.tracker-project.org/ontologies/tracker#> .
+ prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+ prefix nao: <http://www.semanticdesktop.org/ontologies/2007/08/15/nao#> .
+
+example: a tracker:Namespace, tracker:Ontology ;
+	nao:lastModified "2010-03-23T11:00:03Z" ;
+	tracker:prefix "example" .
+
+example:A a rdfs:Class ;
+	rdfs:subClassOf rdfs:Resource .
+
+example:B a rdfs:Class ;
+	rdfs:subClassOf rdfs:Resource .
+
+example:b a rdf:Property ;
+	rdfs:domain example:A ;
+	rdfs:range example:B .
+
+example:i1 a rdf:Property ;
+	rdfs:domain example:A ;
+	rdfs:range xsd:integer .
+
+example:i2 a rdf:Property ;
+	rdfs:domain example:A ;
+	rdfs:range xsd:integer .
+
diff --git a/tests/libtracker-data/change/source/99-example.ontology.v4 b/tests/libtracker-data/change/source/99-example.ontology.v4
new file mode 100644
index 0000000..706d77c
--- /dev/null
+++ b/tests/libtracker-data/change/source/99-example.ontology.v4
@@ -0,0 +1,37 @@
+ prefix example: <http://example/> .
+ prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+ prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+ prefix tracker: <http://www.tracker-project.org/ontologies/tracker#> .
+ prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+ prefix nao: <http://www.semanticdesktop.org/ontologies/2007/08/15/nao#> .
+
+example: a tracker:Namespace, tracker:Ontology ;
+	nao:lastModified "2010-03-23T11:00:04Z" ;
+	tracker:prefix "example" .
+
+example:A a rdfs:Class ;
+	rdfs:subClassOf rdfs:Resource .
+
+example:B a rdfs:Class ;
+	rdfs:subClassOf rdfs:Resource .
+
+example:b a rdf:Property ;
+	rdfs:domain example:A ;
+	rdfs:range example:B .
+
+example:i1 a rdf:Property ;
+	rdfs:domain example:A ;
+	rdfs:range xsd:integer .
+
+example:i2 a rdf:Property ;
+	rdfs:domain example:A ;
+	rdfs:range xsd:integer .
+
+example:ib a rdf:Property ;
+	rdfs:domain example:B ;
+	rdfs:range xsd:integer .
+
+example:sb a rdf:Property ;
+	rdfs:domain example:B ;
+	rdfs:range xsd:string .
+
diff --git a/tests/libtracker-data/change/test-1.out b/tests/libtracker-data/change/test-1.out
new file mode 100644
index 0000000..eb2d304
--- /dev/null
+++ b/tests/libtracker-data/change/test-1.out
@@ -0,0 +1 @@
+"b02"
diff --git a/tests/libtracker-data/change/test-1.rq b/tests/libtracker-data/change/test-1.rq
new file mode 100644
index 0000000..2c33817
--- /dev/null
+++ b/tests/libtracker-data/change/test-1.rq
@@ -0,0 +1 @@
+select ?b02 { <a01> example:b ?b02 }
diff --git a/tests/libtracker-data/change/test-2.out b/tests/libtracker-data/change/test-2.out
new file mode 100644
index 0000000..a6550ef
--- /dev/null
+++ b/tests/libtracker-data/change/test-2.out
@@ -0,0 +1 @@
+"2"	"2"
diff --git a/tests/libtracker-data/change/test-2.rq b/tests/libtracker-data/change/test-2.rq
new file mode 100644
index 0000000..552f800
--- /dev/null
+++ b/tests/libtracker-data/change/test-2.rq
@@ -0,0 +1 @@
+select ?a ?b { <a01> example:i2 ?a ; example:i1 ?b }
diff --git a/tests/libtracker-data/change/test-3.out b/tests/libtracker-data/change/test-3.out
new file mode 100644
index 0000000..dc3682e
--- /dev/null
+++ b/tests/libtracker-data/change/test-3.out
@@ -0,0 +1 @@
+"2"	"s2"
diff --git a/tests/libtracker-data/change/test-3.rq b/tests/libtracker-data/change/test-3.rq
new file mode 100644
index 0000000..25d5f3c
--- /dev/null
+++ b/tests/libtracker-data/change/test-3.rq
@@ -0,0 +1 @@
+select ?ib ?sb { <b02> example:ib ?ib; example:sb ?sb }
diff --git a/tests/libtracker-data/change/updates/99-example.queries.v2 b/tests/libtracker-data/change/updates/99-example.queries.v2
new file mode 100644
index 0000000..eca5c37
--- /dev/null
+++ b/tests/libtracker-data/change/updates/99-example.queries.v2
@@ -0,0 +1,3 @@
+insert { <b01> a example:B . <a01> a example:A ; example:b <b01> }
+delete { <a01> example:b <b01> }
+insert { <b02> a example:B . <a01> example:b <b02> }
diff --git a/tests/libtracker-data/change/updates/99-example.queries.v3 b/tests/libtracker-data/change/updates/99-example.queries.v3
new file mode 100644
index 0000000..de01e37
--- /dev/null
+++ b/tests/libtracker-data/change/updates/99-example.queries.v3
@@ -0,0 +1,6 @@
+insert { <a01> example:i1 1 }
+delete { <a01> example:i1 1 }
+insert { <a01> example:i1 2 }
+insert { <a01> example:i2 1 }
+delete { <a01> example:i2 1 }
+insert { <a01> example:i2 2 }
diff --git a/tests/libtracker-data/change/updates/99-example.queries.v4 b/tests/libtracker-data/change/updates/99-example.queries.v4
new file mode 100644
index 0000000..6f37824
--- /dev/null
+++ b/tests/libtracker-data/change/updates/99-example.queries.v4
@@ -0,0 +1,6 @@
+insert { <b02> example:ib 1 }
+delete { <b02> example:ib 1 }
+insert { <b02> example:ib 2 }
+insert { <b02> example:sb "s1" }
+delete { <b02> example:sb "s1" }
+insert { <b02> example:sb "s2" }
diff --git a/tests/libtracker-data/ontologies/20-dc.ontology b/tests/libtracker-data/ontologies/20-dc.ontology
new file mode 100644
index 0000000..3567110
--- /dev/null
+++ b/tests/libtracker-data/ontologies/20-dc.ontology
@@ -0,0 +1,19 @@
+ prefix dc: <http://purl.org/dc/elements/1.1/> .
+ prefix nrl: <http://www.semanticdesktop.org/ontologies/2007/08/15/nrl#> .
+ prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+ prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+ prefix tracker: <http://www.tracker-project.org/ontologies/tracker#> .
+ prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+ prefix nao: <http://www.semanticdesktop.org/ontologies/2007/08/15/nao#> .
+
+dc: a tracker:Namespace, tracker:Ontology ;
+	tracker:prefix "dc" ;
+	nao:lastModified "2010-03-23T16:00:00Z" .
+
+dc:date a rdf:Property ;
+	rdfs:label "Date" ;
+	rdfs:comment "A point or period of time associated with an event in the lifecycle of the resource." ;
+	rdfs:domain rdfs:Resource ;
+	rdfs:range xsd:dateTime .
+
+
diff --git a/tests/libtracker-data/ontologies/31-nao.ontology b/tests/libtracker-data/ontologies/31-nao.ontology
new file mode 100644
index 0000000..8303bc1
--- /dev/null
+++ b/tests/libtracker-data/ontologies/31-nao.ontology
@@ -0,0 +1,23 @@
+ prefix dc: <http://purl.org/dc/elements/1.1/> .
+ prefix nao: <http://www.semanticdesktop.org/ontologies/2007/08/15/nao#> .
+ prefix nie: <http://www.semanticdesktop.org/ontologies/2007/01/19/nie#> .
+ prefix nrl: <http://www.semanticdesktop.org/ontologies/2007/08/15/nrl#> .
+ prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+ prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+ prefix tracker: <http://www.tracker-project.org/ontologies/tracker#> .
+ prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+ prefix nao: <http://www.semanticdesktop.org/ontologies/2007/08/15/nao#> .
+
+nao: a tracker:Namespace, tracker:Ontology ;
+	tracker:prefix "nao" ;
+	nao:lastModified "2010-03-23T16:00:00Z" .
+
+nao:lastModified a rdf:Property ;
+	rdfs:label "lastModified" ;
+	rdfs:comment "last modification date" ;
+	rdfs:subPropertyOf dc:date ;
+	nrl:maxCardinality 1 ;
+	rdfs:domain rdfs:Resource ;
+	rdfs:range xsd:dateTime .
+
+
diff --git a/tests/libtracker-data/tracker-backup-test.c b/tests/libtracker-data/tracker-backup-test.c
index c58c02d..1e0abd4 100644
--- a/tests/libtracker-data/tracker-backup-test.c
+++ b/tests/libtracker-data/tracker-backup-test.c
@@ -39,8 +39,8 @@ static GMainLoop *loop = NULL;
 static void
 backup_finished_cb (GError *error, gpointer user_data)
 {
-        g_assert (TRUE);
-        backup_calls += 1;
+	g_assert (TRUE);
+	backup_calls += 1;
 
 	if (loop != NULL) {
 		/* backup callback, quit main loop */
@@ -51,30 +51,30 @@ backup_finished_cb (GError *error, gpointer user_data)
 static gboolean
 check_content_in_db (gint expected_instances, gint expected_relations)
 {
-        GError *error = NULL;
-        const gchar  *query_instances_1 = "SELECT ?u WHERE { ?u a foo:class1. }";
-        const gchar  *query_relation = "SELECT ?a ?b WHERE { ?a foo:propertyX ?b }";
-        TrackerDBResultSet *result_set;
-
-        result_set = tracker_data_query_sparql (query_instances_1, &error);
-        g_assert_no_error (error);
-        if (expected_instances == 0) {
-                g_assert (result_set == NULL);
-        } else {
-                g_assert_cmpint (tracker_db_result_set_get_n_rows (result_set), ==, expected_instances);
-                g_object_unref (result_set);
-        }
-        
-        result_set = tracker_data_query_sparql (query_relation, &error);
-        g_assert_no_error (error);
-        if (expected_relations == 0) {
-                g_assert (result_set == NULL);
-        } else {
-                g_assert_cmpint (tracker_db_result_set_get_n_rows (result_set), ==, expected_relations);
-                g_object_unref (result_set);
-        }
-
-        return TRUE;
+	GError *error = NULL;
+	const gchar  *query_instances_1 = "SELECT ?u WHERE { ?u a foo:class1. }";
+	const gchar  *query_relation = "SELECT ?a ?b WHERE { ?a foo:propertyX ?b }";
+	TrackerDBResultSet *result_set;
+
+	result_set = tracker_data_query_sparql (query_instances_1, &error);
+	g_assert_no_error (error);
+	if (expected_instances == 0) {
+		g_assert (result_set == NULL);
+	} else {
+		g_assert_cmpint (tracker_db_result_set_get_n_rows (result_set), ==, expected_instances);
+		g_object_unref (result_set);
+	}
+
+	result_set = tracker_data_query_sparql (query_relation, &error);
+	g_assert_no_error (error);
+	if (expected_relations == 0) {
+		g_assert (result_set == NULL);
+	} else {
+		g_assert_cmpint (tracker_db_result_set_get_n_rows (result_set), ==, expected_relations);
+		g_object_unref (result_set);
+	}
+
+	return TRUE;
 }
 /*
  * Load ontology a few instances
@@ -87,20 +87,25 @@ check_content_in_db (gint expected_instances, gint expected_relations)
 static void
 test_backup_and_restore (void)
 {
-        gchar  *data_prefix, *data_filename, *backup_filename, *db_location, *meta_db;
-        GError *error = NULL;
-        GFile  *backup_file;
-
-        db_location = g_build_path (G_DIR_SEPARATOR_S, g_get_current_dir (), "tracker", NULL);
-        data_prefix = g_build_path (G_DIR_SEPARATOR_S, 
-                                    TOP_SRCDIR, "tests", "libtracker-data", "backup", "backup",
-                                    NULL);
-
-        /*
-         * This function uses $(data_prefix).ontology
-         */ 
+	gchar  *data_prefix, *data_filename, *backup_filename, *db_location, *meta_db;
+	GError *error = NULL;
+	GFile  *backup_file;
+	gchar *test_schemas[4] = { NULL, NULL, NULL, NULL };
+
+	db_location = g_build_path (G_DIR_SEPARATOR_S, g_get_current_dir (), "tracker", NULL);
+	data_prefix = g_build_path (G_DIR_SEPARATOR_S, 
+	                            TOP_SRCDIR, "tests", "libtracker-data", "backup", "backup",
+	                            NULL);
+
+	/*
+	 * This function uses $(data_prefix).ontology
+	 */ 
+	test_schemas[0] = g_build_path (G_DIR_SEPARATOR_S, TOP_SRCDIR, "tests", "libtracker-data", "ontologies", "20-dc", NULL);
+	test_schemas[1] = g_build_path (G_DIR_SEPARATOR_S, TOP_SRCDIR, "tests", "libtracker-data", "ontologies", "31-nao", NULL);
+	test_schemas[2] = data_prefix;
+
 	tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
-	                           data_prefix,
+	                           (const gchar **) test_schemas,
 	                           NULL, FALSE);
 
 	/* load data set */
@@ -110,24 +115,24 @@ test_backup_and_restore (void)
 		tracker_turtle_reader_load (data_filename, &error);
 		tracker_data_commit_db_transaction ();
 		g_assert_no_error (error);
-        } else {
-                g_assert_not_reached ();
-        }
-        g_free (data_filename);
+	} else {
+		g_assert_not_reached ();
+	}
+	g_free (data_filename);
 
 
-        /* Check everything is correct */
-        check_content_in_db (3, 1);
+	/* Check everything is correct */
+	check_content_in_db (3, 1);
 
-        backup_filename = g_build_path (G_DIR_SEPARATOR_S, 
-                                        db_location, "tracker.dump",
-                                        NULL);
-        backup_file = g_file_new_for_path (backup_filename);
-        g_free (backup_filename);
-        tracker_data_backup_save (backup_file,
-                                  backup_finished_cb,
-                                  NULL,
-                                  NULL);
+	backup_filename = g_build_path (G_DIR_SEPARATOR_S, 
+	                                db_location, "tracker.dump",
+	                                NULL);
+	backup_file = g_file_new_for_path (backup_filename);
+	g_free (backup_filename);
+	tracker_data_backup_save (backup_file,
+	                          backup_finished_cb,
+	                          NULL,
+	                          NULL);
 
 	/* Backup is asynchronous, wait until it is finished */
 	loop = g_main_loop_new (NULL, FALSE);
@@ -137,27 +142,31 @@ test_backup_and_restore (void)
 
 	tracker_data_manager_shutdown ();
 
-        meta_db = g_build_path (G_DIR_SEPARATOR_S, db_location, "meta.db", NULL);
-        g_unlink (meta_db);
-        g_free (meta_db);
+	meta_db = g_build_path (G_DIR_SEPARATOR_S, db_location, "meta.db", NULL);
+	g_unlink (meta_db);
+	g_free (meta_db);
+
+	meta_db = g_build_path (G_DIR_SEPARATOR_S, db_location, "data", "tracker-store.journal", NULL);
+	g_unlink (meta_db);
+	g_free (meta_db);
 
-        meta_db = g_build_path (G_DIR_SEPARATOR_S, db_location, "data", "tracker-store.journal", NULL);
-        g_unlink (meta_db);
-        g_free (meta_db);
+	meta_db = g_build_path (G_DIR_SEPARATOR_S, db_location, "data", ".meta.isrunning", NULL);
+	g_unlink (meta_db);
+	g_free (meta_db);
 
-        meta_db = g_build_path (G_DIR_SEPARATOR_S, db_location, "data", ".meta.isrunning", NULL);
-        g_unlink (meta_db);
-        g_free (meta_db);
+	tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
+	                           (const gchar **) test_schemas,
+	                           NULL, FALSE);
+	check_content_in_db (0, 0);
 
-        tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
-                                   data_prefix,
-                                   NULL, FALSE);
-        check_content_in_db (0, 0);
+	test_schemas[0] = data_prefix;
+	tracker_data_backup_restore (backup_file, backup_finished_cb, NULL, NULL, (const gchar **) test_schemas);
+	check_content_in_db (3, 1);
 
-        tracker_data_backup_restore (backup_file, backup_finished_cb, NULL, NULL, data_prefix);
-        check_content_in_db (3, 1);
+	g_free (test_schemas[0]);
+	g_free (test_schemas[1]);
 
-        g_assert_cmpint (backup_calls, ==, 2);
+	g_assert_cmpint (backup_calls, ==, 2);
 }
 
 int
@@ -183,8 +192,8 @@ main (int argc, char **argv)
 
 	g_free (current_dir);
 
-        g_test_add_func ("/tracker/libtracker-data/backup/save_and_restore",
-                         test_backup_and_restore);
+	g_test_add_func ("/tracker/libtracker-data/backup/save_and_restore",
+	                 test_backup_and_restore);
 	/* run tests */
 	result = g_test_run ();
 
diff --git a/tests/libtracker-data/tracker-ontology-test.c b/tests/libtracker-data/tracker-ontology-test.c
index 1d0d22e..a289a67 100644
--- a/tests/libtracker-data/tracker-ontology-test.c
+++ b/tests/libtracker-data/tracker-ontology-test.c
@@ -23,6 +23,7 @@
 
 #include <glib.h>
 #include <gio/gio.h>
+#include <glib/gstdio.h>
 
 #include <libtracker-db/tracker-db.h>
 
@@ -38,6 +39,13 @@ struct _TestInfo {
 	const gchar *data;
 };
 
+typedef struct _ChangeInfo ChangeInfo;
+
+struct _ChangeInfo {
+	const gchar *ontology;
+	const gchar *update;
+};
+
 const TestInfo nie_tests[] = {
 	{ "nie/filter-subject-1", "nie/data-1" },
 	{ "nie/filter-characterset-1", "nie/data-1" },
@@ -72,70 +80,60 @@ const TestInfo nmo_tests[] = {
 	{ NULL }
 };
 
+
+const TestInfo change_tests[] = {
+	{ "change/test-1", "change/data-1" },
+	{ "change/test-2", "change/data-2" },
+	{ "change/test-3", "change/data-3" },
+	{ NULL }
+};
+
+const ChangeInfo changes[] = {
+	{ "99-example.ontology.v1", "99-example.queries.v1" },
+	{ "99-example.ontology.v2", "99-example.queries.v2" },
+	{ "99-example.ontology.v3", "99-example.queries.v3" },
+	{ "99-example.ontology.v4", "99-example.queries.v4" },
+	{ NULL }
+};
+
 static void
-test_ontology_init (void)
+delete_db (gboolean del_journal)
 {
-	/* first-time initialization */
-	tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
-	                           NULL,
-	                           NULL,
-	                           FALSE);
+	gchar *meta_db, *db_location;
 
-	tracker_data_manager_shutdown ();
+	db_location = g_build_path (G_DIR_SEPARATOR_S, g_get_current_dir (), "tracker", NULL);
+	meta_db = g_build_path (G_DIR_SEPARATOR_S, db_location, "meta.db", NULL);
+	g_unlink (meta_db);
+	g_free (meta_db);
 
-	/* initialization from existing database */
-	tracker_data_manager_init (0,
-	                           NULL,
-	                           NULL,
-	                           FALSE);
+	if (del_journal) {
+		meta_db = g_build_path (G_DIR_SEPARATOR_S, db_location, "data", "tracker-store.journal", NULL);
+		g_unlink (meta_db);
+		g_free (meta_db);
+	}
 
-	tracker_data_manager_shutdown ();
+	meta_db = g_build_path (G_DIR_SEPARATOR_S, db_location, "data", ".meta.isrunning", NULL);
+	g_unlink (meta_db);
+	g_free (meta_db);
+
+	g_free (db_location);
 }
 
 static void
-test_query (gconstpointer test_data)
+query_helper (const gchar *query_filename, const gchar *results_filename)
 {
 	TrackerDBResultSet *result_set;
-	const TestInfo *test_info;
-	GError *error;
+	GError *error = NULL;
+	gchar *query = NULL;
+	gchar *results = NULL;
 	GString *test_results;
-	gchar *data_filename;
-	gchar *query, *query_filename;
-	gchar *results, *results_filename;
-	gchar *prefix, *data_prefix, *test_prefix;
-
-	error = NULL;
-	test_info = test_data;
-
-	prefix = g_build_path (G_DIR_SEPARATOR_S, TOP_SRCDIR, "tests", "libtracker-data", NULL);
-	data_prefix = g_build_filename (prefix, test_info->data, NULL);
-	test_prefix = g_build_filename (prefix, test_info->test_name, NULL);
-	g_free (prefix);
-
-	/* initialization */
-	tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
-	                           NULL,
-	                           NULL, 
-	                           FALSE);
-
-	/* load data set */
-	data_filename = g_strconcat (data_prefix, ".ttl", NULL);
-	tracker_data_begin_db_transaction ();
-	tracker_turtle_reader_load (data_filename, &error);
-	tracker_data_commit_db_transaction ();
-	g_assert_no_error (error);
 
-	query_filename = g_strconcat (test_prefix, ".rq", NULL);
 	g_file_get_contents (query_filename, &query, NULL, &error);
 	g_assert_no_error (error);
 
-	results_filename = g_strconcat (test_prefix, ".out", NULL);
 	g_file_get_contents (results_filename, &results, NULL, &error);
 	g_assert_no_error (error);
 
-	g_free (data_prefix);
-	g_free (test_prefix);
-
 	/* perform actual query */
 
 	result_set = tracker_data_query_sparql (query, &error);
@@ -210,14 +208,170 @@ test_query (gconstpointer test_data)
 		g_free (diff);
 	}
 
+	g_string_free (test_results, TRUE);
+	g_free (results);
+	g_free (query);
+}
+
+static void
+test_ontology_change (void)
+{
+	gchar *ontology_file;
+	GFile *file2;
+	gchar *prefix;
+	guint i;
+	GError *error = NULL;
+	gchar *test_schemas[4] = { NULL, NULL, NULL, NULL };
+
+	delete_db (TRUE);
+
+	prefix = g_build_path (G_DIR_SEPARATOR_S, TOP_SRCDIR, "tests", "libtracker-data", NULL);
+
+	test_schemas[0] = g_build_path (G_DIR_SEPARATOR_S, prefix, "ontologies", "20-dc", NULL);
+	test_schemas[1] = g_build_path (G_DIR_SEPARATOR_S, prefix, "ontologies", "31-nao", NULL);
+	test_schemas[2] = g_build_path (G_DIR_SEPARATOR_S, prefix, "change", "ontologies", "99-example", NULL);
+
+	ontology_file = g_build_path (G_DIR_SEPARATOR_S, prefix, "change", "ontologies", "99-example.ontology", NULL);
+
+	file2 = g_file_new_for_path (ontology_file);
+
+	g_file_delete (file2, NULL, NULL);
+
+	for (i = 0; changes[i].ontology; i++) {
+		GFile *file1;
+		gchar *queries = NULL;
+		gchar *source = g_build_path (G_DIR_SEPARATOR_S, prefix, "change", "source", changes[i].ontology, NULL);
+		gchar *update = g_build_path (G_DIR_SEPARATOR_S, prefix, "change", "updates", changes[i].update, NULL);
+		gchar *from, *to;
+
+		file1 = g_file_new_for_path (source);
+
+		from = g_file_get_path (file1);
+		to = g_file_get_path (file2);
+		g_debug ("copy %s to %s", from, to);
+		g_free (from);
+		g_free (to);
+
+		g_file_copy (file1, file2, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, NULL);
+
+		tracker_data_manager_init (0, (const gchar **) test_schemas,
+		                           NULL, FALSE);
+
+		if (g_file_get_contents (update, &queries, NULL, NULL)) {
+			gchar *query = strtok (queries, "\n");
+			while (query) {
+
+				tracker_data_begin_db_transaction ();
+				tracker_data_update_sparql (query, &error);
+				tracker_data_commit_db_transaction ();
+
+				g_assert_no_error (error);
+				query = strtok (NULL, "\n");
+			}
+			g_free (queries);
+		}
+
+		g_free (update);
+		g_free (source);
+		g_object_unref (file1);
+
+		tracker_data_manager_shutdown ();
+	}
+
+	delete_db (FALSE);
+
+	tracker_data_manager_init (0, (const gchar **) test_schemas,
+	                           NULL, TRUE);
+
+	for (i = 0; change_tests[i].test_name != NULL; i++) {
+		gchar *query_filename;
+		gchar *results_filename;
+		gchar *test_prefix;
+
+		test_prefix = g_build_filename (prefix, change_tests[i].test_name, NULL);
+		query_filename = g_strconcat (test_prefix, ".rq", NULL);
+		results_filename = g_strconcat (test_prefix, ".out", NULL);
+
+		query_helper (query_filename, results_filename);
+
+		g_free (test_prefix);
+		g_free (query_filename);
+		g_free (results_filename);
+	}
+
+	tracker_data_manager_shutdown ();
+
+	g_object_unref (file2);
+	g_free (test_schemas[0]);
+	g_free (test_schemas[1]);
+	g_free (test_schemas[2]);
+	g_free (prefix);
+}
+
+static void
+test_ontology_init (void)
+{
+	/* first-time initialization */
+	tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
+	                           NULL,
+	                           NULL,
+	                           FALSE);
+
+	tracker_data_manager_shutdown ();
+
+	/* initialization from existing database */
+	tracker_data_manager_init (0,
+	                           NULL,
+	                           NULL,
+	                           FALSE);
+
+	tracker_data_manager_shutdown ();
+}
+
+static void
+test_query (gconstpointer test_data)
+{
+	const TestInfo *test_info;
+	GError *error;
+	gchar *data_filename;
+	gchar *query_filename;
+	gchar *results_filename;
+	gchar *prefix, *data_prefix, *test_prefix;
+
+	error = NULL;
+	test_info = test_data;
+
+	prefix = g_build_path (G_DIR_SEPARATOR_S, TOP_SRCDIR, "tests", "libtracker-data", NULL);
+	data_prefix = g_build_filename (prefix, test_info->data, NULL);
+	test_prefix = g_build_filename (prefix, test_info->test_name, NULL);
+	g_free (prefix);
+
+	/* initialization */
+	tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
+	                           NULL,
+	                           NULL, 
+	                           FALSE);
+
+	/* load data set */
+	data_filename = g_strconcat (data_prefix, ".ttl", NULL);
+	tracker_data_begin_db_transaction ();
+	tracker_turtle_reader_load (data_filename, &error);
+	tracker_data_commit_db_transaction ();
+	g_assert_no_error (error);
+
+	query_filename = g_strconcat (test_prefix, ".rq", NULL);
+	results_filename = g_strconcat (test_prefix, ".out", NULL);
+
+	g_free (data_prefix);
+	g_free (test_prefix);
+
+	query_helper (query_filename, results_filename);
+
 	/* cleanup */
 
 	g_free (data_filename);
 	g_free (query_filename);
-	g_free (query);
 	g_free (results_filename);
-	g_free (results);
-	g_string_free (test_results, TRUE);
 
 	tracker_data_manager_shutdown ();
 }
@@ -246,6 +400,8 @@ main (int argc, char **argv)
 
 	/* add test cases */
 
+	g_test_add_func ("/libtracker-data/ontology-change", test_ontology_change);
+
 	g_test_add_func ("/libtracker-data/ontology-init", test_ontology_init);
 
 	for (i = 0; nie_tests[i].test_name; i++) {
diff --git a/tests/libtracker-data/tracker-sparql-test.c b/tests/libtracker-data/tracker-sparql-test.c
index 60beec0..62841de 100644
--- a/tests/libtracker-data/tracker-sparql-test.c
+++ b/tests/libtracker-data/tracker-sparql-test.c
@@ -117,6 +117,7 @@ test_sparql_query (gconstpointer test_data)
 	gchar *query, *query_filename;
 	gchar *results, *results_filename;
 	gchar *prefix, *data_prefix, *test_prefix;
+	const gchar *test_schemas[2] = { NULL, NULL };
 
 	error = NULL;
 	test_info = test_data;
@@ -127,8 +128,9 @@ test_sparql_query (gconstpointer test_data)
 	test_prefix = g_build_filename (prefix, test_info->test_name, NULL);
 	g_free (prefix);
 
+	test_schemas[0] = data_prefix;
 	tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
-	                           data_prefix,
+	                           test_schemas,
 	                           NULL, FALSE);
 
 	/* data_path = g_build_path (G_DIR_SEPARATOR_S, TOP_SRCDIR, "tests", "libtracker-data", NULL); */
diff --git a/tests/libtracker-fts/tracker-fts-test.c b/tests/libtracker-fts/tracker-fts-test.c
index adb5000..3a136c6 100644
--- a/tests/libtracker-fts/tracker-fts-test.c
+++ b/tests/libtracker-fts/tracker-fts-test.c
@@ -60,6 +60,7 @@ test_sparql_query (gconstpointer test_data)
 	gchar *results, *results_filename;
 	gchar *prefix, *data_prefix, *test_prefix;
 	gint i;
+	const gchar *test_schemas[2] = { NULL, NULL };
 
 	error = NULL;
 	test_info = test_data;
@@ -70,8 +71,9 @@ test_sparql_query (gconstpointer test_data)
 	test_prefix = g_build_filename (prefix, test_info->test_name, NULL);
 	g_free (prefix);
 
+	test_schemas[0] = data_prefix;
 	tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
-	                           data_prefix,
+	                           test_schemas,
 	                           NULL, FALSE);
 
 	/* load data / perform updates */



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