ef75933f75bb3509965ef1c253a47fc88cbacc31
[platform/upstream/dbus.git] / bus / dispatch.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dispatch.c  Message dispatcher
3  *
4  * Copyright (C) 2003  CodeFactory AB
5  * Copyright (C) 2003, 2004, 2005  Red Hat, Inc.
6  * Copyright (C) 2004  Imendio HB
7  *
8  * Licensed under the Academic Free License version 2.1
9  * 
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  * 
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  *
24  */
25
26 #include "dispatch.h"
27 #include "connection.h"
28 #include "driver.h"
29 #include "services.h"
30 #include "activation.h"
31 #include "utils.h"
32 #include "bus.h"
33 #include "signals.h"
34 #include "test.h"
35 #include <dbus/dbus-internals.h>
36 #include <string.h>
37
38 static dbus_bool_t
39 send_one_message (DBusConnection *connection,
40                   BusContext     *context,
41                   DBusConnection *sender,
42                   DBusConnection *addressed_recipient,
43                   DBusMessage    *message,
44                   BusTransaction *transaction,
45                   DBusError      *error)
46 {
47   if (!bus_context_check_security_policy (context, transaction,
48                                           sender,
49                                           addressed_recipient,
50                                           connection,
51                                           message,
52                                           NULL))
53     return TRUE; /* silently don't send it */
54   
55   if (!bus_transaction_send (transaction,
56                              connection,
57                              message))
58     {
59       BUS_SET_OOM (error);
60       return FALSE;
61     }
62
63   return TRUE;
64 }
65
66 dbus_bool_t
67 bus_dispatch_matches (BusTransaction *transaction,
68                       DBusConnection *sender,
69                       DBusConnection *addressed_recipient,
70                       DBusMessage    *message,
71                       DBusError      *error)
72 {
73   DBusError tmp_error;
74   BusConnections *connections;
75   DBusList *recipients;
76   BusMatchmaker *matchmaker;
77   DBusList *link;
78   BusContext *context;
79
80   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
81
82   /* sender and recipient can both be NULL for the bus driver,
83    * or for signals with no particular recipient
84    */
85
86   _dbus_assert (sender == NULL || bus_connection_is_active (sender));
87   _dbus_assert (dbus_message_get_sender (message) != NULL);
88
89   connections = bus_transaction_get_connections (transaction);
90   
91   dbus_error_init (&tmp_error);
92   context = bus_transaction_get_context (transaction);
93   matchmaker = bus_context_get_matchmaker (context);
94
95   recipients = NULL;
96   if (!bus_matchmaker_get_recipients (matchmaker, connections,
97                                       sender, addressed_recipient, message,
98                                       &recipients))
99     {
100       BUS_SET_OOM (error);
101       return FALSE;
102     }
103
104   link = _dbus_list_get_first_link (&recipients);
105   while (link != NULL)
106     {
107       DBusConnection *dest;
108
109       dest = link->data;
110
111       if (!send_one_message (dest, context, sender, addressed_recipient,
112                              message, transaction, &tmp_error))
113         break;
114
115       link = _dbus_list_get_next_link (&recipients, link);
116     }
117
118   _dbus_list_clear (&recipients);
119   
120   if (dbus_error_is_set (&tmp_error))
121     {
122       dbus_move_error (&tmp_error, error);
123       return FALSE;
124     }
125   else
126     return TRUE;
127 }
128
129 static DBusHandlerResult
130 bus_dispatch (DBusConnection *connection,
131               DBusMessage    *message)
132 {
133   const char *sender, *service_name;
134   DBusError error;
135   BusTransaction *transaction;
136   BusContext *context;
137   DBusHandlerResult result;
138   DBusConnection *addressed_recipient;
139   
140   result = DBUS_HANDLER_RESULT_HANDLED;
141   
142   transaction = NULL;
143   addressed_recipient = NULL;
144   dbus_error_init (&error);
145   
146   context = bus_connection_get_context (connection);
147   _dbus_assert (context != NULL);
148   
149   /* If we can't even allocate an OOM error, we just go to sleep
150    * until we can.
151    */
152   while (!bus_connection_preallocate_oom_error (connection))
153     _dbus_wait_for_memory ();
154   
155   /* Ref connection in case we disconnect it at some point in here */
156   dbus_connection_ref (connection);
157   
158   service_name = dbus_message_get_destination (message);
159
160 #ifdef DBUS_ENABLE_VERBOSE_MODE
161   {
162     const char *interface_name, *member_name, *error_name;
163
164     interface_name = dbus_message_get_interface (message);
165     member_name = dbus_message_get_member (message);
166     error_name = dbus_message_get_error_name (message);
167     
168     _dbus_verbose ("DISPATCH: %s %s %s to %s\n",
169                    interface_name ? interface_name : "(no interface)",
170                    member_name ? member_name : "(no member)",
171                    error_name ? error_name : "(no error name)",
172                    service_name ? service_name : "peer");
173   }
174 #endif /* DBUS_ENABLE_VERBOSE_MODE */
175   
176   /* If service_name is NULL, if it's a signal we send it to all
177    * connections with a match rule. If it's not a signal, there
178    * are some special cases here but mostly we just bail out.
179    */
180   if (service_name == NULL)
181     {
182       if (dbus_message_is_signal (message,
183                                   DBUS_INTERFACE_LOCAL,
184                                   "Disconnected"))
185         {
186           bus_connection_disconnected (connection);
187           goto out;
188         }
189
190       if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL)
191         {
192           /* DBusConnection also handles some of these automatically, we leave
193            * it to do so.
194            */
195           result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
196           goto out;
197         }
198     }
199   
200   /* Create our transaction */
201   transaction = bus_transaction_new (context);
202   if (transaction == NULL)
203     {
204       BUS_SET_OOM (&error);
205       goto out;
206     }
207   
208   /* Assign a sender to the message */
209   if (bus_connection_is_active (connection))
210     {
211       sender = bus_connection_get_name (connection);
212       _dbus_assert (sender != NULL);
213
214       if (!dbus_message_set_sender (message, sender))
215         {
216           BUS_SET_OOM (&error);
217           goto out;
218         }
219
220       /* We need to refetch the service name here, because
221        * dbus_message_set_sender can cause the header to be
222        * reallocated, and thus the service_name pointer will become
223        * invalid.
224        */
225       service_name = dbus_message_get_destination (message);
226     }
227   
228   if (service_name &&
229       strcmp (service_name, DBUS_SERVICE_DBUS) == 0) /* to bus driver */
230     {
231       if (!bus_context_check_security_policy (context, transaction,
232                                               connection, NULL, NULL, message, &error))
233         {
234           _dbus_verbose ("Security policy rejected message\n");
235           goto out;
236         }
237
238       _dbus_verbose ("Giving message to %s\n", DBUS_SERVICE_DBUS);
239       if (!bus_driver_handle_message (connection, transaction, message, &error))
240         goto out;
241     }
242   else if (!bus_connection_is_active (connection)) /* clients must talk to bus driver first */
243     {
244       _dbus_verbose ("Received message from non-registered client. Disconnecting.\n");
245       dbus_connection_close (connection);
246       goto out;
247     }
248   else if (service_name != NULL) /* route to named service */
249     {
250       DBusString service_string;
251       BusService *service;
252       BusRegistry *registry;
253
254       _dbus_assert (service_name != NULL);
255       
256       registry = bus_connection_get_registry (connection);
257       
258       _dbus_string_init_const (&service_string, service_name);
259       service = bus_registry_lookup (registry, &service_string);
260
261       if (service == NULL && dbus_message_get_auto_start (message))
262         {
263           BusActivation *activation;
264           /* We can't do the security policy check here, since the addressed
265            * recipient service doesn't exist yet. We do it before sending the
266            * message after the service has been created.
267            */
268           activation = bus_connection_get_activation (connection);
269
270           if (!bus_activation_activate_service (activation, connection, transaction, TRUE,
271                                                 message, service_name, &error))
272             {
273               _DBUS_ASSERT_ERROR_IS_SET (&error);
274               _dbus_verbose ("bus_activation_activate_service() failed: %s\n", error.name);
275               goto out;
276             }
277           
278           goto out;
279         }
280       else if (service == NULL)
281         {
282           dbus_set_error (&error,
283                           DBUS_ERROR_NAME_HAS_NO_OWNER,
284                           "Name \"%s\" does not exist",
285                           service_name);
286           goto out;
287         }
288       else
289         {
290           addressed_recipient = bus_service_get_primary_owners_connection (service);
291           _dbus_assert (addressed_recipient != NULL);
292           
293           if (!bus_context_check_security_policy (context, transaction,
294                                                   connection, addressed_recipient,
295                                                   addressed_recipient,
296                                                   message, &error))
297             goto out;
298           
299           /* Dispatch the message */
300           if (!bus_transaction_send (transaction, addressed_recipient, message))
301             {
302               BUS_SET_OOM (&error);
303               goto out;
304             }
305         }
306     }
307
308   /* Now match the messages against any match rules, which will send
309    * out signals and such. addressed_recipient may == NULL.
310    */
311   if (!bus_dispatch_matches (transaction, connection, addressed_recipient, message, &error))
312     goto out;
313   
314  out:
315   if (dbus_error_is_set (&error))
316     {
317       if (!dbus_connection_get_is_connected (connection))
318         {
319           /* If we disconnected it, we won't bother to send it any error
320            * messages.
321            */
322           _dbus_verbose ("Not sending error to connection we disconnected\n");
323         }
324       else if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
325         {
326           bus_connection_send_oom_error (connection, message);
327
328           /* cancel transaction due to OOM */
329           if (transaction != NULL)
330             {
331               bus_transaction_cancel_and_free (transaction);
332               transaction = NULL;
333             }
334         }
335       else
336         {
337           /* Try to send the real error, if no mem to do that, send
338            * the OOM error
339            */
340           _dbus_assert (transaction != NULL);
341           if (!bus_transaction_send_error_reply (transaction, connection,
342                                                  &error, message))
343             {
344               bus_connection_send_oom_error (connection, message);
345               
346               /* cancel transaction due to OOM */
347               if (transaction != NULL)
348                 {
349                   bus_transaction_cancel_and_free (transaction);
350                   transaction = NULL;
351                 }
352             }
353         }
354      
355       
356       dbus_error_free (&error);
357     }
358
359   if (transaction != NULL)
360     {
361       bus_transaction_execute_and_free (transaction);
362     }
363
364   dbus_connection_unref (connection);
365
366   return result;
367 }
368
369 static DBusHandlerResult
370 bus_dispatch_message_filter (DBusConnection     *connection,
371                              DBusMessage        *message,
372                              void               *user_data)
373 {
374   return bus_dispatch (connection, message);
375 }
376
377 dbus_bool_t
378 bus_dispatch_add_connection (DBusConnection *connection)
379 {  
380   if (!dbus_connection_add_filter (connection,
381                                    bus_dispatch_message_filter,
382                                    NULL, NULL))
383     return FALSE;
384   
385   return TRUE;
386 }
387
388 void
389 bus_dispatch_remove_connection (DBusConnection *connection)
390 {
391   /* Here we tell the bus driver that we want to get off. */
392   bus_driver_remove_connection (connection);
393
394   dbus_connection_remove_filter (connection,
395                                  bus_dispatch_message_filter,
396                                  NULL);
397 }
398
399 #ifdef DBUS_BUILD_TESTS
400
401 #include <stdio.h>
402 #ifdef DBUS_UNIX
403 #include <sys/types.h>
404 #include <unistd.h>
405 #endif
406
407 /* This is used to know whether we need to block in order to finish
408  * sending a message, or whether the initial dbus_connection_send()
409  * already flushed the queue.
410  */
411 #define SEND_PENDING(connection) (dbus_connection_has_messages_to_send (connection))
412
413 typedef dbus_bool_t (* Check1Func) (BusContext     *context);
414 typedef dbus_bool_t (* Check2Func) (BusContext     *context,
415                                     DBusConnection *connection);
416
417 static dbus_bool_t check_no_leftovers (BusContext *context);
418
419 static void
420 block_connection_until_message_from_bus (BusContext     *context,
421                                          DBusConnection *connection,
422                                          const char     *what_is_expected)
423 {
424   _dbus_verbose ("expecting: %s\n", what_is_expected);
425   
426   while (dbus_connection_get_dispatch_status (connection) ==
427          DBUS_DISPATCH_COMPLETE &&
428          dbus_connection_get_is_connected (connection))
429     {
430       bus_test_run_bus_loop (context, TRUE);
431       bus_test_run_clients_loop (FALSE);
432     }
433 }
434
435 static void
436 spin_connection_until_authenticated (BusContext     *context,
437                                      DBusConnection *connection)
438 {
439   _dbus_verbose ("Spinning to auth connection %p\n", connection);
440   while (!dbus_connection_get_is_authenticated (connection) &&
441          dbus_connection_get_is_connected (connection))
442     {
443       bus_test_run_bus_loop (context, FALSE);
444       bus_test_run_clients_loop (FALSE);
445     }
446   _dbus_verbose (" ... done spinning to auth connection %p\n", connection);
447 }
448
449 /* compensate for fact that pop_message() can return #NULL due to OOM */
450 static DBusMessage*
451 pop_message_waiting_for_memory (DBusConnection *connection)
452 {
453   while (dbus_connection_get_dispatch_status (connection) ==
454          DBUS_DISPATCH_NEED_MEMORY)
455     _dbus_wait_for_memory ();
456
457   return dbus_connection_pop_message (connection);
458 }
459
460 static DBusMessage*
461 borrow_message_waiting_for_memory (DBusConnection *connection)
462 {
463   while (dbus_connection_get_dispatch_status (connection) ==
464          DBUS_DISPATCH_NEED_MEMORY)
465     _dbus_wait_for_memory ();
466
467   return dbus_connection_borrow_message (connection);
468 }
469
470 static void
471 warn_unexpected_real (DBusConnection *connection,
472                       DBusMessage    *message,
473                       const char     *expected,
474                       const char     *function,
475                       int             line)
476 {
477   if (message)
478     _dbus_warn ("%s:%d received message interface \"%s\" member \"%s\" error name \"%s\" on %p, expecting %s\n",
479                 function, line,
480                 dbus_message_get_interface (message) ?
481                 dbus_message_get_interface (message) : "(unset)",
482                 dbus_message_get_member (message) ?
483                 dbus_message_get_member (message) : "(unset)",
484                 dbus_message_get_error_name (message) ?
485                 dbus_message_get_error_name (message) : "(unset)",
486                 connection,
487                 expected);
488   else
489     _dbus_warn ("%s:%d received no message on %p, expecting %s\n",
490                 function, line, connection, expected);
491 }
492
493 #define warn_unexpected(connection, message, expected) \
494   warn_unexpected_real (connection, message, expected, _DBUS_FUNCTION_NAME, __LINE__)
495
496 static void
497 verbose_message_received (DBusConnection *connection,
498                           DBusMessage    *message)
499 {
500   _dbus_verbose ("Received message interface \"%s\" member \"%s\" error name \"%s\" on %p\n",
501                  dbus_message_get_interface (message) ?
502                  dbus_message_get_interface (message) : "(unset)",
503                  dbus_message_get_member (message) ?
504                  dbus_message_get_member (message) : "(unset)",
505                  dbus_message_get_error_name (message) ?
506                  dbus_message_get_error_name (message) : "(unset)",
507                  connection);
508 }
509
510 typedef enum
511 {
512   SERVICE_CREATED,
513   OWNER_CHANGED,
514   SERVICE_DELETED
515 } ServiceInfoKind;
516
517 typedef struct
518 {
519   ServiceInfoKind expected_kind;
520   const char *expected_service_name;
521   dbus_bool_t failed;
522   DBusConnection *skip_connection;
523 } CheckServiceOwnerChangedData;
524
525 static dbus_bool_t
526 check_service_owner_changed_foreach (DBusConnection *connection,
527                                      void           *data)
528 {
529   CheckServiceOwnerChangedData *d = data;
530   DBusMessage *message;
531   DBusError error;
532   const char *service_name, *old_owner, *new_owner;
533
534   if (d->expected_kind == SERVICE_CREATED 
535       && connection == d->skip_connection)
536     return TRUE;
537
538   dbus_error_init (&error);
539   d->failed = TRUE;
540   
541   message = pop_message_waiting_for_memory (connection);
542   if (message == NULL)
543     {
544       _dbus_warn ("Did not receive a message on %p, expecting %s\n",
545                   connection, "NameOwnerChanged");
546       goto out;
547     }
548   else if (!dbus_message_is_signal (message,
549                                     DBUS_INTERFACE_DBUS,
550                                     "NameOwnerChanged"))
551     {
552       warn_unexpected (connection, message, "NameOwnerChanged");
553
554       goto out;
555     }
556   else
557     {
558     reget_service_info_data:
559       service_name = NULL;
560       old_owner = NULL;
561       new_owner = NULL;
562
563       dbus_message_get_args (message, &error,
564                              DBUS_TYPE_STRING, &service_name,
565                              DBUS_TYPE_STRING, &old_owner,
566                              DBUS_TYPE_STRING, &new_owner,
567                              DBUS_TYPE_INVALID);
568
569       if (dbus_error_is_set (&error))
570         {
571           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
572             {
573               dbus_error_free (&error);
574               _dbus_wait_for_memory ();              
575               goto reget_service_info_data;
576             }
577           else
578             {
579               _dbus_warn ("Did not get the expected arguments\n");
580               goto out;
581             }
582         }
583
584       if ((d->expected_kind == SERVICE_CREATED    && ( old_owner[0] || !new_owner[0]))
585           || (d->expected_kind == OWNER_CHANGED   && (!old_owner[0] || !new_owner[0]))
586           || (d->expected_kind == SERVICE_DELETED && (!old_owner[0] ||  new_owner[0])))
587         {
588           _dbus_warn ("inconsistent NameOwnerChanged arguments\n");
589           goto out;
590         }
591
592       if (strcmp (service_name, d->expected_service_name) != 0)
593         {
594           _dbus_warn ("expected info on service %s, got info on %s\n",
595                       d->expected_service_name,
596                       service_name);
597           goto out;
598         }
599
600       if (*service_name == ':' && new_owner[0] 
601           && strcmp (service_name, new_owner) != 0)
602         {
603           _dbus_warn ("inconsistent ServiceOwnedChanged message (\"%s\" [ %s -> %s ])\n",
604                       service_name, old_owner, new_owner);
605           goto out;
606         }
607     }
608
609   d->failed = FALSE;
610   
611  out:
612   dbus_error_free (&error);
613   
614   if (message)
615     dbus_message_unref (message);
616
617   return !d->failed;
618 }
619
620
621 static void
622 kill_client_connection (BusContext     *context,
623                         DBusConnection *connection)
624 {
625   char *base_service;
626   const char *s;
627   CheckServiceOwnerChangedData socd;
628
629   _dbus_verbose ("killing connection %p\n", connection);
630   
631   s = dbus_bus_get_unique_name (connection);
632   _dbus_assert (s != NULL);
633
634   while ((base_service = _dbus_strdup (s)) == NULL)
635     _dbus_wait_for_memory ();
636
637   dbus_connection_ref (connection);
638   
639   /* kick in the disconnect handler that unrefs the connection */
640   dbus_connection_close (connection);
641
642   bus_test_run_everything (context);
643   
644   _dbus_assert (bus_test_client_listed (connection));
645   
646   /* Run disconnect handler in test.c */
647   if (bus_connection_dispatch_one_message (connection))
648     _dbus_assert_not_reached ("something received on connection being killed other than the disconnect");
649   
650   _dbus_assert (!dbus_connection_get_is_connected (connection));
651   dbus_connection_unref (connection);
652   connection = NULL;
653   _dbus_assert (!bus_test_client_listed (connection));
654   
655   socd.expected_kind = SERVICE_DELETED;
656   socd.expected_service_name = base_service;
657   socd.failed = FALSE;
658   socd.skip_connection = NULL;
659   
660   bus_test_clients_foreach (check_service_owner_changed_foreach,
661                             &socd);
662
663   dbus_free (base_service);
664   
665   if (socd.failed)
666     _dbus_assert_not_reached ("didn't get the expected NameOwnerChanged (deletion) messages");
667   
668   if (!check_no_leftovers (context))
669     _dbus_assert_not_reached ("stuff left in message queues after disconnecting a client");
670 }
671
672 static void
673 kill_client_connection_unchecked (DBusConnection *connection)
674 {
675   /* This kills the connection without expecting it to affect
676    * the rest of the bus.
677    */  
678   _dbus_verbose ("Unchecked kill of connection %p\n", connection);
679
680   dbus_connection_ref (connection);
681   dbus_connection_close (connection);
682   /* dispatching disconnect handler will unref once */
683   if (bus_connection_dispatch_one_message (connection))
684     _dbus_assert_not_reached ("message other than disconnect dispatched after failure to register");
685
686   _dbus_assert (!bus_test_client_listed (connection));
687   dbus_connection_unref (connection);
688 }
689
690 typedef struct
691 {
692   dbus_bool_t failed;
693 } CheckNoMessagesData;
694
695 static dbus_bool_t
696 check_no_messages_foreach (DBusConnection *connection,
697                            void           *data)
698 {
699   CheckNoMessagesData *d = data;
700   DBusMessage *message;
701
702   message = pop_message_waiting_for_memory (connection);
703   if (message != NULL)
704     {
705       warn_unexpected (connection, message, "no messages");
706
707       d->failed = TRUE;
708     }
709
710   if (message)
711     dbus_message_unref (message);
712   return !d->failed;
713 }
714
715 static dbus_bool_t
716 check_no_leftovers (BusContext *context)
717 {
718   CheckNoMessagesData nmd;
719
720   nmd.failed = FALSE;
721   bus_test_clients_foreach (check_no_messages_foreach,
722                             &nmd);
723   
724   if (nmd.failed)
725     {
726       _dbus_verbose ("%s: leftover message found\n",
727                      _DBUS_FUNCTION_NAME);
728       return FALSE;
729     }
730   else
731     return TRUE;
732 }
733
734 /* returns TRUE if the correct thing happens,
735  * but the correct thing may include OOM errors.
736  */
737 static dbus_bool_t
738 check_hello_message (BusContext     *context,
739                      DBusConnection *connection)
740 {
741   DBusMessage *message;
742   DBusMessage *name_message;
743   dbus_uint32_t serial;
744   dbus_bool_t retval;
745   DBusError error;
746   const char *name;
747   const char *acquired;
748
749   retval = FALSE;
750   dbus_error_init (&error);
751   name = NULL;
752   acquired = NULL;
753   message = NULL;
754   name_message = NULL;
755
756   _dbus_verbose ("check_hello_message for %p\n", connection);
757   
758   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
759                                           DBUS_PATH_DBUS,
760                                           DBUS_INTERFACE_DBUS,
761                                           "Hello");
762
763   if (message == NULL)
764     return TRUE;
765
766   dbus_connection_ref (connection); /* because we may get disconnected */
767   
768   if (!dbus_connection_send (connection, message, &serial))
769     {
770       dbus_message_unref (message);
771       dbus_connection_unref (connection);
772       return TRUE;
773     }
774
775   _dbus_assert (dbus_message_has_signature (message, ""));
776   
777   dbus_message_unref (message);
778   message = NULL;
779
780   if (!dbus_connection_get_is_connected (connection))
781     {
782       _dbus_verbose ("connection was disconnected (presumably auth failed)\n");
783       
784       dbus_connection_unref (connection);
785       
786       return TRUE;
787     }
788   
789   /* send our message */
790   bus_test_run_clients_loop (SEND_PENDING (connection));
791
792   if (!dbus_connection_get_is_connected (connection))
793     {
794       _dbus_verbose ("connection was disconnected (presumably auth failed)\n");
795       
796       dbus_connection_unref (connection);
797       
798       return TRUE;
799     }
800   
801   block_connection_until_message_from_bus (context, connection, "reply to Hello");
802
803   if (!dbus_connection_get_is_connected (connection))
804     {
805       _dbus_verbose ("connection was disconnected (presumably auth failed)\n");
806       
807       dbus_connection_unref (connection);
808       
809       return TRUE;
810     }
811
812   dbus_connection_unref (connection);
813   
814   message = pop_message_waiting_for_memory (connection);
815   if (message == NULL)
816     {
817       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
818                   "Hello", serial, connection);
819       goto out;
820     }
821
822   verbose_message_received (connection, message);
823
824   if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
825     {
826       _dbus_warn ("Message has wrong sender %s\n",
827                   dbus_message_get_sender (message) ?
828                   dbus_message_get_sender (message) : "(none)");
829       goto out;
830     }
831   
832   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
833     {
834       if (dbus_message_is_error (message,
835                                  DBUS_ERROR_NO_MEMORY))
836         {
837           ; /* good, this is a valid response */
838         }
839       else
840         {
841           warn_unexpected (connection, message, "not this error");
842
843           goto out;
844         }
845     }
846   else
847     {
848       CheckServiceOwnerChangedData socd;
849       
850       if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
851         {
852           ; /* good, expected */
853         }
854       else
855         {
856           warn_unexpected (connection, message, "method return for Hello");
857
858           goto out;
859         }
860
861     retry_get_hello_name:
862       if (!dbus_message_get_args (message, &error,
863                                   DBUS_TYPE_STRING, &name,
864                                   DBUS_TYPE_INVALID))
865         {
866           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
867             {
868               _dbus_verbose ("no memory to get service name arg from hello\n");
869               dbus_error_free (&error);
870               _dbus_wait_for_memory ();
871               goto retry_get_hello_name;
872             }
873           else
874             {
875               _dbus_assert (dbus_error_is_set (&error));
876               _dbus_warn ("Did not get the expected single string argument to hello\n");
877               goto out;
878             }
879         }
880
881       _dbus_verbose ("Got hello name: %s\n", name);
882
883       while (!dbus_bus_set_unique_name (connection, name))
884         _dbus_wait_for_memory ();
885       
886       socd.expected_kind = SERVICE_CREATED;
887       socd.expected_service_name = name;
888       socd.failed = FALSE;
889       socd.skip_connection = connection; /* we haven't done AddMatch so won't get it ourselves */
890       bus_test_clients_foreach (check_service_owner_changed_foreach,
891                                 &socd);
892       
893       if (socd.failed)
894         goto out;
895
896       name_message = message;
897       /* Client should also have gotten ServiceAcquired */
898
899       message = pop_message_waiting_for_memory (connection);
900       if (message == NULL)
901         {
902           _dbus_warn ("Expecting %s, got nothing\n",
903                       "NameAcquired");
904           goto out;
905         }
906       if (! dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
907                                     "NameAcquired"))
908         {
909           _dbus_warn ("Expecting %s, got smthg else\n",
910                       "NameAcquired");
911           goto out;
912         }
913       
914     retry_get_acquired_name:
915       if (!dbus_message_get_args (message, &error,
916                                   DBUS_TYPE_STRING, &acquired,
917                                   DBUS_TYPE_INVALID))
918         {
919           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
920             {
921               _dbus_verbose ("no memory to get service name arg from acquired\n");
922               dbus_error_free (&error);
923               _dbus_wait_for_memory ();
924               goto retry_get_acquired_name;
925             }
926           else
927             {
928               _dbus_assert (dbus_error_is_set (&error));
929               _dbus_warn ("Did not get the expected single string argument to ServiceAcquired\n");
930               goto out;
931             }
932         }
933
934       _dbus_verbose ("Got acquired name: %s\n", acquired);
935
936       if (strcmp (acquired, name) != 0)
937         {
938           _dbus_warn ("Acquired name is %s but expected %s\n",
939                       acquired, name);
940           goto out;
941         }
942       acquired = NULL;
943     }
944
945   if (!check_no_leftovers (context))
946     goto out;
947   
948   retval = TRUE;
949   
950  out:
951   _dbus_verbose ("ending %s retval = %d\n", _DBUS_FUNCTION_NAME, retval);
952   
953   dbus_error_free (&error);
954   
955   if (message)
956     dbus_message_unref (message);
957
958   if (name_message)
959     dbus_message_unref (name_message);
960   
961   return retval;
962 }
963
964 /* returns TRUE if the correct thing happens,
965  * but the correct thing may include OOM errors.
966  */
967 static dbus_bool_t
968 check_double_hello_message (BusContext     *context,
969                             DBusConnection *connection)
970 {
971   DBusMessage *message;
972   dbus_uint32_t serial;
973   dbus_bool_t retval;
974   DBusError error;
975
976   retval = FALSE;
977   dbus_error_init (&error);
978   message = NULL;
979
980   _dbus_verbose ("check_double_hello_message for %p\n", connection);
981   
982   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
983                                           DBUS_PATH_DBUS,
984                                           DBUS_INTERFACE_DBUS,
985                                           "Hello");
986
987   if (message == NULL)
988     return TRUE;
989   
990   if (!dbus_connection_send (connection, message, &serial))
991     {
992       dbus_message_unref (message);
993       return TRUE;
994     }
995
996   dbus_message_unref (message);
997   message = NULL;
998
999   /* send our message */
1000   bus_test_run_clients_loop (SEND_PENDING (connection));
1001
1002   dbus_connection_ref (connection); /* because we may get disconnected */
1003   block_connection_until_message_from_bus (context, connection, "reply to Hello");
1004
1005   if (!dbus_connection_get_is_connected (connection))
1006     {
1007       _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
1008       
1009       dbus_connection_unref (connection);
1010       
1011       return TRUE;
1012     }
1013
1014   dbus_connection_unref (connection);
1015   
1016   message = pop_message_waiting_for_memory (connection);
1017   if (message == NULL)
1018     {
1019       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1020                   "Hello", serial, connection);
1021       goto out;
1022     }
1023
1024   verbose_message_received (connection, message);
1025
1026   if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
1027     {
1028       _dbus_warn ("Message has wrong sender %s\n",
1029                   dbus_message_get_sender (message) ?
1030                   dbus_message_get_sender (message) : "(none)");
1031       goto out;
1032     }
1033   
1034   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
1035     {
1036       warn_unexpected (connection, message, "method return for Hello");
1037       goto out;
1038     }
1039
1040   if (!check_no_leftovers (context))
1041     goto out;
1042   
1043   retval = TRUE;
1044   
1045  out:
1046   dbus_error_free (&error);
1047   
1048   if (message)
1049     dbus_message_unref (message);
1050   
1051   return retval;
1052 }
1053
1054 /* returns TRUE if the correct thing happens,
1055  * but the correct thing may include OOM errors.
1056  */
1057 static dbus_bool_t
1058 check_get_connection_unix_user (BusContext     *context,
1059                                 DBusConnection *connection)
1060 {
1061   DBusMessage *message;
1062   dbus_uint32_t serial;
1063   dbus_bool_t retval;
1064   DBusError error;
1065   const char *base_service_name;
1066   dbus_uint32_t uid;
1067
1068   retval = FALSE;
1069   dbus_error_init (&error);
1070   message = NULL;
1071
1072   _dbus_verbose ("check_get_connection_unix_user for %p\n", connection);
1073   
1074   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1075                                           DBUS_PATH_DBUS,
1076                                           DBUS_INTERFACE_DBUS,
1077                                           "GetConnectionUnixUser");
1078
1079   if (message == NULL)
1080     return TRUE;
1081
1082   base_service_name = dbus_bus_get_unique_name (connection);
1083
1084   if (!dbus_message_append_args (message, 
1085                                  DBUS_TYPE_STRING, &base_service_name,
1086                                  DBUS_TYPE_INVALID))
1087     {
1088       dbus_message_unref (message);
1089       return TRUE;
1090     }
1091
1092   if (!dbus_connection_send (connection, message, &serial))
1093     {
1094       dbus_message_unref (message);
1095       return TRUE;
1096     }
1097
1098   /* send our message */
1099   bus_test_run_clients_loop (SEND_PENDING (connection));
1100
1101   dbus_message_unref (message);
1102   message = NULL;
1103
1104   dbus_connection_ref (connection); /* because we may get disconnected */
1105   block_connection_until_message_from_bus (context, connection, "reply to GetConnectionUnixUser");
1106
1107   if (!dbus_connection_get_is_connected (connection))
1108     {
1109       _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
1110       
1111       dbus_connection_unref (connection);
1112       
1113       return TRUE;
1114     }
1115
1116   dbus_connection_unref (connection);
1117
1118   message = pop_message_waiting_for_memory (connection);
1119   if (message == NULL)
1120     {
1121       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1122                   "GetConnectionUnixUser", serial, connection);
1123       goto out;
1124     }
1125
1126   verbose_message_received (connection, message);
1127
1128   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1129     {
1130       if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY))
1131         {
1132           ; /* good, this is a valid response */
1133         }
1134       else
1135         {
1136           warn_unexpected (connection, message, "not this error");
1137
1138           goto out;
1139         }
1140     }
1141   else
1142     {
1143       if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1144         {
1145           ; /* good, expected */
1146         }
1147       else
1148         {
1149           warn_unexpected (connection, message,
1150                            "method_return for GetConnectionUnixUser");
1151
1152           goto out;
1153         }
1154
1155     retry_get_property:
1156
1157       if (!dbus_message_get_args (message, &error,
1158                                   DBUS_TYPE_UINT32, &uid,
1159                                   DBUS_TYPE_INVALID))
1160         {
1161           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1162             {
1163               _dbus_verbose ("no memory to get uid by GetConnectionUnixUser\n");
1164               dbus_error_free (&error);
1165               _dbus_wait_for_memory ();
1166               goto retry_get_property;
1167             }
1168           else
1169             {
1170               _dbus_assert (dbus_error_is_set (&error));
1171               _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetConnectionUnixUser\n");
1172               goto out;
1173             }
1174         }
1175     }
1176
1177   if (!check_no_leftovers (context))
1178     goto out;
1179
1180   retval = TRUE;
1181
1182  out:
1183   dbus_error_free (&error);
1184   
1185   if (message)
1186     dbus_message_unref (message);
1187   
1188   return retval;
1189 }
1190
1191 /* returns TRUE if the correct thing happens,
1192  * but the correct thing may include OOM errors.
1193  */
1194 static dbus_bool_t
1195 check_get_connection_unix_process_id (BusContext     *context,
1196                                       DBusConnection *connection)
1197 {
1198   DBusMessage *message;
1199   dbus_uint32_t serial;
1200   dbus_bool_t retval;
1201   DBusError error;
1202   const char *base_service_name;
1203   dbus_uint32_t pid;
1204
1205   retval = FALSE;
1206   dbus_error_init (&error);
1207   message = NULL;
1208
1209   _dbus_verbose ("check_get_connection_unix_process_id for %p\n", connection);
1210   
1211   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1212                                           DBUS_PATH_DBUS,
1213                                           DBUS_INTERFACE_DBUS,
1214                                           "GetConnectionUnixProcessID");
1215
1216   if (message == NULL)
1217     return TRUE;
1218
1219   base_service_name = dbus_bus_get_unique_name (connection);
1220
1221   if (!dbus_message_append_args (message, 
1222                                  DBUS_TYPE_STRING, &base_service_name,
1223                                  DBUS_TYPE_INVALID))
1224     {
1225       dbus_message_unref (message);
1226       return TRUE;
1227     }
1228
1229   if (!dbus_connection_send (connection, message, &serial))
1230     {
1231       dbus_message_unref (message);
1232       return TRUE;
1233     }
1234
1235   /* send our message */
1236   bus_test_run_clients_loop (SEND_PENDING (connection));
1237
1238   dbus_message_unref (message);
1239   message = NULL;
1240
1241   dbus_connection_ref (connection); /* because we may get disconnected */
1242   block_connection_until_message_from_bus (context, connection, "reply to GetConnectionUnixProcessID");
1243
1244   if (!dbus_connection_get_is_connected (connection))
1245     {
1246       _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
1247       
1248       dbus_connection_unref (connection);
1249       
1250       return TRUE;
1251     }
1252
1253   dbus_connection_unref (connection);
1254
1255   message = pop_message_waiting_for_memory (connection);
1256   if (message == NULL)
1257     {
1258       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1259                   "GetConnectionUnixProcessID", serial, connection);
1260       goto out;
1261     }
1262
1263   verbose_message_received (connection, message);
1264
1265   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1266     {
1267       if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY))
1268         {
1269           ; /* good, this is a valid response */
1270         }
1271       else
1272         {
1273           warn_unexpected (connection, message, "not this error");
1274
1275           goto out;
1276         }
1277     }
1278   else
1279     {
1280       if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1281         {
1282           ; /* good, expected */
1283         }
1284       else
1285         {
1286           warn_unexpected (connection, message,
1287                            "method_return for GetConnectionUnixProcessID");
1288
1289           goto out;
1290         }
1291
1292     retry_get_property:
1293
1294       if (!dbus_message_get_args (message, &error,
1295                                   DBUS_TYPE_UINT32, &pid,
1296                                   DBUS_TYPE_INVALID))
1297         {
1298           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1299             {
1300               _dbus_verbose ("no memory to get pid by GetConnectionUnixProcessID\n");
1301               dbus_error_free (&error);
1302               _dbus_wait_for_memory ();
1303               goto retry_get_property;
1304             }
1305           else
1306             {
1307               _dbus_assert (dbus_error_is_set (&error));
1308               _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetConnectionUnixProcessID\n");
1309               goto out;
1310             }
1311         } else {
1312
1313           /* test if returned pid is the same as our own pid
1314            *
1315            * @todo It would probably be good to restructure the tests
1316            *       in a way so our parent is the bus that we're testing
1317            *       cause then we can test that the pid returned matches
1318            *       getppid()
1319            */
1320           if (pid != (dbus_uint32_t) getpid ())
1321             {
1322               _dbus_assert (dbus_error_is_set (&error));
1323               _dbus_warn ("Result from GetConnectionUnixProcessID is not our own pid\n");
1324               goto out;
1325             }
1326         }
1327     }
1328
1329   if (!check_no_leftovers (context))
1330     goto out;
1331
1332   retval = TRUE;
1333
1334  out:
1335   dbus_error_free (&error);
1336   
1337   if (message)
1338     dbus_message_unref (message);
1339   
1340   return retval;
1341 }
1342
1343 /* returns TRUE if the correct thing happens,
1344  * but the correct thing may include OOM errors.
1345  */
1346 static dbus_bool_t
1347 check_add_match_all (BusContext     *context,
1348                      DBusConnection *connection)
1349 {
1350   DBusMessage *message;
1351   dbus_bool_t retval;
1352   dbus_uint32_t serial;
1353   DBusError error;
1354   const char *empty = "";
1355
1356   retval = FALSE;
1357   dbus_error_init (&error);
1358   message = NULL;
1359
1360   _dbus_verbose ("check_add_match_all for %p\n", connection);
1361   
1362   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1363                                           DBUS_PATH_DBUS,
1364                                           DBUS_INTERFACE_DBUS,
1365                                           "AddMatch");
1366
1367   if (message == NULL)
1368     return TRUE;
1369
1370   /* empty string match rule matches everything */
1371   if (!dbus_message_append_args (message, DBUS_TYPE_STRING, &empty,
1372                                  DBUS_TYPE_INVALID))
1373     {
1374       dbus_message_unref (message);
1375       return TRUE;
1376     }
1377   
1378   if (!dbus_connection_send (connection, message, &serial))
1379     {
1380       dbus_message_unref (message);
1381       return TRUE;
1382     }
1383
1384   dbus_message_unref (message);
1385   message = NULL;
1386
1387   dbus_connection_ref (connection); /* because we may get disconnected */
1388   
1389   /* send our message */
1390   bus_test_run_clients_loop (SEND_PENDING (connection));
1391
1392   if (!dbus_connection_get_is_connected (connection))
1393     {
1394       _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
1395       
1396       dbus_connection_unref (connection);
1397       
1398       return TRUE;
1399     }
1400   
1401   block_connection_until_message_from_bus (context, connection, "reply to AddMatch");
1402
1403   if (!dbus_connection_get_is_connected (connection))
1404     {
1405       _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
1406       
1407       dbus_connection_unref (connection);
1408       
1409       return TRUE;
1410     }
1411
1412   dbus_connection_unref (connection);
1413   
1414   message = pop_message_waiting_for_memory (connection);
1415   if (message == NULL)
1416     {
1417       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1418                   "AddMatch", serial, connection);
1419       goto out;
1420     }
1421
1422   verbose_message_received (connection, message);
1423
1424   if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
1425     {
1426       _dbus_warn ("Message has wrong sender %s\n",
1427                   dbus_message_get_sender (message) ?
1428                   dbus_message_get_sender (message) : "(none)");
1429       goto out;
1430     }
1431   
1432   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1433     {
1434       if (dbus_message_is_error (message,
1435                                  DBUS_ERROR_NO_MEMORY))
1436         {
1437           ; /* good, this is a valid response */
1438         }
1439       else
1440         {
1441           warn_unexpected (connection, message, "not this error");
1442
1443           goto out;
1444         }
1445     }
1446   else
1447     {
1448       if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1449         {
1450           ; /* good, expected */
1451           _dbus_assert (dbus_message_get_reply_serial (message) == serial);
1452         }
1453       else
1454         {
1455           warn_unexpected (connection, message, "method return for AddMatch");
1456
1457           goto out;
1458         }
1459     }
1460
1461   if (!check_no_leftovers (context))
1462     goto out;
1463   
1464   retval = TRUE;
1465   
1466  out:
1467   dbus_error_free (&error);
1468   
1469   if (message)
1470     dbus_message_unref (message);
1471   
1472   return retval;
1473 }
1474
1475 /* returns TRUE if the correct thing happens,
1476  * but the correct thing may include OOM errors.
1477  */
1478 static dbus_bool_t
1479 check_hello_connection (BusContext *context)
1480 {
1481   DBusConnection *connection;
1482   DBusError error;
1483
1484   dbus_error_init (&error);
1485
1486   connection = dbus_connection_open_private ("debug-pipe:name=test-server", &error);
1487   if (connection == NULL)
1488     {
1489       _DBUS_ASSERT_ERROR_IS_SET (&error);
1490       dbus_error_free (&error);
1491       return TRUE;
1492     }
1493
1494   if (!bus_setup_debug_client (connection))
1495     {
1496       dbus_connection_close (connection);
1497       dbus_connection_unref (connection);
1498       return TRUE;
1499     }
1500
1501   spin_connection_until_authenticated (context, connection);
1502   
1503   if (!check_hello_message (context, connection))
1504     return FALSE;
1505   
1506   if (dbus_bus_get_unique_name (connection) == NULL)
1507     {
1508       /* We didn't successfully register, so we can't
1509        * do the usual kill_client_connection() checks
1510        */
1511       kill_client_connection_unchecked (connection);
1512     }
1513   else
1514     {
1515       if (!check_add_match_all (context, connection))
1516         return FALSE;
1517       
1518       kill_client_connection (context, connection);
1519     }
1520
1521   return TRUE;
1522 }
1523
1524 #define NONEXISTENT_SERVICE_NAME "test.this.service.does.not.exist.ewuoiurjdfxcvn"
1525
1526 /* returns TRUE if the correct thing happens,
1527  * but the correct thing may include OOM errors.
1528  */
1529 static dbus_bool_t
1530 check_nonexistent_service_no_auto_start (BusContext     *context,
1531                                          DBusConnection *connection)
1532 {
1533   DBusMessage *message;
1534   dbus_uint32_t serial;
1535   dbus_bool_t retval;
1536   const char *nonexistent = NONEXISTENT_SERVICE_NAME;
1537   dbus_uint32_t flags;
1538   
1539   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1540                                           DBUS_PATH_DBUS,
1541                                           DBUS_INTERFACE_DBUS,
1542                                           "StartServiceByName");
1543   
1544   if (message == NULL)
1545     return TRUE;
1546
1547   dbus_message_set_auto_start (message, FALSE);
1548   
1549   flags = 0;
1550   if (!dbus_message_append_args (message,
1551                                  DBUS_TYPE_STRING, &nonexistent,
1552                                  DBUS_TYPE_UINT32, &flags,
1553                                  DBUS_TYPE_INVALID))
1554     {
1555       dbus_message_unref (message);
1556       return TRUE;
1557     }
1558   
1559   if (!dbus_connection_send (connection, message, &serial))
1560     {
1561       dbus_message_unref (message);
1562       return TRUE;
1563     }
1564
1565   dbus_message_unref (message);
1566   message = NULL;
1567
1568   bus_test_run_everything (context);
1569   block_connection_until_message_from_bus (context, connection, "reply to ActivateService on nonexistent");
1570   bus_test_run_everything (context);
1571
1572   if (!dbus_connection_get_is_connected (connection))
1573     {
1574       _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
1575       return TRUE;
1576     }
1577   
1578   retval = FALSE;
1579   
1580   message = pop_message_waiting_for_memory (connection);
1581   if (message == NULL)
1582     {
1583       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1584                   "StartServiceByName", serial, connection);
1585       goto out;
1586     }
1587
1588   verbose_message_received (connection, message);
1589
1590   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1591     {
1592       if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
1593         {
1594           _dbus_warn ("Message has wrong sender %s\n",
1595                       dbus_message_get_sender (message) ?
1596                       dbus_message_get_sender (message) : "(none)");
1597           goto out;
1598         }
1599       
1600       if (dbus_message_is_error (message,
1601                                  DBUS_ERROR_NO_MEMORY))
1602         {
1603           ; /* good, this is a valid response */
1604         }
1605       else if (dbus_message_is_error (message,
1606                                       DBUS_ERROR_SERVICE_UNKNOWN))
1607         {
1608           ; /* good, this is expected also */
1609         }
1610       else
1611         {
1612           warn_unexpected (connection, message, "not this error");
1613           goto out;
1614         }
1615     }
1616   else
1617     {
1618       _dbus_warn ("Did not expect to successfully activate %s\n",
1619                   NONEXISTENT_SERVICE_NAME);
1620       goto out;
1621     }
1622
1623   retval = TRUE;
1624   
1625  out:
1626   if (message)
1627     dbus_message_unref (message);
1628   
1629   return retval;
1630 }
1631
1632 /* returns TRUE if the correct thing happens,
1633  * but the correct thing may include OOM errors.
1634  */
1635 static dbus_bool_t
1636 check_nonexistent_service_auto_start (BusContext     *context,
1637                                       DBusConnection *connection)
1638 {
1639   DBusMessage *message;
1640   dbus_uint32_t serial;
1641   dbus_bool_t retval;
1642     
1643   message = dbus_message_new_method_call (NONEXISTENT_SERVICE_NAME,
1644                                           "/org/freedesktop/TestSuite",
1645                                           "org.freedesktop.TestSuite",
1646                                           "Echo");
1647   
1648   if (message == NULL)
1649     return TRUE;
1650  
1651   if (!dbus_connection_send (connection, message, &serial))
1652     {
1653       dbus_message_unref (message);
1654       return TRUE;
1655     }
1656
1657   dbus_message_unref (message);
1658   message = NULL;
1659
1660   bus_test_run_everything (context);
1661   block_connection_until_message_from_bus (context, connection, "reply to Echo");
1662   bus_test_run_everything (context);
1663
1664   if (!dbus_connection_get_is_connected (connection))
1665     {
1666       _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
1667       return TRUE;
1668     }
1669   
1670   retval = FALSE;
1671   
1672   message = pop_message_waiting_for_memory (connection);
1673
1674   if (message == NULL)
1675     {
1676       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1677                   "Echo message (auto activation)", serial, connection);
1678       goto out;
1679     }
1680
1681   verbose_message_received (connection, message);
1682
1683   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1684     {
1685       if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
1686         {
1687           _dbus_warn ("Message has wrong sender %s\n",
1688                       dbus_message_get_sender (message) ?
1689                       dbus_message_get_sender (message) : "(none)");
1690           goto out;
1691         }
1692       
1693       if (dbus_message_is_error (message,
1694                                  DBUS_ERROR_NO_MEMORY))
1695         {
1696           ; /* good, this is a valid response */
1697         }
1698       else if (dbus_message_is_error (message,
1699                                       DBUS_ERROR_SERVICE_UNKNOWN))
1700         {
1701           ; /* good, this is expected also */
1702         }
1703       else
1704         {
1705           warn_unexpected (connection, message, "not this error");
1706           goto out;
1707         }
1708     }
1709   else
1710     {
1711       _dbus_warn ("Did not expect to successfully activate %s\n",
1712                   NONEXISTENT_SERVICE_NAME);
1713       goto out;
1714     }
1715
1716   retval = TRUE;
1717   
1718  out:
1719   if (message)
1720     dbus_message_unref (message);
1721   
1722   return retval;
1723 }
1724
1725 static dbus_bool_t
1726 check_base_service_activated (BusContext     *context,
1727                               DBusConnection *connection,
1728                               DBusMessage    *initial_message,
1729                               const char    **base_service_p)
1730 {
1731   DBusMessage *message;
1732   dbus_bool_t retval;
1733   DBusError error;
1734   const char *base_service, *base_service_from_bus, *old_owner;
1735   
1736   retval = FALSE;
1737   
1738   dbus_error_init (&error);
1739   base_service = NULL;
1740   old_owner = NULL;
1741   base_service_from_bus = NULL;
1742
1743   message = initial_message;
1744   dbus_message_ref (message);  
1745
1746   if (dbus_message_is_signal (message,
1747                               DBUS_INTERFACE_DBUS,
1748                               "NameOwnerChanged"))
1749     {
1750       CheckServiceOwnerChangedData socd;
1751
1752     reget_service_name_arg:
1753       base_service = NULL;
1754       old_owner = NULL;
1755       base_service_from_bus = NULL;
1756
1757       if (!dbus_message_get_args (message, &error,
1758                                   DBUS_TYPE_STRING, &base_service,
1759                                   DBUS_TYPE_STRING, &old_owner,
1760                                   DBUS_TYPE_STRING, &base_service_from_bus,
1761                                   DBUS_TYPE_INVALID))
1762         {
1763           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1764             {
1765               dbus_error_free (&error);
1766               _dbus_wait_for_memory ();
1767               goto reget_service_name_arg;
1768             }
1769           else
1770             {
1771               _dbus_warn ("Message %s doesn't have a service name: %s\n",
1772                           "NameOwnerChanged (creation)",
1773                           error.message);
1774               goto out;
1775             }
1776         }
1777
1778       if (*base_service != ':')
1779         {
1780           _dbus_warn ("Expected base service activation, got \"%s\" instead\n",
1781                       base_service);
1782           goto out;
1783         }
1784          
1785       if (strcmp (base_service, base_service_from_bus) != 0)
1786         {
1787           _dbus_warn ("Expected base service activation, got \"%s\" instead with owner \"%s\"\n",
1788                       base_service, base_service_from_bus);
1789           goto out;
1790         }
1791
1792       if (old_owner[0])
1793         {
1794           _dbus_warn ("Received an old_owner argument during base service activation, \"%s\"\n",
1795                       old_owner);
1796           goto out;
1797         }
1798      
1799       socd.expected_kind = SERVICE_CREATED;
1800       socd.expected_service_name = base_service;
1801       socd.failed = FALSE;
1802       socd.skip_connection = connection;
1803       bus_test_clients_foreach (check_service_owner_changed_foreach,
1804                                 &socd);
1805       
1806       if (socd.failed)
1807         goto out;
1808     }
1809   else
1810     {
1811       warn_unexpected (connection, message, "NameOwnerChanged (creation) for base service");
1812
1813       goto out;
1814     }
1815
1816   if (base_service_p)
1817     *base_service_p = base_service;
1818
1819   retval = TRUE;
1820   
1821  out:
1822   if (message)
1823     dbus_message_unref (message);
1824   dbus_error_free (&error);
1825
1826   return retval;
1827 }
1828
1829 static dbus_bool_t
1830 check_service_activated (BusContext     *context,
1831                          DBusConnection *connection,
1832                          const char     *activated_name,
1833                          const char     *base_service_name,
1834                          DBusMessage    *initial_message)
1835 {
1836   DBusMessage *message;
1837   dbus_bool_t retval;
1838   DBusError error;
1839   dbus_uint32_t activation_result;
1840   
1841   retval = FALSE;
1842   
1843   dbus_error_init (&error);
1844
1845   message = initial_message;
1846   dbus_message_ref (message);
1847
1848   if (dbus_message_is_signal (message,
1849                               DBUS_INTERFACE_DBUS,
1850                               "NameOwnerChanged"))
1851     {
1852       CheckServiceOwnerChangedData socd;
1853       const char *service_name, *base_service_from_bus, *old_owner;
1854
1855     reget_service_name_arg:
1856       service_name = NULL;
1857       old_owner = NULL;
1858       base_service_from_bus = NULL;
1859
1860       if (!dbus_message_get_args (message, &error,
1861                                   DBUS_TYPE_STRING, &service_name,
1862                                    DBUS_TYPE_STRING, &old_owner,
1863                                   DBUS_TYPE_STRING, &base_service_from_bus,
1864                                   DBUS_TYPE_INVALID))
1865         {
1866           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1867             {
1868               dbus_error_free (&error);
1869               _dbus_wait_for_memory ();
1870               goto reget_service_name_arg;
1871             }
1872           else
1873             {
1874               _dbus_warn ("Message %s doesn't have a service name: %s\n",
1875                           "NameOwnerChanged (creation)",
1876                           error.message);
1877               goto out;
1878             }
1879         }
1880
1881       if (strcmp (service_name, activated_name) != 0)
1882         {
1883           _dbus_warn ("Expected to see service %s created, saw %s instead\n",
1884                       activated_name, service_name);
1885           goto out;
1886         }
1887
1888       if (strcmp (base_service_name, base_service_from_bus) != 0)
1889         {
1890           _dbus_warn ("NameOwnerChanged reports wrong base service: %s owner, expected %s instead\n",
1891                       base_service_from_bus, base_service_name);
1892           goto out;
1893         }
1894
1895       if (old_owner[0])
1896         {
1897           _dbus_warn ("expected a %s, got a %s\n",
1898                       "NameOwnerChanged (creation)",
1899                       "NameOwnerChanged (change)");
1900           goto out;
1901         }
1902
1903       socd.expected_kind = SERVICE_CREATED;
1904       socd.skip_connection = connection;
1905       socd.failed = FALSE;
1906       socd.expected_service_name = service_name;
1907       bus_test_clients_foreach (check_service_owner_changed_foreach,
1908                                 &socd);
1909           
1910       if (socd.failed)
1911         goto out;
1912           
1913       dbus_message_unref (message);
1914       service_name = NULL;
1915       old_owner = NULL;
1916       base_service_from_bus = NULL;
1917       
1918       message = pop_message_waiting_for_memory (connection);
1919       if (message == NULL)
1920         {
1921           _dbus_warn ("Expected a reply to %s, got nothing\n",
1922                       "StartServiceByName");
1923           goto out;
1924         }
1925     }
1926   else
1927     {
1928       warn_unexpected (connection, message, "NameOwnerChanged for the activated name");
1929       
1930       goto out;
1931     }
1932   
1933   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
1934     {
1935       warn_unexpected (connection, message, "reply to StartServiceByName");
1936
1937       goto out;
1938     }
1939
1940   activation_result = 0;
1941   if (!dbus_message_get_args (message, &error,
1942                               DBUS_TYPE_UINT32, &activation_result,
1943                               DBUS_TYPE_INVALID))
1944     {
1945       if (!dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1946         {
1947           _dbus_warn ("Did not have activation result first argument to %s: %s\n",
1948                       "StartServiceByName", error.message);
1949           goto out;
1950         }
1951
1952       dbus_error_free (&error);
1953     }
1954   else
1955     {
1956       if (activation_result == DBUS_START_REPLY_SUCCESS)
1957         ; /* Good */
1958       else if (activation_result == DBUS_START_REPLY_ALREADY_RUNNING)
1959         ; /* Good also */
1960       else
1961         {
1962           _dbus_warn ("Activation result was %u, no good.\n",
1963                       activation_result);
1964           goto out;
1965         }
1966     }
1967
1968   dbus_message_unref (message);
1969   message = NULL;
1970       
1971   if (!check_no_leftovers (context))
1972     {
1973       _dbus_warn ("Messages were left over after verifying existent activation results\n");
1974       goto out;
1975     }
1976
1977   retval = TRUE;
1978   
1979  out:
1980   if (message)
1981     dbus_message_unref (message);
1982   dbus_error_free (&error);
1983   
1984   return retval;
1985 }
1986
1987 static dbus_bool_t
1988 check_service_auto_activated (BusContext     *context,
1989                               DBusConnection *connection,
1990                               const char     *activated_name,
1991                               const char     *base_service_name,
1992                               DBusMessage    *initial_message)
1993 {
1994   DBusMessage *message;
1995   dbus_bool_t retval;
1996   DBusError error;
1997   
1998   retval = FALSE;
1999   
2000   dbus_error_init (&error);
2001
2002   message = initial_message;
2003   dbus_message_ref (message);
2004
2005   if (dbus_message_is_signal (message,
2006                               DBUS_INTERFACE_DBUS,
2007                               "NameOwnerChanged"))
2008     {
2009       const char *service_name;
2010       CheckServiceOwnerChangedData socd;
2011       
2012     reget_service_name_arg:
2013       if (!dbus_message_get_args (message, &error,
2014                                   DBUS_TYPE_STRING, &service_name,
2015                                   DBUS_TYPE_INVALID))
2016         {
2017           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
2018             {
2019               dbus_error_free (&error);
2020               _dbus_wait_for_memory ();
2021               goto reget_service_name_arg;
2022             }
2023           else
2024             {
2025               _dbus_warn ("Message %s doesn't have a service name: %s\n",
2026                           "NameOwnerChanged",
2027                           error.message);
2028               dbus_error_free (&error);
2029               goto out;
2030             }
2031         }
2032       
2033       if (strcmp (service_name, activated_name) != 0)
2034         {
2035           _dbus_warn ("Expected to see service %s created, saw %s instead\n",
2036                       activated_name, service_name);
2037           goto out;
2038         }
2039       
2040       socd.expected_kind = SERVICE_CREATED;
2041       socd.expected_service_name = service_name;
2042       socd.failed = FALSE;
2043       socd.skip_connection = connection; 
2044       bus_test_clients_foreach (check_service_owner_changed_foreach,
2045                                 &socd);
2046       
2047       if (socd.failed)
2048         goto out;
2049       
2050       /* Note that this differs from regular activation in that we don't get a
2051        * reply to ActivateService here.
2052        */
2053       
2054       dbus_message_unref (message);
2055       message = NULL;
2056       service_name = NULL;
2057     }
2058   else
2059     {
2060       warn_unexpected (connection, message, "NameOwnerChanged for the activated name");
2061       
2062       goto out;
2063     }
2064   
2065   retval = TRUE;
2066   
2067  out:
2068   if (message)
2069     dbus_message_unref (message);
2070   
2071   return retval;
2072 }
2073
2074 static dbus_bool_t
2075 check_service_deactivated (BusContext     *context,
2076                            DBusConnection *connection,
2077                            const char     *activated_name,
2078                            const char     *base_service)
2079 {
2080   dbus_bool_t retval;
2081   CheckServiceOwnerChangedData socd;
2082
2083   retval = FALSE;
2084   
2085   /* Now we are expecting ServiceOwnerChanged (deletion) messages for the base
2086    * service and the activated_name.  The base service
2087    * notification is required to come last.
2088    */
2089   socd.expected_kind = SERVICE_DELETED;
2090   socd.expected_service_name = activated_name;
2091   socd.failed = FALSE;
2092   socd.skip_connection = NULL;
2093   bus_test_clients_foreach (check_service_owner_changed_foreach,
2094                             &socd);      
2095
2096   if (socd.failed)
2097     goto out;
2098       
2099   socd.expected_kind = SERVICE_DELETED;
2100   socd.expected_service_name = base_service;
2101   socd.failed = FALSE;
2102   socd.skip_connection = NULL;
2103   bus_test_clients_foreach (check_service_owner_changed_foreach,
2104                             &socd);
2105
2106   if (socd.failed)
2107     goto out;
2108
2109   retval = TRUE;
2110   
2111  out:
2112   return retval;
2113 }
2114
2115 static dbus_bool_t
2116 check_send_exit_to_service (BusContext     *context,
2117                             DBusConnection *connection,
2118                             const char     *service_name,
2119                             const char     *base_service)
2120 {
2121   dbus_bool_t got_error;
2122   DBusMessage *message;
2123   dbus_uint32_t serial;
2124   dbus_bool_t retval;
2125   
2126   _dbus_verbose ("Sending exit message to the test service\n");
2127
2128   retval = FALSE;
2129   
2130   /* Kill off the test service by sending it a quit message */
2131   message = dbus_message_new_method_call (service_name,
2132                                           "/org/freedesktop/TestSuite",
2133                                           "org.freedesktop.TestSuite",
2134                                           "Exit");
2135       
2136   if (message == NULL)
2137     {
2138       /* Do this again; we still need the service to exit... */
2139       if (!check_send_exit_to_service (context, connection,
2140                                        service_name, base_service))
2141         goto out;
2142       
2143       return TRUE;
2144     }
2145       
2146   if (!dbus_connection_send (connection, message, &serial))
2147     {
2148       dbus_message_unref (message);
2149
2150       /* Do this again; we still need the service to exit... */
2151       if (!check_send_exit_to_service (context, connection,
2152                                        service_name, base_service))
2153         goto out;
2154       
2155       return TRUE;
2156     }
2157
2158   dbus_message_unref (message);
2159   message = NULL;
2160
2161   /* send message */
2162   bus_test_run_clients_loop (SEND_PENDING (connection));
2163
2164   /* read it in and write it out to test service */
2165   bus_test_run_bus_loop (context, FALSE);
2166
2167   /* see if we got an error during message bus dispatching */
2168   bus_test_run_clients_loop (FALSE);
2169   message = borrow_message_waiting_for_memory (connection);
2170   got_error = message != NULL && dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR;
2171   if (message)
2172     {
2173       dbus_connection_return_message (connection, message);
2174       message = NULL;
2175     }
2176           
2177   if (!got_error)
2178     {
2179       /* If no error, wait for the test service to exit */
2180       block_connection_until_message_from_bus (context, connection, "test service to exit");
2181               
2182       bus_test_run_everything (context);
2183     }
2184
2185   if (got_error)
2186     {
2187       message = pop_message_waiting_for_memory (connection);
2188       _dbus_assert (message != NULL);
2189
2190       if (dbus_message_get_reply_serial (message) != serial)
2191         {
2192           warn_unexpected (connection, message,
2193                            "error with the correct reply serial");
2194           goto out;
2195         }
2196       
2197       if (!dbus_message_is_error (message,
2198                                   DBUS_ERROR_NO_MEMORY))
2199         {
2200           warn_unexpected (connection, message,
2201                            "a no memory error from asking test service to exit");
2202           goto out;
2203         }
2204
2205       _dbus_verbose ("Got error %s when asking test service to exit\n",
2206                      dbus_message_get_error_name (message));
2207
2208       /* Do this again; we still need the service to exit... */
2209       if (!check_send_exit_to_service (context, connection,
2210                                        service_name, base_service))
2211         goto out;
2212     }
2213   else
2214     {
2215       if (!check_service_deactivated (context, connection,
2216                                       service_name, base_service))
2217         goto out;
2218
2219       /* Should now have a NoReply error from the Exit() method
2220        * call; it should have come after all the deactivation
2221        * stuff.
2222        */
2223       message = pop_message_waiting_for_memory (connection);
2224           
2225       if (message == NULL)
2226         {
2227           warn_unexpected (connection, NULL,
2228                            "reply to Exit() method call");
2229           goto out;
2230         }
2231       if (!dbus_message_is_error (message,
2232                                   DBUS_ERROR_NO_REPLY))
2233         {
2234           warn_unexpected (connection, message,
2235                            "NoReply error from Exit() method call");
2236           goto out;
2237         }
2238
2239       if (dbus_message_get_reply_serial (message) != serial)
2240         {
2241           warn_unexpected (connection, message,
2242                            "error with the correct reply serial");
2243           goto out;
2244         }
2245           
2246       _dbus_verbose ("Got error %s after test service exited\n",
2247                      dbus_message_get_error_name (message));
2248       
2249       if (!check_no_leftovers (context))
2250         {
2251           _dbus_warn ("Messages were left over after %s\n",
2252                       _DBUS_FUNCTION_NAME);
2253           goto out;
2254         }
2255     }
2256   
2257   retval = TRUE;
2258   
2259  out:
2260   if (message)
2261     dbus_message_unref (message);
2262   
2263   return retval;
2264 }
2265
2266 static dbus_bool_t
2267 check_got_error (BusContext     *context,
2268                  DBusConnection *connection,
2269                  const char     *first_error_name,
2270                  ...)
2271 {
2272   DBusMessage *message;
2273   dbus_bool_t retval;
2274   va_list ap;
2275   dbus_bool_t error_found;
2276   const char *error_name;
2277   
2278   retval = FALSE;
2279   
2280   message = pop_message_waiting_for_memory (connection);
2281   if (message == NULL)
2282     {
2283       _dbus_warn ("Did not get an expected error\n");
2284       goto out;
2285     }
2286
2287   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
2288     {
2289       warn_unexpected (connection, message, "an error");
2290
2291       goto out;
2292     }
2293
2294   error_found = FALSE;
2295
2296   va_start (ap, first_error_name);
2297   error_name = first_error_name;
2298   while (error_name != NULL)
2299     {
2300       if (dbus_message_is_error (message, error_name))
2301         {
2302           error_found = TRUE;
2303           break;
2304         }
2305       error_name = va_arg (ap, char*);
2306     }
2307   va_end (ap);
2308
2309   if (!error_found)
2310     {
2311       _dbus_warn ("Expected error %s or other, got %s instead\n",
2312                   first_error_name,
2313                   dbus_message_get_error_name (message));
2314       goto out;
2315     }
2316
2317   retval = TRUE;
2318   
2319  out:
2320   if (message)
2321     dbus_message_unref (message);
2322   
2323   return retval;
2324 }
2325           
2326 typedef enum
2327
2328   GOT_SERVICE_CREATED,
2329   GOT_SERVICE_DELETED,
2330   GOT_ERROR,
2331   GOT_SOMETHING_ELSE 
2332 } GotServiceInfo;
2333
2334 static GotServiceInfo
2335 check_got_service_info (DBusMessage *message)
2336 {
2337   GotServiceInfo message_kind;
2338
2339   if (dbus_message_is_signal (message,
2340                               DBUS_INTERFACE_DBUS,
2341                               "NameOwnerChanged"))
2342     {
2343       DBusError error;
2344       const char *service_name, *old_owner, *new_owner;
2345       dbus_error_init (&error);
2346
2347     reget_service_info_data:
2348       service_name = NULL;
2349       old_owner = NULL;
2350       new_owner = NULL;
2351
2352       dbus_message_get_args (message, &error,
2353                              DBUS_TYPE_STRING, &service_name,
2354                              DBUS_TYPE_STRING, &old_owner,
2355                              DBUS_TYPE_STRING, &new_owner,
2356                              DBUS_TYPE_INVALID);
2357       if (dbus_error_is_set (&error))
2358         {
2359           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
2360             {
2361               dbus_error_free (&error);
2362               goto reget_service_info_data;
2363             }
2364           else
2365             {
2366               _dbus_warn ("unexpected arguments for NameOwnerChanged message\n");
2367               message_kind = GOT_SOMETHING_ELSE;
2368             }
2369         }
2370       else if (!old_owner[0])
2371         message_kind = GOT_SERVICE_CREATED;
2372       else if (!new_owner[0])
2373         message_kind = GOT_SERVICE_DELETED;
2374       else
2375         message_kind = GOT_SOMETHING_ELSE;
2376
2377       dbus_error_free (&error);
2378     }
2379   else if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
2380     message_kind = GOT_ERROR;
2381   else
2382     message_kind = GOT_SOMETHING_ELSE;
2383
2384   return message_kind;
2385 }
2386
2387 #define EXISTENT_SERVICE_NAME "org.freedesktop.DBus.TestSuiteEchoService"
2388
2389 /* returns TRUE if the correct thing happens,
2390  * but the correct thing may include OOM errors.
2391  */
2392 static dbus_bool_t
2393 check_existent_service_no_auto_start (BusContext     *context,
2394                                       DBusConnection *connection)
2395 {
2396   DBusMessage *message;
2397   DBusMessage *base_service_message;
2398   const char *base_service;
2399   dbus_uint32_t serial;
2400   dbus_bool_t retval;
2401   const char *existent = EXISTENT_SERVICE_NAME;
2402   dbus_uint32_t flags;
2403
2404   base_service_message = NULL;
2405   
2406   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
2407                                           DBUS_PATH_DBUS,
2408                                           DBUS_INTERFACE_DBUS,
2409                                           "StartServiceByName");
2410
2411   if (message == NULL)
2412     return TRUE;
2413
2414   dbus_message_set_auto_start (message, FALSE);
2415   
2416   flags = 0;
2417   if (!dbus_message_append_args (message,
2418                                  DBUS_TYPE_STRING, &existent,
2419                                  DBUS_TYPE_UINT32, &flags,
2420                                  DBUS_TYPE_INVALID))
2421     {
2422       dbus_message_unref (message);
2423       return TRUE;
2424     }
2425   
2426   if (!dbus_connection_send (connection, message, &serial))
2427     {
2428       dbus_message_unref (message);
2429       return TRUE;
2430     }
2431
2432   dbus_message_unref (message);
2433   message = NULL;
2434
2435   bus_test_run_everything (context);
2436
2437   /* now wait for the message bus to hear back from the activated
2438    * service.
2439    */
2440   block_connection_until_message_from_bus (context, connection, "activated service to connect");
2441
2442   bus_test_run_everything (context);
2443
2444   if (!dbus_connection_get_is_connected (connection))
2445     {
2446       _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
2447       return TRUE;
2448     }
2449   
2450   retval = FALSE;
2451   
2452   message = pop_message_waiting_for_memory (connection);
2453   if (message == NULL)
2454     {
2455       _dbus_warn ("Did not receive any messages after %s %d on %p\n",
2456                   "StartServiceByName", serial, connection);
2457       goto out;
2458     }
2459
2460   verbose_message_received (connection, message);
2461   _dbus_verbose ("  (after sending %s)\n", "StartServiceByName");
2462
2463   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
2464     {
2465       if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
2466         {
2467           _dbus_warn ("Message has wrong sender %s\n",
2468                       dbus_message_get_sender (message) ?
2469                       dbus_message_get_sender (message) : "(none)");
2470           goto out;
2471         }
2472       
2473       if (dbus_message_is_error (message,
2474                                  DBUS_ERROR_NO_MEMORY))
2475         {
2476           ; /* good, this is a valid response */
2477         }
2478       else if (dbus_message_is_error (message,
2479                                       DBUS_ERROR_SPAWN_CHILD_EXITED) ||
2480                dbus_message_is_error (message,
2481                                       DBUS_ERROR_SPAWN_CHILD_SIGNALED) ||
2482                dbus_message_is_error (message,
2483                                       DBUS_ERROR_SPAWN_EXEC_FAILED))
2484         {
2485           ; /* good, this is expected also */
2486         }
2487       else
2488         {
2489           _dbus_warn ("Did not expect error %s\n",
2490                       dbus_message_get_error_name (message));
2491           goto out;
2492         }
2493     }
2494   else
2495     {
2496       GotServiceInfo message_kind;
2497       
2498       if (!check_base_service_activated (context, connection,
2499                                          message, &base_service))
2500         goto out;
2501
2502       base_service_message = message;
2503       message = NULL;
2504
2505       /* We may need to block here for the test service to exit or finish up */
2506       block_connection_until_message_from_bus (context, connection, "test service to exit or finish up");
2507       
2508       message = dbus_connection_borrow_message (connection);
2509       if (message == NULL)
2510         {
2511           _dbus_warn ("Did not receive any messages after base service creation notification\n");
2512           goto out;
2513         }
2514
2515       message_kind = check_got_service_info (message);
2516
2517       dbus_connection_return_message (connection, message);
2518       message = NULL;
2519
2520       switch (message_kind)
2521         {
2522         case GOT_SOMETHING_ELSE:
2523           _dbus_warn ("Unexpected message after ActivateService "
2524                       "(should be an error or a service announcement");
2525           goto out;
2526
2527         case GOT_ERROR:
2528           if (!check_got_error (context, connection,
2529                                 DBUS_ERROR_SPAWN_CHILD_EXITED,
2530                                 DBUS_ERROR_NO_MEMORY,
2531                                 NULL))
2532             goto out;
2533           /* A service deleted should be coming along now after this error.
2534            * We can also get the error *after* the service deleted.
2535            */
2536
2537           /* fall through */
2538
2539         case GOT_SERVICE_DELETED:
2540           {
2541             /* The service started up and got a base address, but then
2542              * failed to register under EXISTENT_SERVICE_NAME
2543              */
2544             CheckServiceOwnerChangedData socd;
2545
2546             socd.expected_kind = SERVICE_DELETED;
2547             socd.expected_service_name = base_service;
2548             socd.failed = FALSE;
2549             socd.skip_connection = NULL;
2550             
2551             bus_test_clients_foreach (check_service_owner_changed_foreach,
2552                                       &socd);
2553
2554             if (socd.failed)
2555               goto out;
2556
2557             /* Now we should get an error about the service exiting
2558              * if we didn't get it before.
2559              */
2560             if (message_kind != GOT_ERROR)
2561               {
2562                 block_connection_until_message_from_bus (context, connection, "error about service exiting");
2563                 
2564                 /* and process everything again */
2565                 bus_test_run_everything (context);
2566               
2567                 if (!check_got_error (context, connection,
2568                                       DBUS_ERROR_SPAWN_CHILD_EXITED,
2569                                       DBUS_ERROR_NO_MEMORY,
2570                                       NULL))
2571                   goto out;
2572               }
2573             break;
2574           }
2575
2576         case GOT_SERVICE_CREATED:
2577           message = pop_message_waiting_for_memory (connection);
2578           if (message == NULL)
2579             {
2580               _dbus_warn ("Failed to pop message we just put back! "
2581                           "should have been a NameOwnerChanged (creation)\n");
2582               goto out;
2583             }
2584           
2585           if (!check_service_activated (context, connection, EXISTENT_SERVICE_NAME,
2586                                         base_service, message))
2587             goto out;
2588           
2589           dbus_message_unref (message);
2590           message = NULL;
2591
2592           if (!check_no_leftovers (context))
2593             {
2594               _dbus_warn ("Messages were left over after successful activation\n");
2595               goto out;
2596             }
2597
2598           if (!check_send_exit_to_service (context, connection,
2599                                            EXISTENT_SERVICE_NAME, base_service))
2600             goto out;
2601
2602           break;
2603         }
2604     }
2605
2606   retval = TRUE;
2607   
2608  out:
2609   if (message)
2610     dbus_message_unref (message);
2611
2612   if (base_service_message)
2613     dbus_message_unref (base_service_message);
2614   
2615   return retval;
2616 }
2617
2618 #ifndef DBUS_WIN_FIXME
2619 /* returns TRUE if the correct thing happens,
2620  * but the correct thing may include OOM errors.
2621  */
2622 static dbus_bool_t
2623 check_segfault_service_no_auto_start (BusContext     *context,
2624                                       DBusConnection *connection)
2625 {
2626   DBusMessage *message;
2627   dbus_uint32_t serial;
2628   dbus_bool_t retval;
2629   const char *segv_service;
2630   dbus_uint32_t flags;
2631   
2632   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
2633                                           DBUS_PATH_DBUS,
2634                                           DBUS_INTERFACE_DBUS,
2635                                           "StartServiceByName");
2636
2637   if (message == NULL)
2638     return TRUE;
2639
2640   dbus_message_set_auto_start (message, FALSE);
2641   
2642   segv_service = "org.freedesktop.DBus.TestSuiteSegfaultService";
2643   flags = 0;
2644   if (!dbus_message_append_args (message,
2645                                  DBUS_TYPE_STRING, &segv_service,
2646                                  DBUS_TYPE_UINT32, &flags,
2647                                  DBUS_TYPE_INVALID))
2648     {
2649       dbus_message_unref (message);
2650       return TRUE;
2651     }
2652   
2653   if (!dbus_connection_send (connection, message, &serial))
2654     {
2655       dbus_message_unref (message);
2656       return TRUE;
2657     }
2658
2659   dbus_message_unref (message);
2660   message = NULL;
2661
2662   bus_test_run_everything (context);
2663   block_connection_until_message_from_bus (context, connection, "reply to activating segfault service");
2664   bus_test_run_everything (context);
2665
2666   if (!dbus_connection_get_is_connected (connection))
2667     {
2668       _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
2669       return TRUE;
2670     }
2671   
2672   retval = FALSE;
2673   
2674   message = pop_message_waiting_for_memory (connection);
2675   if (message == NULL)
2676     {
2677       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
2678                   "StartServiceByName", serial, connection);
2679       goto out;
2680     }
2681
2682   verbose_message_received (connection, message);
2683
2684   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
2685     {
2686       if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
2687         {
2688           _dbus_warn ("Message has wrong sender %s\n",
2689                       dbus_message_get_sender (message) ?
2690                       dbus_message_get_sender (message) : "(none)");
2691           goto out;
2692         }
2693       
2694       if (dbus_message_is_error (message,
2695                                  DBUS_ERROR_NO_MEMORY))
2696         {
2697           ; /* good, this is a valid response */
2698         }
2699       else if (dbus_message_is_error (message,
2700                                       DBUS_ERROR_SPAWN_CHILD_SIGNALED))
2701         {
2702           ; /* good, this is expected also */
2703         }
2704       else
2705         {
2706           warn_unexpected (connection, message, "not this error");
2707
2708           goto out;
2709         }
2710     }
2711   else
2712     {
2713       _dbus_warn ("Did not expect to successfully activate segfault service\n");
2714       goto out;
2715     }
2716
2717   retval = TRUE;
2718   
2719  out:
2720   if (message)
2721     dbus_message_unref (message);
2722   
2723   return retval;
2724 }
2725
2726
2727 /* returns TRUE if the correct thing happens,
2728  * but the correct thing may include OOM errors.
2729  */
2730 static dbus_bool_t
2731 check_segfault_service_auto_start (BusContext     *context,
2732                                    DBusConnection *connection)
2733 {
2734   DBusMessage *message;
2735   dbus_uint32_t serial;
2736   dbus_bool_t retval;
2737
2738   message = dbus_message_new_method_call ("org.freedesktop.DBus.TestSuiteSegfaultService",
2739                                           "/org/freedesktop/TestSuite",
2740                                           "org.freedesktop.TestSuite",
2741                                           "Echo");
2742   
2743   if (message == NULL)
2744     return TRUE;
2745   
2746   if (!dbus_connection_send (connection, message, &serial))
2747     {
2748       dbus_message_unref (message);
2749       return TRUE;
2750     }
2751
2752   dbus_message_unref (message);
2753   message = NULL;
2754
2755   bus_test_run_everything (context);
2756   block_connection_until_message_from_bus (context, connection, "reply to Echo on segfault service");
2757   bus_test_run_everything (context);
2758
2759   if (!dbus_connection_get_is_connected (connection))
2760     {
2761       _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
2762       return TRUE;
2763     }
2764   
2765   retval = FALSE;
2766   
2767   message = pop_message_waiting_for_memory (connection);
2768   if (message == NULL)
2769     {
2770       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
2771                   "Echo message (auto activation)", serial, connection);
2772       goto out;
2773     }
2774
2775   verbose_message_received (connection, message);
2776
2777   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
2778     {
2779       if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
2780         {
2781           _dbus_warn ("Message has wrong sender %s\n",
2782                       dbus_message_get_sender (message) ?
2783                       dbus_message_get_sender (message) : "(none)");
2784           goto out;
2785         }
2786       
2787       if (dbus_message_is_error (message,
2788                                  DBUS_ERROR_NO_MEMORY))
2789         {
2790           ; /* good, this is a valid response */
2791         }
2792       else if (dbus_message_is_error (message,
2793                                       DBUS_ERROR_SPAWN_CHILD_SIGNALED))
2794         {
2795           ; /* good, this is expected also */
2796         }
2797       else
2798         {
2799           warn_unexpected (connection, message, "not this error");
2800
2801           goto out;
2802         }
2803     }
2804   else
2805     {
2806       _dbus_warn ("Did not expect to successfully activate segfault service\n");
2807       goto out;
2808     }
2809
2810   retval = TRUE;
2811   
2812  out:
2813   if (message)
2814     dbus_message_unref (message);
2815   
2816   return retval;
2817 }
2818 #endif
2819
2820 #define TEST_ECHO_MESSAGE "Test echo message"
2821 #define TEST_RUN_HELLO_FROM_SELF_MESSAGE "Test sending message to self"
2822
2823 /* returns TRUE if the correct thing happens,
2824  * but the correct thing may include OOM errors.
2825  */
2826 static dbus_bool_t
2827 check_existent_hello_from_self (BusContext     *context,
2828                                 DBusConnection *connection)
2829 {
2830   DBusMessage *message;
2831   dbus_uint32_t serial;
2832   const char *text;
2833
2834   message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME,
2835                                           "/org/freedesktop/TestSuite",
2836                                           "org.freedesktop.TestSuite",
2837                                           "RunHelloFromSelf");
2838   
2839   if (message == NULL)
2840     return TRUE;
2841
2842   text = TEST_RUN_HELLO_FROM_SELF_MESSAGE;
2843   if (!dbus_message_append_args (message,
2844                                  DBUS_TYPE_STRING, &text,
2845                                  DBUS_TYPE_INVALID))
2846     {
2847       dbus_message_unref (message);
2848       return TRUE;
2849     }
2850
2851   if (!dbus_connection_send (connection, message, &serial))
2852     {
2853       dbus_message_unref (message);
2854       return TRUE;
2855     }
2856
2857   dbus_message_unref (message);
2858   message = NULL;
2859
2860   bus_test_run_everything (context);
2861
2862   /* Note: if this test is run in OOM mode, it will block when the bus
2863    * doesn't send a reply due to OOM.
2864    */
2865   block_connection_until_message_from_bus (context, connection, "reply from running hello from self");
2866       
2867   message = pop_message_waiting_for_memory (connection);
2868   if (message == NULL)
2869     {
2870       _dbus_warn ("Failed to pop message! Should have been reply from RunHelloFromSelf message\n");
2871       return FALSE;
2872     }
2873
2874   if (dbus_message_get_reply_serial (message) != serial)
2875     {
2876       _dbus_warn ("Wrong reply serial\n");
2877       dbus_message_unref (message);
2878       return FALSE;
2879     }
2880
2881   dbus_message_unref (message);
2882   message = NULL;
2883       
2884   return TRUE;
2885 }
2886
2887 /* returns TRUE if the correct thing happens,
2888  * but the correct thing may include OOM errors.
2889  */
2890 static dbus_bool_t
2891 check_existent_ping (BusContext     *context,
2892                      DBusConnection *connection)
2893 {
2894   DBusMessage *message;
2895   dbus_uint32_t serial;
2896   message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME,
2897                                           "/org/freedesktop/TestSuite",
2898                                           "org.freedesktop.DBus.Peer",
2899                                           "Ping");
2900   
2901   if (message == NULL)
2902     return TRUE;
2903
2904   if (!dbus_connection_send (connection, message, &serial))
2905     {
2906       dbus_message_unref (message);
2907       return TRUE;
2908     }
2909
2910   dbus_message_unref (message);
2911   message = NULL;
2912
2913   bus_test_run_everything (context);
2914
2915   /* Note: if this test is run in OOM mode, it will block when the bus
2916    * doesn't send a reply due to OOM.
2917    */
2918   block_connection_until_message_from_bus (context, connection, "reply from running Ping");
2919       
2920   message = pop_message_waiting_for_memory (connection);
2921   if (message == NULL)
2922     {
2923       _dbus_warn ("Failed to pop message! Should have been reply from Ping message\n");
2924       return FALSE;
2925     }
2926
2927   if (dbus_message_get_reply_serial (message) != serial)
2928     {
2929       _dbus_warn ("Wrong reply serial\n");
2930       dbus_message_unref (message);
2931       return FALSE;
2932     }
2933
2934   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
2935     {
2936       _dbus_warn ("Unexpected message return during Ping\n");
2937       dbus_message_unref (message);
2938       return FALSE;
2939     }
2940
2941   dbus_message_unref (message);
2942   message = NULL;
2943       
2944   return TRUE;
2945 }
2946
2947 /* returns TRUE if the correct thing happens,
2948  * but the correct thing may include OOM errors.
2949  */
2950 static dbus_bool_t
2951 check_existent_get_machine_id (BusContext     *context,
2952                                DBusConnection *connection)
2953 {
2954   DBusMessage *message;
2955   dbus_uint32_t serial;
2956   const char *machine_id;
2957   
2958   message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME,
2959                                           "/org/freedesktop/TestSuite",
2960                                           "org.freedesktop.DBus.Peer",
2961                                           "GetMachineId");
2962   
2963   if (message == NULL)
2964     return TRUE;
2965
2966   if (!dbus_connection_send (connection, message, &serial))
2967     {
2968       dbus_message_unref (message);
2969       return TRUE;
2970     }
2971
2972   dbus_message_unref (message);
2973   message = NULL;
2974
2975   bus_test_run_everything (context);
2976
2977   /* Note: if this test is run in OOM mode, it will block when the bus
2978    * doesn't send a reply due to OOM.
2979    */
2980   block_connection_until_message_from_bus (context, connection, "reply from running GetMachineId");
2981       
2982   message = pop_message_waiting_for_memory (connection);
2983   if (message == NULL)
2984     {
2985       _dbus_warn ("Failed to pop message! Should have been reply from GetMachineId message\n");
2986       return FALSE;
2987     }
2988
2989   if (dbus_message_get_reply_serial (message) != serial)
2990     {
2991       _dbus_warn ("Wrong reply serial\n");
2992       dbus_message_unref (message);
2993       return FALSE;
2994     }
2995
2996   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
2997     {
2998       _dbus_warn ("Unexpected message return during GetMachineId\n");
2999       dbus_message_unref (message);
3000       return FALSE;
3001     }
3002
3003   machine_id = NULL;
3004   if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &machine_id, DBUS_TYPE_INVALID))
3005     {
3006       _dbus_warn ("Did not get a machine ID in reply to GetMachineId\n");
3007       dbus_message_unref (message);
3008       return FALSE;
3009     }
3010
3011   if (machine_id == NULL || strlen (machine_id) != 32)
3012     {
3013       _dbus_warn ("Machine id looks bogus: '%s'\n", machine_id ? machine_id : "null");
3014       dbus_message_unref (message);
3015       return FALSE;
3016     }
3017   
3018   /* We can't check that the machine id is correct because during make check it is
3019    * just made up for each process separately
3020    */
3021   
3022   dbus_message_unref (message);
3023   message = NULL;
3024       
3025   return TRUE;
3026 }
3027
3028 /* returns TRUE if the correct thing happens,
3029  * but the correct thing may include OOM errors.
3030  */
3031 static dbus_bool_t
3032 check_existent_service_auto_start (BusContext     *context,
3033                                    DBusConnection *connection)
3034 {
3035   DBusMessage *message;
3036   DBusMessage *base_service_message;
3037   dbus_uint32_t serial;
3038   dbus_bool_t retval;
3039   const char *base_service;
3040   const char *text;
3041
3042   base_service_message = NULL;
3043
3044   message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME,
3045                                           "/org/freedesktop/TestSuite",
3046                                           "org.freedesktop.TestSuite",
3047                                           "Echo");
3048   
3049   if (message == NULL)
3050     return TRUE;
3051
3052   text = TEST_ECHO_MESSAGE;
3053   if (!dbus_message_append_args (message,
3054                                  DBUS_TYPE_STRING, &text,
3055                                  DBUS_TYPE_INVALID))
3056     {
3057       dbus_message_unref (message);
3058       return TRUE;
3059     }
3060
3061   if (!dbus_connection_send (connection, message, &serial))
3062     {
3063       dbus_message_unref (message);
3064       return TRUE;
3065     }
3066
3067   dbus_message_unref (message);
3068   message = NULL;
3069
3070   bus_test_run_everything (context);
3071
3072   /* now wait for the message bus to hear back from the activated
3073    * service.
3074    */
3075   block_connection_until_message_from_bus (context, connection, "reply to Echo on existent service");
3076   bus_test_run_everything (context);
3077
3078   if (!dbus_connection_get_is_connected (connection))
3079     {
3080       _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
3081       return TRUE;
3082     }
3083
3084   retval = FALSE;
3085   
3086   message = pop_message_waiting_for_memory (connection);
3087   if (message == NULL)
3088     {
3089       _dbus_warn ("Did not receive any messages after auto start %d on %p\n",
3090                   serial, connection);
3091       goto out;
3092     }
3093
3094   verbose_message_received (connection, message);
3095   _dbus_verbose ("  (after sending %s)\n", "auto start");
3096
3097   /* we should get zero or two ServiceOwnerChanged signals */
3098   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL)
3099     {
3100       GotServiceInfo message_kind;
3101
3102       if (!check_base_service_activated (context, connection,
3103                                          message, &base_service))
3104         goto out;
3105
3106       base_service_message = message;
3107       message = NULL;
3108
3109       /* We may need to block here for the test service to exit or finish up */
3110       block_connection_until_message_from_bus (context, connection, "service to exit");
3111
3112       /* Should get a service creation notification for the activated
3113        * service name, or a service deletion on the base service name
3114        */
3115       message = dbus_connection_borrow_message (connection);
3116       if (message == NULL)
3117         {
3118           _dbus_warn ("No message after auto activation "
3119                       "(should be a service announcement)\n");
3120           dbus_connection_return_message (connection, message);
3121           message = NULL;
3122           goto out;
3123         }
3124
3125       message_kind = check_got_service_info (message);
3126
3127       dbus_connection_return_message (connection, message);
3128       message = NULL;
3129
3130       switch (message_kind) 
3131         {
3132         case GOT_SERVICE_CREATED:
3133           message = pop_message_waiting_for_memory (connection);
3134           if (message == NULL)
3135             {
3136               _dbus_warn ("Failed to pop message we just put back! "
3137                           "should have been a NameOwnerChanged (creation)\n");
3138               goto out;
3139             }
3140             
3141           /* Check that ServiceOwnerChanged (creation) was correctly received */
3142           if (!check_service_auto_activated (context, connection, EXISTENT_SERVICE_NAME,
3143                                              base_service, message))
3144             goto out;
3145           
3146           dbus_message_unref (message);
3147           message = NULL;
3148
3149           break;
3150
3151         case GOT_SERVICE_DELETED:
3152           {
3153             /* The service started up and got a base address, but then
3154              * failed to register under EXISTENT_SERVICE_NAME
3155              */
3156             CheckServiceOwnerChangedData socd;
3157           
3158             socd.expected_kind = SERVICE_DELETED;
3159             socd.expected_service_name = base_service;
3160             socd.failed = FALSE;
3161             socd.skip_connection = NULL;
3162             bus_test_clients_foreach (check_service_owner_changed_foreach,
3163                                       &socd);
3164
3165             if (socd.failed)
3166               goto out;
3167
3168             break;
3169           }
3170
3171         case GOT_ERROR:
3172         case GOT_SOMETHING_ELSE:
3173           _dbus_warn ("Unexpected message after auto activation\n");
3174           goto out;
3175         }
3176     }
3177
3178   /* OK, now we've dealt with ServiceOwnerChanged signals, now should
3179    * come the method reply (or error) from the initial method call
3180    */
3181
3182   /* Note: if this test is run in OOM mode, it will block when the bus
3183    * doesn't send a reply due to OOM.
3184    */
3185   block_connection_until_message_from_bus (context, connection, "reply from echo message after auto-activation");
3186       
3187   message = pop_message_waiting_for_memory (connection);
3188   if (message == NULL)
3189     {
3190       _dbus_warn ("Failed to pop message! Should have been reply from echo message\n");
3191       goto out;
3192     }
3193
3194   if (dbus_message_get_reply_serial (message) != serial)
3195     {
3196       _dbus_warn ("Wrong reply serial\n");
3197       goto out;
3198     }
3199
3200   dbus_message_unref (message);
3201   message = NULL;
3202
3203   if (!check_existent_ping (context, connection))
3204     goto out;
3205
3206   if (!check_existent_get_machine_id (context, connection))
3207     goto out;
3208   
3209   if (!check_existent_hello_from_self (context, connection))
3210     goto out;
3211
3212   if (!check_send_exit_to_service (context, connection,
3213                                    EXISTENT_SERVICE_NAME,
3214                                    base_service))
3215     goto out;
3216   
3217   retval = TRUE;
3218
3219  out:
3220   if (message)
3221     dbus_message_unref (message);
3222
3223   if (base_service_message)
3224     dbus_message_unref (base_service_message);
3225
3226   return retval;
3227 }
3228
3229 #define SHELL_FAIL_SERVICE_NAME "org.freedesktop.DBus.TestSuiteShellEchoServiceFail"
3230
3231 /* returns TRUE if the correct thing happens,
3232  * but the correct thing may include OOM errors.
3233  */
3234 static dbus_bool_t
3235 check_shell_fail_service_auto_start (BusContext     *context,
3236                                      DBusConnection *connection)
3237 {
3238   DBusMessage *message;
3239   dbus_uint32_t serial;
3240   dbus_bool_t retval;
3241
3242   message = dbus_message_new_method_call (SHELL_FAIL_SERVICE_NAME,
3243                                           "/org/freedesktop/TestSuite",
3244                                           "org.freedesktop.TestSuite",
3245                                           "Echo");
3246   
3247   if (message == NULL)
3248     return TRUE;
3249   
3250   if (!dbus_connection_send (connection, message, &serial))
3251     {
3252       dbus_message_unref (message);
3253       return TRUE;
3254     }
3255
3256   dbus_message_unref (message);
3257   message = NULL;
3258
3259   bus_test_run_everything (context);
3260   block_connection_until_message_from_bus (context, connection, "reply to shell Echo on service which should fail to auto-start");
3261   bus_test_run_everything (context);
3262
3263   if (!dbus_connection_get_is_connected (connection))
3264     {
3265       _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
3266       return TRUE;
3267     }
3268   
3269   retval = FALSE;
3270   
3271   message = pop_message_waiting_for_memory (connection);
3272   if (message == NULL)
3273     {
3274       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
3275                   "Echo message (auto activation)", serial, connection);
3276       goto out;
3277     }
3278
3279   verbose_message_received (connection, message);
3280
3281   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
3282     {
3283       if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
3284         {
3285           _dbus_warn ("Message has wrong sender %s\n",
3286                       dbus_message_get_sender (message) ?
3287                       dbus_message_get_sender (message) : "(none)");
3288           goto out;
3289         }
3290       
3291       if (dbus_message_is_error (message,
3292                                  DBUS_ERROR_NO_MEMORY))
3293         {
3294           ; /* good, this is a valid response */
3295         }
3296       else if (dbus_message_is_error (message,
3297                                       DBUS_ERROR_INVALID_ARGS))
3298         {
3299           _dbus_verbose("got invalid args\n");
3300           ; /* good, this is expected also */
3301         }
3302       else
3303         {
3304           warn_unexpected (connection, message, "not this error");
3305
3306           goto out;
3307         }
3308     }
3309   else
3310     {
3311       _dbus_warn ("Did not expect to successfully auto-start shell fail service\n");
3312       goto out;
3313     }
3314
3315   retval = TRUE;
3316   
3317  out:
3318   if (message)
3319     dbus_message_unref (message);
3320   
3321   return retval;
3322 }
3323
3324 #define SHELL_SUCCESS_SERVICE_NAME "org.freedesktop.DBus.TestSuiteShellEchoServiceSuccess"
3325
3326 /* returns TRUE if the correct thing happens,
3327  * but the correct thing may include OOM errors.
3328  */
3329 static dbus_bool_t
3330 check_shell_service_success_auto_start (BusContext     *context,
3331                                         DBusConnection *connection)
3332 {
3333   DBusMessage *message;
3334   DBusMessage *base_service_message;
3335   dbus_uint32_t serial;
3336   dbus_bool_t retval;
3337   const char *base_service;
3338   const char *argv[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
3339
3340   base_service_message = NULL;
3341
3342   message = dbus_message_new_method_call (SHELL_SUCCESS_SERVICE_NAME,
3343                                           "/org/freedesktop/TestSuite",
3344                                           "org.freedesktop.TestSuite",
3345                                           "Echo");
3346   
3347   if (message == NULL)
3348     return TRUE;
3349
3350   if (!dbus_connection_send (connection, message, &serial))
3351     {
3352       dbus_message_unref (message);
3353       return TRUE;
3354     }
3355
3356   dbus_message_unref (message);
3357   message = NULL;
3358
3359   bus_test_run_everything (context);
3360
3361   /* now wait for the message bus to hear back from the activated
3362    * service.
3363    */
3364   block_connection_until_message_from_bus (context, connection, "reply to Echo on shell success service");
3365   bus_test_run_everything (context);
3366
3367   if (!dbus_connection_get_is_connected (connection))
3368     {
3369       _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
3370       return TRUE;
3371     }
3372
3373   retval = FALSE;
3374   
3375   message = pop_message_waiting_for_memory (connection);
3376   if (message == NULL)
3377     {
3378       _dbus_warn ("Did not receive any messages after auto start %d on %p\n",
3379                   serial, connection);
3380       goto out;
3381     }
3382
3383   verbose_message_received (connection, message);
3384   _dbus_verbose ("  (after sending %s)\n", "auto start");
3385
3386   /* we should get zero or two ServiceOwnerChanged signals */
3387   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL)
3388     {
3389       GotServiceInfo message_kind;
3390
3391       if (!check_base_service_activated (context, connection,
3392                                          message, &base_service))
3393         goto out;
3394
3395       base_service_message = message;
3396       message = NULL;
3397
3398       /* We may need to block here for the test service to exit or finish up */
3399       block_connection_until_message_from_bus (context, connection, "service to exit");
3400
3401       /* Should get a service creation notification for the activated
3402        * service name, or a service deletion on the base service name
3403        */
3404       message = dbus_connection_borrow_message (connection);
3405       if (message == NULL)
3406         {
3407           _dbus_warn ("No message after auto activation "
3408                       "(should be a service announcement)\n");
3409           dbus_connection_return_message (connection, message);
3410           message = NULL;
3411           goto out;
3412         }
3413
3414       message_kind = check_got_service_info (message);
3415
3416       dbus_connection_return_message (connection, message);
3417       message = NULL;
3418
3419       switch (message_kind) 
3420         {
3421         case GOT_SERVICE_CREATED:
3422           message = pop_message_waiting_for_memory (connection);
3423           if (message == NULL)
3424             {
3425               _dbus_warn ("Failed to pop message we just put back! "
3426                           "should have been a NameOwnerChanged (creation)\n");
3427               goto out;
3428             }
3429             
3430           /* Check that ServiceOwnerChanged (creation) was correctly received */
3431           if (!check_service_auto_activated (context, connection, SHELL_SUCCESS_SERVICE_NAME,
3432                                              base_service, message))
3433             goto out;
3434           
3435           dbus_message_unref (message);
3436           message = NULL;
3437
3438           break;
3439
3440         case GOT_SERVICE_DELETED:
3441           {
3442             /* The service started up and got a base address, but then
3443              * failed to register under SHELL_SUCCESS_SERVICE_NAME
3444              */
3445             CheckServiceOwnerChangedData socd;
3446           
3447             socd.expected_kind = SERVICE_DELETED;
3448             socd.expected_service_name = base_service;
3449             socd.failed = FALSE;
3450             socd.skip_connection = NULL;
3451             bus_test_clients_foreach (check_service_owner_changed_foreach,
3452                                       &socd);
3453
3454             if (socd.failed)
3455               goto out;
3456
3457             break;
3458           }
3459
3460         case GOT_ERROR:
3461         case GOT_SOMETHING_ELSE:
3462           _dbus_warn ("Unexpected message after auto activation\n");
3463           goto out;
3464         }
3465     }
3466
3467   /* OK, now we've dealt with ServiceOwnerChanged signals, now should
3468    * come the method reply (or error) from the initial method call
3469    */
3470
3471   /* Note: if this test is run in OOM mode, it will block when the bus
3472    * doesn't send a reply due to OOM.
3473    */
3474   block_connection_until_message_from_bus (context, connection, "reply from echo message after auto-activation");
3475       
3476   message = pop_message_waiting_for_memory (connection);
3477   if (message == NULL)
3478     {
3479       _dbus_warn ("Failed to pop message! Should have been reply from echo message\n");
3480       goto out;
3481     }
3482
3483   if (dbus_message_get_reply_serial (message) != serial)
3484     {
3485       _dbus_warn ("Wrong reply serial\n");
3486       goto out;
3487     }
3488
3489   if (!dbus_message_get_args (message, NULL,
3490                                        DBUS_TYPE_STRING, &argv[0], 
3491                                        DBUS_TYPE_STRING, &argv[1],
3492                                        DBUS_TYPE_STRING, &argv[2],
3493                                        DBUS_TYPE_STRING, &argv[3],
3494                                        DBUS_TYPE_STRING, &argv[4],
3495                                        DBUS_TYPE_STRING, &argv[5],
3496                                        DBUS_TYPE_STRING, &argv[6],
3497                                        DBUS_TYPE_INVALID))
3498     {
3499       _dbus_warn ("Error getting arguments from return\n");
3500       goto out;
3501     }
3502
3503    /* don't worry about arg[0] as it may be different 
3504       depending on the path to the tests
3505    */
3506   if (strcmp("-test", argv[1]) != 0)
3507     {
3508       _dbus_warn ("Unexpected argv[1] in shell success service test (expected: %s, got: %s)\n", 
3509                   "-test", argv[1]);
3510       goto out;
3511     } 
3512
3513   if (strcmp("that", argv[2]) != 0)
3514     {
3515       _dbus_warn ("Unexpected argv[2] in shell success service test (expected: %s, got: %s)\n", 
3516                    "that", argv[2]);
3517       goto out;
3518     } 
3519
3520   if (strcmp("we get", argv[3]) != 0)
3521     {
3522       _dbus_warn ("Unexpected argv[3] in shell success service test (expected: %s, got: %s)\n", 
3523                    "we get", argv[3]);
3524       goto out;
3525     } 
3526    
3527   if (strcmp("back", argv[4]) != 0)
3528     {
3529       _dbus_warn ("Unexpected argv[4] in shell success service test (expected: %s, got: %s)\n", 
3530                    "back", argv[4]);
3531       goto out;
3532     } 
3533
3534   if (strcmp("--what", argv[5]) != 0)
3535     {
3536       _dbus_warn ("Unexpected argv[5] in shell success service test (expected: %s, got: %s)\n", 
3537                    "--what", argv[5]);
3538       goto out;
3539     } 
3540
3541   if (strcmp("we put in", argv[6]) != 0)
3542     {
3543       _dbus_warn ("Unexpected argv[6] in shell success service test (expected: %s, got: %s)\n", 
3544                    "we put in", argv[6]);
3545       goto out;
3546     } 
3547
3548   dbus_message_unref (message);
3549   message = NULL;
3550       
3551   if (!check_send_exit_to_service (context, connection,
3552                                    SHELL_SUCCESS_SERVICE_NAME,
3553                                    base_service))
3554     goto out;
3555   
3556   retval = TRUE;
3557
3558  out:
3559   if (message)
3560     dbus_message_unref (message);
3561
3562   if (base_service_message)
3563     dbus_message_unref (base_service_message);
3564
3565   return retval;
3566 }
3567
3568 typedef struct
3569 {
3570   Check1Func func;
3571   BusContext *context;
3572 } Check1Data;
3573
3574 static dbus_bool_t
3575 check_oom_check1_func (void *data)
3576 {
3577   Check1Data *d = data;
3578
3579   if (! (* d->func) (d->context))
3580     return FALSE;
3581   
3582   if (!check_no_leftovers (d->context))
3583     {
3584       _dbus_warn ("Messages were left over, should be covered by test suite\n");
3585       return FALSE;
3586     }
3587
3588   return TRUE;
3589 }
3590
3591 static void
3592 check1_try_iterations (BusContext *context,
3593                        const char *description,
3594                        Check1Func  func)
3595 {
3596   Check1Data d;
3597
3598   d.func = func;
3599   d.context = context;
3600
3601   if (!_dbus_test_oom_handling (description, check_oom_check1_func,
3602                                 &d))
3603     _dbus_assert_not_reached ("test failed");
3604 }
3605
3606 static dbus_bool_t
3607 check_get_services (BusContext     *context,
3608                     DBusConnection *connection,
3609                     const char     *method,
3610                     char         ***services,
3611                     int            *len)
3612 {
3613   DBusMessage *message;
3614   dbus_uint32_t serial;
3615   dbus_bool_t retval;
3616   DBusError error;
3617   char **srvs;
3618   int l;
3619
3620   retval = FALSE;
3621   dbus_error_init (&error);
3622   message = NULL;
3623
3624   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
3625                                           DBUS_PATH_DBUS,
3626                                           DBUS_INTERFACE_DBUS,
3627                                           method);
3628
3629   if (message == NULL)
3630     return TRUE;
3631
3632   if (!dbus_connection_send (connection, message, &serial))
3633     {
3634       dbus_message_unref (message);
3635       return TRUE;
3636     }
3637
3638   /* send our message */
3639   bus_test_run_clients_loop (SEND_PENDING (connection));
3640
3641   dbus_message_unref (message);
3642   message = NULL;
3643
3644   dbus_connection_ref (connection); /* because we may get disconnected */
3645   block_connection_until_message_from_bus (context, connection, "reply to ListActivatableNames/ListNames");
3646
3647   if (!dbus_connection_get_is_connected (connection))
3648     {
3649       _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
3650
3651       dbus_connection_unref (connection);
3652
3653       return TRUE;
3654     }
3655
3656   dbus_connection_unref (connection);
3657
3658   message = pop_message_waiting_for_memory (connection);
3659   if (message == NULL)
3660     {
3661       _dbus_warn ("Did not receive a reply to %s %d on %p\n",
3662                   method, serial, connection);
3663       goto out;
3664     }
3665
3666   verbose_message_received (connection, message);
3667
3668   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
3669     {
3670       if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY))
3671         {
3672           ; /* good, this is a valid response */
3673         }
3674       else
3675         {
3676           warn_unexpected (connection, message, "not this error");
3677
3678           goto out;
3679         }
3680     }
3681   else
3682     {
3683       if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
3684         {
3685           ; /* good, expected */
3686         }
3687       else
3688         {
3689           warn_unexpected (connection, message,
3690                            "method_return for ListActivatableNames/ListNames");
3691
3692           goto out;
3693         }
3694
3695     retry_get_property:
3696
3697       if (!dbus_message_get_args (message, &error,
3698                                   DBUS_TYPE_ARRAY,
3699                                   DBUS_TYPE_STRING,
3700                                   &srvs, &l,
3701                                   DBUS_TYPE_INVALID))
3702         {
3703           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
3704             {
3705               _dbus_verbose ("no memory to list services by %s\n", method);
3706               dbus_error_free (&error);
3707               _dbus_wait_for_memory ();
3708               goto retry_get_property;
3709             }
3710           else
3711             {
3712               _dbus_assert (dbus_error_is_set (&error));
3713               _dbus_warn ("Did not get the expected DBUS_TYPE_ARRAY from %s\n", method);
3714               goto out;
3715             }
3716         } else {
3717           *services = srvs;
3718           *len = l;
3719         }
3720     }
3721   
3722   if (!check_no_leftovers (context))
3723     goto out;
3724   
3725   retval = TRUE;
3726   
3727  out:
3728   dbus_error_free (&error);
3729   
3730   if (message)
3731     dbus_message_unref (message);
3732
3733   return retval;
3734 }
3735
3736 /* returns TRUE if the correct thing happens,
3737  * but the correct thing may include OOM errors.
3738  */
3739 static dbus_bool_t
3740 check_list_services (BusContext     *context,
3741                      DBusConnection *connection)
3742 {
3743   DBusMessage  *message;
3744   DBusMessage  *base_service_message;
3745   const char   *base_service;
3746   dbus_uint32_t serial;
3747   dbus_bool_t   retval;
3748   const char   *existent = EXISTENT_SERVICE_NAME;
3749   dbus_uint32_t flags;
3750   char        **services;
3751   int           len;
3752
3753   _dbus_verbose ("check_list_services for %p\n", connection);
3754
3755   if (!check_get_services (context, connection, "ListActivatableNames", &services, &len))
3756     {
3757       return TRUE;
3758     }
3759
3760   if (!_dbus_string_array_contains ((const char **)services, existent))
3761     {
3762       _dbus_warn ("Did not get the expected %s from ListActivatableNames\n", existent);
3763       return FALSE;
3764     }
3765
3766   dbus_free_string_array (services);
3767
3768   base_service_message = NULL;
3769
3770   message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
3771                                           DBUS_PATH_DBUS,
3772                                           DBUS_INTERFACE_DBUS,
3773                                           "StartServiceByName");
3774
3775   if (message == NULL)
3776     return TRUE;
3777
3778   dbus_message_set_auto_start (message, FALSE);
3779
3780   flags = 0;
3781   if (!dbus_message_append_args (message,
3782                                  DBUS_TYPE_STRING, &existent,
3783                                  DBUS_TYPE_UINT32, &flags,
3784                                  DBUS_TYPE_INVALID))
3785     {
3786       dbus_message_unref (message);
3787       return TRUE;
3788     }
3789
3790   if (!dbus_connection_send (connection, message, &serial))
3791     {
3792       dbus_message_unref (message);
3793       return TRUE;
3794     }
3795
3796   dbus_message_unref (message);
3797   message = NULL;
3798
3799   bus_test_run_everything (context);
3800
3801   /* now wait for the message bus to hear back from the activated
3802    * service.
3803    */
3804   block_connection_until_message_from_bus (context, connection, "activated service to connect");
3805
3806   bus_test_run_everything (context);
3807
3808   if (!dbus_connection_get_is_connected (connection))
3809     {
3810       _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
3811       return TRUE;
3812     }
3813
3814   retval = FALSE;
3815
3816   message = pop_message_waiting_for_memory (connection);
3817   if (message == NULL)
3818     {
3819       _dbus_warn ("Did not receive any messages after %s %d on %p\n",
3820                   "StartServiceByName", serial, connection);
3821       goto out;
3822     }
3823
3824   verbose_message_received (connection, message);
3825   _dbus_verbose ("  (after sending %s)\n", "StartServiceByName");
3826
3827   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
3828     {
3829       if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
3830         {
3831           _dbus_warn ("Message has wrong sender %s\n",
3832                       dbus_message_get_sender (message) ?
3833                       dbus_message_get_sender (message) : "(none)");
3834           goto out;
3835         }
3836
3837       if (dbus_message_is_error (message,
3838                                  DBUS_ERROR_NO_MEMORY))
3839         {
3840           ; /* good, this is a valid response */
3841         }
3842       else if (dbus_message_is_error (message,
3843                                       DBUS_ERROR_SPAWN_CHILD_EXITED) ||
3844                dbus_message_is_error (message,
3845                                       DBUS_ERROR_SPAWN_CHILD_SIGNALED) ||
3846                dbus_message_is_error (message,
3847                                       DBUS_ERROR_SPAWN_EXEC_FAILED))
3848         {
3849           ; /* good, this is expected also */
3850         }
3851       else
3852         {
3853           _dbus_warn ("Did not expect error %s\n",
3854                       dbus_message_get_error_name (message));
3855           goto out;
3856         }
3857     }
3858   else
3859     {
3860       GotServiceInfo message_kind;
3861
3862       if (!check_base_service_activated (context, connection,
3863                                          message, &base_service))
3864         goto out;
3865
3866       base_service_message = message;
3867       message = NULL;
3868
3869       /* We may need to block here for the test service to exit or finish up */
3870       block_connection_until_message_from_bus (context, connection, "test service to exit or finish up");
3871
3872       message = dbus_connection_borrow_message (connection);
3873       if (message == NULL)
3874         {
3875           _dbus_warn ("Did not receive any messages after base service creation notification\n");
3876           goto out;
3877         }
3878
3879       message_kind = check_got_service_info (message);
3880
3881       dbus_connection_return_message (connection, message);
3882       message = NULL;
3883
3884       switch (message_kind)
3885         {
3886         case GOT_SOMETHING_ELSE:
3887         case GOT_ERROR:
3888         case GOT_SERVICE_DELETED:
3889           _dbus_warn ("Unexpected message after ActivateService "
3890                       "(should be an error or a service announcement)\n");
3891           goto out;
3892
3893         case GOT_SERVICE_CREATED:
3894           message = pop_message_waiting_for_memory (connection);
3895           if (message == NULL)
3896             {
3897               _dbus_warn ("Failed to pop message we just put back! "
3898                           "should have been a NameOwnerChanged (creation)\n");
3899               goto out;
3900             }
3901           
3902           if (!check_service_activated (context, connection, EXISTENT_SERVICE_NAME,
3903                                         base_service, message))
3904             goto out;
3905
3906           dbus_message_unref (message);
3907           message = NULL;
3908
3909           if (!check_no_leftovers (context))
3910             {
3911               _dbus_warn ("Messages were left over after successful activation\n");
3912               goto out;
3913             }
3914
3915           break;
3916         }
3917     }
3918   
3919   if (!check_get_services (context, connection, "ListNames", &services, &len))
3920     {
3921       return TRUE;
3922     }
3923
3924   if (!_dbus_string_array_contains ((const char **)services, existent))
3925     {
3926       _dbus_warn ("Did not get the expected %s from ListNames\n", existent);
3927       goto out;
3928     }
3929
3930   dbus_free_string_array (services);
3931
3932   if (!check_send_exit_to_service (context, connection,
3933                                    EXISTENT_SERVICE_NAME, base_service))
3934     goto out;
3935
3936   retval = TRUE;
3937
3938  out:
3939   if (message)
3940     dbus_message_unref (message);
3941
3942   if (base_service_message)
3943     dbus_message_unref (base_service_message);
3944
3945   return retval;
3946 }
3947
3948 typedef struct
3949 {
3950   Check2Func func;
3951   BusContext *context;
3952   DBusConnection *connection;
3953 } Check2Data;
3954
3955 static dbus_bool_t
3956 check_oom_check2_func (void *data)
3957 {
3958   Check2Data *d = data;
3959
3960   if (! (* d->func) (d->context, d->connection))
3961     return FALSE;
3962   
3963   if (!check_no_leftovers (d->context))
3964     {
3965       _dbus_warn ("Messages were left over, should be covered by test suite\n");
3966       return FALSE;
3967     }
3968
3969   return TRUE;
3970 }
3971
3972 static void
3973 check2_try_iterations (BusContext     *context,
3974                        DBusConnection *connection,
3975                        const char     *description,
3976                        Check2Func      func)
3977 {
3978   Check2Data d;
3979
3980   d.func = func;
3981   d.context = context;
3982   d.connection = connection;
3983   
3984   if (!_dbus_test_oom_handling (description, check_oom_check2_func,
3985                                 &d))
3986     {
3987       _dbus_warn ("%s failed during oom\n", description);
3988       _dbus_assert_not_reached ("test failed");
3989     }
3990 }
3991
3992 dbus_bool_t
3993 bus_dispatch_test (const DBusString *test_data_dir)
3994 {
3995   BusContext *context;
3996   DBusConnection *foo;
3997   DBusConnection *bar;
3998   DBusConnection *baz;
3999   DBusError error;
4000
4001   dbus_error_init (&error);
4002   
4003   context = bus_context_new_test (test_data_dir,
4004                                   "valid-config-files/debug-allow-all.conf");
4005   if (context == NULL)
4006     return FALSE;
4007   
4008   foo = dbus_connection_open_private ("debug-pipe:name=test-server", &error);
4009   if (foo == NULL)
4010     _dbus_assert_not_reached ("could not alloc connection");
4011
4012   if (!bus_setup_debug_client (foo))
4013     _dbus_assert_not_reached ("could not set up connection");
4014
4015   spin_connection_until_authenticated (context, foo);
4016   
4017   if (!check_hello_message (context, foo))
4018     _dbus_assert_not_reached ("hello message failed");
4019
4020   if (!check_double_hello_message (context, foo))
4021     _dbus_assert_not_reached ("double hello message failed");
4022
4023   if (!check_add_match_all (context, foo))
4024     _dbus_assert_not_reached ("AddMatch message failed");
4025   
4026   bar = dbus_connection_open_private ("debug-pipe:name=test-server", &error);
4027   if (bar == NULL)
4028     _dbus_assert_not_reached ("could not alloc connection");
4029
4030   if (!bus_setup_debug_client (bar))
4031     _dbus_assert_not_reached ("could not set up connection");
4032
4033   spin_connection_until_authenticated (context, bar);
4034   
4035   if (!check_hello_message (context, bar))
4036     _dbus_assert_not_reached ("hello message failed");
4037
4038   if (!check_add_match_all (context, bar))
4039     _dbus_assert_not_reached ("AddMatch message failed");
4040   
4041   baz = dbus_connection_open_private ("debug-pipe:name=test-server", &error);
4042   if (baz == NULL)
4043     _dbus_assert_not_reached ("could not alloc connection");
4044
4045   if (!bus_setup_debug_client (baz))
4046     _dbus_assert_not_reached ("could not set up connection");
4047
4048   spin_connection_until_authenticated (context, baz);
4049   
4050   if (!check_hello_message (context, baz))
4051     _dbus_assert_not_reached ("hello message failed");
4052
4053   if (!check_add_match_all (context, baz))
4054     _dbus_assert_not_reached ("AddMatch message failed");
4055
4056   if (!check_get_connection_unix_user (context, baz))
4057     _dbus_assert_not_reached ("GetConnectionUnixUser message failed");
4058
4059   if (!check_get_connection_unix_process_id (context, baz))
4060     _dbus_assert_not_reached ("GetConnectionUnixProcessID message failed");
4061
4062   if (!check_list_services (context, baz))
4063     _dbus_assert_not_reached ("ListActivatableNames message failed");
4064   
4065   if (!check_no_leftovers (context))
4066     {
4067       _dbus_warn ("Messages were left over after setting up initial connections\n");
4068       _dbus_assert_not_reached ("initial connection setup failed");
4069     }
4070   
4071   check1_try_iterations (context, "create_and_hello",
4072                          check_hello_connection);
4073   
4074   check2_try_iterations (context, foo, "nonexistent_service_no_auto_start",
4075                          check_nonexistent_service_no_auto_start);
4076
4077 #ifdef DBUS_WIN_FIXME
4078   _dbus_warn("TODO: dispatch.c segfault_service_no_auto_start test\n");
4079 #else
4080   check2_try_iterations (context, foo, "segfault_service_no_auto_start",
4081                          check_segfault_service_no_auto_start);
4082 #endif
4083   
4084   check2_try_iterations (context, foo, "existent_service_no_auto_start",
4085                          check_existent_service_no_auto_start);
4086   
4087   check2_try_iterations (context, foo, "nonexistent_service_auto_start",
4088                          check_nonexistent_service_auto_start);
4089   
4090
4091 #ifdef DBUS_WIN_FIXME    
4092   _dbus_warn("TODO: dispatch.c segfault_service_auto_start test\n");
4093 #else
4094   check2_try_iterations (context, foo, "segfault_service_auto_start",
4095                          check_segfault_service_auto_start);
4096 #endif
4097
4098   check2_try_iterations (context, foo, "shell_fail_service_auto_start",
4099                          check_shell_fail_service_auto_start);
4100
4101 #if 0
4102   /* Note: need to resolve some issues with the testing code in order to run
4103    * this in oom (handle that we sometimes don't get replies back from the bus
4104    * when oom happens, without blocking the test).
4105    */
4106   check2_try_iterations (context, foo, "existent_service_auto_auto_start",
4107                          check_existent_service_auto_start);
4108 #endif
4109   
4110   if (!check_existent_service_auto_start (context, foo))
4111     _dbus_assert_not_reached ("existent service auto start failed");
4112
4113   if (!check_shell_service_success_auto_start (context, foo))
4114     _dbus_assert_not_reached ("shell success service auto start failed");
4115
4116   _dbus_verbose ("Disconnecting foo, bar, and baz\n");
4117
4118   kill_client_connection_unchecked (foo);
4119   kill_client_connection_unchecked (bar);
4120   kill_client_connection_unchecked (baz);
4121
4122   bus_context_unref (context);
4123   
4124   return TRUE;
4125 }
4126
4127 dbus_bool_t
4128 bus_dispatch_sha1_test (const DBusString *test_data_dir)
4129 {
4130   BusContext *context;
4131   DBusConnection *foo;
4132   DBusError error;
4133
4134   dbus_error_init (&error);
4135   
4136   /* Test SHA1 authentication */
4137   _dbus_verbose ("Testing SHA1 context\n");
4138   
4139   context = bus_context_new_test (test_data_dir,
4140                                   "valid-config-files/debug-allow-all-sha1.conf");
4141   if (context == NULL)
4142     return FALSE;
4143
4144   foo = dbus_connection_open_private ("debug-pipe:name=test-server", &error);
4145   if (foo == NULL)
4146     _dbus_assert_not_reached ("could not alloc connection");
4147
4148   if (!bus_setup_debug_client (foo))
4149     _dbus_assert_not_reached ("could not set up connection");
4150
4151   spin_connection_until_authenticated (context, foo);
4152   
4153   if (!check_hello_message (context, foo))
4154     _dbus_assert_not_reached ("hello message failed");
4155
4156   if (!check_add_match_all (context, foo))
4157     _dbus_assert_not_reached ("addmatch message failed");
4158   
4159   if (!check_no_leftovers (context))
4160     {
4161       _dbus_warn ("Messages were left over after setting up initial SHA-1 connection\n");
4162       _dbus_assert_not_reached ("initial connection setup failed");
4163     }
4164   
4165   check1_try_iterations (context, "create_and_hello_sha1",
4166                          check_hello_connection);
4167
4168   kill_client_connection_unchecked (foo);
4169
4170   bus_context_unref (context);
4171
4172   return TRUE;
4173 }
4174
4175 #endif /* DBUS_BUILD_TESTS */