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