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