Improve GDBus introspection test coverage
[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 /* for g_unlink() */
33 #include <glib/gstdio.h>
34
35 #include <gio/gnetworkingprivate.h>
36 #include <gio/gunixsocketaddress.h>
37 #include <gio/gunixfdlist.h>
38
39 /* used in test_overflow */
40 #ifdef G_OS_UNIX
41 #include <gio/gunixconnection.h>
42 #endif
43
44 #include "gdbus-tests.h"
45
46 #ifdef G_OS_UNIX
47 static gboolean is_unix = TRUE;
48 #else
49 static gboolean is_unix = FALSE;
50 #endif
51
52 static gchar *test_guid = NULL;
53 static GMainLoop *service_loop = NULL;
54 static GDBusServer *server = NULL;
55 static GMainLoop *loop = NULL;
56
57 /* ---------------------------------------------------------------------------------------------------- */
58 /* Test that peer-to-peer connections work */
59 /* ---------------------------------------------------------------------------------------------------- */
60
61
62 typedef struct
63 {
64   gboolean accept_connection;
65   gint num_connection_attempts;
66   GPtrArray *current_connections;
67   guint num_method_calls;
68   gboolean signal_received;
69 } PeerData;
70
71 static const gchar *test_interface_introspection_xml =
72   "<node>"
73   "  <interface name='org.gtk.GDBus.PeerTestInterface'>"
74   "    <method name='HelloPeer'>"
75   "      <arg type='s' name='greeting' direction='in'/>"
76   "      <arg type='s' name='response' direction='out'/>"
77   "    </method>"
78   "    <method name='EmitSignal'/>"
79   "    <method name='EmitSignalWithNameSet'/>"
80   "    <method name='OpenFile'>"
81   "      <arg type='s' name='path' direction='in'/>"
82   "    </method>"
83   "    <signal name='PeerSignal'>"
84   "      <arg type='s' name='a_string'/>"
85   "    </signal>"
86   "    <property type='s' name='PeerProperty' access='read'/>"
87   "  </interface>"
88   "</node>";
89 static GDBusInterfaceInfo *test_interface_introspection_data = NULL;
90
91 static void
92 test_interface_method_call (GDBusConnection       *connection,
93                             const gchar           *sender,
94                             const gchar           *object_path,
95                             const gchar           *interface_name,
96                             const gchar           *method_name,
97                             GVariant              *parameters,
98                             GDBusMethodInvocation *invocation,
99                             gpointer               user_data)
100 {
101   PeerData *data = user_data;
102   const GDBusMethodInfo *info;
103
104   data->num_method_calls++;
105
106   g_assert_cmpstr (object_path, ==, "/org/gtk/GDBus/PeerTestObject");
107   g_assert_cmpstr (interface_name, ==, "org.gtk.GDBus.PeerTestInterface");
108
109   info = g_dbus_method_invocation_get_method_info (invocation);
110   g_assert_cmpstr (info->name, ==, method_name);
111
112   if (g_strcmp0 (method_name, "HelloPeer") == 0)
113     {
114       const gchar *greeting;
115       gchar *response;
116
117       g_variant_get (parameters, "(&s)", &greeting);
118
119       response = g_strdup_printf ("You greeted me with '%s'.",
120                                   greeting);
121       g_dbus_method_invocation_return_value (invocation,
122                                              g_variant_new ("(s)", response));
123       g_free (response);
124     }
125   else if (g_strcmp0 (method_name, "EmitSignal") == 0)
126     {
127       GError *error;
128
129       error = NULL;
130       g_dbus_connection_emit_signal (connection,
131                                      NULL,
132                                      "/org/gtk/GDBus/PeerTestObject",
133                                      "org.gtk.GDBus.PeerTestInterface",
134                                      "PeerSignal",
135                                      NULL,
136                                      &error);
137       g_assert_no_error (error);
138       g_dbus_method_invocation_return_value (invocation, NULL);
139     }
140   else if (g_strcmp0 (method_name, "EmitSignalWithNameSet") == 0)
141     {
142       GError *error;
143       gboolean ret;
144       GDBusMessage *message;
145
146       message = g_dbus_message_new_signal ("/org/gtk/GDBus/PeerTestObject",
147                                            "org.gtk.GDBus.PeerTestInterface",
148                                            "PeerSignalWithNameSet");
149       g_dbus_message_set_sender (message, ":1.42");
150
151       error = NULL;
152       ret = g_dbus_connection_send_message (connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error);
153       g_assert_no_error (error);
154       g_assert (ret);
155       g_object_unref (message);
156
157       g_dbus_method_invocation_return_value (invocation, NULL);
158     }
159   else if (g_strcmp0 (method_name, "OpenFile") == 0)
160     {
161 #ifdef G_OS_UNIX
162       const gchar *path;
163       GDBusMessage *reply;
164       GError *error;
165       gint fd;
166       GUnixFDList *fd_list;
167
168       g_variant_get (parameters, "(&s)", &path);
169
170       fd_list = g_unix_fd_list_new ();
171
172       error = NULL;
173
174       fd = open (path, O_RDONLY);
175       g_unix_fd_list_append (fd_list, fd, &error);
176       g_assert_no_error (error);
177       close (fd);
178
179       reply = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation));
180       g_dbus_message_set_unix_fd_list (reply, fd_list);
181       g_object_unref (invocation);
182
183       error = NULL;
184       g_dbus_connection_send_message (connection,
185                                       reply,
186                                       G_DBUS_SEND_MESSAGE_FLAGS_NONE,
187                                       NULL, /* out_serial */
188                                       &error);
189       g_assert_no_error (error);
190       g_object_unref (reply);
191 #else
192       g_dbus_method_invocation_return_dbus_error (invocation,
193                                                   "org.gtk.GDBus.NotOnUnix",
194                                                   "Your OS does not support file descriptor passing");
195 #endif
196     }
197   else
198     {
199       g_assert_not_reached ();
200     }
201 }
202
203 static GVariant *
204 test_interface_get_property (GDBusConnection  *connection,
205                              const gchar      *sender,
206                              const gchar      *object_path,
207                              const gchar      *interface_name,
208                              const gchar      *property_name,
209                              GError          **error,
210                              gpointer          user_data)
211 {
212   g_assert_cmpstr (object_path, ==, "/org/gtk/GDBus/PeerTestObject");
213   g_assert_cmpstr (interface_name, ==, "org.gtk.GDBus.PeerTestInterface");
214   g_assert_cmpstr (property_name, ==, "PeerProperty");
215
216   return g_variant_new_string ("ThePropertyValue");
217 }
218
219
220 static const GDBusInterfaceVTable test_interface_vtable =
221 {
222   test_interface_method_call,
223   test_interface_get_property,
224   NULL  /* set_property */
225 };
226
227 static void
228 on_proxy_signal_received (GDBusProxy *proxy,
229                           gchar      *sender_name,
230                           gchar      *signal_name,
231                           GVariant   *parameters,
232                           gpointer    user_data)
233 {
234   PeerData *data = user_data;
235
236   data->signal_received = TRUE;
237
238   g_assert (sender_name == NULL);
239   g_assert_cmpstr (signal_name, ==, "PeerSignal");
240   g_main_loop_quit (loop);
241 }
242
243 static void
244 on_proxy_signal_received_with_name_set (GDBusProxy *proxy,
245                                         gchar      *sender_name,
246                                         gchar      *signal_name,
247                                         GVariant   *parameters,
248                                         gpointer    user_data)
249 {
250   PeerData *data = user_data;
251
252   data->signal_received = TRUE;
253
254   g_assert_cmpstr (sender_name, ==, ":1.42");
255   g_assert_cmpstr (signal_name, ==, "PeerSignalWithNameSet");
256   g_main_loop_quit (loop);
257 }
258
259 /* ---------------------------------------------------------------------------------------------------- */
260
261 static gboolean
262 on_authorize_authenticated_peer (GDBusAuthObserver *observer,
263                                  GIOStream         *stream,
264                                  GCredentials      *credentials,
265                                  gpointer           user_data)
266 {
267   PeerData *data = user_data;
268   gboolean authorized;
269
270   data->num_connection_attempts++;
271
272   authorized = TRUE;
273   if (!data->accept_connection)
274     {
275       authorized = FALSE;
276       g_main_loop_quit (loop);
277     }
278
279   return authorized;
280 }
281
282 /* Runs in thread we created GDBusServer in (since we didn't pass G_DBUS_SERVER_FLAGS_RUN_IN_THREAD) */
283 static void
284 on_new_connection (GDBusServer *server,
285                    GDBusConnection *connection,
286                    gpointer user_data)
287 {
288   PeerData *data = user_data;
289   GError *error;
290   guint reg_id;
291
292   //g_print ("Client connected.\n"
293   //         "Negotiated capabilities: unix-fd-passing=%d\n",
294   //         g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING);
295
296   g_ptr_array_add (data->current_connections, g_object_ref (connection));
297
298   /* export object on the newly established connection */
299   error = NULL;
300   reg_id = g_dbus_connection_register_object (connection,
301                                               "/org/gtk/GDBus/PeerTestObject",
302                                               test_interface_introspection_data,
303                                               &test_interface_vtable,
304                                               data,
305                                               NULL, /* GDestroyNotify for data */
306                                               &error);
307   g_assert_no_error (error);
308   g_assert (reg_id > 0);
309
310   g_main_loop_quit (loop);
311 }
312
313 static gpointer
314 service_thread_func (gpointer user_data)
315 {
316   PeerData *data = user_data;
317   GMainContext *service_context;
318   GDBusAuthObserver *observer;
319   GError *error;
320
321   service_context = g_main_context_new ();
322   g_main_context_push_thread_default (service_context);
323
324   error = NULL;
325   observer = g_dbus_auth_observer_new ();
326   server = g_dbus_server_new_sync (is_unix ? "unix:tmpdir=/tmp/gdbus-test-" : "nonce-tcp:",
327                                    G_DBUS_SERVER_FLAGS_NONE,
328                                    test_guid,
329                                    observer,
330                                    NULL, /* cancellable */
331                                    &error);
332   g_assert_no_error (error);
333
334   g_signal_connect (server,
335                     "new-connection",
336                     G_CALLBACK (on_new_connection),
337                     data);
338   g_signal_connect (observer,
339                     "authorize-authenticated-peer",
340                     G_CALLBACK (on_authorize_authenticated_peer),
341                     data);
342   g_object_unref (observer);
343
344   g_dbus_server_start (server);
345
346   service_loop = g_main_loop_new (service_context, FALSE);
347   g_main_loop_run (service_loop);
348
349   g_main_context_pop_thread_default (service_context);
350
351   g_main_loop_unref (service_loop);
352   g_main_context_unref (service_context);
353
354   /* test code specifically unrefs the server - see below */
355   g_assert (server == NULL);
356
357   return NULL;
358 }
359
360 #if 0
361 static gboolean
362 on_incoming_connection (GSocketService     *service,
363                         GSocketConnection  *socket_connection,
364                         GObject            *source_object,
365                         gpointer           user_data)
366 {
367   PeerData *data = user_data;
368
369   if (data->accept_connection)
370     {
371       GError *error;
372       guint reg_id;
373       GDBusConnection *connection;
374
375       error = NULL;
376       connection = g_dbus_connection_new_sync (G_IO_STREAM (socket_connection),
377                                                test_guid,
378                                                G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER,
379                                                NULL, /* cancellable */
380                                                &error);
381       g_assert_no_error (error);
382
383       g_ptr_array_add (data->current_connections, connection);
384
385       /* export object on the newly established connection */
386       error = NULL;
387       reg_id = g_dbus_connection_register_object (connection,
388                                                   "/org/gtk/GDBus/PeerTestObject",
389                                                   &test_interface_introspection_data,
390                                                   &test_interface_vtable,
391                                                   data,
392                                                   NULL, /* GDestroyNotify for data */
393                                                   &error);
394       g_assert_no_error (error);
395       g_assert (reg_id > 0);
396
397     }
398   else
399     {
400       /* don't do anything */
401     }
402
403   data->num_connection_attempts++;
404
405   g_main_loop_quit (loop);
406
407   /* stops other signal handlers from being invoked */
408   return TRUE;
409 }
410
411 static gpointer
412 service_thread_func (gpointer data)
413 {
414   GMainContext *service_context;
415   gchar *socket_path;
416   GSocketAddress *address;
417   GError *error;
418
419   service_context = g_main_context_new ();
420   g_main_context_push_thread_default (service_context);
421
422   socket_path = g_strdup_printf ("/tmp/gdbus-test-pid-%d", getpid ());
423   address = g_unix_socket_address_new (socket_path);
424
425   service = g_socket_service_new ();
426   error = NULL;
427   g_socket_listener_add_address (G_SOCKET_LISTENER (service),
428                                  address,
429                                  G_SOCKET_TYPE_STREAM,
430                                  G_SOCKET_PROTOCOL_DEFAULT,
431                                  NULL, /* source_object */
432                                  NULL, /* effective_address */
433                                  &error);
434   g_assert_no_error (error);
435   g_signal_connect (service,
436                     "incoming",
437                     G_CALLBACK (on_incoming_connection),
438                     data);
439   g_socket_service_start (service);
440
441   service_loop = g_main_loop_new (service_context, FALSE);
442   g_main_loop_run (service_loop);
443
444   g_main_context_pop_thread_default (service_context);
445
446   g_main_loop_unref (service_loop);
447   g_main_context_unref (service_context);
448
449   g_object_unref (address);
450   g_free (socket_path);
451   return NULL;
452 }
453 #endif
454
455 /* ---------------------------------------------------------------------------------------------------- */
456
457 #if 0
458 static gboolean
459 check_connection (gpointer user_data)
460 {
461   PeerData *data = user_data;
462   guint n;
463
464   for (n = 0; n < data->current_connections->len; n++)
465     {
466       GDBusConnection *c;
467       GIOStream *stream;
468
469       c = G_DBUS_CONNECTION (data->current_connections->pdata[n]);
470       stream = g_dbus_connection_get_stream (c);
471
472       g_debug ("In check_connection for %d: connection %p, stream %p", n, c, stream);
473       g_debug ("closed = %d", g_io_stream_is_closed (stream));
474
475       GSocket *socket;
476       socket = g_socket_connection_get_socket (G_SOCKET_CONNECTION (stream));
477       g_debug ("socket_closed = %d", g_socket_is_closed (socket));
478       g_debug ("socket_condition_check = %d", g_socket_condition_check (socket, G_IO_IN|G_IO_OUT|G_IO_ERR|G_IO_HUP));
479
480       gchar buf[128];
481       GError *error;
482       gssize num_read;
483       error = NULL;
484       num_read = g_input_stream_read (g_io_stream_get_input_stream (stream),
485                                       buf,
486                                       128,
487                                       NULL,
488                                       &error);
489       if (num_read < 0)
490         {
491           g_debug ("error: %s", error->message);
492           g_error_free (error);
493         }
494       else
495         {
496           g_debug ("no error, read %d bytes", (gint) num_read);
497         }
498     }
499
500   return FALSE;
501 }
502
503 static gboolean
504 on_do_disconnect_in_idle (gpointer data)
505 {
506   GDBusConnection *c = G_DBUS_CONNECTION (data);
507   g_debug ("GDC %p has ref_count %d", c, G_OBJECT (c)->ref_count);
508   g_dbus_connection_disconnect (c);
509   g_object_unref (c);
510   return FALSE;
511 }
512 #endif
513
514 static void
515 test_peer (void)
516 {
517   GDBusConnection *c;
518   GDBusConnection *c2;
519   GDBusProxy *proxy;
520   GError *error;
521   PeerData data;
522   GVariant *value;
523   GVariant *result;
524   const gchar *s;
525   GThread *service_thread;
526   gulong signal_handler_id;
527
528   memset (&data, '\0', sizeof (PeerData));
529   data.current_connections = g_ptr_array_new_with_free_func (g_object_unref);
530
531   /* first try to connect when there is no server */
532   error = NULL;
533   c = g_dbus_connection_new_for_address_sync (is_unix ? "unix:path=/tmp/gdbus-test-does-not-exist-pid" :
534                                               /* NOTE: Even if something is listening on port 12345 the connection
535                                                * will fail because the nonce file doesn't exist */
536                                               "nonce-tcp:host=localhost,port=12345,noncefile=this-does-not-exist-gdbus",
537                                               G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
538                                               NULL, /* GDBusAuthObserver */
539                                               NULL, /* cancellable */
540                                               &error);
541   _g_assert_error_domain (error, G_IO_ERROR);
542   g_assert (!g_dbus_error_is_remote_error (error));
543   g_clear_error (&error);
544   g_assert (c == NULL);
545
546   /* bring up a server - we run the server in a different thread to avoid deadlocks */
547   error = NULL;
548   service_thread = g_thread_create (service_thread_func,
549                                     &data,
550                                     TRUE,
551                                     &error);
552   while (service_loop == NULL)
553     g_thread_yield ();
554   g_assert (server != NULL);
555
556   /* bring up a connection and accept it */
557   data.accept_connection = TRUE;
558   error = NULL;
559   c = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (server),
560                                               G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
561                                               NULL, /* GDBusAuthObserver */
562                                               NULL, /* cancellable */
563                                               &error);
564   g_assert_no_error (error);
565   g_assert (c != NULL);
566   while (data.current_connections->len < 1)
567     g_main_loop_run (loop);
568   g_assert_cmpint (data.current_connections->len, ==, 1);
569   g_assert_cmpint (data.num_connection_attempts, ==, 1);
570   g_assert (g_dbus_connection_get_unique_name (c) == NULL);
571   g_assert_cmpstr (g_dbus_connection_get_guid (c), ==, test_guid);
572
573   /* check that we create a proxy, read properties, receive signals and invoke
574    * the HelloPeer() method. Since the server runs in another thread it's fine
575    * to use synchronous blocking API here.
576    */
577   error = NULL;
578   proxy = g_dbus_proxy_new_sync (c,
579                                  G_DBUS_PROXY_FLAGS_NONE,
580                                  NULL,
581                                  NULL, /* bus_name */
582                                  "/org/gtk/GDBus/PeerTestObject",
583                                  "org.gtk.GDBus.PeerTestInterface",
584                                  NULL, /* GCancellable */
585                                  &error);
586   g_assert_no_error (error);
587   g_assert (proxy != NULL);
588   error = NULL;
589   value = g_dbus_proxy_get_cached_property (proxy, "PeerProperty");
590   g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "ThePropertyValue");
591
592   /* try invoking a method */
593   error = NULL;
594   result = g_dbus_proxy_call_sync (proxy,
595                                    "HelloPeer",
596                                    g_variant_new ("(s)", "Hey Peer!"),
597                                    G_DBUS_CALL_FLAGS_NONE,
598                                    -1,
599                                    NULL,  /* GCancellable */
600                                    &error);
601   g_assert_no_error (error);
602   g_variant_get (result, "(&s)", &s);
603   g_assert_cmpstr (s, ==, "You greeted me with 'Hey Peer!'.");
604   g_variant_unref (result);
605   g_assert_cmpint (data.num_method_calls, ==, 1);
606
607   /* make the other peer emit a signal - catch it */
608   signal_handler_id = g_signal_connect (proxy,
609                                         "g-signal",
610                                         G_CALLBACK (on_proxy_signal_received),
611                                         &data);
612   g_assert (!data.signal_received);
613   g_dbus_proxy_call (proxy,
614                      "EmitSignal",
615                      NULL,  /* no arguments */
616                      G_DBUS_CALL_FLAGS_NONE,
617                      -1,
618                      NULL,  /* GCancellable */
619                      NULL,  /* GAsyncReadyCallback - we don't care about the result */
620                      NULL); /* user_data */
621   g_main_loop_run (loop);
622   g_assert (data.signal_received);
623   g_assert_cmpint (data.num_method_calls, ==, 2);
624   g_signal_handler_disconnect (proxy, signal_handler_id);
625
626   /* Also ensure that messages with the sender header-field set gets
627    * delivered to the proxy - note that this doesn't really make sense
628    * e.g. names are meaning-less in a peer-to-peer case... but we
629    * support it because it makes sense in certain bridging
630    * applications - see e.g. #623815.
631    */
632   signal_handler_id = g_signal_connect (proxy,
633                                         "g-signal",
634                                         G_CALLBACK (on_proxy_signal_received_with_name_set),
635                                         &data);
636   data.signal_received = FALSE;
637   g_dbus_proxy_call (proxy,
638                      "EmitSignalWithNameSet",
639                      NULL,  /* no arguments */
640                      G_DBUS_CALL_FLAGS_NONE,
641                      -1,
642                      NULL,  /* GCancellable */
643                      NULL,  /* GAsyncReadyCallback - we don't care about the result */
644                      NULL); /* user_data */
645   g_main_loop_run (loop);
646   g_assert (data.signal_received);
647   g_assert_cmpint (data.num_method_calls, ==, 3);
648   g_signal_handler_disconnect (proxy, signal_handler_id);
649
650   /* check for UNIX fd passing */
651 #ifdef G_OS_UNIX
652   {
653     GDBusMessage *method_call_message;
654     GDBusMessage *method_reply_message;
655     GUnixFDList *fd_list;
656     gint fd;
657     gchar buf[1024];
658     gssize len;
659     gchar *buf2;
660     gsize len2;
661
662     method_call_message = g_dbus_message_new_method_call (NULL, /* name */
663                                                           "/org/gtk/GDBus/PeerTestObject",
664                                                           "org.gtk.GDBus.PeerTestInterface",
665                                                           "OpenFile");
666     g_dbus_message_set_body (method_call_message, g_variant_new ("(s)", "/etc/hosts"));
667     error = NULL;
668     method_reply_message = g_dbus_connection_send_message_with_reply_sync (c,
669                                                                            method_call_message,
670                                                                            G_DBUS_SEND_MESSAGE_FLAGS_NONE,
671                                                                            -1,
672                                                                            NULL, /* out_serial */
673                                                                            NULL, /* cancellable */
674                                                                            &error);
675     g_assert_no_error (error);
676     g_assert (g_dbus_message_get_message_type (method_reply_message) == G_DBUS_MESSAGE_TYPE_METHOD_RETURN);
677     fd_list = g_dbus_message_get_unix_fd_list (method_reply_message);
678     g_assert (fd_list != NULL);
679     g_assert_cmpint (g_unix_fd_list_get_length (fd_list), ==, 1);
680     error = NULL;
681     fd = g_unix_fd_list_get (fd_list, 0, &error);
682     g_assert_no_error (error);
683     g_object_unref (method_call_message);
684     g_object_unref (method_reply_message);
685
686     memset (buf, '\0', sizeof (buf));
687     len = read (fd, buf, sizeof (buf) - 1);
688     close (fd);
689
690     error = NULL;
691     g_file_get_contents ("/etc/hosts",
692                          &buf2,
693                          &len2,
694                          &error);
695     g_assert_no_error (error);
696     if (len2 > sizeof (buf))
697       buf2[sizeof (buf)] = '\0';
698     g_assert_cmpstr (buf, ==, buf2);
699     g_free (buf2);
700   }
701 #else
702   error = NULL;
703   result = g_dbus_proxy_call_sync (proxy,
704                                    "OpenFile",
705                                    g_variant_new ("(s)", "boo"),
706                                    G_DBUS_CALL_FLAGS_NONE,
707                                    -1,
708                                    NULL,  /* GCancellable */
709                                    &error);
710   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR);
711   g_assert (result == NULL);
712   g_error_free (error);
713 #endif /* G_OS_UNIX */
714
715   /* Check that g_socket_get_credentials() work - this really should
716    * be in a GSocket-specific test suite but no such test suite exists
717    * right now.
718    */
719   {
720     GSocket *socket;
721     GCredentials *credentials;
722     socket = g_socket_connection_get_socket (G_SOCKET_CONNECTION (g_dbus_connection_get_stream (c)));
723     g_assert (G_IS_SOCKET (socket));
724     error = NULL;
725     credentials = g_socket_get_credentials (socket, &error);
726 #ifdef __linux__
727     {
728       struct ucred *native_creds;
729       g_assert_no_error (error);
730       g_assert (G_IS_CREDENTIALS (credentials));
731       native_creds = g_credentials_get_native (credentials, G_CREDENTIALS_TYPE_LINUX_UCRED);
732       g_assert (native_creds != NULL);
733       g_assert (native_creds->uid == getuid ());
734       g_assert (native_creds->gid == getgid ());
735       g_assert (native_creds->pid == getpid ());
736     }
737     g_object_unref (credentials);
738 #else
739     g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
740     g_assert (credentials == NULL);
741 #endif
742   }
743
744
745   /* bring up a connection - don't accept it - this should fail
746    */
747   data.accept_connection = FALSE;
748   error = NULL;
749   c2 = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (server),
750                                                G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
751                                                NULL, /* GDBusAuthObserver */
752                                                NULL, /* cancellable */
753                                                &error);
754   _g_assert_error_domain (error, G_IO_ERROR);
755   g_assert (c2 == NULL);
756
757 #if 0
758   /* TODO: THIS TEST DOESN'T WORK YET */
759
760   /* bring up a connection - accept it.. then disconnect from the client side - check
761    * that the server side gets the disconnect signal.
762    */
763   error = NULL;
764   data.accept_connection = TRUE;
765   c2 = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (server),
766                                                G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
767                                                NULL, /* GDBusAuthObserver */
768                                                NULL, /* cancellable */
769                                                &error);
770   g_assert_no_error (error);
771   g_assert (c2 != NULL);
772   g_assert (!g_dbus_connection_get_is_disconnected (c2));
773   while (data.num_connection_attempts < 3)
774     g_main_loop_run (loop);
775   g_assert_cmpint (data.current_connections->len, ==, 2);
776   g_assert_cmpint (data.num_connection_attempts, ==, 3);
777   g_assert (!g_dbus_connection_get_is_disconnected (G_DBUS_CONNECTION (data.current_connections->pdata[1])));
778   g_idle_add (on_do_disconnect_in_idle, c2);
779   g_debug ("==================================================");
780   g_debug ("==================================================");
781   g_debug ("==================================================");
782   g_debug ("waiting for disconnect on connection %p, stream %p",
783            data.current_connections->pdata[1],
784            g_dbus_connection_get_stream (data.current_connections->pdata[1]));
785
786   g_timeout_add (2000, check_connection, &data);
787   //_g_assert_signal_received (G_DBUS_CONNECTION (data.current_connections->pdata[1]), "closed");
788   g_main_loop_run (loop);
789   g_assert (g_dbus_connection_get_is_disconnected (G_DBUS_CONNECTION (data.current_connections->pdata[1])));
790   g_ptr_array_set_size (data.current_connections, 1); /* remove disconnected connection object */
791 #endif
792
793   /* unref the server and stop listening for new connections
794    *
795    * This won't bring down the established connections - check that c is still connected
796    * by invoking a method
797    */
798   //g_socket_service_stop (service);
799   //g_object_unref (service);
800   g_dbus_server_stop (server);
801   g_object_unref (server);
802   server = NULL;
803
804   error = NULL;
805   result = g_dbus_proxy_call_sync (proxy,
806                                    "HelloPeer",
807                                    g_variant_new ("(s)", "Hey Again Peer!"),
808                                    G_DBUS_CALL_FLAGS_NONE,
809                                    -1,
810                                    NULL,  /* GCancellable */
811                                    &error);
812   g_assert_no_error (error);
813   g_variant_get (result, "(&s)", &s);
814   g_assert_cmpstr (s, ==, "You greeted me with 'Hey Again Peer!'.");
815   g_variant_unref (result);
816   g_assert_cmpint (data.num_method_calls, ==, 5);
817
818 #if 0
819   /* TODO: THIS TEST DOESN'T WORK YET */
820
821   /* now disconnect from the server side - check that the client side gets the signal */
822   g_assert_cmpint (data.current_connections->len, ==, 1);
823   g_assert (G_DBUS_CONNECTION (data.current_connections->pdata[0]) != c);
824   g_dbus_connection_disconnect (G_DBUS_CONNECTION (data.current_connections->pdata[0]));
825   if (!g_dbus_connection_get_is_disconnected (c))
826     _g_assert_signal_received (c, "closed");
827   g_assert (g_dbus_connection_get_is_disconnected (c));
828 #endif
829
830   g_object_unref (c);
831   g_ptr_array_unref (data.current_connections);
832   g_object_unref (proxy);
833
834   g_main_loop_quit (service_loop);
835   g_thread_join (service_thread);
836 }
837
838 /* ---------------------------------------------------------------------------------------------------- */
839
840 typedef struct
841 {
842   GDBusServer *server;
843   GMainContext *context;
844   GMainLoop *loop;
845
846   GList *connections;
847 } DmpData;
848
849 static void
850 dmp_data_free (DmpData *data)
851 {
852   g_main_loop_unref (data->loop);
853   g_main_context_unref (data->context);
854   g_object_unref (data->server);
855   g_list_foreach (data->connections, (GFunc) g_object_unref, NULL);
856   g_list_free (data->connections);
857   g_free (data);
858 }
859
860 static void
861 dmp_on_method_call (GDBusConnection       *connection,
862                     const gchar           *sender,
863                     const gchar           *object_path,
864                     const gchar           *interface_name,
865                     const gchar           *method_name,
866                     GVariant              *parameters,
867                     GDBusMethodInvocation *invocation,
868                     gpointer               user_data)
869 {
870   //DmpData *data = user_data;
871   gint32 first;
872   gint32 second;
873   g_variant_get (parameters,
874                  "(ii)",
875                  &first,
876                  &second);
877   g_dbus_method_invocation_return_value (invocation,
878                                          g_variant_new ("(i)", first + second));
879 }
880
881 static const GDBusInterfaceVTable dmp_interface_vtable =
882 {
883   dmp_on_method_call,
884   NULL,  /* get_property */
885   NULL   /* set_property */
886 };
887
888
889 /* Runs in thread we created GDBusServer in (since we didn't pass G_DBUS_SERVER_FLAGS_RUN_IN_THREAD) */
890 static void
891 dmp_on_new_connection (GDBusServer     *server,
892                        GDBusConnection *connection,
893                        gpointer         user_data)
894 {
895   DmpData *data = user_data;
896   GDBusNodeInfo *node;
897   GError *error;
898
899   /* accept the connection */
900   data->connections = g_list_prepend (data->connections, g_object_ref (connection));
901
902   error = NULL;
903   node = g_dbus_node_info_new_for_xml ("<node>"
904                                        "  <interface name='org.gtk.GDBus.DmpInterface'>"
905                                        "    <method name='AddPair'>"
906                                        "      <arg type='i' name='first' direction='in'/>"
907                                        "      <arg type='i' name='second' direction='in'/>"
908                                        "      <arg type='i' name='sum' direction='out'/>"
909                                        "    </method>"
910                                        "  </interface>"
911                                        "</node>",
912                                        &error);
913   g_assert_no_error (error);
914
915   /* sleep 100ms before exporting an object - this is to test that
916    * G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING really works
917    * (GDBusServer uses this feature).
918    */
919   usleep (100 * 1000);
920
921   /* export an object */
922   error = NULL;
923   g_dbus_connection_register_object (connection,
924                                      "/dmp/test",
925                                      node->interfaces[0],
926                                      &dmp_interface_vtable,
927                                      data,
928                                      NULL,
929                                      &error);
930   g_dbus_node_info_unref (node);
931 }
932
933 static gpointer
934 dmp_thread_func (gpointer user_data)
935 {
936   DmpData *data = user_data;
937   GError *error;
938   gchar *guid;
939
940   data->context = g_main_context_new ();
941   g_main_context_push_thread_default (data->context);
942
943   error = NULL;
944   guid = g_dbus_generate_guid ();
945   data->server = g_dbus_server_new_sync ("unix:tmpdir=/tmp/gdbus-test-",
946                                          G_DBUS_SERVER_FLAGS_NONE,
947                                          guid,
948                                          NULL, /* GDBusAuthObserver */
949                                          NULL, /* GCancellable */
950                                          &error);
951   g_assert_no_error (error);
952   g_signal_connect (data->server,
953                     "new-connection",
954                     G_CALLBACK (dmp_on_new_connection),
955                     data);
956
957   g_dbus_server_start (data->server);
958
959   data->loop = g_main_loop_new (data->context, FALSE);
960   g_main_loop_run (data->loop);
961
962   g_main_context_pop_thread_default (data->context);
963
964   g_free (guid);
965   return NULL;
966 }
967
968 static void
969 delayed_message_processing (void)
970 {
971   GError *error;
972   DmpData *data;
973   GThread *service_thread;
974   guint n;
975
976   data = g_new0 (DmpData, 1);
977
978   error = NULL;
979   service_thread = g_thread_create (dmp_thread_func,
980                                     data,
981                                     TRUE,
982                                     &error);
983   while (data->server == NULL || !g_dbus_server_is_active (data->server))
984     g_thread_yield ();
985
986   for (n = 0; n < 5; n++)
987     {
988       GDBusConnection *c;
989       GVariant *res;
990       gint32 val;
991
992       error = NULL;
993       c = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (data->server),
994                                                   G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
995                                                   NULL, /* GDBusAuthObserver */
996                                                   NULL, /* GCancellable */
997                                                   &error);
998       g_assert_no_error (error);
999
1000       error = NULL;
1001       res = g_dbus_connection_call_sync (c,
1002                                          NULL,    /* bus name */
1003                                          "/dmp/test",
1004                                          "org.gtk.GDBus.DmpInterface",
1005                                          "AddPair",
1006                                          g_variant_new ("(ii)", 2, n),
1007                                          G_VARIANT_TYPE ("(i)"),
1008                                          G_DBUS_CALL_FLAGS_NONE,
1009                                          -1, /* timeout_msec */
1010                                          NULL, /* GCancellable */
1011                                          &error);
1012       g_assert_no_error (error);
1013       g_variant_get (res, "(i)", &val);
1014       g_assert_cmpint (val, ==, 2 + n);
1015       g_variant_unref (res);
1016       g_object_unref (c);
1017   }
1018
1019   g_main_loop_quit (data->loop);
1020   g_thread_join (service_thread);
1021   dmp_data_free (data);
1022 }
1023
1024 /* ---------------------------------------------------------------------------------------------------- */
1025
1026 static gboolean
1027 nonce_tcp_on_authorize_authenticated_peer (GDBusAuthObserver *observer,
1028                                            GIOStream         *stream,
1029                                            GCredentials      *credentials,
1030                                            gpointer           user_data)
1031 {
1032   PeerData *data = user_data;
1033   gboolean authorized;
1034
1035   data->num_connection_attempts++;
1036
1037   authorized = TRUE;
1038   if (!data->accept_connection)
1039     {
1040       authorized = FALSE;
1041       g_main_loop_quit (loop);
1042     }
1043
1044   return authorized;
1045 }
1046
1047 /* Runs in thread we created GDBusServer in (since we didn't pass G_DBUS_SERVER_FLAGS_RUN_IN_THREAD) */
1048 static void
1049 nonce_tcp_on_new_connection (GDBusServer *server,
1050                              GDBusConnection *connection,
1051                              gpointer user_data)
1052 {
1053   PeerData *data = user_data;
1054
1055   g_ptr_array_add (data->current_connections, g_object_ref (connection));
1056
1057   g_main_loop_quit (loop);
1058 }
1059
1060 static gpointer
1061 nonce_tcp_service_thread_func (gpointer user_data)
1062 {
1063   PeerData *data = user_data;
1064   GMainContext *service_context;
1065   GDBusAuthObserver *observer;
1066   GError *error;
1067
1068   service_context = g_main_context_new ();
1069   g_main_context_push_thread_default (service_context);
1070
1071   error = NULL;
1072   observer = g_dbus_auth_observer_new ();
1073   server = g_dbus_server_new_sync ("nonce-tcp:",
1074                                    G_DBUS_SERVER_FLAGS_NONE,
1075                                    test_guid,
1076                                    observer,
1077                                    NULL, /* cancellable */
1078                                    &error);
1079   g_assert_no_error (error);
1080
1081   g_signal_connect (server,
1082                     "new-connection",
1083                     G_CALLBACK (nonce_tcp_on_new_connection),
1084                     data);
1085   g_signal_connect (observer,
1086                     "authorize-authenticated-peer",
1087                     G_CALLBACK (nonce_tcp_on_authorize_authenticated_peer),
1088                     data);
1089   g_object_unref (observer);
1090
1091   g_dbus_server_start (server);
1092
1093   service_loop = g_main_loop_new (service_context, FALSE);
1094   g_main_loop_run (service_loop);
1095
1096   g_main_context_pop_thread_default (service_context);
1097
1098   g_main_loop_unref (service_loop);
1099   g_main_context_unref (service_context);
1100
1101   /* test code specifically unrefs the server - see below */
1102   g_assert (server == NULL);
1103
1104   return NULL;
1105 }
1106
1107 static void
1108 test_nonce_tcp (void)
1109 {
1110   PeerData data;
1111   GError *error;
1112   GThread *service_thread;
1113   GDBusConnection *c;
1114   gchar *s;
1115   gchar *nonce_file;
1116   gboolean res;
1117   const gchar *address;
1118
1119   memset (&data, '\0', sizeof (PeerData));
1120   data.current_connections = g_ptr_array_new_with_free_func (g_object_unref);
1121
1122   error = NULL;
1123   server = NULL;
1124   service_loop = NULL;
1125   service_thread = g_thread_create (nonce_tcp_service_thread_func,
1126                                     &data,
1127                                     TRUE,
1128                                     &error);
1129   while (service_loop == NULL)
1130     g_thread_yield ();
1131   g_assert (server != NULL);
1132
1133
1134   /* bring up a connection and accept it */
1135   data.accept_connection = TRUE;
1136   error = NULL;
1137   c = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (server),
1138                                               G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
1139                                               NULL, /* GDBusAuthObserver */
1140                                               NULL, /* cancellable */
1141                                               &error);
1142   g_assert_no_error (error);
1143   g_assert (c != NULL);
1144   while (data.current_connections->len < 1)
1145     g_main_loop_run (loop);
1146   g_assert_cmpint (data.current_connections->len, ==, 1);
1147   g_assert_cmpint (data.num_connection_attempts, ==, 1);
1148   g_assert (g_dbus_connection_get_unique_name (c) == NULL);
1149   g_assert_cmpstr (g_dbus_connection_get_guid (c), ==, test_guid);
1150   g_object_unref (c);
1151
1152   /* now, try to subvert the nonce file (this assumes noncefile is the last key/value pair)
1153    */
1154
1155   address = g_dbus_server_get_client_address (server);
1156
1157   s = strstr (address, "noncefile=");
1158   g_assert (s != NULL);
1159   s += sizeof "noncefile=" - 1;
1160   nonce_file = g_strdup (s);
1161
1162   /* First try invalid data in the nonce file - this will actually
1163    * make the client send this and the server will reject it. The way
1164    * it works is that if the nonce doesn't match, the server will
1165    * simply close the connection. So, from the client point of view,
1166    * we can see a variety of errors.
1167    */
1168   error = NULL;
1169   res = g_file_set_contents (nonce_file,
1170                              "0123456789012345",
1171                              -1,
1172                              &error);
1173   g_assert_no_error (error);
1174   g_assert (res);
1175   c = g_dbus_connection_new_for_address_sync (address,
1176                                               G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
1177                                               NULL, /* GDBusAuthObserver */
1178                                               NULL, /* cancellable */
1179                                               &error);
1180   _g_assert_error_domain (error, G_IO_ERROR);
1181   g_assert (c == NULL);
1182
1183   /* Then try with a nonce-file of incorrect length - this will make
1184    * the client complain - we won't even try connecting to the server
1185    * for this
1186    */
1187   error = NULL;
1188   res = g_file_set_contents (nonce_file,
1189                              "0123456789012345_",
1190                              -1,
1191                              &error);
1192   g_assert_no_error (error);
1193   g_assert (res);
1194   c = g_dbus_connection_new_for_address_sync (address,
1195                                               G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
1196                                               NULL, /* GDBusAuthObserver */
1197                                               NULL, /* cancellable */
1198                                               &error);
1199   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1200   g_assert (c == NULL);
1201
1202   /* Finally try with no nonce-file at all */
1203   g_assert_cmpint (g_unlink (nonce_file), ==, 0);
1204   error = NULL;
1205   c = g_dbus_connection_new_for_address_sync (address,
1206                                               G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
1207                                               NULL, /* GDBusAuthObserver */
1208                                               NULL, /* cancellable */
1209                                               &error);
1210   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
1211   g_assert (c == NULL);
1212
1213   g_free (nonce_file);
1214
1215   g_dbus_server_stop (server);
1216   g_object_unref (server);
1217   server = NULL;
1218
1219   g_main_loop_quit (service_loop);
1220   g_thread_join (service_thread);
1221 }
1222
1223 static void
1224 test_credentials (void)
1225 {
1226   GCredentials *c1, *c2;
1227   GError *error;
1228   gchar *desc;
1229
1230   c1 = g_credentials_new ();
1231   c2 = g_credentials_new ();
1232
1233   error = NULL;
1234   if (g_credentials_set_unix_user (c2, getuid (), &error))
1235     g_assert_no_error (error);
1236
1237   g_clear_error (&error);
1238   g_assert (g_credentials_is_same_user (c1, c2, &error));
1239   g_assert_no_error (error);
1240
1241   desc = g_credentials_to_string (c1);
1242   g_assert (desc != NULL);
1243   g_free (desc);
1244
1245   g_object_unref (c1);
1246   g_object_unref (c2);
1247 }
1248
1249 /* ---------------------------------------------------------------------------------------------------- */
1250
1251 #ifdef G_OS_UNIX
1252
1253 /* Chosen to be big enough to overflow the socket buffer */
1254 #define OVERFLOW_NUM_SIGNALS 5000
1255 #define OVERFLOW_TIMEOUT_SEC 10
1256
1257 static GDBusMessageFilterResult
1258 overflow_filter_func (GDBusConnection *connection,
1259                       GDBusMessage    *message,
1260                       gboolean         incoming,
1261                       gpointer         user_data)
1262 {
1263   volatile gint *counter = user_data;
1264   *counter += 1;
1265   return G_DBUS_MESSAGE_FILTER_RESULT_NO_EFFECT;
1266 }
1267
1268 static gboolean
1269 overflow_on_500ms_later_func (gpointer user_data)
1270 {
1271   g_main_loop_quit (loop);
1272   return FALSE; /* don't keep the idle */
1273 }
1274
1275 static void
1276 test_overflow (void)
1277 {
1278   gint sv[2];
1279   gint n;
1280   GSocket *socket;
1281   GSocketConnection *socket_connection;
1282   GDBusConnection *producer, *consumer;
1283   GError *error;
1284   GTimer *timer;
1285   volatile gint n_messages_received;
1286   volatile gint n_messages_sent;
1287
1288   g_assert_cmpint (socketpair (AF_UNIX, SOCK_STREAM, 0, sv), ==, 0);
1289
1290   error = NULL;
1291   socket = g_socket_new_from_fd (sv[0], &error);
1292   g_assert_no_error (error);
1293   socket_connection = g_socket_connection_factory_create_connection (socket);
1294   g_assert (socket_connection != NULL);
1295   g_object_unref (socket);
1296   producer = g_dbus_connection_new_sync (G_IO_STREAM (socket_connection),
1297                                          NULL, /* guid */
1298                                          G_DBUS_CONNECTION_FLAGS_NONE,
1299                                          NULL, /* GDBusAuthObserver */
1300                                          NULL, /* GCancellable */
1301                                          &error);
1302   g_dbus_connection_set_exit_on_close (producer, TRUE);
1303   g_assert_no_error (error);
1304   g_object_unref (socket_connection);
1305   n_messages_sent = 0;
1306   g_dbus_connection_add_filter (producer, overflow_filter_func, (gpointer) &n_messages_sent, NULL);
1307
1308   /* send enough data that we get an EAGAIN */
1309   for (n = 0; n < OVERFLOW_NUM_SIGNALS; n++)
1310     {
1311       error = NULL;
1312       g_dbus_connection_emit_signal (producer,
1313                                      NULL, /* destination */
1314                                      "/org/foo/Object",
1315                                      "org.foo.Interface",
1316                                      "Member",
1317                                      g_variant_new ("(s)", "a string"),
1318                                      &error);
1319       g_assert_no_error (error);
1320     }
1321
1322   /* sleep for 0.5 sec (to allow the GDBus IO thread to fill up the
1323    * kernel buffers) and verify that n_messages_sent <
1324    * OVERFLOW_NUM_SIGNALS
1325    *
1326    * This is to verify that not all the submitted messages have been
1327    * sent to the underlying transport.
1328    */
1329   g_timeout_add (500, overflow_on_500ms_later_func, NULL);
1330   g_main_loop_run (loop);
1331   g_assert_cmpint (n_messages_sent, <, OVERFLOW_NUM_SIGNALS);
1332
1333   /* now suck it all out as a client, and add it up */
1334   socket = g_socket_new_from_fd (sv[1], &error);
1335   g_assert_no_error (error);
1336   socket_connection = g_socket_connection_factory_create_connection (socket);
1337   g_assert (socket_connection != NULL);
1338   g_object_unref (socket);
1339   consumer = g_dbus_connection_new_sync (G_IO_STREAM (socket_connection),
1340                                          NULL, /* guid */
1341                                          G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING,
1342                                          NULL, /* GDBusAuthObserver */
1343                                          NULL, /* GCancellable */
1344                                          &error);
1345   g_assert_no_error (error);
1346   g_object_unref (socket_connection);
1347   n_messages_received = 0;
1348   g_dbus_connection_add_filter (consumer, overflow_filter_func, (gpointer) &n_messages_received, NULL);
1349   g_dbus_connection_start_message_processing (consumer);
1350
1351   timer = g_timer_new ();
1352   g_timer_start (timer);
1353
1354   while (n_messages_received < OVERFLOW_NUM_SIGNALS && g_timer_elapsed (timer, NULL) < OVERFLOW_TIMEOUT_SEC)
1355       g_main_context_iteration (NULL, FALSE);
1356
1357   g_assert_cmpint (n_messages_sent, ==, OVERFLOW_NUM_SIGNALS);
1358   g_assert_cmpint (n_messages_received, ==, OVERFLOW_NUM_SIGNALS);
1359
1360   g_timer_destroy (timer);
1361   g_object_unref (consumer);
1362   g_object_unref (producer);
1363 }
1364 #else
1365 static void
1366 test_overflow (void)
1367 {
1368   /* TODO: test this with e.g. GWin32InputStream/GWin32OutputStream */
1369 }
1370 #endif
1371
1372 /* ---------------------------------------------------------------------------------------------------- */
1373
1374 int
1375 main (int   argc,
1376       char *argv[])
1377 {
1378   gint ret;
1379   GDBusNodeInfo *introspection_data = NULL;
1380
1381   g_type_init ();
1382   g_thread_init (NULL);
1383   g_test_init (&argc, &argv, NULL);
1384
1385   introspection_data = g_dbus_node_info_new_for_xml (test_interface_introspection_xml, NULL);
1386   g_assert (introspection_data != NULL);
1387   test_interface_introspection_data = introspection_data->interfaces[0];
1388
1389   test_guid = g_dbus_generate_guid ();
1390
1391   /* all the tests rely on a shared main loop */
1392   loop = g_main_loop_new (NULL, FALSE);
1393
1394   g_test_add_func ("/gdbus/peer-to-peer", test_peer);
1395   g_test_add_func ("/gdbus/delayed-message-processing", delayed_message_processing);
1396   g_test_add_func ("/gdbus/nonce-tcp", test_nonce_tcp);
1397   g_test_add_func ("/gdbus/credentials", test_credentials);
1398   g_test_add_func ("/gdbus/overflow", test_overflow);
1399
1400   ret = g_test_run();
1401
1402   g_main_loop_unref (loop);
1403   g_free (test_guid);
1404   g_dbus_node_info_unref (introspection_data);
1405
1406   return ret;
1407 }