1 /* GLib testing framework examples and tests
2 *
3 * Copyright (C) 2008-2010 Red Hat, Inc.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 *
18 * Author: David Zeuthen <davidz@redhat.com>
19 */
20
21 #include <gio/gio.h>
22 #include <unistd.h>
23 #include <string.h>
24
25 #include <sys/types.h>
26
27 #include "gdbus-tests.h"
28
29 /* all tests rely on a shared mainloop */
30 static GMainLoop *loop = NULL;
31
32 #if 0
33 G_GNUC_UNUSED static void
34 _log (const gchar *format, ...)
35 {
36 GTimeVal now;
37 time_t now_time;
38 struct tm *now_tm;
39 gchar time_buf[128];
40 gchar *str;
41 va_list var_args;
42
43 va_start (var_args, format);
44 str = g_strdup_vprintf (format, var_args);
45 va_end (var_args);
46
47 g_get_current_time (&now);
48 now_time = (time_t) now.tv_sec;
49 now_tm = localtime (&now_time);
50 strftime (time_buf, sizeof time_buf, "%H:%M:%S", now_tm);
51
52 g_printerr ("%s.%06d: %s\n",
53 time_buf, (gint) now.tv_usec / 1000,
54 str);
55 g_free (str);
56 }
57 #else
58 #define _log(...)
59 #endif
60
61 static gboolean
test_connection_quit_mainloop(gpointer user_data)62 test_connection_quit_mainloop (gpointer user_data)
63 {
64 gboolean *quit_mainloop_fired = user_data; /* (atomic) */
65 _log ("quit_mainloop_fired");
66 g_atomic_int_set (quit_mainloop_fired, TRUE);
67 g_main_loop_quit (loop);
68 return G_SOURCE_CONTINUE;
69 }
70
71 /* ---------------------------------------------------------------------------------------------------- */
72 /* Connection life-cycle testing */
73 /* ---------------------------------------------------------------------------------------------------- */
74
75 static const GDBusInterfaceInfo boo_interface_info =
76 {
77 -1,
78 "org.example.Boo",
79 (GDBusMethodInfo **) NULL,
80 (GDBusSignalInfo **) NULL,
81 (GDBusPropertyInfo **) NULL,
82 NULL,
83 };
84
85 static const GDBusInterfaceVTable boo_vtable =
86 {
87 NULL, /* _method_call */
88 NULL, /* _get_property */
89 NULL /* _set_property */
90 };
91
92 /* Runs in a worker thread. */
93 static GDBusMessage *
some_filter_func(GDBusConnection * connection,GDBusMessage * message,gboolean incoming,gpointer user_data)94 some_filter_func (GDBusConnection *connection,
95 GDBusMessage *message,
96 gboolean incoming,
97 gpointer user_data)
98 {
99 return message;
100 }
101
102 static void
on_name_owner_changed(GDBusConnection * connection,const gchar * sender_name,const gchar * object_path,const gchar * interface_name,const gchar * signal_name,GVariant * parameters,gpointer user_data)103 on_name_owner_changed (GDBusConnection *connection,
104 const gchar *sender_name,
105 const gchar *object_path,
106 const gchar *interface_name,
107 const gchar *signal_name,
108 GVariant *parameters,
109 gpointer user_data)
110 {
111 }
112
113 static void
a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop(gpointer user_data)114 a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop (gpointer user_data)
115 {
116 gboolean *val = user_data; /* (atomic) */
117 g_atomic_int_set (val, TRUE);
118 _log ("destroynotify fired for %p", val);
119 g_main_loop_quit (loop);
120 }
121
122 static void
test_connection_bus_failure(void)123 test_connection_bus_failure (void)
124 {
125 GDBusConnection *c;
126 GError *error = NULL;
127
128 /*
129 * Check for correct behavior when no bus is present
130 *
131 */
132 c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
133 g_assert_nonnull (error);
134 g_assert_false (g_dbus_error_is_remote_error (error));
135 g_assert_null (c);
136 g_error_free (error);
137 }
138
139 static void
test_connection_life_cycle(void)140 test_connection_life_cycle (void)
141 {
142 gboolean ret;
143 GDBusConnection *c;
144 GDBusConnection *c2;
145 GError *error;
146 gboolean on_signal_registration_freed_called; /* (atomic) */
147 gboolean on_filter_freed_called; /* (atomic) */
148 gboolean on_register_object_freed_called; /* (atomic) */
149 gboolean quit_mainloop_fired; /* (atomic) */
150 guint quit_mainloop_id;
151 guint registration_id;
152
153 error = NULL;
154
155 /*
156 * Check for correct behavior when a bus is present
157 */
158 session_bus_up ();
159 /* case 1 */
160 error = NULL;
161 c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
162 g_assert_no_error (error);
163 g_assert_nonnull (c);
164 g_assert_false (g_dbus_connection_is_closed (c));
165
166 /*
167 * Check that singleton handling work
168 */
169 error = NULL;
170 c2 = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
171 g_assert_no_error (error);
172 g_assert_nonnull (c2);
173 g_assert_true (c == c2);
174 g_object_unref (c2);
175
176 /*
177 * Check that private connections work
178 */
179 c2 = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, &error);
180 g_assert_no_error (error);
181 g_assert_nonnull (c2);
182 g_assert_true (c != c2);
183 g_object_unref (c2);
184
185 c2 = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, &error);
186 g_assert_no_error (error);
187 g_assert_nonnull (c2);
188 g_assert_false (g_dbus_connection_is_closed (c2));
189 ret = g_dbus_connection_close_sync (c2, NULL, &error);
190 g_assert_no_error (error);
191 g_assert_true (ret);
192 _g_assert_signal_received (c2, "closed");
193 g_assert_true (g_dbus_connection_is_closed (c2));
194 ret = g_dbus_connection_close_sync (c2, NULL, &error);
195 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED);
196 g_error_free (error);
197 g_assert_false (ret);
198 g_object_unref (c2);
199
200 /*
201 * Check that the finalization code works
202 *
203 * (and that the GDestroyNotify for filters and objects and signal
204 * registrations are run as expected)
205 */
206 error = NULL;
207 c2 = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, &error);
208 g_assert_no_error (error);
209 g_assert_nonnull (c2);
210 /* signal registration */
211 g_atomic_int_set (&on_signal_registration_freed_called, FALSE);
212 g_dbus_connection_signal_subscribe (c2,
213 "org.freedesktop.DBus", /* bus name */
214 "org.freedesktop.DBus", /* interface */
215 "NameOwnerChanged", /* member */
216 "/org/freesktop/DBus", /* path */
217 NULL, /* arg0 */
218 G_DBUS_SIGNAL_FLAGS_NONE,
219 on_name_owner_changed,
220 (gpointer) &on_signal_registration_freed_called,
221 a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop);
222 /* filter func */
223 g_atomic_int_set (&on_filter_freed_called, FALSE);
224 g_dbus_connection_add_filter (c2,
225 some_filter_func,
226 (gpointer) &on_filter_freed_called,
227 a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop);
228 /* object registration */
229 g_atomic_int_set (&on_register_object_freed_called, FALSE);
230 error = NULL;
231 registration_id = g_dbus_connection_register_object (c2,
232 "/foo",
233 (GDBusInterfaceInfo *) &boo_interface_info,
234 &boo_vtable,
235 (gpointer) &on_register_object_freed_called,
236 a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop,
237 &error);
238 g_assert_no_error (error);
239 g_assert_cmpuint (registration_id, >, 0);
240 /* ok, finalize the connection and check that all the GDestroyNotify functions are invoked as expected */
241 g_object_unref (c2);
242 g_atomic_int_set (&quit_mainloop_fired, FALSE);
243 quit_mainloop_id = g_timeout_add (30000, test_connection_quit_mainloop, (gpointer) &quit_mainloop_fired);
244 _log ("destroynotifies for\n"
245 " register_object %p\n"
246 " filter %p\n"
247 " signal %p",
248 &on_register_object_freed_called,
249 &on_filter_freed_called,
250 &on_signal_registration_freed_called);
251 while (TRUE)
252 {
253 if (g_atomic_int_get (&on_signal_registration_freed_called) &&
254 g_atomic_int_get (&on_filter_freed_called) &&
255 g_atomic_int_get (&on_register_object_freed_called))
256 break;
257 if (g_atomic_int_get (&quit_mainloop_fired))
258 break;
259 _log ("entering loop");
260 g_main_loop_run (loop);
261 _log ("exiting loop");
262 }
263 g_source_remove (quit_mainloop_id);
264 g_assert_true (g_atomic_int_get (&on_signal_registration_freed_called));
265 g_assert_true (g_atomic_int_get (&on_filter_freed_called));
266 g_assert_true (g_atomic_int_get (&on_register_object_freed_called));
267 g_assert_false (g_atomic_int_get (&quit_mainloop_fired));
268
269 /*
270 * Check for correct behavior when the bus goes away
271 *
272 */
273 g_assert_false (g_dbus_connection_is_closed (c));
274 g_dbus_connection_set_exit_on_close (c, FALSE);
275 session_bus_stop ();
276 _g_assert_signal_received (c, "closed");
277 g_assert_true (g_dbus_connection_is_closed (c));
278 g_object_unref (c);
279
280 session_bus_down ();
281 }
282
283 /* ---------------------------------------------------------------------------------------------------- */
284 /* Test that sending and receiving messages work as expected */
285 /* ---------------------------------------------------------------------------------------------------- */
286
287 static void
msg_cb_expect_error_disconnected(GDBusConnection * connection,GAsyncResult * res,gpointer user_data)288 msg_cb_expect_error_disconnected (GDBusConnection *connection,
289 GAsyncResult *res,
290 gpointer user_data)
291 {
292 GError *error;
293 GVariant *result;
294
295 /* Make sure gdbusconnection isn't holding @connection's lock. (#747349) */
296 g_dbus_connection_get_last_serial (connection);
297
298 error = NULL;
299 result = g_dbus_connection_call_finish (connection,
300 res,
301 &error);
302 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED);
303 g_assert_false (g_dbus_error_is_remote_error (error));
304 g_error_free (error);
305 g_assert_null (result);
306
307 g_main_loop_quit (loop);
308 }
309
310 static void
msg_cb_expect_error_unknown_method(GDBusConnection * connection,GAsyncResult * res,gpointer user_data)311 msg_cb_expect_error_unknown_method (GDBusConnection *connection,
312 GAsyncResult *res,
313 gpointer user_data)
314 {
315 GError *error;
316 GVariant *result;
317
318 /* Make sure gdbusconnection isn't holding @connection's lock. (#747349) */
319 g_dbus_connection_get_last_serial (connection);
320
321 error = NULL;
322 result = g_dbus_connection_call_finish (connection,
323 res,
324 &error);
325 g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD);
326 g_assert_true (g_dbus_error_is_remote_error (error));
327 g_error_free (error);
328 g_assert_null (result);
329
330 g_main_loop_quit (loop);
331 }
332
333 static void
msg_cb_expect_success(GDBusConnection * connection,GAsyncResult * res,gpointer user_data)334 msg_cb_expect_success (GDBusConnection *connection,
335 GAsyncResult *res,
336 gpointer user_data)
337 {
338 GError *error;
339 GVariant *result;
340
341 /* Make sure gdbusconnection isn't holding @connection's lock. (#747349) */
342 g_dbus_connection_get_last_serial (connection);
343
344 error = NULL;
345 result = g_dbus_connection_call_finish (connection,
346 res,
347 &error);
348 g_assert_no_error (error);
349 g_assert_nonnull (result);
350 g_variant_unref (result);
351
352 g_main_loop_quit (loop);
353 }
354
355 static void
msg_cb_expect_error_cancelled(GDBusConnection * connection,GAsyncResult * res,gpointer user_data)356 msg_cb_expect_error_cancelled (GDBusConnection *connection,
357 GAsyncResult *res,
358 gpointer user_data)
359 {
360 GError *error;
361 GVariant *result;
362
363 /* Make sure gdbusconnection isn't holding @connection's lock. (#747349) */
364 g_dbus_connection_get_last_serial (connection);
365
366 error = NULL;
367 result = g_dbus_connection_call_finish (connection,
368 res,
369 &error);
370 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
371 g_assert_false (g_dbus_error_is_remote_error (error));
372 g_error_free (error);
373 g_assert_null (result);
374
375 g_main_loop_quit (loop);
376 }
377
378 static void
msg_cb_expect_error_cancelled_2(GDBusConnection * connection,GAsyncResult * res,gpointer user_data)379 msg_cb_expect_error_cancelled_2 (GDBusConnection *connection,
380 GAsyncResult *res,
381 gpointer user_data)
382 {
383 GError *error;
384 GVariant *result;
385
386 /* Make sure gdbusconnection isn't holding @connection's lock. (#747349) */
387 g_dbus_connection_get_last_serial (connection);
388
389 error = NULL;
390 result = g_dbus_connection_call_finish (connection,
391 res,
392 &error);
393 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
394 g_assert_false (g_dbus_error_is_remote_error (error));
395 g_error_free (error);
396 g_assert_null (result);
397
398 g_main_loop_quit (loop);
399 }
400
401 /* ---------------------------------------------------------------------------------------------------- */
402
403 static void
test_connection_send(void)404 test_connection_send (void)
405 {
406 GDBusConnection *c;
407 GCancellable *ca;
408
409 session_bus_up ();
410
411 /* First, get an unopened connection */
412 c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
413 g_assert_nonnull (c);
414 g_assert_false (g_dbus_connection_is_closed (c));
415
416 /*
417 * Check that we never actually send a message if the GCancellable
418 * is already cancelled - i.e. we should get #G_IO_ERROR_CANCELLED
419 * when the actual connection is not up.
420 */
421 ca = g_cancellable_new ();
422 g_cancellable_cancel (ca);
423 g_dbus_connection_call (c,
424 "org.freedesktop.DBus", /* bus_name */
425 "/org/freedesktop/DBus", /* object path */
426 "org.freedesktop.DBus", /* interface name */
427 "GetId", /* method name */
428 NULL, NULL,
429 G_DBUS_CALL_FLAGS_NONE,
430 -1,
431 ca,
432 (GAsyncReadyCallback) msg_cb_expect_error_cancelled,
433 NULL);
434 g_main_loop_run (loop);
435 g_object_unref (ca);
436
437 /*
438 * Check that we get a reply to the GetId() method call.
439 */
440 g_dbus_connection_call (c,
441 "org.freedesktop.DBus", /* bus_name */
442 "/org/freedesktop/DBus", /* object path */
443 "org.freedesktop.DBus", /* interface name */
444 "GetId", /* method name */
445 NULL, NULL,
446 G_DBUS_CALL_FLAGS_NONE,
447 -1,
448 NULL,
449 (GAsyncReadyCallback) msg_cb_expect_success,
450 NULL);
451 g_main_loop_run (loop);
452
453 /*
454 * Check that we get an error reply to the NonExistantMethod() method call.
455 */
456 g_dbus_connection_call (c,
457 "org.freedesktop.DBus", /* bus_name */
458 "/org/freedesktop/DBus", /* object path */
459 "org.freedesktop.DBus", /* interface name */
460 "NonExistantMethod", /* method name */
461 NULL, NULL,
462 G_DBUS_CALL_FLAGS_NONE,
463 -1,
464 NULL,
465 (GAsyncReadyCallback) msg_cb_expect_error_unknown_method,
466 NULL);
467 g_main_loop_run (loop);
468
469 /*
470 * Check that cancellation works when the message is already in flight.
471 */
472 ca = g_cancellable_new ();
473 g_dbus_connection_call (c,
474 "org.freedesktop.DBus", /* bus_name */
475 "/org/freedesktop/DBus", /* object path */
476 "org.freedesktop.DBus", /* interface name */
477 "GetId", /* method name */
478 NULL, NULL,
479 G_DBUS_CALL_FLAGS_NONE,
480 -1,
481 ca,
482 (GAsyncReadyCallback) msg_cb_expect_error_cancelled_2,
483 NULL);
484 g_cancellable_cancel (ca);
485 g_main_loop_run (loop);
486 g_object_unref (ca);
487
488 /*
489 * Check that we get an error when sending to a connection that is disconnected.
490 */
491 g_dbus_connection_set_exit_on_close (c, FALSE);
492 session_bus_stop ();
493 _g_assert_signal_received (c, "closed");
494 g_assert_true (g_dbus_connection_is_closed (c));
495
496 g_dbus_connection_call (c,
497 "org.freedesktop.DBus", /* bus_name */
498 "/org/freedesktop/DBus", /* object path */
499 "org.freedesktop.DBus", /* interface name */
500 "GetId", /* method name */
501 NULL, NULL,
502 G_DBUS_CALL_FLAGS_NONE,
503 -1,
504 NULL,
505 (GAsyncReadyCallback) msg_cb_expect_error_disconnected,
506 NULL);
507 g_main_loop_run (loop);
508
509 g_object_unref (c);
510
511 session_bus_down ();
512 }
513
514 /* ---------------------------------------------------------------------------------------------------- */
515 /* Connection signal tests */
516 /* ---------------------------------------------------------------------------------------------------- */
517
518 static void
test_connection_signal_handler(GDBusConnection * connection,const gchar * sender_name,const gchar * object_path,const gchar * interface_name,const gchar * signal_name,GVariant * parameters,gpointer user_data)519 test_connection_signal_handler (GDBusConnection *connection,
520 const gchar *sender_name,
521 const gchar *object_path,
522 const gchar *interface_name,
523 const gchar *signal_name,
524 GVariant *parameters,
525 gpointer user_data)
526 {
527 gint *counter = user_data;
528 *counter += 1;
529
530 /*g_debug ("in test_connection_signal_handler (sender=%s path=%s interface=%s member=%s)",
531 sender_name,
532 object_path,
533 interface_name,
534 signal_name);*/
535
536 g_main_loop_quit (loop);
537 }
538
539 static void
test_connection_signals(void)540 test_connection_signals (void)
541 {
542 GDBusConnection *c1;
543 GDBusConnection *c2;
544 GDBusConnection *c3;
545 guint s1;
546 guint s1b;
547 guint s2;
548 guint s3;
549 gint count_s1;
550 gint count_s1b;
551 gint count_s2;
552 gint count_name_owner_changed;
553 GError *error;
554 gboolean ret;
555 GVariant *result;
556 gboolean quit_mainloop_fired;
557 guint quit_mainloop_id;
558
559 error = NULL;
560
561 /*
562 * Bring up first separate connections
563 */
564 session_bus_up ();
565 /* if running with dbus-monitor, it claims the name :1.0 - so if we don't run with the monitor
566 * emulate this
567 */
568 if (g_getenv ("G_DBUS_MONITOR") == NULL)
569 {
570 c1 = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, NULL);
571 g_assert_nonnull (c1);
572 g_assert_false (g_dbus_connection_is_closed (c1));
573 g_object_unref (c1);
574 }
575 c1 = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
576 g_assert_nonnull (c1);
577 g_assert_false (g_dbus_connection_is_closed (c1));
578 g_assert_cmpstr (g_dbus_connection_get_unique_name (c1), ==, ":1.1");
579
580 /*
581 * Install two signal handlers for the first connection
582 *
583 * - Listen to the signal "Foo" from :1.2 (e.g. c2)
584 * - Listen to the signal "Foo" from anyone (e.g. both c2 and c3)
585 *
586 * and then count how many times this signal handler was invoked.
587 */
588 s1 = g_dbus_connection_signal_subscribe (c1,
589 ":1.2",
590 "org.gtk.GDBus.ExampleInterface",
591 "Foo",
592 "/org/gtk/GDBus/ExampleInterface",
593 NULL,
594 G_DBUS_SIGNAL_FLAGS_NONE,
595 test_connection_signal_handler,
596 &count_s1,
597 NULL);
598 s2 = g_dbus_connection_signal_subscribe (c1,
599 NULL, /* match any sender */
600 "org.gtk.GDBus.ExampleInterface",
601 "Foo",
602 "/org/gtk/GDBus/ExampleInterface",
603 NULL,
604 G_DBUS_SIGNAL_FLAGS_NONE,
605 test_connection_signal_handler,
606 &count_s2,
607 NULL);
608 s3 = g_dbus_connection_signal_subscribe (c1,
609 "org.freedesktop.DBus", /* sender */
610 "org.freedesktop.DBus", /* interface */
611 "NameOwnerChanged", /* member */
612 "/org/freedesktop/DBus", /* path */
613 NULL,
614 G_DBUS_SIGNAL_FLAGS_NONE,
615 test_connection_signal_handler,
616 &count_name_owner_changed,
617 NULL);
618 /* Note that s1b is *just like* s1 - this is to catch a bug where N
619 * subscriptions of the same rule causes N calls to each of the N
620 * subscriptions instead of just 1 call to each of the N subscriptions.
621 */
622 s1b = g_dbus_connection_signal_subscribe (c1,
623 ":1.2",
624 "org.gtk.GDBus.ExampleInterface",
625 "Foo",
626 "/org/gtk/GDBus/ExampleInterface",
627 NULL,
628 G_DBUS_SIGNAL_FLAGS_NONE,
629 test_connection_signal_handler,
630 &count_s1b,
631 NULL);
632 g_assert_cmpuint (s1, !=, 0);
633 g_assert_cmpuint (s1b, !=, 0);
634 g_assert_cmpuint (s2, !=, 0);
635 g_assert_cmpuint (s3, !=, 0);
636
637 count_s1 = 0;
638 count_s1b = 0;
639 count_s2 = 0;
640 count_name_owner_changed = 0;
641
642 /*
643 * Make c2 emit "Foo" - we should catch it twice
644 *
645 * Note that there is no way to be sure that the signal subscriptions
646 * on c1 are effective yet - for all we know, the AddMatch() messages
647 * could sit waiting in a buffer somewhere between this process and
648 * the message bus. And emitting signals on c2 (a completely other
649 * socket!) will not necessarily change this.
650 *
651 * To ensure this is not the case, do a synchronous call on c1.
652 */
653 result = g_dbus_connection_call_sync (c1,
654 "org.freedesktop.DBus", /* bus name */
655 "/org/freedesktop/DBus", /* object path */
656 "org.freedesktop.DBus", /* interface name */
657 "GetId", /* method name */
658 NULL, /* parameters */
659 NULL, /* return type */
660 G_DBUS_CALL_FLAGS_NONE,
661 -1,
662 NULL,
663 &error);
664 g_assert_no_error (error);
665 g_assert_nonnull (result);
666 g_variant_unref (result);
667
668 /*
669 * Bring up two other connections
670 */
671 c2 = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, NULL);
672 g_assert_nonnull (c2);
673 g_assert_false (g_dbus_connection_is_closed (c2));
674 g_assert_cmpstr (g_dbus_connection_get_unique_name (c2), ==, ":1.2");
675 c3 = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, NULL);
676 g_assert_nonnull (c3);
677 g_assert_false (g_dbus_connection_is_closed (c3));
678 g_assert_cmpstr (g_dbus_connection_get_unique_name (c3), ==, ":1.3");
679
680 /* now, emit the signal on c2 */
681 ret = g_dbus_connection_emit_signal (c2,
682 NULL, /* destination bus name */
683 "/org/gtk/GDBus/ExampleInterface",
684 "org.gtk.GDBus.ExampleInterface",
685 "Foo",
686 NULL,
687 &error);
688 g_assert_no_error (error);
689 g_assert_true (ret);
690 while (!(count_s1 >= 1 && count_s2 >= 1))
691 g_main_loop_run (loop);
692 g_assert_cmpint (count_s1, ==, 1);
693 g_assert_cmpint (count_s2, ==, 1);
694
695 /*
696 * Make c3 emit "Foo" - we should catch it only once
697 */
698 ret = g_dbus_connection_emit_signal (c3,
699 NULL, /* destination bus name */
700 "/org/gtk/GDBus/ExampleInterface",
701 "org.gtk.GDBus.ExampleInterface",
702 "Foo",
703 NULL,
704 &error);
705 g_assert_no_error (error);
706 g_assert_true (ret);
707 while (!(count_s1 == 1 && count_s2 == 2))
708 g_main_loop_run (loop);
709 g_assert_cmpint (count_s1, ==, 1);
710 g_assert_cmpint (count_s2, ==, 2);
711
712 /*
713 * Also to check the total amount of NameOwnerChanged signals - use a 5 second ceiling
714 * to avoid spinning forever
715 */
716 quit_mainloop_fired = FALSE;
717 quit_mainloop_id = g_timeout_add (30000, test_connection_quit_mainloop, &quit_mainloop_fired);
718 while (count_name_owner_changed < 2 && !quit_mainloop_fired)
719 g_main_loop_run (loop);
720 g_source_remove (quit_mainloop_id);
721 g_assert_cmpint (count_s1, ==, 1);
722 g_assert_cmpint (count_s2, ==, 2);
723 g_assert_cmpint (count_name_owner_changed, ==, 2);
724
725 g_dbus_connection_signal_unsubscribe (c1, s1);
726 g_dbus_connection_signal_unsubscribe (c1, s2);
727 g_dbus_connection_signal_unsubscribe (c1, s3);
728 g_dbus_connection_signal_unsubscribe (c1, s1b);
729
730 g_object_unref (c1);
731 g_object_unref (c2);
732 g_object_unref (c3);
733
734 session_bus_down ();
735 }
736
737 static void
test_match_rule(GDBusConnection * connection,GDBusSignalFlags flags,gchar * arg0_rule,gchar * arg0,gboolean should_match)738 test_match_rule (GDBusConnection *connection,
739 GDBusSignalFlags flags,
740 gchar *arg0_rule,
741 gchar *arg0,
742 gboolean should_match)
743 {
744 guint subscription_ids[2];
745 gint emissions = 0;
746 gint matches = 0;
747 GError *error = NULL;
748
749 subscription_ids[0] = g_dbus_connection_signal_subscribe (connection,
750 NULL, "org.gtk.ExampleInterface", "Foo", "/",
751 NULL,
752 G_DBUS_SIGNAL_FLAGS_NONE,
753 test_connection_signal_handler,
754 &emissions, NULL);
755 subscription_ids[1] = g_dbus_connection_signal_subscribe (connection,
756 NULL, "org.gtk.ExampleInterface", "Foo", "/",
757 arg0_rule,
758 flags,
759 test_connection_signal_handler,
760 &matches, NULL);
761 g_assert_cmpint (subscription_ids[0], !=, 0);
762 g_assert_cmpint (subscription_ids[1], !=, 0);
763
764 g_dbus_connection_emit_signal (connection,
765 NULL, "/", "org.gtk.ExampleInterface",
766 "Foo", g_variant_new ("(s)", arg0),
767 &error);
768 g_assert_no_error (error);
769
770 /* synchronously ping a non-existent method to make sure the signals are dispatched */
771 g_dbus_connection_call_sync (connection, "org.gtk.ExampleInterface", "/", "org.gtk.ExampleInterface",
772 "Bar", g_variant_new ("()"), G_VARIANT_TYPE_UNIT, G_DBUS_CALL_FLAGS_NONE,
773 -1, NULL, NULL);
774
775 while (g_main_context_iteration (NULL, FALSE))
776 ;
777
778 g_assert_cmpint (emissions, ==, 1);
779 g_assert_cmpint (matches, ==, should_match ? 1 : 0);
780
781 g_dbus_connection_signal_unsubscribe (connection, subscription_ids[0]);
782 g_dbus_connection_signal_unsubscribe (connection, subscription_ids[1]);
783 }
784
785 static void
test_connection_signal_match_rules(void)786 test_connection_signal_match_rules (void)
787 {
788 GDBusConnection *con;
789
790 session_bus_up ();
791 con = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
792
793 test_match_rule (con, G_DBUS_SIGNAL_FLAGS_NONE, "foo", "foo", TRUE);
794 test_match_rule (con, G_DBUS_SIGNAL_FLAGS_NONE, "foo", "bar", FALSE);
795
796 test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, "org.gtk", "", FALSE);
797 test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, "org.gtk", "org", FALSE);
798 test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, "org.gtk", "org.gtk", TRUE);
799 test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, "org.gtk", "org.gtk.Example", TRUE);
800 test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, "org.gtk", "org.gtk+", FALSE);
801
802 test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/", "/", TRUE);
803 test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/", "", FALSE);
804 test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/org/gtk/Example", "/org/gtk/Example", TRUE);
805 test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/org/gtk/", "/org/gtk/Example", TRUE);
806 test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/org/gtk/Example", "/org/gtk/", TRUE);
807 test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/org/gtk/Example", "/org/gtk", FALSE);
808 test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/org/gtk+", "/org/gtk", FALSE);
809
810 g_object_unref (con);
811 session_bus_down ();
812 }
813
814 /* ---------------------------------------------------------------------------------------------------- */
815
816 /* Accessed both from the test code and the filter function (in a worker thread)
817 * so all accesses must be atomic. */
818 typedef struct
819 {
820 GAsyncQueue *incoming_queue; /* (element-type GDBusMessage) */
821 guint num_outgoing; /* (atomic) */
822 } FilterData;
823
824 /* Runs in a worker thread. */
825 static GDBusMessage *
filter_func(GDBusConnection * connection,GDBusMessage * message,gboolean incoming,gpointer user_data)826 filter_func (GDBusConnection *connection,
827 GDBusMessage *message,
828 gboolean incoming,
829 gpointer user_data)
830 {
831 FilterData *data = user_data;
832
833 if (incoming)
834 g_async_queue_push (data->incoming_queue, g_object_ref (message));
835 else
836 g_atomic_int_inc (&data->num_outgoing);
837
838 return message;
839 }
840
841 static void
wait_for_filtered_reply(GAsyncQueue * incoming_queue,guint32 expected_serial)842 wait_for_filtered_reply (GAsyncQueue *incoming_queue,
843 guint32 expected_serial)
844 {
845 GDBusMessage *popped_message = NULL;
846
847 while ((popped_message = g_async_queue_pop (incoming_queue)) != NULL)
848 {
849 guint32 reply_serial = g_dbus_message_get_reply_serial (popped_message);
850 g_object_unref (popped_message);
851 if (reply_serial == expected_serial)
852 return;
853 }
854
855 g_assert_not_reached ();
856 }
857
858 typedef struct
859 {
860 gboolean alter_incoming;
861 gboolean alter_outgoing;
862 } FilterEffects;
863
864 /* Runs in a worker thread. */
865 static GDBusMessage *
other_filter_func(GDBusConnection * connection,GDBusMessage * message,gboolean incoming,gpointer user_data)866 other_filter_func (GDBusConnection *connection,
867 GDBusMessage *message,
868 gboolean incoming,
869 gpointer user_data)
870 {
871 const FilterEffects *effects = user_data;
872 GDBusMessage *ret;
873 gboolean alter;
874
875 if (incoming)
876 alter = effects->alter_incoming;
877 else
878 alter = effects->alter_outgoing;
879
880 if (alter)
881 {
882 GDBusMessage *copy;
883 GVariant *body;
884 gchar *s;
885 gchar *s2;
886
887 copy = g_dbus_message_copy (message, NULL);
888 g_object_unref (message);
889
890 body = g_dbus_message_get_body (copy);
891 g_variant_get (body, "(s)", &s);
892 s2 = g_strdup_printf ("MOD: %s", s);
893 g_dbus_message_set_body (copy, g_variant_new ("(s)", s2));
894 g_free (s2);
895 g_free (s);
896
897 ret = copy;
898 }
899 else
900 {
901 ret = message;
902 }
903
904 return ret;
905 }
906
907 static void
test_connection_filter_name_owner_changed_signal_handler(GDBusConnection * connection,const gchar * sender_name,const gchar * object_path,const gchar * interface_name,const gchar * signal_name,GVariant * parameters,gpointer user_data)908 test_connection_filter_name_owner_changed_signal_handler (GDBusConnection *connection,
909 const gchar *sender_name,
910 const gchar *object_path,
911 const gchar *interface_name,
912 const gchar *signal_name,
913 GVariant *parameters,
914 gpointer user_data)
915 {
916 const gchar *name;
917 const gchar *old_owner;
918 const gchar *new_owner;
919
920 g_variant_get (parameters,
921 "(&s&s&s)",
922 &name,
923 &old_owner,
924 &new_owner);
925
926 if (g_strcmp0 (name, "com.example.TestService") == 0 && strlen (new_owner) > 0)
927 {
928 g_main_loop_quit (loop);
929 }
930 }
931
932 static gboolean
test_connection_filter_on_timeout(gpointer user_data)933 test_connection_filter_on_timeout (gpointer user_data)
934 {
935 g_printerr ("Timeout waiting 30 sec on service\n");
936 g_assert_not_reached ();
937 return G_SOURCE_REMOVE;
938 }
939
940 static void
test_connection_filter(void)941 test_connection_filter (void)
942 {
943 GDBusConnection *c;
944 FilterData data = { NULL, 0 };
945 GDBusMessage *m;
946 GDBusMessage *m2;
947 GDBusMessage *r;
948 GError *error;
949 guint filter_id;
950 guint timeout_mainloop_id;
951 guint signal_handler_id;
952 FilterEffects effects;
953 GVariant *result;
954 const gchar *s;
955 guint32 serial_temp;
956
957 session_bus_up ();
958
959 error = NULL;
960 c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
961 g_assert_no_error (error);
962 g_assert_nonnull (c);
963
964 data.incoming_queue = g_async_queue_new_full (g_object_unref);
965 data.num_outgoing = 0;
966 filter_id = g_dbus_connection_add_filter (c,
967 filter_func,
968 &data,
969 NULL);
970
971 m = g_dbus_message_new_method_call ("org.freedesktop.DBus", /* name */
972 "/org/freedesktop/DBus", /* path */
973 "org.freedesktop.DBus", /* interface */
974 "GetNameOwner");
975 g_dbus_message_set_body (m, g_variant_new ("(s)", "org.freedesktop.DBus"));
976 error = NULL;
977 g_dbus_connection_send_message (c, m, G_DBUS_SEND_MESSAGE_FLAGS_NONE, &serial_temp, &error);
978 g_assert_no_error (error);
979
980 wait_for_filtered_reply (data.incoming_queue, serial_temp);
981
982 m2 = g_dbus_message_copy (m, &error);
983 g_assert_no_error (error);
984 g_dbus_connection_send_message (c, m2, G_DBUS_SEND_MESSAGE_FLAGS_NONE, &serial_temp, &error);
985 g_object_unref (m2);
986 g_assert_no_error (error);
987
988 wait_for_filtered_reply (data.incoming_queue, serial_temp);
989
990 m2 = g_dbus_message_copy (m, &error);
991 g_assert_no_error (error);
992 g_dbus_message_set_serial (m2, serial_temp);
993 /* lock the message to test PRESERVE_SERIAL flag. */
994 g_dbus_message_lock (m2);
995 g_dbus_connection_send_message (c, m2, G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL, &serial_temp, &error);
996 g_object_unref (m2);
997 g_assert_no_error (error);
998
999 wait_for_filtered_reply (data.incoming_queue, serial_temp);
1000
1001 m2 = g_dbus_message_copy (m, &error);
1002 g_assert_no_error (error);
1003 r = g_dbus_connection_send_message_with_reply_sync (c,
1004 m2,
1005 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
1006 -1,
1007 &serial_temp,
1008 NULL, /* GCancellable */
1009 &error);
1010 g_object_unref (m2);
1011 g_assert_no_error (error);
1012 g_assert_nonnull (r);
1013 g_object_unref (r);
1014
1015 wait_for_filtered_reply (data.incoming_queue, serial_temp);
1016 g_assert_cmpint (g_async_queue_length (data.incoming_queue), ==, 0);
1017
1018 g_dbus_connection_remove_filter (c, filter_id);
1019
1020 m2 = g_dbus_message_copy (m, &error);
1021 g_assert_no_error (error);
1022 r = g_dbus_connection_send_message_with_reply_sync (c,
1023 m2,
1024 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
1025 -1,
1026 &serial_temp,
1027 NULL, /* GCancellable */
1028 &error);
1029 g_object_unref (m2);
1030 g_assert_no_error (error);
1031 g_assert_nonnull (r);
1032 g_object_unref (r);
1033 g_assert_cmpint (g_async_queue_length (data.incoming_queue), ==, 0);
1034 g_assert_cmpint (g_atomic_int_get (&data.num_outgoing), ==, 4);
1035
1036 /* wait for service to be available */
1037 signal_handler_id = g_dbus_connection_signal_subscribe (c,
1038 "org.freedesktop.DBus", /* sender */
1039 "org.freedesktop.DBus",
1040 "NameOwnerChanged",
1041 "/org/freedesktop/DBus",
1042 NULL, /* arg0 */
1043 G_DBUS_SIGNAL_FLAGS_NONE,
1044 test_connection_filter_name_owner_changed_signal_handler,
1045 NULL,
1046 NULL);
1047 g_assert_cmpint (signal_handler_id, !=, 0);
1048
1049 /* this is safe; testserver will exit once the bus goes away */
1050 g_assert_true (g_spawn_command_line_async (g_test_get_filename (G_TEST_BUILT, "gdbus-testserver", NULL), NULL));
1051
1052 timeout_mainloop_id = g_timeout_add (30000, test_connection_filter_on_timeout, NULL);
1053 g_main_loop_run (loop);
1054 g_source_remove (timeout_mainloop_id);
1055 g_dbus_connection_signal_unsubscribe (c, signal_handler_id);
1056
1057 /* now test some combinations... */
1058 filter_id = g_dbus_connection_add_filter (c,
1059 other_filter_func,
1060 &effects,
1061 NULL);
1062 /* -- */
1063 effects.alter_incoming = FALSE;
1064 effects.alter_outgoing = FALSE;
1065 error = NULL;
1066 result = g_dbus_connection_call_sync (c,
1067 "com.example.TestService", /* bus name */
1068 "/com/example/TestObject", /* object path */
1069 "com.example.Frob", /* interface name */
1070 "HelloWorld", /* method name */
1071 g_variant_new ("(s)", "Cat"), /* parameters */
1072 G_VARIANT_TYPE ("(s)"), /* return type */
1073 G_DBUS_CALL_FLAGS_NONE,
1074 -1,
1075 NULL,
1076 &error);
1077 g_assert_no_error (error);
1078 g_variant_get (result, "(&s)", &s);
1079 g_assert_cmpstr (s, ==, "You greeted me with 'Cat'. Thanks!");
1080 g_variant_unref (result);
1081 /* -- */
1082 effects.alter_incoming = TRUE;
1083 effects.alter_outgoing = TRUE;
1084 error = NULL;
1085 result = g_dbus_connection_call_sync (c,
1086 "com.example.TestService", /* bus name */
1087 "/com/example/TestObject", /* object path */
1088 "com.example.Frob", /* interface name */
1089 "HelloWorld", /* method name */
1090 g_variant_new ("(s)", "Cat"), /* parameters */
1091 G_VARIANT_TYPE ("(s)"), /* return type */
1092 G_DBUS_CALL_FLAGS_NONE,
1093 -1,
1094 NULL,
1095 &error);
1096 g_assert_no_error (error);
1097 g_variant_get (result, "(&s)", &s);
1098 g_assert_cmpstr (s, ==, "MOD: You greeted me with 'MOD: Cat'. Thanks!");
1099 g_variant_unref (result);
1100
1101
1102 g_dbus_connection_remove_filter (c, filter_id);
1103
1104 g_object_unref (c);
1105 g_object_unref (m);
1106 g_async_queue_unref (data.incoming_queue);
1107
1108 session_bus_down ();
1109 }
1110
1111 /* ---------------------------------------------------------------------------------------------------- */
1112
1113 #define NUM_THREADS 50
1114
1115 static void
send_bogus_message(GDBusConnection * c,guint32 * out_serial)1116 send_bogus_message (GDBusConnection *c, guint32 *out_serial)
1117 {
1118 GDBusMessage *m;
1119 GError *error;
1120
1121 m = g_dbus_message_new_method_call ("org.freedesktop.DBus", /* name */
1122 "/org/freedesktop/DBus", /* path */
1123 "org.freedesktop.DBus", /* interface */
1124 "GetNameOwner");
1125 g_dbus_message_set_body (m, g_variant_new ("(s)", "org.freedesktop.DBus"));
1126 error = NULL;
1127 g_dbus_connection_send_message (c, m, G_DBUS_SEND_MESSAGE_FLAGS_NONE, out_serial, &error);
1128 g_assert_no_error (error);
1129 g_object_unref (m);
1130 }
1131
1132 #define SLEEP_USEC (100 * 1000)
1133
1134 static gpointer
serials_thread_func(GDBusConnection * c)1135 serials_thread_func (GDBusConnection *c)
1136 {
1137 guint32 message_serial;
1138 guint i;
1139
1140 /* No calls on this thread yet */
1141 g_assert_cmpint (g_dbus_connection_get_last_serial(c), ==, 0);
1142
1143 /* Send a bogus message and store its serial */
1144 message_serial = 0;
1145 send_bogus_message (c, &message_serial);
1146
1147 /* Give it some time to actually send the message out. 10 seconds
1148 * should be plenty, even on slow machines. */
1149 for (i = 0; i < 10 * G_USEC_PER_SEC / SLEEP_USEC; i++)
1150 {
1151 if (g_dbus_connection_get_last_serial(c) != 0)
1152 break;
1153
1154 g_usleep (SLEEP_USEC);
1155 }
1156
1157 g_assert_cmpint (g_dbus_connection_get_last_serial(c), !=, 0);
1158 g_assert_cmpint (g_dbus_connection_get_last_serial(c), ==, message_serial);
1159
1160 return NULL;
1161 }
1162
1163 static void
test_connection_serials(void)1164 test_connection_serials (void)
1165 {
1166 GDBusConnection *c;
1167 GError *error;
1168 GThread *pool[NUM_THREADS];
1169 int i;
1170
1171 session_bus_up ();
1172
1173 error = NULL;
1174 c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
1175 g_assert_no_error (error);
1176 g_assert_nonnull (c);
1177
1178 /* Status after initialization */
1179 g_assert_cmpint (g_dbus_connection_get_last_serial (c), ==, 1);
1180
1181 /* Send a bogus message */
1182 send_bogus_message (c, NULL);
1183 g_assert_cmpint (g_dbus_connection_get_last_serial (c), ==, 2);
1184
1185 /* Start the threads */
1186 for (i = 0; i < NUM_THREADS; i++)
1187 pool[i] = g_thread_new (NULL, (GThreadFunc) serials_thread_func, c);
1188
1189 /* Wait until threads are finished */
1190 for (i = 0; i < NUM_THREADS; i++)
1191 g_thread_join (pool[i]);
1192
1193 /* No calls in between on this thread, should be the last value */
1194 g_assert_cmpint (g_dbus_connection_get_last_serial (c), ==, 2);
1195
1196 send_bogus_message (c, NULL);
1197
1198 /* All above calls + calls in threads */
1199 g_assert_cmpint (g_dbus_connection_get_last_serial (c), ==, 3 + NUM_THREADS);
1200
1201 g_object_unref (c);
1202
1203 session_bus_down ();
1204 }
1205
1206 /* ---------------------------------------------------------------------------------------------------- */
1207
1208 static void
test_connection_basic(void)1209 test_connection_basic (void)
1210 {
1211 GDBusConnection *connection;
1212 GError *error;
1213 GDBusCapabilityFlags flags;
1214 GDBusConnectionFlags connection_flags;
1215 gchar *guid;
1216 gchar *name;
1217 gboolean closed;
1218 gboolean exit_on_close;
1219 GIOStream *stream;
1220 GCredentials *credentials;
1221
1222 session_bus_up ();
1223
1224 error = NULL;
1225 connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
1226 g_assert_no_error (error);
1227 g_assert_nonnull (connection);
1228
1229 flags = g_dbus_connection_get_capabilities (connection);
1230 g_assert_true (flags == G_DBUS_CAPABILITY_FLAGS_NONE ||
1231 flags == G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING);
1232
1233 connection_flags = g_dbus_connection_get_flags (connection);
1234 g_assert_cmpint (connection_flags, ==,
1235 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
1236 G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION);
1237
1238 credentials = g_dbus_connection_get_peer_credentials (connection);
1239 g_assert_null (credentials);
1240
1241 g_object_get (connection,
1242 "stream", &stream,
1243 "guid", &guid,
1244 "unique-name", &name,
1245 "closed", &closed,
1246 "exit-on-close", &exit_on_close,
1247 "capabilities", &flags,
1248 NULL);
1249
1250 g_assert_true (G_IS_IO_STREAM (stream));
1251 g_assert_true (g_dbus_is_guid (guid));
1252 g_assert_true (g_dbus_is_unique_name (name));
1253 g_assert_false (closed);
1254 g_assert_true (exit_on_close);
1255 g_assert_true (flags == G_DBUS_CAPABILITY_FLAGS_NONE ||
1256 flags == G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING);
1257 g_object_unref (stream);
1258 g_free (name);
1259 g_free (guid);
1260
1261 g_object_unref (connection);
1262
1263 session_bus_down ();
1264 }
1265
1266 /* ---------------------------------------------------------------------------------------------------- */
1267
1268 int
main(int argc,char * argv[])1269 main (int argc,
1270 char *argv[])
1271 {
1272 int ret;
1273
1274 g_test_init (&argc, &argv, NULL);
1275
1276 /* all the tests rely on a shared main loop */
1277 loop = g_main_loop_new (NULL, FALSE);
1278
1279 g_test_dbus_unset ();
1280
1281 /* gdbus cleanup is pretty racy due to worker threads, so always do this test first */
1282 g_test_add_func ("/gdbus/connection/bus-failure", test_connection_bus_failure);
1283
1284 g_test_add_func ("/gdbus/connection/basic", test_connection_basic);
1285 g_test_add_func ("/gdbus/connection/life-cycle", test_connection_life_cycle);
1286 g_test_add_func ("/gdbus/connection/send", test_connection_send);
1287 g_test_add_func ("/gdbus/connection/signals", test_connection_signals);
1288 g_test_add_func ("/gdbus/connection/signal-match-rules", test_connection_signal_match_rules);
1289 g_test_add_func ("/gdbus/connection/filter", test_connection_filter);
1290 g_test_add_func ("/gdbus/connection/serials", test_connection_serials);
1291 ret = g_test_run();
1292
1293 g_main_loop_unref (loop);
1294 return ret;
1295 }
1296