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