2005-03-01 Colin Walters <walters@verbum.org>
[platform/upstream/dbus.git] / test / glib / test-dbus-glib.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 #include <dbus/dbus-glib.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include "test-service-glib-bindings.h"
7 #include <glib/dbus-gidl.h>
8 #include <glib/dbus-gparser.h>
9
10 static GMainLoop *loop = NULL;
11 static int n_times_foo_received = 0;
12
13 static gboolean
14 timed_exit (gpointer loop)
15 {
16   g_main_loop_quit (loop);
17   return TRUE;
18 }
19
20 static void
21 foo_signal_handler (DBusGProxy  *proxy,
22                     double       d,
23                     void        *user_data)
24 {
25   n_times_foo_received += 1;
26
27   g_main_loop_quit (loop);
28 }
29
30 static void lose (const char *fmt, ...) G_GNUC_NORETURN G_GNUC_PRINTF (1, 2);
31 static void lose_gerror (const char *prefix, GError *error) G_GNUC_NORETURN;
32
33 static void
34 lose (const char *str, ...)
35 {
36   va_list args;
37
38   va_start (args, str);
39
40   vfprintf (stderr, str, args);
41   fputc ('\n', stderr);
42
43   va_end (args);
44
45   exit (1);
46 }
47
48 static void
49 lose_gerror (const char *prefix, GError *error) 
50 {
51   lose ("%s: %s", prefix, error->message);
52 }
53
54 int
55 main (int argc, char **argv)
56 {
57   DBusGConnection *connection;
58   GError *error;
59   DBusGProxy *driver;
60   DBusGProxy *proxy;
61   DBusGPendingCall *call;
62   char **name_list;
63   int name_list_len;
64   int i;
65   guint32 result;
66   const char *v_STRING;
67   char *v_STRING_2;
68   guint32 v_UINT32;
69   guint32 v_UINT32_2;
70   double v_DOUBLE;
71   double v_DOUBLE_2;
72     
73   g_type_init ();
74   
75   loop = g_main_loop_new (NULL, FALSE);
76
77   error = NULL;
78   connection = dbus_g_bus_get (DBUS_BUS_SESSION,
79                                &error);
80   if (connection == NULL)
81     lose_gerror ("Failed to open connection to bus", error);
82
83   /* should always get the same one */
84   g_assert (connection == dbus_g_bus_get (DBUS_BUS_SESSION, NULL));
85   g_assert (connection == dbus_g_bus_get (DBUS_BUS_SESSION, NULL));
86   g_assert (connection == dbus_g_bus_get (DBUS_BUS_SESSION, NULL));
87   
88   /* Create a proxy object for the "bus driver" */
89   
90   driver = dbus_g_proxy_new_for_name (connection,
91                                       DBUS_SERVICE_DBUS,
92                                       DBUS_PATH_DBUS,
93                                       DBUS_INTERFACE_DBUS);
94
95   /* Call ListNames method */
96   
97   call = dbus_g_proxy_begin_call (driver, "ListNames", DBUS_TYPE_INVALID);
98
99   error = NULL;
100   if (!dbus_g_proxy_end_call (driver, call, &error,
101                               DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
102                               &name_list, &name_list_len,
103                               DBUS_TYPE_INVALID))
104     lose_gerror ("Failed to complete ListNames call", error);
105
106   g_print ("Names on the message bus:\n");
107   i = 0;
108   while (i < name_list_len)
109     {
110       g_assert (name_list[i] != NULL);
111       g_print ("  %s\n", name_list[i]);
112       ++i;
113     }
114   g_assert (name_list[i] == NULL);
115
116   g_strfreev (name_list);
117
118   /* Test handling of unknown method */
119   v_STRING = "blah blah blah blah blah";
120   v_UINT32 = 10;
121   call = dbus_g_proxy_begin_call (driver, "ThisMethodDoesNotExist",
122                                   DBUS_TYPE_STRING,
123                                   &v_STRING,
124                                   DBUS_TYPE_INT32,
125                                   &v_UINT32,
126                                   DBUS_TYPE_INVALID);
127
128   error = NULL;
129   if (dbus_g_proxy_end_call (driver, call, &error,
130                              DBUS_TYPE_INVALID))
131     lose ("Calling nonexistent method succeeded!");
132
133   g_print ("Got EXPECTED error from calling unknown method: %s\n", error->message);
134   g_error_free (error);
135   
136   /* Activate a service */
137   v_STRING = "org.freedesktop.DBus.TestSuiteEchoService";
138   v_UINT32 = 0;
139   call = dbus_g_proxy_begin_call (driver, "StartServiceByName",
140                                   DBUS_TYPE_STRING,
141                                   &v_STRING,
142                                   DBUS_TYPE_UINT32,
143                                   &v_UINT32,
144                                   DBUS_TYPE_INVALID);
145
146   error = NULL;
147   if (!dbus_g_proxy_end_call (driver, call, &error,
148                               DBUS_TYPE_UINT32, &result,
149                               DBUS_TYPE_INVALID))
150     lose_gerror ("Failed to complete Activate call", error);
151
152   g_print ("Starting echo service result = 0x%x\n", result);
153
154   /* Activate a service again */
155   v_STRING = "org.freedesktop.DBus.TestSuiteEchoService";
156   v_UINT32 = 0;
157   call = dbus_g_proxy_begin_call (driver, "StartServiceByName",
158                                   DBUS_TYPE_STRING,
159                                   &v_STRING,
160                                   DBUS_TYPE_UINT32,
161                                   &v_UINT32,
162                                   DBUS_TYPE_INVALID);
163
164   error = NULL;
165   if (!dbus_g_proxy_end_call (driver, call, &error,
166                              DBUS_TYPE_UINT32, &result,
167                              DBUS_TYPE_INVALID))
168     lose_gerror ("Failed to complete Activate call", error);
169
170   g_print ("Duplicate start of echo service = 0x%x\n", result);
171
172   /* Talk to the new service */
173   
174   proxy = dbus_g_proxy_new_for_name_owner (connection,
175                                            "org.freedesktop.DBus.TestSuiteEchoService",
176                                            "/org/freedesktop/TestSuite",
177                                            "org.freedesktop.TestSuite",
178                                            &error);
179   
180   if (proxy == NULL)
181     lose_gerror ("Failed to create proxy for name owner", error);
182
183   v_STRING = "my string hello";
184   call = dbus_g_proxy_begin_call (proxy, "Echo",
185                                   DBUS_TYPE_STRING,
186                                   &v_STRING,
187                                   DBUS_TYPE_INVALID);
188
189   error = NULL;
190   if (!dbus_g_proxy_end_call (proxy, call, &error,
191                               DBUS_TYPE_STRING, &v_STRING,
192                               DBUS_TYPE_INVALID))
193     lose_gerror ("Failed to complete Echo call", error);
194
195   g_print ("String echoed = \"%s\"\n", v_STRING);
196
197   /* Test oneway call and signal handling */
198
199   dbus_g_proxy_add_signal (proxy, "Foo", DBUS_TYPE_DOUBLE_AS_STRING);
200   
201   dbus_g_proxy_connect_signal (proxy, "Foo",
202                                G_CALLBACK (foo_signal_handler),
203                                NULL, NULL);
204   
205   dbus_g_proxy_call_no_reply (proxy, "EmitFoo",
206                               DBUS_TYPE_INVALID);
207   
208   dbus_g_connection_flush (connection);
209   
210   g_timeout_add (5000, timed_exit, loop);
211
212   g_main_loop_run (loop);
213
214   if (n_times_foo_received != 1)
215     lose ("Foo signal received %d times, should have been 1", n_times_foo_received);
216   
217   /* Activate test servie */ 
218   g_print ("Activating TestSuiteGLibService\n");
219   v_STRING = "org.freedesktop.DBus.TestSuiteGLibService";
220   v_UINT32 = 0;
221   call = dbus_g_proxy_begin_call (driver, "StartServiceByName",
222                                   DBUS_TYPE_STRING,
223                                   &v_STRING,
224                                   DBUS_TYPE_UINT32,
225                                   &v_UINT32,
226                                   DBUS_TYPE_INVALID);
227
228   error = NULL;
229   if (!dbus_g_proxy_end_call (driver, call, &error,
230                              DBUS_TYPE_UINT32, &result,
231                              DBUS_TYPE_INVALID))
232     lose_gerror ("Failed to complete Activate call", error);
233
234   g_object_unref (G_OBJECT (proxy));
235
236   proxy = dbus_g_proxy_new_for_name_owner (connection,
237                                            "org.freedesktop.DBus.TestSuiteGLibService",
238                                            "/org/freedesktop/DBus/Tests/MyTestObject",
239                                            "org.freedesktop.DBus.Tests.MyObject",
240                                            &error);
241   
242   if (proxy == NULL)
243     lose_gerror ("Failed to create proxy for name owner", error);
244
245   call = dbus_g_proxy_begin_call (proxy, "DoNothing",
246                                   DBUS_TYPE_INVALID);
247   error = NULL;
248   if (!dbus_g_proxy_end_call (proxy, call, &error, DBUS_TYPE_INVALID))
249     lose_gerror ("Failed to complete DoNothing call", error);
250
251   v_UINT32 = 42;
252   call = dbus_g_proxy_begin_call (proxy, "Increment",
253                                   DBUS_TYPE_UINT32, &v_UINT32,
254                                   DBUS_TYPE_INVALID);
255   error = NULL;
256   if (!dbus_g_proxy_end_call (proxy, call, &error,
257                               DBUS_TYPE_UINT32, &v_UINT32_2,
258                               DBUS_TYPE_INVALID))
259     lose_gerror ("Failed to complete Increment call", error);
260
261   if (v_UINT32_2 != v_UINT32 + 1)
262     lose ("Increment call returned %d, should be 43", v_UINT32_2);
263
264   call = dbus_g_proxy_begin_call (proxy, "ThrowError", DBUS_TYPE_INVALID);
265   error = NULL;
266   if (dbus_g_proxy_end_call (proxy, call, &error, DBUS_TYPE_INVALID) != FALSE)
267     lose ("ThrowError call unexpectedly succeeded!");
268
269   g_print ("ThrowError failed (as expected) returned error: %s\n", error->message);
270   g_error_free (error);
271
272   v_STRING = "foobar";
273   call = dbus_g_proxy_begin_call (proxy, "Uppercase",
274                                   DBUS_TYPE_STRING, &v_STRING,
275                                   DBUS_TYPE_INVALID);
276   error = NULL;
277   if (!dbus_g_proxy_end_call (proxy, call, &error,
278                               DBUS_TYPE_STRING, &v_STRING_2,
279                               DBUS_TYPE_INVALID))
280     lose_gerror ("Failed to complete Uppercase call", error);
281   if (strcmp ("FOOBAR", v_STRING_2) != 0)
282     lose ("Uppercase call returned unexpected string %s", v_STRING_2);
283
284   v_STRING = "bazwhee";
285   v_UINT32 = 26;
286   v_DOUBLE = G_PI;
287   call = dbus_g_proxy_begin_call (proxy, "ManyArgs",
288                                   DBUS_TYPE_UINT32, &v_UINT32,
289                                   DBUS_TYPE_STRING, &v_STRING,
290                                   DBUS_TYPE_DOUBLE, &v_DOUBLE,
291                                   DBUS_TYPE_INVALID);
292   error = NULL;
293   if (!dbus_g_proxy_end_call (proxy, call, &error,
294                               DBUS_TYPE_DOUBLE, &v_DOUBLE_2,
295                               DBUS_TYPE_STRING, &v_STRING_2,
296                               DBUS_TYPE_INVALID))
297     lose_gerror ("Failed to complete ManyArgs call", error);
298   if (v_DOUBLE_2 < 55 || v_DOUBLE_2 > 56)
299     lose ("ManyArgs call returned unexpected double value %f", v_DOUBLE_2);
300   if (strcmp ("BAZWHEE", v_STRING_2) != 0)
301     lose ("ManyArgs call returned unexpected string %s", v_STRING_2);
302
303   if (!org_freedesktop_DBus_Tests_MyObject_do_nothing (proxy, &error))
304     lose_gerror ("Failed to complete (wrapped) DoNothing call", error);
305
306   if (!org_freedesktop_DBus_Tests_MyObject_increment (proxy, 42, &v_UINT32_2, &error))
307     lose_gerror ("Failed to complete (wrapped) Increment call", error);
308
309   if (v_UINT32_2 != 43)
310     lose ("(wrapped) increment call returned %d, should be 43", v_UINT32_2);
311
312   if (org_freedesktop_DBus_Tests_MyObject_throw_error (proxy, &error) != FALSE)
313     lose ("(wrapped) ThrowError call unexpectedly succeeded!");
314
315   g_print ("(wrapped) ThrowError failed (as expected) returned error: %s\n", error->message);
316   g_error_free (error);
317
318   if (!org_freedesktop_DBus_Tests_MyObject_uppercase (proxy, "foobar", &v_STRING_2, &error)) 
319     lose_gerror ("Failed to complete (wrapped) Uppercase call", error);
320   if (strcmp ("FOOBAR", v_STRING_2) != 0)
321     lose ("(wrapped) Uppercase call returned unexpected string %s", v_STRING_2);
322
323   if (!org_freedesktop_DBus_Tests_MyObject_many_args (proxy, 26, "bazwhee", G_PI,
324                                                       &v_DOUBLE_2, &v_STRING_2, &error))
325     lose_gerror ("Failed to complete (wrapped) ManyArgs call", error);
326
327   if (v_DOUBLE_2 < 55 || v_DOUBLE_2 > 56)
328     
329     lose ("(wrapped) ManyArgs call returned unexpected double value %f", v_DOUBLE_2);
330
331   if (strcmp ("BAZWHEE", v_STRING_2) != 0)
332     lose ("(wrapped) ManyArgs call returned unexpected string %s", v_STRING_2);
333
334   g_object_unref (G_OBJECT (proxy));
335
336   proxy = dbus_g_proxy_new_for_name_owner (connection,
337                                            "org.freedesktop.DBus.TestSuiteGLibService",
338                                            "/org/freedesktop/DBus/Tests/MyTestObject",
339                                            "org.freedesktop.DBus.Introspectable",
340                                            &error);
341   
342   if (proxy == NULL)
343     lose_gerror ("Failed to create proxy for name owner", error);
344
345   call = dbus_g_proxy_begin_call (proxy, "Introspect",
346                                   DBUS_TYPE_INVALID);
347   error = NULL;
348   if (!dbus_g_proxy_end_call (proxy, call, &error,
349                               DBUS_TYPE_STRING, &v_STRING,
350                               DBUS_TYPE_INVALID))
351     lose_gerror ("Failed to complete Introspect call", error);
352
353   /* Could just do strcmp(), but that seems more fragile */
354   {
355     NodeInfo *node;
356     GSList *elt;
357     gboolean found_introspectable;
358     gboolean found_properties;
359     gboolean found_myobject;
360     gboolean found_gtk_myobject;
361
362     node = description_load_from_string (v_STRING, strlen (v_STRING), &error);
363     if (!node)
364       lose_gerror ("Failed to parse introspection data: %s", error);
365
366     found_introspectable = FALSE;
367     found_properties = FALSE;
368     found_gtk_myobject = FALSE;
369     found_myobject = FALSE;
370     for (elt = node_info_get_interfaces (node); elt ; elt = elt->next)
371       {
372         InterfaceInfo *iface = elt->data;
373
374         if (!found_introspectable && strcmp (interface_info_get_name (iface), "org.freedesktop.DBus.Introspectable") == 0)
375           found_introspectable = TRUE;
376         else if (!found_properties && strcmp (interface_info_get_name (iface), "org.freedesktop.DBus.Properties") == 0)
377           found_properties = TRUE;
378         else if (!found_gtk_myobject && strcmp (interface_info_get_name (iface), "org.gtk.objects.MyObject") == 0)
379           found_gtk_myobject = TRUE;
380         else if (!found_myobject && strcmp (interface_info_get_name (iface), "org.freedesktop.DBus.Tests.MyObject") == 0)
381           {
382             GSList *elt;
383             gboolean found_manyargs;
384             
385             found_myobject = TRUE;
386             
387             found_manyargs = FALSE;
388             for (elt = interface_info_get_methods (iface); elt; elt = elt->next)
389               {
390                 MethodInfo *method;
391
392                 method = elt->data;
393                 if (strcmp (method_info_get_name (method), "ManyArgs") == 0)
394                   {
395                     found_manyargs = TRUE;
396                     break;
397                   }
398               }
399             if (!found_manyargs)
400               lose ("Missing method org.freedesktop.DBus.Tests.MyObject.ManyArgs");
401           }
402         else
403           lose ("Unexpected or duplicate interface %s", interface_info_get_name (iface));
404       }
405
406     if (!(found_introspectable && found_gtk_myobject && found_myobject && found_properties))
407       lose ("Missing interface"); 
408   }
409   
410   g_object_unref (G_OBJECT (driver));
411
412   g_print ("Successfully completed %s\n", argv[0]);
413   
414   return 0;
415 }