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