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