Merge branch 'dbus-1.4' of ssh://git.freedesktop.org/git/dbus/dbus into dbus-1.4
[platform/upstream/dbus.git] / test / test-service.c
1 #include <config.h>
2
3 #include "test-utils.h"
4 #ifdef HAVE_UNISTD_H
5 #include <unistd.h>
6 #endif
7
8 static DBusLoop *loop;
9 static dbus_bool_t already_quit = FALSE;
10 static dbus_bool_t hello_from_self_reply_received = FALSE;
11
12 static void
13 quit (void)
14 {
15   if (!already_quit)
16     {
17       _dbus_loop_quit (loop);
18       already_quit = TRUE;
19     }
20 }
21
22 static void
23 die (const char *message)
24 {
25   fprintf (stderr, "*** test-service: %s", message);
26   exit (1);
27 }
28
29 static void
30 check_hello_from_self_reply (DBusPendingCall *pcall, 
31                              void *user_data)
32 {
33   DBusMessage *reply;
34   DBusMessage *echo_message, *echo_reply = NULL;
35   DBusError error;
36   DBusConnection *connection;
37   
38   int type;
39   
40   dbus_error_init (&error);
41  
42   connection = dbus_bus_get (DBUS_BUS_STARTER, &error);
43   if (connection == NULL)
44     {
45       fprintf (stderr, "*** Failed to open connection to activating message bus: %s\n",
46                error.message);
47       dbus_error_free (&error);
48       die("no memory");
49     }
50
51   
52   echo_message = (DBusMessage *)user_data;
53     
54   reply = dbus_pending_call_steal_reply (pcall);
55     
56   type = dbus_message_get_type (reply);
57     
58   if (type == DBUS_MESSAGE_TYPE_METHOD_RETURN)
59     {
60       const char *s;
61       printf ("Reply from HelloFromSelf received\n");
62      
63       if (!dbus_message_get_args (echo_message,
64                               &error,
65                               DBUS_TYPE_STRING, &s,
66                               DBUS_TYPE_INVALID))
67         {
68             echo_reply = dbus_message_new_error (echo_message,
69                                       error.name,
70                                       error.message);
71
72             if (echo_reply == NULL)
73               die ("No memory\n");
74
75         } 
76       else
77         {  
78           echo_reply = dbus_message_new_method_return (echo_message);
79           if (echo_reply == NULL)
80             die ("No memory\n");
81   
82           if (!dbus_message_append_args (echo_reply,
83                                  DBUS_TYPE_STRING, &s,
84                                  DBUS_TYPE_INVALID))
85             die ("No memory");
86         }
87         
88       if (!dbus_connection_send (connection, echo_reply, NULL))
89         die ("No memory\n");
90       
91       dbus_message_unref (echo_reply);
92     }
93   else if (type == DBUS_MESSAGE_TYPE_ERROR)
94     {
95       dbus_set_error_from_message (&error, reply);
96       printf ("Error type in reply: %s\n", error.message);
97
98       if (strcmp (error.name, DBUS_ERROR_NO_MEMORY) != 0)
99         {
100             echo_reply = dbus_message_new_error (echo_reply,
101                                       error.name,
102                                       error.message);
103
104             if (echo_reply == NULL)
105               die ("No memory\n");
106
107             if (!dbus_connection_send (connection, echo_reply, NULL))
108               die ("No memory\n");
109
110             dbus_message_unref (echo_reply);
111         }
112       dbus_error_free (&error);
113     }
114   else
115      _dbus_assert_not_reached ("Unexpected message received\n");
116
117   hello_from_self_reply_received = TRUE;
118   
119   dbus_message_unref (reply);
120   dbus_message_unref (echo_message);
121   dbus_pending_call_unref (pcall);
122   dbus_connection_unref (connection);
123 }
124
125 static DBusHandlerResult
126 handle_run_hello_from_self (DBusConnection     *connection,
127                                                DBusMessage        *message)
128 {
129   DBusError error;
130   DBusMessage *reply, *self_message;
131   DBusPendingCall *pcall;
132   char *s;
133
134   _dbus_verbose ("sending reply to Echo method\n");
135   
136   dbus_error_init (&error);
137   
138   if (!dbus_message_get_args (message,
139                               &error,
140                               DBUS_TYPE_STRING, &s,
141                               DBUS_TYPE_INVALID))
142     {
143       reply = dbus_message_new_error (message,
144                                       error.name,
145                                       error.message);
146
147       if (reply == NULL)
148         die ("No memory\n");
149
150       if (!dbus_connection_send (connection, reply, NULL))
151         die ("No memory\n");
152
153       dbus_message_unref (reply);
154
155       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
156     }
157     printf ("Sending HelloFromSelf\n");
158
159  _dbus_verbose ("*** Sending message to self\n");
160  self_message = dbus_message_new_method_call ("org.freedesktop.DBus.TestSuiteEchoService",
161                                           "/org/freedesktop/TestSuite",
162                                           "org.freedesktop.TestSuite",
163                                           "HelloFromSelf");
164   
165   if (self_message == NULL)
166     die ("No memory");
167   
168   if (!dbus_connection_send_with_reply (connection, self_message, &pcall, -1))
169     die("No memory");
170   
171   dbus_message_ref (message);
172   if (!dbus_pending_call_set_notify (pcall, check_hello_from_self_reply, (void *)message, NULL))
173     die("No memory");
174     
175   printf ("Sent HelloFromSelf\n");
176   return DBUS_HANDLER_RESULT_HANDLED;
177 }
178
179 static DBusHandlerResult
180 handle_echo (DBusConnection     *connection,
181              DBusMessage        *message)
182 {
183   DBusError error;
184   DBusMessage *reply;
185   char *s;
186
187   _dbus_verbose ("sending reply to Echo method\n");
188   
189   dbus_error_init (&error);
190   
191   if (!dbus_message_get_args (message,
192                               &error,
193                               DBUS_TYPE_STRING, &s,
194                               DBUS_TYPE_INVALID))
195     {
196       reply = dbus_message_new_error (message,
197                                       error.name,
198                                       error.message);
199
200       if (reply == NULL)
201         die ("No memory\n");
202
203       if (!dbus_connection_send (connection, reply, NULL))
204         die ("No memory\n");
205
206       dbus_message_unref (reply);
207
208       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
209     }
210
211   reply = dbus_message_new_method_return (message);
212   if (reply == NULL)
213     die ("No memory\n");
214   
215   if (!dbus_message_append_args (reply,
216                                  DBUS_TYPE_STRING, &s,
217                                  DBUS_TYPE_INVALID))
218     die ("No memory");
219   
220   if (!dbus_connection_send (connection, reply, NULL))
221     die ("No memory\n");
222
223   fprintf (stderr, "Echo service echoed string: \"%s\"\n", s);
224   
225   dbus_message_unref (reply);
226     
227   return DBUS_HANDLER_RESULT_HANDLED;
228 }
229
230 static DBusHandlerResult
231 handle_delay_echo (DBusConnection     *connection,
232                    DBusMessage        *message)
233 {
234   DBusError error;
235   DBusMessage *reply;
236   char *s;
237
238   _dbus_verbose ("sleeping for a short time\n");
239
240   _dbus_sleep_milliseconds (50);
241
242   _dbus_verbose ("sending reply to DelayEcho method\n");
243   
244   dbus_error_init (&error);
245   
246   if (!dbus_message_get_args (message,
247                               &error,
248                               DBUS_TYPE_STRING, &s,
249                               DBUS_TYPE_INVALID))
250     {
251       reply = dbus_message_new_error (message,
252                                       error.name,
253                                       error.message);
254
255       if (reply == NULL)
256         die ("No memory\n");
257
258       if (!dbus_connection_send (connection, reply, NULL))
259         die ("No memory\n");
260
261       dbus_message_unref (reply);
262
263       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
264     }
265
266   reply = dbus_message_new_method_return (message);
267   if (reply == NULL)
268     die ("No memory\n");
269   
270   if (!dbus_message_append_args (reply,
271                                  DBUS_TYPE_STRING, &s,
272                                  DBUS_TYPE_INVALID))
273     die ("No memory");
274   
275   if (!dbus_connection_send (connection, reply, NULL))
276     die ("No memory\n");
277
278   fprintf (stderr, "DelayEcho service echoed string: \"%s\"\n", s);
279   
280   dbus_message_unref (reply);
281     
282   return DBUS_HANDLER_RESULT_HANDLED;
283 }
284
285
286 static void
287 path_unregistered_func (DBusConnection  *connection,
288                         void            *user_data)
289 {
290   /* connection was finalized */
291 }
292
293 static DBusHandlerResult
294 path_message_func (DBusConnection  *connection,
295                    DBusMessage     *message,
296                    void            *user_data)
297 {
298   if (dbus_message_is_method_call (message,
299                                    "org.freedesktop.TestSuite",
300                                    "Echo"))
301     return handle_echo (connection, message);
302   else if (dbus_message_is_method_call (message,
303                                         "org.freedesktop.TestSuite",
304                                         "DelayEcho"))
305     return handle_delay_echo (connection, message);
306   else if (dbus_message_is_method_call (message,
307                                         "org.freedesktop.TestSuite",
308                                         "Exit"))
309     {
310       quit ();
311       return DBUS_HANDLER_RESULT_HANDLED;
312     }
313   else if (dbus_message_is_method_call (message,
314                                         "org.freedesktop.TestSuite",
315                                         "EmitFoo"))
316     {
317       /* Emit the Foo signal */
318       DBusMessage *signal;
319       double v_DOUBLE;
320
321       _dbus_verbose ("emitting signal Foo\n");
322       
323       signal = dbus_message_new_signal ("/org/freedesktop/TestSuite",
324                                         "org.freedesktop.TestSuite",
325                                         "Foo");
326       if (signal == NULL)
327         die ("No memory\n");
328
329       v_DOUBLE = 42.6;
330       if (!dbus_message_append_args (signal,
331                                      DBUS_TYPE_DOUBLE, &v_DOUBLE,
332                                      DBUS_TYPE_INVALID))
333         die ("No memory");
334   
335       if (!dbus_connection_send (connection, signal, NULL))
336         die ("No memory\n");
337       
338       return DBUS_HANDLER_RESULT_HANDLED;
339     }
340     
341   else if (dbus_message_is_method_call (message,
342                                    "org.freedesktop.TestSuite",
343                                    "RunHelloFromSelf"))
344     {
345       return handle_run_hello_from_self (connection, message);
346     }
347   else if (dbus_message_is_method_call (message,
348                                         "org.freedesktop.TestSuite",
349                                         "HelloFromSelf"))
350     {
351         DBusMessage *reply;
352         printf ("Received the HelloFromSelf message\n");
353         
354         reply = dbus_message_new_method_return (message);
355         if (reply == NULL)
356           die ("No memory");
357         
358         if (!dbus_connection_send (connection, reply, NULL))
359           die ("No memory");
360
361         return DBUS_HANDLER_RESULT_HANDLED;
362     }
363   else
364     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
365 }
366
367 static DBusObjectPathVTable
368 echo_vtable = {
369   path_unregistered_func,
370   path_message_func,
371   NULL,
372 };
373
374
375 static const char* echo_path = "/org/freedesktop/TestSuite" ;
376
377 static DBusHandlerResult
378 filter_func (DBusConnection     *connection,
379              DBusMessage        *message,
380              void               *user_data)
381 {
382   if (dbus_message_is_signal (message,
383                               DBUS_INTERFACE_LOCAL,
384                               "Disconnected"))
385     {
386       quit ();
387       return DBUS_HANDLER_RESULT_HANDLED;
388     }
389   else
390     {
391       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
392     }
393 }
394
395 int
396 main (int    argc,
397       char **argv)
398 {
399   DBusError error;
400   int result;
401   DBusConnection *connection;
402   const char *name;
403   dbus_bool_t do_fork;
404
405   if (argc != 3)
406     {
407       name = "org.freedesktop.DBus.TestSuiteEchoService";
408       do_fork = FALSE;
409     }
410   else
411     {
412       name = argv[1];
413 #ifndef DBUS_WIN
414       do_fork = strcmp (argv[2], "fork") == 0;
415 #else
416       do_fork = FALSE;
417 #endif
418     }
419
420   /* The bare minimum for simulating a program "daemonizing"; the intent
421    * is to test services which move from being legacy init scripts to
422    * activated services.
423    * https://bugzilla.redhat.com/show_bug.cgi?id=545267
424    */
425 #ifndef DBUS_WIN
426    if (do_fork)
427     {
428       pid_t pid = fork ();
429       if (pid != 0)
430         exit (0);
431       sleep (1);
432     }
433 #endif
434
435   dbus_error_init (&error);
436   connection = dbus_bus_get (DBUS_BUS_STARTER, &error);
437   if (connection == NULL)
438     {
439       fprintf (stderr, "*** Failed to open connection to activating message bus: %s\n",
440                error.message);
441       dbus_error_free (&error);
442       return 1;
443     }
444
445   loop = _dbus_loop_new ();
446   if (loop == NULL)
447     die ("No memory\n");
448   
449   if (!test_connection_setup (loop, connection))
450     die ("No memory\n");
451
452   if (!dbus_connection_add_filter (connection,
453                                    filter_func, NULL, NULL))
454     die ("No memory");
455
456   if (!dbus_connection_register_object_path (connection,
457                                              echo_path,
458                                              &echo_vtable,
459                                              (void*) 0xdeadbeef))
460     die ("No memory");
461
462   {
463     void *d;
464     if (!dbus_connection_get_object_path_data (connection, echo_path, &d))
465       die ("No memory");
466     if (d != (void*) 0xdeadbeef)
467       die ("dbus_connection_get_object_path_data() doesn't seem to work right\n");
468   }
469
470   result = dbus_bus_request_name (connection, name,
471                                   0, &error);
472   if (dbus_error_is_set (&error))
473     {
474       fprintf (stderr, "Error %s\n", error.message);
475       _dbus_verbose ("*** Failed to acquire service: %s\n",
476                      error.message);
477       dbus_error_free (&error);
478       exit (1);
479     }
480
481   if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
482     {
483       fprintf (stderr, "Unable to acquire service: code %d\n", result);
484       _dbus_verbose ("*** Failed to acquire service: %d\n", result);
485       exit (1);
486     }
487
488   _dbus_verbose ("*** Test service entering main loop\n");
489   _dbus_loop_run (loop);
490   
491   test_connection_shutdown (loop, connection);
492
493   dbus_connection_remove_filter (connection, filter_func, NULL);
494   
495   dbus_connection_unref (connection);
496
497   _dbus_loop_unref (loop);
498   loop = NULL;
499   
500   dbus_shutdown ();
501
502   _dbus_verbose ("*** Test service exiting\n");
503   
504   return 0;
505 }