GDBus: Nuke G_BUS_TYPE_NONE
[platform/upstream/glib.git] / gio / tests / gdbus-peer.c
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 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, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: David Zeuthen <davidz@redhat.com>
21  */
22
23 #include <gio/gio.h>
24 #include <unistd.h>
25 #include <string.h>
26
27 /* for open(2) */
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31
32 #include <gio/gunixsocketaddress.h>
33
34 #include "gdbus-tests.h"
35
36
37 #ifdef G_OS_UNIX
38 static gboolean is_unix = TRUE;
39 #else
40 static gboolean is_unix = FALSE;
41 #endif
42
43 static gchar *test_guid = NULL;
44 static GMainLoop *service_loop = NULL;
45 static GDBusServer *server = NULL;
46 static GMainLoop *loop = NULL;
47
48 /* ---------------------------------------------------------------------------------------------------- */
49 /* Test that peer-to-peer connections work */
50 /* ---------------------------------------------------------------------------------------------------- */
51
52
53 typedef struct
54 {
55   gboolean accept_connection;
56   gint num_connection_attempts;
57   GPtrArray *current_connections;
58   guint num_method_calls;
59   gboolean signal_received;
60 } PeerData;
61
62 static const gchar *test_interface_introspection_xml =
63   "<node>"
64   "  <interface name='org.gtk.GDBus.PeerTestInterface'>"
65   "    <method name='HelloPeer'>"
66   "      <arg type='s' name='greeting' direction='in'/>"
67   "      <arg type='s' name='response' direction='out'/>"
68   "    </method>"
69   "    <method name='EmitSignal'/>"
70   "    <method name='OpenFile'>"
71   "      <arg type='s' name='path' direction='in'/>"
72   "    </method>"
73   "    <signal name='PeerSignal'>"
74   "      <arg type='s' name='a_string'/>"
75   "    </signal>"
76   "    <property type='s' name='PeerProperty' access='read'/>"
77   "  </interface>"
78   "</node>";
79 static const GDBusInterfaceInfo *test_interface_introspection_data = NULL;
80
81 static void
82 test_interface_method_call (GDBusConnection       *connection,
83                             const gchar           *sender,
84                             const gchar           *object_path,
85                             const gchar           *interface_name,
86                             const gchar           *method_name,
87                             GVariant              *parameters,
88                             GDBusMethodInvocation *invocation,
89                             gpointer               user_data)
90 {
91   PeerData *data = user_data;
92
93   data->num_method_calls++;
94
95   g_assert_cmpstr (object_path, ==, "/org/gtk/GDBus/PeerTestObject");
96   g_assert_cmpstr (interface_name, ==, "org.gtk.GDBus.PeerTestInterface");
97
98   if (g_strcmp0 (method_name, "HelloPeer") == 0)
99     {
100       const gchar *greeting;
101       gchar *response;
102
103       g_variant_get (parameters, "(s)", &greeting);
104
105       response = g_strdup_printf ("You greeted me with '%s'.",
106                                   greeting);
107       g_dbus_method_invocation_return_value (invocation,
108                                              g_variant_new ("(s)", response));
109       g_free (response);
110     }
111   else if (g_strcmp0 (method_name, "EmitSignal") == 0)
112     {
113       GError *error;
114
115       error = NULL;
116       g_dbus_connection_emit_signal (connection,
117                                      NULL,
118                                      "/org/gtk/GDBus/PeerTestObject",
119                                      "org.gtk.GDBus.PeerTestInterface",
120                                      "PeerSignal",
121                                      NULL,
122                                      &error);
123       g_assert_no_error (error);
124       g_dbus_method_invocation_return_value (invocation, NULL);
125     }
126   else if (g_strcmp0 (method_name, "OpenFile") == 0)
127     {
128       const gchar *path;
129       GDBusMessage *reply;
130       GError *error;
131       gint fd;
132       GUnixFDList *fd_list;
133
134       g_variant_get (parameters, "(s)", &path);
135
136       fd_list = g_unix_fd_list_new ();
137
138       error = NULL;
139
140       fd = open (path, O_RDONLY);
141       g_unix_fd_list_append (fd_list, fd, &error);
142       g_assert_no_error (error);
143       close (fd);
144
145       reply = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation));
146       g_dbus_message_set_unix_fd_list (reply, fd_list);
147       g_object_unref (invocation);
148
149       error = NULL;
150       g_dbus_connection_send_message (connection,
151                                       reply,
152                                       NULL, /* out_serial */
153                                       &error);
154       g_assert_no_error (error);
155       g_object_unref (reply);
156     }
157   else
158     {
159       g_assert_not_reached ();
160     }
161 }
162
163 static GVariant *
164 test_interface_get_property (GDBusConnection  *connection,
165                              const gchar      *sender,
166                              const gchar      *object_path,
167                              const gchar      *interface_name,
168                              const gchar      *property_name,
169                              GError          **error,
170                              gpointer          user_data)
171 {
172   g_assert_cmpstr (object_path, ==, "/org/gtk/GDBus/PeerTestObject");
173   g_assert_cmpstr (interface_name, ==, "org.gtk.GDBus.PeerTestInterface");
174   g_assert_cmpstr (property_name, ==, "PeerProperty");
175
176   return g_variant_new_string ("ThePropertyValue");
177 }
178
179
180 static const GDBusInterfaceVTable test_interface_vtable =
181 {
182   test_interface_method_call,
183   test_interface_get_property,
184   NULL  /* set_property */
185 };
186
187 static void
188 on_proxy_signal_received (GDBusProxy *proxy,
189                           gchar      *sender_name,
190                           gchar      *signal_name,
191                           GVariant   *parameters,
192                           gpointer    user_data)
193 {
194   PeerData *data = user_data;
195
196   data->signal_received = TRUE;
197
198   g_assert (sender_name == NULL);
199   g_assert_cmpstr (signal_name, ==, "PeerSignal");
200   g_main_loop_quit (loop);
201 }
202
203 /* ---------------------------------------------------------------------------------------------------- */
204
205 static gboolean
206 on_authorize_authenticated_peer (GDBusAuthObserver *observer,
207                                  GIOStream         *stream,
208                                  GCredentials      *credentials,
209                                  gpointer           user_data)
210 {
211   PeerData *data = user_data;
212   gboolean authorized;
213
214   data->num_connection_attempts++;
215
216   authorized = TRUE;
217   if (!data->accept_connection)
218     {
219       authorized = FALSE;
220       g_main_loop_quit (loop);
221     }
222
223   return authorized;
224 }
225
226 /* Runs in thread we created GDBusServer in (since we didn't pass G_DBUS_SERVER_FLAGS_RUN_IN_THREAD) */
227 static void
228 on_new_connection (GDBusServer *server,
229                    GDBusConnection *connection,
230                    gpointer user_data)
231 {
232   PeerData *data = user_data;
233   GError *error;
234   guint reg_id;
235
236   //g_print ("Client connected.\n"
237   //         "Negotiated capabilities: unix-fd-passing=%d\n",
238   //         g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING);
239
240   g_ptr_array_add (data->current_connections, g_object_ref (connection));
241
242   /* export object on the newly established connection */
243   error = NULL;
244   reg_id = g_dbus_connection_register_object (connection,
245                                               "/org/gtk/GDBus/PeerTestObject",
246                                               test_interface_introspection_data,
247                                               &test_interface_vtable,
248                                               data,
249                                               NULL, /* GDestroyNotify for data */
250                                               &error);
251   g_assert_no_error (error);
252   g_assert (reg_id > 0);
253
254   g_main_loop_quit (loop);
255 }
256
257 static gpointer
258 service_thread_func (gpointer user_data)
259 {
260   PeerData *data = user_data;
261   GMainContext *service_context;
262   GDBusAuthObserver *observer;
263   GError *error;
264
265   service_context = g_main_context_new ();
266   g_main_context_push_thread_default (service_context);
267
268   error = NULL;
269   observer = g_dbus_auth_observer_new ();
270   server = g_dbus_server_new_sync (is_unix ? "unix:tmpdir=/tmp/gdbus-test-" : "nonce-tcp:",
271                                    G_DBUS_SERVER_FLAGS_NONE,
272                                    test_guid,
273                                    observer,
274                                    NULL, /* cancellable */
275                                    &error);
276   g_assert_no_error (error);
277
278   g_signal_connect (server,
279                     "new-connection",
280                     G_CALLBACK (on_new_connection),
281                     data);
282   g_signal_connect (observer,
283                     "authorize-authenticated-peer",
284                     G_CALLBACK (on_authorize_authenticated_peer),
285                     data);
286   g_object_unref (observer);
287
288   g_dbus_server_start (server);
289
290   service_loop = g_main_loop_new (service_context, FALSE);
291   g_main_loop_run (service_loop);
292
293   g_main_context_pop_thread_default (service_context);
294
295   g_main_loop_unref (service_loop);
296   g_main_context_unref (service_context);
297
298   /* test code specifically unrefs the server - see below */
299   g_assert (server == NULL);
300
301   return NULL;
302 }
303
304 #if 0
305 static gboolean
306 on_incoming_connection (GSocketService     *service,
307                         GSocketConnection  *socket_connection,
308                         GObject            *source_object,
309                         gpointer           user_data)
310 {
311   PeerData *data = user_data;
312
313   if (data->accept_connection)
314     {
315       GError *error;
316       guint reg_id;
317       GDBusConnection *connection;
318
319       error = NULL;
320       connection = g_dbus_connection_new_sync (G_IO_STREAM (socket_connection),
321                                                test_guid,
322                                                G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER,
323                                                NULL, /* cancellable */
324                                                &error);
325       g_assert_no_error (error);
326
327       g_ptr_array_add (data->current_connections, connection);
328
329       /* export object on the newly established connection */
330       error = NULL;
331       reg_id = g_dbus_connection_register_object (connection,
332                                                   "/org/gtk/GDBus/PeerTestObject",
333                                                   &test_interface_introspection_data,
334                                                   &test_interface_vtable,
335                                                   data,
336                                                   NULL, /* GDestroyNotify for data */
337                                                   &error);
338       g_assert_no_error (error);
339       g_assert (reg_id > 0);
340
341     }
342   else
343     {
344       /* don't do anything */
345     }
346
347   data->num_connection_attempts++;
348
349   g_main_loop_quit (loop);
350
351   /* stops other signal handlers from being invoked */
352   return TRUE;
353 }
354
355 static gpointer
356 service_thread_func (gpointer data)
357 {
358   GMainContext *service_context;
359   gchar *socket_path;
360   GSocketAddress *address;
361   GError *error;
362
363   service_context = g_main_context_new ();
364   g_main_context_push_thread_default (service_context);
365
366   socket_path = g_strdup_printf ("/tmp/gdbus-test-pid-%d", getpid ());
367   address = g_unix_socket_address_new (socket_path);
368
369   service = g_socket_service_new ();
370   error = NULL;
371   g_socket_listener_add_address (G_SOCKET_LISTENER (service),
372                                  address,
373                                  G_SOCKET_TYPE_STREAM,
374                                  G_SOCKET_PROTOCOL_DEFAULT,
375                                  NULL, /* source_object */
376                                  NULL, /* effective_address */
377                                  &error);
378   g_assert_no_error (error);
379   g_signal_connect (service,
380                     "incoming",
381                     G_CALLBACK (on_incoming_connection),
382                     data);
383   g_socket_service_start (service);
384
385   service_loop = g_main_loop_new (service_context, FALSE);
386   g_main_loop_run (service_loop);
387
388   g_main_context_pop_thread_default (service_context);
389
390   g_main_loop_unref (service_loop);
391   g_main_context_unref (service_context);
392
393   g_object_unref (address);
394   g_free (socket_path);
395   return NULL;
396 }
397 #endif
398
399 /* ---------------------------------------------------------------------------------------------------- */
400
401 #if 0
402 static gboolean
403 check_connection (gpointer user_data)
404 {
405   PeerData *data = user_data;
406   guint n;
407
408   for (n = 0; n < data->current_connections->len; n++)
409     {
410       GDBusConnection *c;
411       GIOStream *stream;
412
413       c = G_DBUS_CONNECTION (data->current_connections->pdata[n]);
414       stream = g_dbus_connection_get_stream (c);
415
416       g_debug ("In check_connection for %d: connection %p, stream %p", n, c, stream);
417       g_debug ("closed = %d", g_io_stream_is_closed (stream));
418
419       GSocket *socket;
420       socket = g_socket_connection_get_socket (G_SOCKET_CONNECTION (stream));
421       g_debug ("socket_closed = %d", g_socket_is_closed (socket));
422       g_debug ("socket_condition_check = %d", g_socket_condition_check (socket, G_IO_IN|G_IO_OUT|G_IO_ERR|G_IO_HUP));
423
424       gchar buf[128];
425       GError *error;
426       gssize num_read;
427       error = NULL;
428       num_read = g_input_stream_read (g_io_stream_get_input_stream (stream),
429                                       buf,
430                                       128,
431                                       NULL,
432                                       &error);
433       if (num_read < 0)
434         {
435           g_debug ("error: %s", error->message);
436           g_error_free (error);
437         }
438       else
439         {
440           g_debug ("no error, read %d bytes", (gint) num_read);
441         }
442     }
443
444   return FALSE;
445 }
446
447 static gboolean
448 on_do_disconnect_in_idle (gpointer data)
449 {
450   GDBusConnection *c = G_DBUS_CONNECTION (data);
451   g_debug ("GDC %p has ref_count %d", c, G_OBJECT (c)->ref_count);
452   g_dbus_connection_disconnect (c);
453   g_object_unref (c);
454   return FALSE;
455 }
456 #endif
457
458 static void
459 test_peer (void)
460 {
461   GDBusConnection *c;
462   GDBusConnection *c2;
463   GDBusProxy *proxy;
464   GError *error;
465   PeerData data;
466   GVariant *value;
467   GVariant *result;
468   const gchar *s;
469   GThread *service_thread;
470
471   memset (&data, '\0', sizeof (PeerData));
472   data.current_connections = g_ptr_array_new_with_free_func (g_object_unref);
473
474   /* first try to connect when there is no server */
475   error = NULL;
476   c = g_dbus_connection_new_for_address_sync (is_unix ? "unix:path=/tmp/gdbus-test-does-not-exist-pid" :
477                                               /* NOTE: Even if something is listening on port 12345 the connection
478                                                * will fail because the nonce file doesn't exist */
479                                               "nonce-tcp:host=localhost,port=12345,noncefile=this-does-not-exist-gdbus",
480                                               G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
481                                               NULL, /* GDBusAuthObserver */
482                                               NULL, /* cancellable */
483                                               &error);
484   _g_assert_error_domain (error, G_IO_ERROR);
485   g_assert (!g_dbus_error_is_remote_error (error));
486   g_clear_error (&error);
487   g_assert (c == NULL);
488
489   /* bring up a server - we run the server in a different thread to avoid deadlocks */
490   error = NULL;
491   service_thread = g_thread_create (service_thread_func,
492                                     &data,
493                                     TRUE,
494                                     &error);
495   while (service_loop == NULL)
496     g_thread_yield ();
497   g_assert (server != NULL);
498
499   /* bring up a connection and accept it */
500   data.accept_connection = TRUE;
501   error = NULL;
502   c = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (server),
503                                               G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
504                                               NULL, /* GDBusAuthObserver */
505                                               NULL, /* cancellable */
506                                               &error);
507   g_assert_no_error (error);
508   g_assert (c != NULL);
509   while (data.current_connections->len < 1)
510     g_main_loop_run (loop);
511   g_assert_cmpint (data.current_connections->len, ==, 1);
512   g_assert_cmpint (data.num_connection_attempts, ==, 1);
513   g_assert (g_dbus_connection_get_unique_name (c) == NULL);
514   g_assert_cmpstr (g_dbus_connection_get_guid (c), ==, test_guid);
515
516   /* check that we create a proxy, read properties, receive signals and invoke
517    * the HelloPeer() method. Since the server runs in another thread it's fine
518    * to use synchronous blocking API here.
519    */
520   error = NULL;
521   proxy = g_dbus_proxy_new_sync (c,
522                                  G_TYPE_DBUS_PROXY,
523                                  G_DBUS_PROXY_FLAGS_NONE,
524                                  NULL,
525                                  NULL, /* bus_name */
526                                  "/org/gtk/GDBus/PeerTestObject",
527                                  "org.gtk.GDBus.PeerTestInterface",
528                                  NULL, /* GCancellable */
529                                  &error);
530   g_assert_no_error (error);
531   g_assert (proxy != NULL);
532   error = NULL;
533   value = g_dbus_proxy_get_cached_property (proxy, "PeerProperty");
534   g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "ThePropertyValue");
535
536   /* try invoking a method */
537   error = NULL;
538   result = g_dbus_proxy_call_sync (proxy,
539                                    "HelloPeer",
540                                    g_variant_new ("(s)", "Hey Peer!"),
541                                    G_DBUS_CALL_FLAGS_NONE,
542                                    -1,
543                                    NULL,  /* GCancellable */
544                                    &error);
545   g_assert_no_error (error);
546   g_variant_get (result, "(s)", &s);
547   g_assert_cmpstr (s, ==, "You greeted me with 'Hey Peer!'.");
548   g_variant_unref (result);
549   g_assert_cmpint (data.num_method_calls, ==, 1);
550
551   /* make the other peer emit a signal - catch it */
552   g_signal_connect (proxy,
553                     "g-signal",
554                     G_CALLBACK (on_proxy_signal_received),
555                     &data);
556   g_assert (!data.signal_received);
557   g_dbus_proxy_call (proxy,
558                      "EmitSignal",
559                      NULL,  /* no arguments */
560                      G_DBUS_CALL_FLAGS_NONE,
561                      -1,
562                      NULL,  /* GCancellable */
563                      NULL,  /* GAsyncReadyCallback - we don't care about the result */
564                      NULL); /* user_data */
565   g_main_loop_run (loop);
566   g_assert (data.signal_received);
567   g_assert_cmpint (data.num_method_calls, ==, 2);
568
569   /* check for UNIX fd passing */
570 #ifdef G_OS_UNIX
571   {
572     GDBusMessage *method_call_message;
573     GDBusMessage *method_reply_message;
574     GUnixFDList *fd_list;
575     gint fd;
576     gchar buf[1024];
577     gssize len;
578     gchar *buf2;
579     gsize len2;
580
581     method_call_message = g_dbus_message_new_method_call (NULL, /* name */
582                                                           "/org/gtk/GDBus/PeerTestObject",
583                                                           "org.gtk.GDBus.PeerTestInterface",
584                                                           "OpenFile");
585     g_dbus_message_set_body (method_call_message, g_variant_new ("(s)", "/etc/hosts"));
586     error = NULL;
587     method_reply_message = g_dbus_connection_send_message_with_reply_sync (c,
588                                                                            method_call_message,
589                                                                            -1,
590                                                                            NULL, /* out_serial */
591                                                                            NULL, /* cancellable */
592                                                                            &error);
593     g_assert_no_error (error);
594     g_assert (g_dbus_message_get_message_type (method_reply_message) == G_DBUS_MESSAGE_TYPE_METHOD_RETURN);
595     fd_list = g_dbus_message_get_unix_fd_list (method_reply_message);
596     g_assert (fd_list != NULL);
597     g_assert_cmpint (g_unix_fd_list_get_length (fd_list), ==, 1);
598     error = NULL;
599     fd = g_unix_fd_list_get (fd_list, 0, &error);
600     g_assert_no_error (error);
601     g_object_unref (method_call_message);
602     g_object_unref (method_reply_message);
603
604     memset (buf, '\0', sizeof (buf));
605     len = read (fd, buf, sizeof (buf) - 1);
606     close (fd);
607
608     error = NULL;
609     g_file_get_contents ("/etc/hosts",
610                          &buf2,
611                          &len2,
612                          &error);
613     g_assert_no_error (error);
614     if (len2 > sizeof (buf))
615       buf2[sizeof (buf)] = '\0';
616     g_assert_cmpstr (buf, ==, buf2);
617     g_free (buf2);
618   }
619 #endif /* G_OS_UNIX */
620
621
622   /* bring up a connection - don't accept it - this should fail
623    */
624   data.accept_connection = FALSE;
625   error = NULL;
626   c2 = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (server),
627                                                G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
628                                                NULL, /* GDBusAuthObserver */
629                                                NULL, /* cancellable */
630                                                &error);
631   _g_assert_error_domain (error, G_IO_ERROR);
632   g_assert (c2 == NULL);
633
634 #if 0
635   /* TODO: THIS TEST DOESN'T WORK YET */
636
637   /* bring up a connection - accept it.. then disconnect from the client side - check
638    * that the server side gets the disconnect signal.
639    */
640   error = NULL;
641   data.accept_connection = TRUE;
642   c2 = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (server),
643                                                G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
644                                                NULL, /* GDBusAuthObserver */
645                                                NULL, /* cancellable */
646                                                &error);
647   g_assert_no_error (error);
648   g_assert (c2 != NULL);
649   g_assert (!g_dbus_connection_get_is_disconnected (c2));
650   while (data.num_connection_attempts < 3)
651     g_main_loop_run (loop);
652   g_assert_cmpint (data.current_connections->len, ==, 2);
653   g_assert_cmpint (data.num_connection_attempts, ==, 3);
654   g_assert (!g_dbus_connection_get_is_disconnected (G_DBUS_CONNECTION (data.current_connections->pdata[1])));
655   g_idle_add (on_do_disconnect_in_idle, c2);
656   g_debug ("==================================================");
657   g_debug ("==================================================");
658   g_debug ("==================================================");
659   g_debug ("waiting for disconnect on connection %p, stream %p",
660            data.current_connections->pdata[1],
661            g_dbus_connection_get_stream (data.current_connections->pdata[1]));
662
663   g_timeout_add (2000, check_connection, &data);
664   //_g_assert_signal_received (G_DBUS_CONNECTION (data.current_connections->pdata[1]), "closed");
665   g_main_loop_run (loop);
666   g_assert (g_dbus_connection_get_is_disconnected (G_DBUS_CONNECTION (data.current_connections->pdata[1])));
667   g_ptr_array_set_size (data.current_connections, 1); /* remove disconnected connection object */
668 #endif
669
670   /* unref the server and stop listening for new connections
671    *
672    * This won't bring down the established connections - check that c is still connected
673    * by invoking a method
674    */
675   //g_socket_service_stop (service);
676   //g_object_unref (service);
677   g_dbus_server_stop (server);
678   g_object_unref (server);
679   server = NULL;
680
681   error = NULL;
682   result = g_dbus_proxy_call_sync (proxy,
683                                    "HelloPeer",
684                                    g_variant_new ("(s)", "Hey Again Peer!"),
685                                    G_DBUS_CALL_FLAGS_NONE,
686                                    -1,
687                                    NULL,  /* GCancellable */
688                                    &error);
689   g_assert_no_error (error);
690   g_variant_get (result, "(s)", &s);
691   g_assert_cmpstr (s, ==, "You greeted me with 'Hey Again Peer!'.");
692   g_variant_unref (result);
693   g_assert_cmpint (data.num_method_calls, ==, 4);
694
695 #if 0
696   /* TODO: THIS TEST DOESN'T WORK YET */
697
698   /* now disconnect from the server side - check that the client side gets the signal */
699   g_assert_cmpint (data.current_connections->len, ==, 1);
700   g_assert (G_DBUS_CONNECTION (data.current_connections->pdata[0]) != c);
701   g_dbus_connection_disconnect (G_DBUS_CONNECTION (data.current_connections->pdata[0]));
702   if (!g_dbus_connection_get_is_disconnected (c))
703     _g_assert_signal_received (c, "closed");
704   g_assert (g_dbus_connection_get_is_disconnected (c));
705 #endif
706
707   g_object_unref (c);
708   g_ptr_array_unref (data.current_connections);
709   g_object_unref (proxy);
710
711   g_main_loop_quit (service_loop);
712   g_thread_join (service_thread);
713 }
714
715 /* ---------------------------------------------------------------------------------------------------- */
716
717 int
718 main (int   argc,
719       char *argv[])
720 {
721   gint ret;
722   GDBusNodeInfo *introspection_data = NULL;
723
724   g_type_init ();
725   g_thread_init (NULL);
726   g_test_init (&argc, &argv, NULL);
727
728   introspection_data = g_dbus_node_info_new_for_xml (test_interface_introspection_xml, NULL);
729   g_assert (introspection_data != NULL);
730   test_interface_introspection_data = introspection_data->interfaces[0];
731
732   test_guid = g_dbus_generate_guid ();
733
734   /* all the tests rely on a shared main loop */
735   loop = g_main_loop_new (NULL, FALSE);
736
737   g_test_add_func ("/gdbus/peer-to-peer", test_peer);
738
739   ret = g_test_run();
740
741   g_main_loop_unref (loop);
742   g_free (test_guid);
743   g_dbus_node_info_unref (introspection_data);
744
745   return ret;
746 }