1 /*
2  * Copyright (C) 2010, Codeminded BVBA <abustany@gnome.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA  02110-1301, USA.
18  */
19 
20 #include "config.h"
21 
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #include <libtracker-sparql/tracker-sparql.h>
26 
27 /* This MUST be larger than TRACKER_STEROIDS_BUFFER_SIZE */
28 #define LONG_NAME_SIZE 128 * 1024 * sizeof(char)
29 
30 typedef struct {
31 	GMainLoop *main_loop;
32 	const gchar *query;
33 } AsyncData;
34 
35 typedef struct {
36 } DataFixture;
37 
38 static TrackerSparqlConnection *connection;
39 
40 static void
delete_test_data(DataFixture * fixture,gconstpointer user_data)41 delete_test_data (DataFixture   *fixture,
42                   gconstpointer  user_data)
43 {
44 	GError *error = NULL;
45 	const char *delete_query = "DELETE { "
46 	                           "<urn:testdata1> a rdfs:Resource ."
47 	                           "<urn:testdata2> a rdfs:Resource ."
48 	                           "<urn:testdata3> a rdfs:Resource ."
49 	                           "<urn:testdata4> a rdfs:Resource ."
50 	                           "}";
51 
52 	tracker_sparql_connection_update (connection, delete_query, 0, NULL, &error);
53 	g_assert_no_error (error);
54 }
55 
56 static void
insert_test_data(DataFixture * fixture,gconstpointer user_data)57 insert_test_data (DataFixture   *fixture,
58                   gconstpointer  user_data)
59 {
60 	GError *error = NULL;
61 	char *longName = g_malloc (LONG_NAME_SIZE);
62 	char *filled_query;
63 
64 	/* Ensure data is deleted */
65 	delete_test_data (fixture, user_data);
66 
67 	memset (longName, 'a', LONG_NAME_SIZE);
68 
69 	longName[LONG_NAME_SIZE - 1] = '\0';
70 
71 	filled_query = g_strdup_printf ("INSERT {"
72 	                                "    <urn:testdata1> a nfo:FileDataObject ; nie:url \"/foo/bar\" ."
73 	                                "    <urn:testdata2> a nfo:FileDataObject ; nie:url \"/plop/coin\" ."
74 	                                "    <urn:testdata3> a nmm:Artist ; nmm:artistName \"testArtist\" ."
75 	                                "    <urn:testdata4> a nmm:Photo ; nao:identifier \"%s\" ."
76 	                                "}", longName);
77 
78 	tracker_sparql_connection_update (connection, filled_query, 0, NULL, &error);
79 	g_assert_no_error (error);
80 
81 	g_free (filled_query);
82 	g_free (longName);
83 }
84 
85 /*
86  * I comment that part out because I don't know how anonymous node hashing
87  * works, but if we know two SparqlUpdate calls are going to return the same
88  * urns we could use those functions to compare the results between the normal
89  * and fast method. I wrote them before realizing I wouldn't know how to use
90  * them.
91  */
92 /*
93 static gboolean
94 compare_hash_tables (GHashTable *h1, GHashTable *h2)
95 {
96 	GHashTableIter i1, i2;
97 	gpointer k1, v1, k2, v2;
98 
99 	if (g_hash_table_size (h1) != g_hash_table_size (h2)) {
100 		return FALSE;
101 	}
102 
103 	g_hash_table_iter_init (&i1, h1);
104 	g_hash_table_iter_init (&i2, h2);
105 
106 	while (g_hash_table_iter_next (&i1, &k1, &v1)) {
107 		g_hash_table_iter_next (&i2, &k2, &v2);
108 
109 		if (g_strcmp0 (k1, k2)) {
110 			return FALSE;
111 		}
112 
113 		if (g_strcmp0 (v1, v2)) {
114 			return FALSE;
115 		}
116 	}
117 
118 	return TRUE;
119 }
120 
121 static gboolean
122 compare_results (GPtrArray *r1, GPtrArray *r2)
123 {
124 	int i, j;
125 
126 	if (!r1 || !r2) {
127 		return FALSE;
128 	}
129 
130 	if (r1->len != r2->len) {
131 		return FALSE;
132 	}
133 
134 	for (i = 0; i < r1->len; i++) {
135 		GPtrArray *inner1, *inner2;
136 
137 		inner1 = g_ptr_array_index (r1, i);
138 		inner2 = g_ptr_array_index (r2, i);
139 
140 		if (inner1->len != inner2->len) {
141 			return FALSE;
142 		}
143 
144 		for (j = 0; j < inner1->len; j++) {
145 			GHashTable *h1, *h2;
146 
147 			h1 = g_ptr_array_index (inner1, j);
148 			h2 = g_ptr_array_index (inner2, j);
149 
150 			if (!compare_hash_tables (h1, h2)) {
151 				return FALSE;
152 			}
153 		}
154 	}
155 
156 	return TRUE;
157 }
158 */
159 
160 static void
query_and_compare_results(const char * query)161 query_and_compare_results (const char *query)
162 {
163 	TrackerSparqlCursor *cursor_glib;
164 	TrackerSparqlCursor *cursor_fd;
165 	GError *error = NULL;
166 
167 	cursor_glib = tracker_sparql_connection_query (connection, query, NULL, &error);
168 
169 	g_assert_no_error (error);
170 
171 	cursor_fd = tracker_sparql_connection_query (connection, query, NULL, &error);
172 
173 	g_assert_no_error (error);
174 
175 	while (tracker_sparql_cursor_next (cursor_glib, NULL, NULL) && tracker_sparql_cursor_next (cursor_fd, NULL, NULL)) {
176 		g_assert_cmpstr (tracker_sparql_cursor_get_string (cursor_glib, 0, NULL),
177 				 ==,
178 				 tracker_sparql_cursor_get_string (cursor_fd, 0, NULL));
179 	}
180 
181 	/* Check that both cursors are at the end (same number of rows) */
182 	g_assert (!tracker_sparql_cursor_next (cursor_glib, NULL, NULL));
183 	g_assert (!tracker_sparql_cursor_next (cursor_fd, NULL, NULL));
184 
185 	g_object_unref (cursor_glib);
186 	g_object_unref (cursor_fd);
187 }
188 
189 static void
test_tracker_sparql_query_iterate(DataFixture * fixture,gconstpointer user_data)190 test_tracker_sparql_query_iterate (DataFixture  *fixture,
191                                    gconstpointer user_data)
192 {
193 	query_and_compare_results ("SELECT ?r nie:url(?r) WHERE {?r a nfo:FileDataObject}");
194 }
195 
196 static void
test_tracker_sparql_query_iterate_largerow(DataFixture * fixture,gconstpointer user_data)197 test_tracker_sparql_query_iterate_largerow (DataFixture  *fixture,
198                                             gconstpointer user_data)
199 {
200 	query_and_compare_results ("SELECT nao:identifier(?r) WHERE {?r a nmm:Photo}");
201 }
202 
203 /* Runs an invalid query */
204 static void
test_tracker_sparql_query_iterate_error(DataFixture * fixture,gconstpointer user_data)205 test_tracker_sparql_query_iterate_error (DataFixture  *fixture,
206                                          gconstpointer user_data)
207 {
208 	TrackerSparqlCursor *cursor;
209 	GError *error = NULL;
210 	const gchar *query = "bork bork bork";
211 
212 	cursor = tracker_sparql_connection_query (connection, query, NULL, &error);
213 
214 	/* tracker_sparql_query_iterate should return null on error */
215 	g_assert (!cursor);
216 
217 	/* error should be set, along with its message, note: we don't
218 	 * use g_assert_error() because the code does not match the
219 	 * enum values for TRACKER_SPARQL_ERROR_*, this is due to
220 	 * dbus/error matching between client/server. This should be
221 	 * fixed in gdbus.
222 	 */
223 	g_assert (error != NULL && error->domain == TRACKER_SPARQL_ERROR);
224 
225 	g_error_free (error);
226 }
227 
228 /* Runs a query returning an empty set */
229 static void
test_tracker_sparql_query_iterate_empty_subprocess(DataFixture * fixture,gconstpointer user_data)230 test_tracker_sparql_query_iterate_empty_subprocess (DataFixture  *fixture,
231                                                     gconstpointer user_data)
232 {
233 	TrackerSparqlCursor *cursor;
234 	GError *error = NULL;
235 	const gchar *query = "SELECT ?r WHERE {?r a nfo:FileDataObject; nao:identifier \"thisannotationdoesnotexist\"}";
236 
237 	cursor = tracker_sparql_connection_query (connection, query, NULL, &error);
238 
239 	g_assert (tracker_sparql_cursor_next (cursor, NULL, NULL));
240 
241 	/* Testing we fail with this error:
242 	 *
243 	 *   Tracker-CRITICAL **:
244 	 *   tracker_bus_fd_cursor_real_get_string: assertion '(_tmp0_
245 	 *   < _tmp2_) && (_tmp3_ != NULL)' failed
246 	 */
247 	tracker_sparql_cursor_get_string (cursor, 0, NULL);
248 }
249 
250 static void
test_tracker_sparql_query_iterate_empty(DataFixture * fixture,gconstpointer user_data)251 test_tracker_sparql_query_iterate_empty (DataFixture  *fixture,
252                                          gconstpointer user_data)
253 {
254 	TrackerSparqlCursor *cursor;
255 	GError *error = NULL;
256 	const gchar *query = "SELECT ?r WHERE {?r a nfo:FileDataObject; nao:identifier \"thisannotationdoesnotexist\"}";
257 
258 	cursor = tracker_sparql_connection_query (connection, query, NULL, &error);
259 
260 	g_assert (cursor);
261 	g_assert_no_error (error);
262 
263 	g_assert (!tracker_sparql_cursor_next (cursor, NULL, NULL));
264 	/* This should be 1, the original test had it wrong: there's one column,
265 	 * no matter if there are no results*/
266 	g_assert (tracker_sparql_cursor_get_n_columns (cursor) == 1);
267 
268 	g_test_trap_subprocess ("/steroids/tracker/tracker_sparql_query_iterate_empty/subprocess", 0, 0);
269 	g_test_trap_assert_failed ();
270 
271 	g_object_unref (cursor);
272 }
273 
274 /* Closes the cursor before all results are read */
275 static void
test_tracker_sparql_query_iterate_sigpipe(DataFixture * fixture,gconstpointer user_data)276 test_tracker_sparql_query_iterate_sigpipe (DataFixture  *fixture,
277                                            gconstpointer user_data)
278 {
279 	TrackerSparqlCursor *cursor;
280 	GError *error = NULL;
281 	const gchar *query = "SELECT ?r WHERE {?r a nfo:FileDataObject}";
282 
283 	cursor = tracker_sparql_connection_query (connection, query, NULL, &error);
284 
285 	g_assert (cursor);
286 	g_assert_no_error (error);
287 
288 	g_assert (tracker_sparql_cursor_next (cursor, NULL, NULL));
289 
290 	g_object_unref (cursor);
291 }
292 
293 static void
test_tracker_sparql_update_fast_small(DataFixture * fixture,gconstpointer user_data)294 test_tracker_sparql_update_fast_small (DataFixture  *fixture,
295                                        gconstpointer user_data)
296 {
297 	GError *error = NULL;
298 	const gchar *query = "INSERT { _:x a nmo:Message }";
299 
300 	tracker_sparql_connection_update (connection, query, 0, NULL, &error);
301 
302 	g_assert_no_error (error);
303 }
304 
305 static void
test_tracker_sparql_update_fast_large(DataFixture * fixture,gconstpointer user_data)306 test_tracker_sparql_update_fast_large (DataFixture  *fixture,
307                                        gconstpointer user_data)
308 {
309 	GError *error = NULL;
310 	gchar *lots;
311 	gchar *query;
312 
313 	lots = g_malloc (LONG_NAME_SIZE);
314 	memset (lots, 'a', LONG_NAME_SIZE);
315 	lots[LONG_NAME_SIZE-1] = '\0';
316 
317 	query = g_strdup_printf ("INSERT { _:x a nmo:Message; nao:identifier \"%s\" }", lots);
318 
319 	tracker_sparql_connection_update (connection, query, 0, NULL, &error);
320 
321 	g_free (lots);
322 	g_free (query);
323 
324 	g_assert_no_error (error);
325 }
326 
327 static void
async_update_array_callback(GObject * source_object,GAsyncResult * result,gpointer user_data)328 async_update_array_callback (GObject      *source_object,
329                              GAsyncResult *result,
330                              gpointer      user_data)
331 {
332 	GError *error = NULL;
333 	AsyncData *data = user_data;
334 	GPtrArray *errors;
335 
336 	errors = tracker_sparql_connection_update_array_finish (connection, result, &error);
337 
338 	/* main error is only set on fatal (D-Bus) errors that apply to the whole update */
339 	g_assert_no_error (error);
340 
341 	g_assert (errors->len == 6);
342 
343 	g_assert (g_ptr_array_index (errors, 0) == NULL);
344 	g_assert (g_ptr_array_index (errors, 1) == NULL);
345 	g_assert (g_ptr_array_index (errors, 2) == NULL);
346 	g_assert (g_ptr_array_index (errors, 3) != NULL);
347 	g_assert (g_ptr_array_index (errors, 4) == NULL);
348 	g_assert (g_ptr_array_index (errors, 5) == NULL);
349 
350 	g_ptr_array_unref (errors);
351 
352 	g_main_loop_quit (data->main_loop);
353 }
354 
355 
356 static void
test_tracker_sparql_update_array_async(DataFixture * fixture,gconstpointer user_data)357 test_tracker_sparql_update_array_async (DataFixture   *fixture,
358                                         gconstpointer  user_data)
359 {
360 	const gchar *queries[6] = { "INSERT { _:a a nmo:Message }",
361 	                            "INSERT { _:b a nmo:Message }",
362 	                            "INSERT { _:c a nmo:Message }",
363 	                            "INSERT { _:d syntax error a nmo:Message }",
364 	                            "INSERT { _:e a nmo:Message }",
365 	                            "INSERT { _:f a nmo:Message }" };
366 
367 	GMainLoop *main_loop;
368 	AsyncData *data;
369 
370 	main_loop = g_main_loop_new (NULL, FALSE);
371 
372 	data = g_slice_new (AsyncData);
373 	data->main_loop = main_loop;
374 
375 	/* Cast here is because vala doesn't make const-char-** possible :( */
376 	tracker_sparql_connection_update_array_async (connection,
377 	                                              (char**) queries,
378 	                                              6,
379 	                                              0,
380 	                                              NULL,
381 	                                              async_update_array_callback,
382 	                                              data);
383 
384 	g_main_loop_run (main_loop);
385 
386 	g_slice_free (AsyncData, data);
387 	g_main_loop_unref (main_loop);
388 
389 }
390 
391 static void
test_tracker_sparql_update_fast_error(DataFixture * fixture,gconstpointer user_data)392 test_tracker_sparql_update_fast_error (DataFixture  *fixture,
393                                        gconstpointer user_data)
394 {
395 	GError *error = NULL;
396 	const gchar *query = "blork blork blork";
397 
398 	tracker_sparql_connection_update (connection, query, 0, NULL, &error);
399 
400 	g_assert (error != NULL && error->domain == TRACKER_SPARQL_ERROR);
401 	g_error_free (error);
402 }
403 
404 static void
test_tracker_sparql_update_blank_fast_small(DataFixture * fixture,gconstpointer user_data)405 test_tracker_sparql_update_blank_fast_small (DataFixture  *fixture,
406                                              gconstpointer user_data)
407 {
408 	GError *error = NULL;
409 	const gchar *query = "INSERT { _:x a nmo:Message }";
410 	GVariant *results;
411 
412 	results = tracker_sparql_connection_update_blank (connection, query, 0, NULL, &error);
413 
414 	g_assert_no_error (error);
415 	g_assert (results);
416 
417 	/* FIXME: Properly test once we get update_blank implemented */
418 }
419 
420 static void
test_tracker_sparql_update_blank_fast_large(DataFixture * fixture,gconstpointer user_data)421 test_tracker_sparql_update_blank_fast_large (DataFixture  *fixture,
422                                              gconstpointer user_data)
423 {
424 	GError *error = NULL;
425 	gchar *lots;
426 	gchar *query;
427 	GVariant *results;
428 
429 	lots = g_malloc (LONG_NAME_SIZE);
430 	memset (lots, 'a', LONG_NAME_SIZE);
431 	lots[LONG_NAME_SIZE-1] = '\0';
432 
433 	query = g_strdup_printf ("INSERT { _:x a nmo:Message; nao:identifier \"%s\" }", lots);
434 
435 	results = tracker_sparql_connection_update_blank (connection, query, 0, NULL, &error);
436 
437 	g_free (lots);
438 	g_free (query);
439 
440 	g_assert_no_error (error);
441 	g_assert (results);
442 
443 	/* FIXME: Properly test once we get update_blank implemented */
444 }
445 
446 static void
test_tracker_sparql_update_blank_fast_error(DataFixture * fixture,gconstpointer user_data)447 test_tracker_sparql_update_blank_fast_error (DataFixture  *fixture,
448                                              gconstpointer user_data)
449 {
450 	GError *error = NULL;
451 	const gchar *query = "blork blork blork";
452 	GVariant *results;
453 
454 	results = tracker_sparql_connection_update_blank (connection, query, 0, NULL, &error);
455 
456 	g_assert (error != NULL && error->domain == TRACKER_SPARQL_ERROR);
457 	g_assert (!results);
458 
459 	g_error_free (error);
460 }
461 
462 static void
test_tracker_sparql_update_blank_fast_no_blanks(DataFixture * fixture,gconstpointer user_data)463 test_tracker_sparql_update_blank_fast_no_blanks (DataFixture  *fixture,
464                                                  gconstpointer user_data)
465 {
466 	GError *error = NULL;
467 	const gchar *query = "INSERT { <urn:not_blank> a nmo:Message }";
468 	GVariant *results;
469 
470 	results = tracker_sparql_connection_update_blank (connection, query, 0, NULL, &error);
471 
472 	/* FIXME: Properly test once we get update_blank implemented */
473 
474 	g_assert_no_error (error);
475 	g_assert (results);
476 }
477 
478 static void
test_tracker_batch_sparql_update_fast(DataFixture * fixture,gconstpointer user_data)479 test_tracker_batch_sparql_update_fast (DataFixture  *fixture,
480                                        gconstpointer user_data)
481 {
482 	/* GError *error = NULL; */
483 	/* const gchar *query = "INSERT { _:x a nmo:Message }"; */
484 
485 	/* FIXME: batch update is missing so far
486 	 * tracker_sparql_connection_batch_update (connection, query, NULL, &error); */
487 
488 	/* g_assert (!error); */
489 }
490 
491 static void
async_query_cb(GObject * source_object,GAsyncResult * result,gpointer user_data)492 async_query_cb (GObject      *source_object,
493                 GAsyncResult *result,
494                 gpointer      user_data)
495 {
496 	TrackerSparqlCursor *cursor_fd;
497 	TrackerSparqlCursor *cursor_glib;
498 	AsyncData *data = user_data;
499 	GError *error = NULL;
500 
501 	g_main_loop_quit (data->main_loop);
502 
503 	cursor_fd = tracker_sparql_connection_query_finish (connection, result, &error);
504 
505 	g_assert_no_error (error);
506 	g_assert (cursor_fd != NULL);
507 
508 	cursor_glib = tracker_sparql_connection_query (connection, data->query, NULL, &error);
509 
510 	g_assert_no_error (error);
511 	g_assert (cursor_glib != NULL);
512 
513 	while (tracker_sparql_cursor_next (cursor_fd, NULL, NULL) &&
514 	       tracker_sparql_cursor_next (cursor_glib, NULL, NULL)) {
515 		g_assert_cmpstr (tracker_sparql_cursor_get_string (cursor_fd, 0, NULL),
516 				 ==,
517 				 tracker_sparql_cursor_get_string (cursor_glib, 0, NULL));
518 	}
519 
520 	g_assert (!tracker_sparql_cursor_next (cursor_fd, NULL, NULL));
521 	g_assert (!tracker_sparql_cursor_next (cursor_glib, NULL, NULL));
522 
523 	g_object_unref (cursor_fd);
524 	g_object_unref (cursor_glib);
525 }
526 
527 static void
test_tracker_sparql_query_iterate_async(DataFixture * fixture,gconstpointer user_data)528 test_tracker_sparql_query_iterate_async (DataFixture  *fixture,
529                                          gconstpointer user_data)
530 {
531 	const gchar *query = "SELECT ?r nie:url(?r) WHERE {?r a nfo:FileDataObject}";
532 	GMainLoop *main_loop;
533 	AsyncData *data;
534 
535 	main_loop = g_main_loop_new (NULL, FALSE);
536 
537 	data = g_slice_new (AsyncData);
538 	data->main_loop = main_loop;
539 	data->query = query;
540 
541 	tracker_sparql_connection_query_async (connection,
542 	                                       query,
543 	                                       NULL,
544 	                                       async_query_cb,
545 	                                       data);
546 
547 	g_main_loop_run (main_loop);
548 
549 	g_slice_free (AsyncData, data);
550 	g_main_loop_unref (main_loop);
551 }
552 
553 static void
cancel_query_cb(GObject * source_object,GAsyncResult * result,gpointer user_data)554 cancel_query_cb (GObject      *source_object,
555                  GAsyncResult *result,
556                  gpointer      user_data)
557 {
558 	GMainLoop *main_loop = user_data;
559 	GError *error = NULL;
560 
561 	g_main_loop_quit (main_loop);
562 
563 	tracker_sparql_connection_query_finish (connection, result, &error);
564 
565 	/* An error should be returned (cancelled!) */
566 	g_assert (error);
567 }
568 
569 static void
test_tracker_sparql_query_iterate_async_cancel(DataFixture * fixture,gconstpointer user_data)570 test_tracker_sparql_query_iterate_async_cancel (DataFixture  *fixture,
571                                                 gconstpointer user_data)
572 {
573 	const gchar *query = "SELECT ?r nie:url(?r) WHERE {?r a nfo:FileDataObject}";
574 	GMainLoop *main_loop;
575 	GCancellable *cancellable = g_cancellable_new ();
576 
577 	main_loop = g_main_loop_new (NULL, FALSE);
578 
579 	tracker_sparql_connection_query_async (connection,
580 	                                       query,
581 	                                       cancellable,
582 	                                       cancel_query_cb,
583 	                                       main_loop);
584 
585 	g_cancellable_cancel (cancellable);
586 
587 	g_main_loop_run (main_loop);
588 
589 	g_main_loop_unref (main_loop);
590 }
591 
592 static void
async_update_callback(GObject * source_object,GAsyncResult * result,gpointer user_data)593 async_update_callback (GObject      *source_object,
594                        GAsyncResult *result,
595                        gpointer      user_data)
596 {
597 	AsyncData *data = user_data;
598 	GError *error = NULL;
599 
600 	tracker_sparql_connection_update_finish (connection, result, &error);
601 
602 	g_assert_no_error (error);
603 
604 	g_main_loop_quit (data->main_loop);
605 }
606 
607 static void
test_tracker_sparql_update_async(DataFixture * fixture,gconstpointer user_data)608 test_tracker_sparql_update_async (DataFixture  *fixture,
609                                   gconstpointer user_data)
610 {
611 	const gchar *query = "INSERT { _:x a nmo:Message }";
612 	GMainLoop *main_loop;
613 	AsyncData *data;
614 
615 	main_loop = g_main_loop_new (NULL, FALSE);
616 
617 	data = g_slice_new (AsyncData);
618 	data->main_loop = main_loop;
619 
620 	tracker_sparql_connection_update_async (connection,
621 	                                        query,
622 	                                        0,
623 	                                        NULL,
624 	                                        async_update_callback,
625 	                                        data);
626 
627 	g_main_loop_run (main_loop);
628 
629 	g_slice_free (AsyncData, data);
630 	g_main_loop_unref (main_loop);
631 }
632 
633 static void
cancel_update_cb(GObject * source_object,GAsyncResult * result,gpointer user_data)634 cancel_update_cb (GObject      *source_object,
635                   GAsyncResult *result,
636                   gpointer      user_data)
637 {
638 	GMainLoop *main_loop = user_data;
639 	GError *error = NULL;
640 
641 	g_main_loop_quit (main_loop);
642 
643 	tracker_sparql_connection_update_finish (connection, result, &error);
644 
645 	/* An error should be returned (cancelled!) */
646 	g_assert (error);
647 }
648 
649 static void
test_tracker_sparql_update_async_cancel(DataFixture * fixture,gconstpointer user_data)650 test_tracker_sparql_update_async_cancel (DataFixture  *fixture,
651                                          gconstpointer user_data)
652 {
653 	GCancellable *cancellable = g_cancellable_new ();
654 	const gchar *query = "INSERT { _:x a nmo:Message }";
655 	GMainLoop *main_loop;
656 
657 	main_loop = g_main_loop_new (NULL, FALSE);
658 
659 	tracker_sparql_connection_update_async (connection,
660 	                                        query,
661 	                                        0,
662 	                                        cancellable,
663 	                                        cancel_update_cb,
664 	                                        main_loop);
665 	g_cancellable_cancel (cancellable);
666 
667 	g_main_loop_run (main_loop);
668 
669 	g_main_loop_unref (main_loop);
670 }
671 
672 static void
async_update_blank_callback(GObject * source_object,GAsyncResult * result,gpointer user_data)673 async_update_blank_callback (GObject      *source_object,
674                              GAsyncResult *result,
675                              gpointer      user_data)
676 {
677 	AsyncData *data = user_data;
678 	GVariant *results;
679 	GError *error = NULL;
680 
681 	g_main_loop_quit (data->main_loop);
682 
683 	results = tracker_sparql_connection_update_blank_finish (connection, result, &error);
684 
685 	g_assert_no_error (error);
686 	g_assert (results != NULL);
687 }
688 
689 static void
test_tracker_sparql_update_blank_async(DataFixture * fixture,gconstpointer user_data)690 test_tracker_sparql_update_blank_async (DataFixture *fixture,
691                                         gconstpointer user_data)
692 {
693 	const gchar *query = "INSERT { _:x a nmo:Message }";
694 	GMainLoop *main_loop;
695 	AsyncData *data;
696 
697 	main_loop = g_main_loop_new (NULL, FALSE);
698 
699 	data = g_slice_new (AsyncData);
700 	data->main_loop = main_loop;
701 
702 	tracker_sparql_connection_update_blank_async (connection,
703 	                                              query,
704 	                                              0,
705 	                                              NULL,
706 	                                              async_update_blank_callback,
707 	                                              data);
708 
709 	g_main_loop_run (main_loop);
710 
711 	g_slice_free (AsyncData, data);
712 	g_main_loop_unref (main_loop);
713 }
714 
715 gint
main(gint argc,gchar ** argv)716 main (gint argc, gchar **argv)
717 {
718 	g_test_init (&argc, &argv, NULL);
719 
720 	/* test D-Bus backend */
721 	g_setenv ("TRACKER_SPARQL_BACKEND", "bus", TRUE);
722 	g_setenv ("TRACKER_TEST_DOMAIN_ONTOLOGY_RULE", TEST_DOMAIN_ONTOLOGY_RULE, TRUE);
723 	g_setenv ("TRACKER_DB_ONTOLOGIES_DIR", TEST_ONTOLOGIES_DIR, TRUE);
724 
725 	connection = tracker_sparql_connection_get (NULL, NULL);
726 
727 	g_test_add ("/steroids/tracker/tracker_sparql_query_iterate", DataFixture, NULL, insert_test_data,
728 			test_tracker_sparql_query_iterate, delete_test_data);
729 	g_test_add ("/steroids/tracker/tracker_sparql_query_iterate_largerow", DataFixture, NULL, insert_test_data,
730 			test_tracker_sparql_query_iterate_largerow, delete_test_data);
731 	g_test_add ("/steroids/tracker/tracker_sparql_query_iterate_error", DataFixture, NULL, insert_test_data,
732 			test_tracker_sparql_query_iterate_error, delete_test_data);
733 	g_test_add ("/steroids/tracker/tracker_sparql_query_iterate_empty", DataFixture, NULL, insert_test_data,
734 			test_tracker_sparql_query_iterate_empty, delete_test_data);
735 	g_test_add ("/steroids/tracker/tracker_sparql_query_iterate_empty/subprocess", DataFixture, NULL,
736 			insert_test_data, test_tracker_sparql_query_iterate_empty_subprocess, delete_test_data);
737 	g_test_add ("/steroids/tracker/tracker_sparql_query_iterate_sigpipe", DataFixture, NULL, insert_test_data,
738 			test_tracker_sparql_query_iterate_sigpipe, delete_test_data);
739 	g_test_add ("/steroids/tracker/tracker_sparql_update_fast_small", DataFixture, NULL, insert_test_data,
740 			test_tracker_sparql_update_fast_small, delete_test_data);
741 	g_test_add ("/steroids/tracker/tracker_sparql_update_fast_large", DataFixture, NULL, insert_test_data,
742 			test_tracker_sparql_update_fast_large, delete_test_data);
743 	g_test_add ("/steroids/tracker/tracker_sparql_update_fast_error", DataFixture, NULL, insert_test_data,
744 			test_tracker_sparql_update_fast_error, delete_test_data);
745 	g_test_add ("/steroids/tracker/tracker_sparql_update_blank_fast_small", DataFixture, NULL, insert_test_data,
746 			test_tracker_sparql_update_blank_fast_small, delete_test_data);
747 	g_test_add ("/steroids/tracker/tracker_sparql_update_blank_fast_large", DataFixture, NULL, insert_test_data,
748 			test_tracker_sparql_update_blank_fast_large, delete_test_data);
749 	g_test_add ("/steroids/tracker/tracker_sparql_update_blank_fast_error", DataFixture, NULL, insert_test_data,
750 			test_tracker_sparql_update_blank_fast_error, delete_test_data);
751 	g_test_add ("/steroids/tracker/tracker_sparql_update_blank_fast_no_blanks", DataFixture, NULL, insert_test_data,
752 			test_tracker_sparql_update_blank_fast_no_blanks, delete_test_data);
753 	g_test_add ("/steroids/tracker/tracker_batch_sparql_update_fast", DataFixture, NULL, insert_test_data,
754 			test_tracker_batch_sparql_update_fast, delete_test_data);
755 	g_test_add ("/steroids/tracker/tracker_sparql_query_iterate_async", DataFixture, NULL, insert_test_data,
756 			test_tracker_sparql_query_iterate_async, delete_test_data);
757 	g_test_add ("/steroids/tracker/tracker_sparql_query_iterate_async_cancel", DataFixture, NULL, insert_test_data,
758 			test_tracker_sparql_query_iterate_async_cancel, delete_test_data);
759 	g_test_add ("/steroids/tracker/tracker_sparql_update_async", DataFixture, NULL, insert_test_data,
760 			test_tracker_sparql_update_async, delete_test_data);
761 	g_test_add ("/steroids/tracker/tracker_sparql_update_async_cancel", DataFixture, NULL, insert_test_data,
762 			test_tracker_sparql_update_async_cancel, delete_test_data);
763 	g_test_add ("/steroids/tracker/tracker_sparql_update_blank_async", DataFixture, NULL, insert_test_data,
764 			test_tracker_sparql_update_blank_async, delete_test_data);
765 	g_test_add ("/steroids/tracker/tracker_sparql_update_array_async", DataFixture, NULL, insert_test_data,
766 			test_tracker_sparql_update_array_async, delete_test_data);
767 
768 	return g_test_run ();
769 }
770