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