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