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