Initial GDBus code-drop from GDBus-standalone repo
[platform/upstream/glib.git] / gio / tests / gdbus-peer.c
1 /* GLib testing framework examples and tests
2  *
3  * Copyright (C) 2008-2009 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_deny_authenticated_peer (GDBusAuthObserver *observer,
207                             GIOStream         *stream,
208                             GCredentials      *credentials,
209                             gpointer           user_data)
210 {
211   PeerData *data = user_data;
212   gboolean deny_peer;
213
214   data->num_connection_attempts++;
215
216   deny_peer = FALSE;
217   if (!data->accept_connection)
218     {
219       deny_peer = TRUE;
220       g_main_loop_quit (loop);
221     }
222
223   return deny_peer;
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                                               "org.gtk.GDBus.PeerTestInterface",
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                     "deny-authenticated-peer",
285                     G_CALLBACK (on_deny_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                                                   "org.gtk.GDBus.PeerTestInterface",
335                                                   &test_interface_introspection_data,
336                                                   &test_interface_vtable,
337                                                   data,
338                                                   NULL, /* GDestroyNotify for data */
339                                                   &error);
340       g_assert_no_error (error);
341       g_assert (reg_id > 0);
342
343     }
344   else
345     {
346       /* don't do anything */
347     }
348
349   data->num_connection_attempts++;
350
351   g_main_loop_quit (loop);
352
353   /* stops other signal handlers from being invoked */
354   return TRUE;
355 }
356
357 static gpointer
358 service_thread_func (gpointer data)
359 {
360   GMainContext *service_context;
361   gchar *socket_path;
362   GSocketAddress *address;
363   GError *error;
364
365   service_context = g_main_context_new ();
366   g_main_context_push_thread_default (service_context);
367
368   socket_path = g_strdup_printf ("/tmp/gdbus-test-pid-%d", getpid ());
369   address = g_unix_socket_address_new (socket_path);
370
371   service = g_socket_service_new ();
372   error = NULL;
373   g_socket_listener_add_address (G_SOCKET_LISTENER (service),
374                                  address,
375                                  G_SOCKET_TYPE_STREAM,
376                                  G_SOCKET_PROTOCOL_DEFAULT,
377                                  NULL, /* source_object */
378                                  NULL, /* effective_address */
379                                  &error);
380   g_assert_no_error (error);
381   g_signal_connect (service,
382                     "incoming",
383                     G_CALLBACK (on_incoming_connection),
384                     data);
385   g_socket_service_start (service);
386
387   service_loop = g_main_loop_new (service_context, FALSE);
388   g_main_loop_run (service_loop);
389
390   g_main_context_pop_thread_default (service_context);
391
392   g_main_loop_unref (service_loop);
393   g_main_context_unref (service_context);
394
395   g_object_unref (address);
396   g_free (socket_path);
397   return NULL;
398 }
399 #endif
400
401 /* ---------------------------------------------------------------------------------------------------- */
402
403 #if 0
404 static gboolean
405 check_connection (gpointer user_data)
406 {
407   PeerData *data = user_data;
408   guint n;
409
410   for (n = 0; n < data->current_connections->len; n++)
411     {
412       GDBusConnection *c;
413       GIOStream *stream;
414
415       c = G_DBUS_CONNECTION (data->current_connections->pdata[n]);
416       stream = g_dbus_connection_get_stream (c);
417
418       g_debug ("In check_connection for %d: connection %p, stream %p", n, c, stream);
419       g_debug ("closed = %d", g_io_stream_is_closed (stream));
420
421       GSocket *socket;
422       socket = g_socket_connection_get_socket (G_SOCKET_CONNECTION (stream));
423       g_debug ("socket_closed = %d", g_socket_is_closed (socket));
424       g_debug ("socket_condition_check = %d", g_socket_condition_check (socket, G_IO_IN|G_IO_OUT|G_IO_ERR|G_IO_HUP));
425
426       gchar buf[128];
427       GError *error;
428       gssize num_read;
429       error = NULL;
430       num_read = g_input_stream_read (g_io_stream_get_input_stream (stream),
431                                       buf,
432                                       128,
433                                       NULL,
434                                       &error);
435       if (num_read < 0)
436         {
437           g_debug ("error: %s", error->message);
438           g_error_free (error);
439         }
440       else
441         {
442           g_debug ("no error, read %d bytes", (gint) num_read);
443         }
444     }
445
446   return FALSE;
447 }
448
449 static gboolean
450 on_do_disconnect_in_idle (gpointer data)
451 {
452   GDBusConnection *c = G_DBUS_CONNECTION (data);
453   g_debug ("GDC %p has ref_count %d", c, G_OBJECT (c)->ref_count);
454   g_dbus_connection_disconnect (c);
455   g_object_unref (c);
456   return FALSE;
457 }
458 #endif
459
460 static void
461 test_peer (void)
462 {
463   GDBusConnection *c;
464   GDBusConnection *c2;
465   GDBusProxy *proxy;
466   GError *error;
467   PeerData data;
468   GVariant *value;
469   GVariant *result;
470   const gchar *s;
471   GThread *service_thread;
472
473   memset (&data, '\0', sizeof (PeerData));
474   data.current_connections = g_ptr_array_new_with_free_func (g_object_unref);
475
476   /* first try to connect when there is no server */
477   error = NULL;
478   c = g_dbus_connection_new_for_address_sync (is_unix ? "unix:path=/tmp/gdbus-test-does-not-exist-pid" :
479                                               /* NOTE: Even if something is listening on port 12345 the connection
480                                                * will fail because the nonce file doesn't exist */
481                                               "nonce-tcp:host=localhost,port=12345,noncefile=this-does-not-exist-gdbus",
482                                               G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
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, /* 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_bus_type (c) == G_BUS_TYPE_NONE);
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", &error);
535   g_assert_no_error (error);
536   g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "ThePropertyValue");
537
538   /* try invoking a method */
539   error = NULL;
540   result = g_dbus_proxy_invoke_method_sync (proxy,
541                                             "HelloPeer",
542                                             g_variant_new ("(s)", "Hey Peer!"),
543                                             G_DBUS_INVOKE_METHOD_FLAGS_NONE,
544                                             -1,
545                                             NULL,  /* GCancellable */
546                                             &error);
547   g_assert_no_error (error);
548   g_variant_get (result, "(s)", &s);
549   g_assert_cmpstr (s, ==, "You greeted me with 'Hey Peer!'.");
550   g_variant_unref (result);
551   g_assert_cmpint (data.num_method_calls, ==, 1);
552
553   /* make the other peer emit a signal - catch it */
554   g_signal_connect (proxy,
555                     "g-signal",
556                     G_CALLBACK (on_proxy_signal_received),
557                     &data);
558   g_assert (!data.signal_received);
559   g_dbus_proxy_invoke_method (proxy,
560                               "EmitSignal",
561                               NULL,  /* no arguments */
562                               G_DBUS_INVOKE_METHOD_FLAGS_NONE,
563                               -1,
564                               NULL,  /* GCancellable */
565                               NULL,  /* GAsyncReadyCallback - we don't care about the result */
566                               NULL); /* user_data */
567   g_main_loop_run (loop);
568   g_assert (data.signal_received);
569   g_assert_cmpint (data.num_method_calls, ==, 2);
570
571   /* check for UNIX fd passing */
572 #ifdef G_OS_UNIX
573   {
574     GDBusMessage *method_call_message;
575     GDBusMessage *method_reply_message;
576     GUnixFDList *fd_list;
577     gint fd;
578     gchar buf[1024];
579     gssize len;
580     gchar *buf2;
581     gsize len2;
582
583     method_call_message = g_dbus_message_new_method_call (NULL, /* name */
584                                                           "/org/gtk/GDBus/PeerTestObject",
585                                                           "org.gtk.GDBus.PeerTestInterface",
586                                                           "OpenFile");
587     g_dbus_message_set_body (method_call_message, g_variant_new ("(s)", "/etc/hosts"));
588     error = NULL;
589     method_reply_message = g_dbus_connection_send_message_with_reply_sync (c,
590                                                                            method_call_message,
591                                                                            -1,
592                                                                            NULL, /* out_serial */
593                                                                            NULL, /* cancellable */
594                                                                            &error);
595     g_assert_no_error (error);
596     g_assert (g_dbus_message_get_type (method_reply_message) == G_DBUS_MESSAGE_TYPE_METHOD_RETURN);
597     fd_list = g_dbus_message_get_unix_fd_list (method_reply_message);
598     g_assert (fd_list != NULL);
599     g_assert_cmpint (g_unix_fd_list_get_length (fd_list), ==, 1);
600     error = NULL;
601     fd = g_unix_fd_list_get (fd_list, 0, &error);
602     g_assert_no_error (error);
603     g_object_unref (method_call_message);
604     g_object_unref (method_reply_message);
605
606     memset (buf, '\0', sizeof (buf));
607     len = read (fd, buf, sizeof (buf) - 1);
608     close (fd);
609
610     error = NULL;
611     g_file_get_contents ("/etc/hosts",
612                          &buf2,
613                          &len2,
614                          &error);
615     g_assert_no_error (error);
616     if (len2 > sizeof (buf))
617       buf2[sizeof (buf)] = '\0';
618     g_assert_cmpstr (buf, ==, buf2);
619     g_free (buf2);
620   }
621 #endif /* G_OS_UNIX */
622
623
624   /* bring up a connection - don't accept it - this should fail
625    */
626   data.accept_connection = FALSE;
627   error = NULL;
628   c2 = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (server),
629                                                G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
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, /* 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_invoke_method_sync (proxy,
683                                             "HelloPeer",
684                                             g_variant_new ("(s)", "Hey Again Peer!"),
685                                             G_DBUS_INVOKE_METHOD_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 }