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