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