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