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 */
30static GMainLoop *loop = NULL;
31
32#if 0
33G_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
61static gboolean
62test_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
75static 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
85static 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. */
93static GDBusMessage *
94some_filter_func (GDBusConnection *connection,
95 GDBusMessage *message,
96 gboolean incoming,
97 gpointer user_data)
98{
99 return message;
100}
101
102static void
103on_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
113static void
114a_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
122static void
123test_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 (bus_type: G_BUS_TYPE_SESSION, NULL, error: &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
139static void
140test_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 (bus_type: G_BUS_TYPE_SESSION, NULL, error: &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 (bus_type: G_BUS_TYPE_SESSION, NULL, error: &error);
171 g_assert_no_error (error);
172 g_assert_nonnull (c2);
173 g_assert_true (c == c2);
174 g_object_unref (object: c2);
175
176 /*
177 * Check that private connections work
178 */
179 c2 = _g_bus_get_priv (bus_type: G_BUS_TYPE_SESSION, NULL, error: &error);
180 g_assert_no_error (error);
181 g_assert_nonnull (c2);
182 g_assert_true (c != c2);
183 g_object_unref (object: c2);
184
185 c2 = _g_bus_get_priv (bus_type: G_BUS_TYPE_SESSION, NULL, error: &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 (connection: c2, NULL, error: &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 (connection: c2, NULL, error: &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 (object: 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 (bus_type: G_BUS_TYPE_SESSION, NULL, error: &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 (connection: c2,
213 sender: "org.freedesktop.DBus", /* bus name */
214 interface_name: "org.freedesktop.DBus", /* interface */
215 member: "NameOwnerChanged", /* member */
216 object_path: "/org/freesktop/DBus", /* path */
217 NULL, /* arg0 */
218 flags: G_DBUS_SIGNAL_FLAGS_NONE,
219 callback: on_name_owner_changed,
220 user_data: (gpointer) &on_signal_registration_freed_called,
221 user_data_free_func: 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 (connection: c2,
225 filter_function: some_filter_func,
226 user_data: (gpointer) &on_filter_freed_called,
227 user_data_free_func: 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 (connection: c2,
232 object_path: "/foo",
233 interface_info: (GDBusInterfaceInfo *) &boo_interface_info,
234 vtable: &boo_vtable,
235 user_data: (gpointer) &on_register_object_freed_called,
236 user_data_free_func: a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop,
237 error: &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 (object: c2);
242 g_atomic_int_set (&quit_mainloop_fired, FALSE);
243 quit_mainloop_id = g_timeout_add (interval: 30000, function: test_connection_quit_mainloop, data: (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 (tag: 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 (connection: 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 (object: c);
279
280 session_bus_down ();
281}
282
283/* ---------------------------------------------------------------------------------------------------- */
284/* Test that sending and receiving messages work as expected */
285/* ---------------------------------------------------------------------------------------------------- */
286
287static void
288msg_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: &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
310static void
311msg_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: &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
333static void
334msg_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: &error);
348 g_assert_no_error (error);
349 g_assert_nonnull (result);
350 g_variant_unref (value: result);
351
352 g_main_loop_quit (loop);
353}
354
355static void
356msg_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: &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
378static void
379msg_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: &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
403static void
404test_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 (bus_type: 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 (cancellable: ca);
423 g_dbus_connection_call (connection: c,
424 bus_name: "org.freedesktop.DBus", /* bus_name */
425 object_path: "/org/freedesktop/DBus", /* object path */
426 interface_name: "org.freedesktop.DBus", /* interface name */
427 method_name: "GetId", /* method name */
428 NULL, NULL,
429 flags: G_DBUS_CALL_FLAGS_NONE,
430 timeout_msec: -1,
431 cancellable: ca,
432 callback: (GAsyncReadyCallback) msg_cb_expect_error_cancelled,
433 NULL);
434 g_main_loop_run (loop);
435 g_object_unref (object: ca);
436
437 /*
438 * Check that we get a reply to the GetId() method call.
439 */
440 g_dbus_connection_call (connection: c,
441 bus_name: "org.freedesktop.DBus", /* bus_name */
442 object_path: "/org/freedesktop/DBus", /* object path */
443 interface_name: "org.freedesktop.DBus", /* interface name */
444 method_name: "GetId", /* method name */
445 NULL, NULL,
446 flags: G_DBUS_CALL_FLAGS_NONE,
447 timeout_msec: -1,
448 NULL,
449 callback: (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 (connection: c,
457 bus_name: "org.freedesktop.DBus", /* bus_name */
458 object_path: "/org/freedesktop/DBus", /* object path */
459 interface_name: "org.freedesktop.DBus", /* interface name */
460 method_name: "NonExistantMethod", /* method name */
461 NULL, NULL,
462 flags: G_DBUS_CALL_FLAGS_NONE,
463 timeout_msec: -1,
464 NULL,
465 callback: (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 (connection: c,
474 bus_name: "org.freedesktop.DBus", /* bus_name */
475 object_path: "/org/freedesktop/DBus", /* object path */
476 interface_name: "org.freedesktop.DBus", /* interface name */
477 method_name: "GetId", /* method name */
478 NULL, NULL,
479 flags: G_DBUS_CALL_FLAGS_NONE,
480 timeout_msec: -1,
481 cancellable: ca,
482 callback: (GAsyncReadyCallback) msg_cb_expect_error_cancelled_2,
483 NULL);
484 g_cancellable_cancel (cancellable: ca);
485 g_main_loop_run (loop);
486 g_object_unref (object: 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 (connection: 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 (connection: c,
497 bus_name: "org.freedesktop.DBus", /* bus_name */
498 object_path: "/org/freedesktop/DBus", /* object path */
499 interface_name: "org.freedesktop.DBus", /* interface name */
500 method_name: "GetId", /* method name */
501 NULL, NULL,
502 flags: G_DBUS_CALL_FLAGS_NONE,
503 timeout_msec: -1,
504 NULL,
505 callback: (GAsyncReadyCallback) msg_cb_expect_error_disconnected,
506 NULL);
507 g_main_loop_run (loop);
508
509 g_object_unref (object: c);
510
511 session_bus_down ();
512}
513
514/* ---------------------------------------------------------------------------------------------------- */
515/* Connection signal tests */
516/* ---------------------------------------------------------------------------------------------------- */
517
518static void
519test_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
539static void
540test_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 (variable: "G_DBUS_MONITOR") == NULL)
569 {
570 c1 = _g_bus_get_priv (bus_type: 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 (object: c1);
574 }
575 c1 = g_bus_get_sync (bus_type: 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 (connection: c1,
589 sender: ":1.2",
590 interface_name: "org.gtk.GDBus.ExampleInterface",
591 member: "Foo",
592 object_path: "/org/gtk/GDBus/ExampleInterface",
593 NULL,
594 flags: G_DBUS_SIGNAL_FLAGS_NONE,
595 callback: test_connection_signal_handler,
596 user_data: &count_s1,
597 NULL);
598 s2 = g_dbus_connection_signal_subscribe (connection: c1,
599 NULL, /* match any sender */
600 interface_name: "org.gtk.GDBus.ExampleInterface",
601 member: "Foo",
602 object_path: "/org/gtk/GDBus/ExampleInterface",
603 NULL,
604 flags: G_DBUS_SIGNAL_FLAGS_NONE,
605 callback: test_connection_signal_handler,
606 user_data: &count_s2,
607 NULL);
608 s3 = g_dbus_connection_signal_subscribe (connection: c1,
609 sender: "org.freedesktop.DBus", /* sender */
610 interface_name: "org.freedesktop.DBus", /* interface */
611 member: "NameOwnerChanged", /* member */
612 object_path: "/org/freedesktop/DBus", /* path */
613 NULL,
614 flags: G_DBUS_SIGNAL_FLAGS_NONE,
615 callback: test_connection_signal_handler,
616 user_data: &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 (connection: c1,
623 sender: ":1.2",
624 interface_name: "org.gtk.GDBus.ExampleInterface",
625 member: "Foo",
626 object_path: "/org/gtk/GDBus/ExampleInterface",
627 NULL,
628 flags: G_DBUS_SIGNAL_FLAGS_NONE,
629 callback: test_connection_signal_handler,
630 user_data: &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 (connection: c1,
654 bus_name: "org.freedesktop.DBus", /* bus name */
655 object_path: "/org/freedesktop/DBus", /* object path */
656 interface_name: "org.freedesktop.DBus", /* interface name */
657 method_name: "GetId", /* method name */
658 NULL, /* parameters */
659 NULL, /* return type */
660 flags: G_DBUS_CALL_FLAGS_NONE,
661 timeout_msec: -1,
662 NULL,
663 error: &error);
664 g_assert_no_error (error);
665 g_assert_nonnull (result);
666 g_variant_unref (value: result);
667
668 /*
669 * Bring up two other connections
670 */
671 c2 = _g_bus_get_priv (bus_type: 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 (bus_type: 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 (connection: c2,
682 NULL, /* destination bus name */
683 object_path: "/org/gtk/GDBus/ExampleInterface",
684 interface_name: "org.gtk.GDBus.ExampleInterface",
685 signal_name: "Foo",
686 NULL,
687 error: &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 (connection: c3,
699 NULL, /* destination bus name */
700 object_path: "/org/gtk/GDBus/ExampleInterface",
701 interface_name: "org.gtk.GDBus.ExampleInterface",
702 signal_name: "Foo",
703 NULL,
704 error: &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 (interval: 30000, function: test_connection_quit_mainloop, data: &quit_mainloop_fired);
718 while (count_name_owner_changed < 2 && !quit_mainloop_fired)
719 g_main_loop_run (loop);
720 g_source_remove (tag: 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 (connection: c1, subscription_id: s1);
726 g_dbus_connection_signal_unsubscribe (connection: c1, subscription_id: s2);
727 g_dbus_connection_signal_unsubscribe (connection: c1, subscription_id: s3);
728 g_dbus_connection_signal_unsubscribe (connection: c1, subscription_id: s1b);
729
730 g_object_unref (object: c1);
731 g_object_unref (object: c2);
732 g_object_unref (object: c3);
733
734 session_bus_down ();
735}
736
737static void
738test_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, interface_name: "org.gtk.ExampleInterface", member: "Foo", object_path: "/",
751 NULL,
752 flags: G_DBUS_SIGNAL_FLAGS_NONE,
753 callback: test_connection_signal_handler,
754 user_data: &emissions, NULL);
755 subscription_ids[1] = g_dbus_connection_signal_subscribe (connection,
756 NULL, interface_name: "org.gtk.ExampleInterface", member: "Foo", object_path: "/",
757 arg0: arg0_rule,
758 flags,
759 callback: test_connection_signal_handler,
760 user_data: &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, object_path: "/", interface_name: "org.gtk.ExampleInterface",
766 signal_name: "Foo", parameters: g_variant_new (format_string: "(s)", arg0),
767 error: &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, bus_name: "org.gtk.ExampleInterface", object_path: "/", interface_name: "org.gtk.ExampleInterface",
772 method_name: "Bar", parameters: g_variant_new (format_string: "()"), G_VARIANT_TYPE_UNIT, flags: G_DBUS_CALL_FLAGS_NONE,
773 timeout_msec: -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_id: subscription_ids[0]);
782 g_dbus_connection_signal_unsubscribe (connection, subscription_id: subscription_ids[1]);
783}
784
785static void
786test_connection_signal_match_rules (void)
787{
788 GDBusConnection *con;
789
790 session_bus_up ();
791 con = g_bus_get_sync (bus_type: G_BUS_TYPE_SESSION, NULL, NULL);
792
793 test_match_rule (connection: con, flags: G_DBUS_SIGNAL_FLAGS_NONE, arg0_rule: "foo", arg0: "foo", TRUE);
794 test_match_rule (connection: con, flags: G_DBUS_SIGNAL_FLAGS_NONE, arg0_rule: "foo", arg0: "bar", FALSE);
795
796 test_match_rule (connection: con, flags: G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, arg0_rule: "org.gtk", arg0: "", FALSE);
797 test_match_rule (connection: con, flags: G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, arg0_rule: "org.gtk", arg0: "org", FALSE);
798 test_match_rule (connection: con, flags: G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, arg0_rule: "org.gtk", arg0: "org.gtk", TRUE);
799 test_match_rule (connection: con, flags: G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, arg0_rule: "org.gtk", arg0: "org.gtk.Example", TRUE);
800 test_match_rule (connection: con, flags: G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, arg0_rule: "org.gtk", arg0: "org.gtk+", FALSE);
801
802 test_match_rule (connection: con, flags: G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, arg0_rule: "/", arg0: "/", TRUE);
803 test_match_rule (connection: con, flags: G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, arg0_rule: "/", arg0: "", FALSE);
804 test_match_rule (connection: con, flags: G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, arg0_rule: "/org/gtk/Example", arg0: "/org/gtk/Example", TRUE);
805 test_match_rule (connection: con, flags: G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, arg0_rule: "/org/gtk/", arg0: "/org/gtk/Example", TRUE);
806 test_match_rule (connection: con, flags: G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, arg0_rule: "/org/gtk/Example", arg0: "/org/gtk/", TRUE);
807 test_match_rule (connection: con, flags: G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, arg0_rule: "/org/gtk/Example", arg0: "/org/gtk", FALSE);
808 test_match_rule (connection: con, flags: G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, arg0_rule: "/org/gtk+", arg0: "/org/gtk", FALSE);
809
810 g_object_unref (object: 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. */
818typedef struct
819{
820 GAsyncQueue *incoming_queue; /* (element-type GDBusMessage) */
821 guint num_outgoing; /* (atomic) */
822} FilterData;
823
824/* Runs in a worker thread. */
825static GDBusMessage *
826filter_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 (queue: data->incoming_queue, g_object_ref (message));
835 else
836 g_atomic_int_inc (&data->num_outgoing);
837
838 return message;
839}
840
841static void
842wait_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 (queue: incoming_queue)) != NULL)
848 {
849 guint32 reply_serial = g_dbus_message_get_reply_serial (message: popped_message);
850 g_object_unref (object: popped_message);
851 if (reply_serial == expected_serial)
852 return;
853 }
854
855 g_assert_not_reached ();
856}
857
858typedef struct
859{
860 gboolean alter_incoming;
861 gboolean alter_outgoing;
862} FilterEffects;
863
864/* Runs in a worker thread. */
865static GDBusMessage *
866other_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 (object: message);
889
890 body = g_dbus_message_get_body (message: copy);
891 g_variant_get (value: body, format_string: "(s)", &s);
892 s2 = g_strdup_printf (format: "MOD: %s", s);
893 g_dbus_message_set_body (message: copy, body: g_variant_new (format_string: "(s)", s2));
894 g_free (mem: s2);
895 g_free (mem: s);
896
897 ret = copy;
898 }
899 else
900 {
901 ret = message;
902 }
903
904 return ret;
905}
906
907static void
908test_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 (value: parameters,
921 format_string: "(&s&s&s)",
922 &name,
923 &old_owner,
924 &new_owner);
925
926 if (g_strcmp0 (str1: name, str2: "com.example.TestService") == 0 && strlen (s: new_owner) > 0)
927 {
928 g_main_loop_quit (loop);
929 }
930}
931
932static gboolean
933test_connection_filter_on_timeout (gpointer user_data)
934{
935 g_printerr (format: "Timeout waiting 30 sec on service\n");
936 g_assert_not_reached ();
937 return G_SOURCE_REMOVE;
938}
939
940static void
941test_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 (bus_type: G_BUS_TYPE_SESSION, NULL, error: &error);
961 g_assert_no_error (error);
962 g_assert_nonnull (c);
963
964 data.incoming_queue = g_async_queue_new_full (item_free_func: g_object_unref);
965 data.num_outgoing = 0;
966 filter_id = g_dbus_connection_add_filter (connection: c,
967 filter_function: filter_func,
968 user_data: &data,
969 NULL);
970
971 m = g_dbus_message_new_method_call (name: "org.freedesktop.DBus", /* name */
972 path: "/org/freedesktop/DBus", /* path */
973 interface_: "org.freedesktop.DBus", /* interface */
974 method: "GetNameOwner");
975 g_dbus_message_set_body (message: m, body: g_variant_new (format_string: "(s)", "org.freedesktop.DBus"));
976 error = NULL;
977 g_dbus_connection_send_message (connection: c, message: m, flags: G_DBUS_SEND_MESSAGE_FLAGS_NONE, out_serial: &serial_temp, error: &error);
978 g_assert_no_error (error);
979
980 wait_for_filtered_reply (incoming_queue: data.incoming_queue, expected_serial: serial_temp);
981
982 m2 = g_dbus_message_copy (message: m, error: &error);
983 g_assert_no_error (error);
984 g_dbus_connection_send_message (connection: c, message: m2, flags: G_DBUS_SEND_MESSAGE_FLAGS_NONE, out_serial: &serial_temp, error: &error);
985 g_object_unref (object: m2);
986 g_assert_no_error (error);
987
988 wait_for_filtered_reply (incoming_queue: data.incoming_queue, expected_serial: serial_temp);
989
990 m2 = g_dbus_message_copy (message: m, error: &error);
991 g_assert_no_error (error);
992 g_dbus_message_set_serial (message: m2, serial: serial_temp);
993 /* lock the message to test PRESERVE_SERIAL flag. */
994 g_dbus_message_lock (message: m2);
995 g_dbus_connection_send_message (connection: c, message: m2, flags: G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL, out_serial: &serial_temp, error: &error);
996 g_object_unref (object: m2);
997 g_assert_no_error (error);
998
999 wait_for_filtered_reply (incoming_queue: data.incoming_queue, expected_serial: serial_temp);
1000
1001 m2 = g_dbus_message_copy (message: m, error: &error);
1002 g_assert_no_error (error);
1003 r = g_dbus_connection_send_message_with_reply_sync (connection: c,
1004 message: m2,
1005 flags: G_DBUS_SEND_MESSAGE_FLAGS_NONE,
1006 timeout_msec: -1,
1007 out_serial: &serial_temp,
1008 NULL, /* GCancellable */
1009 error: &error);
1010 g_object_unref (object: m2);
1011 g_assert_no_error (error);
1012 g_assert_nonnull (r);
1013 g_object_unref (object: r);
1014
1015 wait_for_filtered_reply (incoming_queue: data.incoming_queue, expected_serial: serial_temp);
1016 g_assert_cmpint (g_async_queue_length (data.incoming_queue), ==, 0);
1017
1018 g_dbus_connection_remove_filter (connection: c, filter_id);
1019
1020 m2 = g_dbus_message_copy (message: m, error: &error);
1021 g_assert_no_error (error);
1022 r = g_dbus_connection_send_message_with_reply_sync (connection: c,
1023 message: m2,
1024 flags: G_DBUS_SEND_MESSAGE_FLAGS_NONE,
1025 timeout_msec: -1,
1026 out_serial: &serial_temp,
1027 NULL, /* GCancellable */
1028 error: &error);
1029 g_object_unref (object: m2);
1030 g_assert_no_error (error);
1031 g_assert_nonnull (r);
1032 g_object_unref (object: 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 (connection: c,
1038 sender: "org.freedesktop.DBus", /* sender */
1039 interface_name: "org.freedesktop.DBus",
1040 member: "NameOwnerChanged",
1041 object_path: "/org/freedesktop/DBus",
1042 NULL, /* arg0 */
1043 flags: G_DBUS_SIGNAL_FLAGS_NONE,
1044 callback: 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 (interval: 30000, function: test_connection_filter_on_timeout, NULL);
1053 g_main_loop_run (loop);
1054 g_source_remove (tag: timeout_mainloop_id);
1055 g_dbus_connection_signal_unsubscribe (connection: c, subscription_id: signal_handler_id);
1056
1057 /* now test some combinations... */
1058 filter_id = g_dbus_connection_add_filter (connection: c,
1059 filter_function: other_filter_func,
1060 user_data: &effects,
1061 NULL);
1062 /* -- */
1063 effects.alter_incoming = FALSE;
1064 effects.alter_outgoing = FALSE;
1065 error = NULL;
1066 result = g_dbus_connection_call_sync (connection: c,
1067 bus_name: "com.example.TestService", /* bus name */
1068 object_path: "/com/example/TestObject", /* object path */
1069 interface_name: "com.example.Frob", /* interface name */
1070 method_name: "HelloWorld", /* method name */
1071 parameters: g_variant_new (format_string: "(s)", "Cat"), /* parameters */
1072 G_VARIANT_TYPE ("(s)"), /* return type */
1073 flags: G_DBUS_CALL_FLAGS_NONE,
1074 timeout_msec: -1,
1075 NULL,
1076 error: &error);
1077 g_assert_no_error (error);
1078 g_variant_get (value: result, format_string: "(&s)", &s);
1079 g_assert_cmpstr (s, ==, "You greeted me with 'Cat'. Thanks!");
1080 g_variant_unref (value: result);
1081 /* -- */
1082 effects.alter_incoming = TRUE;
1083 effects.alter_outgoing = TRUE;
1084 error = NULL;
1085 result = g_dbus_connection_call_sync (connection: c,
1086 bus_name: "com.example.TestService", /* bus name */
1087 object_path: "/com/example/TestObject", /* object path */
1088 interface_name: "com.example.Frob", /* interface name */
1089 method_name: "HelloWorld", /* method name */
1090 parameters: g_variant_new (format_string: "(s)", "Cat"), /* parameters */
1091 G_VARIANT_TYPE ("(s)"), /* return type */
1092 flags: G_DBUS_CALL_FLAGS_NONE,
1093 timeout_msec: -1,
1094 NULL,
1095 error: &error);
1096 g_assert_no_error (error);
1097 g_variant_get (value: result, format_string: "(&s)", &s);
1098 g_assert_cmpstr (s, ==, "MOD: You greeted me with 'MOD: Cat'. Thanks!");
1099 g_variant_unref (value: result);
1100
1101
1102 g_dbus_connection_remove_filter (connection: c, filter_id);
1103
1104 g_object_unref (object: c);
1105 g_object_unref (object: m);
1106 g_async_queue_unref (queue: data.incoming_queue);
1107
1108 session_bus_down ();
1109}
1110
1111/* ---------------------------------------------------------------------------------------------------- */
1112
1113#define NUM_THREADS 50
1114
1115static void
1116send_bogus_message (GDBusConnection *c, guint32 *out_serial)
1117{
1118 GDBusMessage *m;
1119 GError *error;
1120
1121 m = g_dbus_message_new_method_call (name: "org.freedesktop.DBus", /* name */
1122 path: "/org/freedesktop/DBus", /* path */
1123 interface_: "org.freedesktop.DBus", /* interface */
1124 method: "GetNameOwner");
1125 g_dbus_message_set_body (message: m, body: g_variant_new (format_string: "(s)", "org.freedesktop.DBus"));
1126 error = NULL;
1127 g_dbus_connection_send_message (connection: c, message: m, flags: G_DBUS_SEND_MESSAGE_FLAGS_NONE, out_serial, error: &error);
1128 g_assert_no_error (error);
1129 g_object_unref (object: m);
1130}
1131
1132#define SLEEP_USEC (100 * 1000)
1133
1134static gpointer
1135serials_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, out_serial: &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(connection: 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
1163static void
1164test_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 (bus_type: G_BUS_TYPE_SESSION, NULL, error: &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, func: (GThreadFunc) serials_thread_func, data: c);
1188
1189 /* Wait until threads are finished */
1190 for (i = 0; i < NUM_THREADS; i++)
1191 g_thread_join (thread: 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 (object: c);
1202
1203 session_bus_down ();
1204}
1205
1206/* ---------------------------------------------------------------------------------------------------- */
1207
1208static void
1209test_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 (bus_type: G_BUS_TYPE_SESSION, NULL, error: &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 (object: connection,
1242 first_property_name: "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 (object: stream);
1258 g_free (mem: name);
1259 g_free (mem: guid);
1260
1261 g_object_unref (object: connection);
1262
1263 session_bus_down ();
1264}
1265
1266/* ---------------------------------------------------------------------------------------------------- */
1267
1268int
1269main (int argc,
1270 char *argv[])
1271{
1272 int ret;
1273
1274 g_test_init (argc: &argc, argv: &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 (testpath: "/gdbus/connection/bus-failure", test_func: test_connection_bus_failure);
1283
1284 g_test_add_func (testpath: "/gdbus/connection/basic", test_func: test_connection_basic);
1285 g_test_add_func (testpath: "/gdbus/connection/life-cycle", test_func: test_connection_life_cycle);
1286 g_test_add_func (testpath: "/gdbus/connection/send", test_func: test_connection_send);
1287 g_test_add_func (testpath: "/gdbus/connection/signals", test_func: test_connection_signals);
1288 g_test_add_func (testpath: "/gdbus/connection/signal-match-rules", test_func: test_connection_signal_match_rules);
1289 g_test_add_func (testpath: "/gdbus/connection/filter", test_func: test_connection_filter);
1290 g_test_add_func (testpath: "/gdbus/connection/serials", test_func: test_connection_serials);
1291 ret = g_test_run();
1292
1293 g_main_loop_unref (loop);
1294 return ret;
1295}
1296

source code of gtk/subprojects/glib/gio/tests/gdbus-connection.c