/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* dispatch.c  Message dispatcher
 *
 * Copyright (C) 2003  CodeFactory AB
 * Copyright (C) 2003, 2004, 2005  Red Hat, Inc.
 * Copyright (C) 2004  Imendio HB
 *
 * Licensed under the Academic Free License version 2.1
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include <config.h>
#include "dispatch.h"
#include "connection.h"
#include "driver.h"
#include "services.h"
#include "activation.h"
#include "utils.h"
#include "bus.h"
#include "signals.h"
#include "test.h"
#include <dbus/dbus-internals.h>
#include <string.h>

#ifdef HAVE_UNIX_FD_PASSING
#include <dbus/dbus-sysdeps-unix.h>
#include <unistd.h>
#endif

#ifndef TEST_CONNECTION
/*
 TODO autotools:
  move to build system as already done for cmake
*/
#ifdef DBUS_UNIX
#define TEST_CONNECTION "debug-pipe:name=test-server"
#else
#define TEST_CONNECTION "tcp:host=localhost,port=1234"
#endif
#endif

static dbus_bool_t
send_one_message (DBusConnection *connection,
                  BusContext     *context,
                  DBusConnection *sender,
                  DBusConnection *addressed_recipient,
                  DBusMessage    *message,
                  BusTransaction *transaction,
                  DBusError      *error)
{
  if (!bus_context_check_security_policy (context, transaction,
                                          sender,
                                          addressed_recipient,
                                          connection,
                                          message,
                                          NULL))
    return TRUE; /* silently don't send it */

  if (dbus_message_contains_unix_fds(message) &&
      !dbus_connection_can_send_type(connection, DBUS_TYPE_UNIX_FD))
    return TRUE; /* silently don't send it */

  if (!bus_transaction_send (transaction,
                             connection,
                             message))
    {
      BUS_SET_OOM (error);
      return FALSE;
    }

  return TRUE;
}

dbus_bool_t
bus_dispatch_matches (BusTransaction *transaction,
                      DBusConnection *sender,
                      DBusConnection *addressed_recipient,
                      DBusMessage    *message,
                      DBusError      *error)
{
  DBusError tmp_error;
  BusConnections *connections;
  DBusList *recipients;
  BusMatchmaker *matchmaker;
  DBusList *link;
  BusContext *context;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

  /* sender and recipient can both be NULL for the bus driver,
   * or for signals with no particular recipient
   */

  _dbus_assert (sender == NULL || bus_connection_is_active (sender));
  _dbus_assert (dbus_message_get_sender (message) != NULL);

  context = bus_transaction_get_context (transaction);

  /* First, send the message to the addressed_recipient, if there is one. */
  if (addressed_recipient != NULL)
    {
      if (!bus_context_check_security_policy (context, transaction,
                                              sender, addressed_recipient,
                                              addressed_recipient,
                                              message, error))
        return FALSE;

      if (dbus_message_contains_unix_fds (message) &&
          !dbus_connection_can_send_type (addressed_recipient,
                                          DBUS_TYPE_UNIX_FD))
        {
          dbus_set_error (error,
                          DBUS_ERROR_NOT_SUPPORTED,
                          "Tried to send message with Unix file descriptors"
                          "to a client that doesn't support that.");
          return FALSE;
      }

      /* Dispatch the message */
      if (!bus_transaction_send (transaction, addressed_recipient, message))
        {
          BUS_SET_OOM (error);
          return FALSE;
        }
    }

  /* Now dispatch to others who look interested in this message */
  connections = bus_transaction_get_connections (transaction);
  dbus_error_init (&tmp_error);
  matchmaker = bus_context_get_matchmaker (context);

  recipients = NULL;
  if (!bus_matchmaker_get_recipients (matchmaker, connections,
                                      sender, addressed_recipient, message,
                                      &recipients))
    {
      BUS_SET_OOM (error);
      return FALSE;
    }

  link = _dbus_list_get_first_link (&recipients);
  while (link != NULL)
    {
      DBusConnection *dest;

      dest = link->data;

      if (!send_one_message (dest, context, sender, addressed_recipient,
                             message, transaction, &tmp_error))
        break;

      link = _dbus_list_get_next_link (&recipients, link);
    }

  _dbus_list_clear (&recipients);

  if (dbus_error_is_set (&tmp_error))
    {
      dbus_move_error (&tmp_error, error);
      return FALSE;
    }
  else
    return TRUE;
}

static DBusHandlerResult
bus_dispatch (DBusConnection *connection,
              DBusMessage    *message)
{
  const char *sender, *service_name;
  DBusError error;
  BusTransaction *transaction;
  BusContext *context;
  DBusHandlerResult result;
  DBusConnection *addressed_recipient;

  result = DBUS_HANDLER_RESULT_HANDLED;

  transaction = NULL;
  addressed_recipient = NULL;
  dbus_error_init (&error);

  context = bus_connection_get_context (connection);
  _dbus_assert (context != NULL);

  /* If we can't even allocate an OOM error, we just go to sleep
   * until we can.
   */
  while (!bus_connection_preallocate_oom_error (connection))
    _dbus_wait_for_memory ();

  /* Ref connection in case we disconnect it at some point in here */
  dbus_connection_ref (connection);

  service_name = dbus_message_get_destination (message);

#ifdef DBUS_ENABLE_VERBOSE_MODE
  {
    const char *interface_name, *member_name, *error_name;

    interface_name = dbus_message_get_interface (message);
    member_name = dbus_message_get_member (message);
    error_name = dbus_message_get_error_name (message);

    _dbus_verbose ("DISPATCH: %s %s %s to %s\n",
                   interface_name ? interface_name : "(no interface)",
                   member_name ? member_name : "(no member)",
                   error_name ? error_name : "(no error name)",
                   service_name ? service_name : "peer");
  }
#endif /* DBUS_ENABLE_VERBOSE_MODE */

  /* If service_name is NULL, if it's a signal we send it to all
   * connections with a match rule. If it's not a signal, there
   * are some special cases here but mostly we just bail out.
   */
  if (service_name == NULL)
    {
      if (dbus_message_is_signal (message,
                                  DBUS_INTERFACE_LOCAL,
                                  "Disconnected"))
        {
          bus_connection_disconnected (connection);
          goto out;
        }

      if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL)
        {
          /* DBusConnection also handles some of these automatically, we leave
           * it to do so.
           */
          result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
          goto out;
        }
    }

  /* Create our transaction */
  transaction = bus_transaction_new (context);
  if (transaction == NULL)
    {
      BUS_SET_OOM (&error);
      goto out;
    }

  /* Assign a sender to the message */
  if (bus_connection_is_active (connection))
    {
      sender = bus_connection_get_name (connection);
      _dbus_assert (sender != NULL);

      if (!dbus_message_set_sender (message, sender))
        {
          BUS_SET_OOM (&error);
          goto out;
        }

      /* We need to refetch the service name here, because
       * dbus_message_set_sender can cause the header to be
       * reallocated, and thus the service_name pointer will become
       * invalid.
       */
      service_name = dbus_message_get_destination (message);
    }

  if (service_name &&
      strcmp (service_name, DBUS_SERVICE_DBUS) == 0) /* to bus driver */
    {
      if (!bus_context_check_security_policy (context, transaction,
                                              connection, NULL, NULL, message, &error))
        {
          _dbus_verbose ("Security policy rejected message\n");
          goto out;
        }

      _dbus_verbose ("Giving message to %s\n", DBUS_SERVICE_DBUS);
      if (!bus_driver_handle_message (connection, transaction, message, &error))
        goto out;
    }
  else if (!bus_connection_is_active (connection)) /* clients must talk to bus driver first */
    {
      _dbus_verbose ("Received message from non-registered client. Disconnecting.\n");
      dbus_connection_close (connection);
      goto out;
    }
  else if (service_name != NULL) /* route to named service */
    {
      DBusString service_string;
      BusService *service;
      BusRegistry *registry;

      _dbus_assert (service_name != NULL);

      registry = bus_connection_get_registry (connection);

      _dbus_string_init_const (&service_string, service_name);
      service = bus_registry_lookup (registry, &service_string);

      if (service == NULL && dbus_message_get_auto_start (message))
        {
          BusActivation *activation;
          /* We can't do the security policy check here, since the addressed
           * recipient service doesn't exist yet. We do it before sending the
           * message after the service has been created.
           */
          activation = bus_connection_get_activation (connection);

          if (!bus_activation_activate_service (activation, connection, transaction, TRUE,
                                                message, service_name, &error))
            {
              _DBUS_ASSERT_ERROR_CONTENT_IS_SET (&error);
              _dbus_verbose ("bus_activation_activate_service() failed: %s\n", error.name);
              goto out;
            }

          goto out;
        }
      else if (service == NULL)
        {
          dbus_set_error (&error,
                          DBUS_ERROR_NAME_HAS_NO_OWNER,
                          "Name \"%s\" does not exist",
                          service_name);
          goto out;
        }
      else
        {
          addressed_recipient = bus_service_get_primary_owners_connection (service);
          _dbus_assert (addressed_recipient != NULL);
        }
    }

  /* Now send the message to its destination (or not, if
   * addressed_recipient == NULL), and match it against other connections'
   * match rules.
   */
  if (!bus_dispatch_matches (transaction, connection, addressed_recipient, message, &error))
    goto out;

 out:
  if (dbus_error_is_set (&error))
    {
      if (!dbus_connection_get_is_connected (connection))
        {
          /* If we disconnected it, we won't bother to send it any error
           * messages.
           */
          _dbus_verbose ("Not sending error to connection we disconnected\n");
        }
      else if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
        {
          bus_connection_send_oom_error (connection, message);

          /* cancel transaction due to OOM */
          if (transaction != NULL)
            {
              bus_transaction_cancel_and_free (transaction);
              transaction = NULL;
            }
        }
      else
        {
          /* Try to send the real error, if no mem to do that, send
           * the OOM error
           */
          _dbus_assert (transaction != NULL);
          if (!bus_transaction_send_error_reply (transaction, connection,
                                                 &error, message))
            {
              bus_connection_send_oom_error (connection, message);

              /* cancel transaction due to OOM */
              if (transaction != NULL)
                {
                  bus_transaction_cancel_and_free (transaction);
                  transaction = NULL;
                }
            }
        }


      dbus_error_free (&error);
    }

  if (transaction != NULL)
    {
      bus_transaction_execute_and_free (transaction);
    }

  dbus_connection_unref (connection);

  return result;
}

static DBusHandlerResult
bus_dispatch_message_filter (DBusConnection     *connection,
                             DBusMessage        *message,
                             void               *user_data)
{
  return bus_dispatch (connection, message);
}

dbus_bool_t
bus_dispatch_add_connection (DBusConnection *connection)
{
  if (!dbus_connection_add_filter (connection,
                                   bus_dispatch_message_filter,
                                   NULL, NULL))
    return FALSE;

  return TRUE;
}

void
bus_dispatch_remove_connection (DBusConnection *connection)
{
  /* Here we tell the bus driver that we want to get off. */
  bus_driver_remove_connection (connection);

  dbus_connection_remove_filter (connection,
                                 bus_dispatch_message_filter,
                                 NULL);
}

#ifdef DBUS_BUILD_TESTS

#include <stdio.h>

/* This is used to know whether we need to block in order to finish
 * sending a message, or whether the initial dbus_connection_send()
 * already flushed the queue.
 */
#define SEND_PENDING(connection) (dbus_connection_has_messages_to_send (connection))

typedef dbus_bool_t (* Check1Func) (BusContext     *context);
typedef dbus_bool_t (* Check2Func) (BusContext     *context,
                                    DBusConnection *connection);

static dbus_bool_t check_no_leftovers (BusContext *context);

static void
block_connection_until_message_from_bus (BusContext     *context,
                                         DBusConnection *connection,
                                         const char     *what_is_expected)
{
  _dbus_verbose ("expecting: %s\n", what_is_expected);

  while (dbus_connection_get_dispatch_status (connection) ==
         DBUS_DISPATCH_COMPLETE &&
         dbus_connection_get_is_connected (connection))
    {
      bus_test_run_bus_loop (context, TRUE);
      bus_test_run_clients_loop (FALSE);
    }
}

static void
spin_connection_until_authenticated (BusContext     *context,
                                     DBusConnection *connection)
{
  _dbus_verbose ("Spinning to auth connection %p\n", connection);
  while (!dbus_connection_get_is_authenticated (connection) &&
         dbus_connection_get_is_connected (connection))
    {
      bus_test_run_bus_loop (context, FALSE);
      bus_test_run_clients_loop (FALSE);
    }
  _dbus_verbose (" ... done spinning to auth connection %p\n", connection);
}

/* compensate for fact that pop_message() can return #NULL due to OOM */
static DBusMessage*
pop_message_waiting_for_memory (DBusConnection *connection)
{
  while (dbus_connection_get_dispatch_status (connection) ==
         DBUS_DISPATCH_NEED_MEMORY)
    _dbus_wait_for_memory ();

  return dbus_connection_pop_message (connection);
}

static DBusMessage*
borrow_message_waiting_for_memory (DBusConnection *connection)
{
  while (dbus_connection_get_dispatch_status (connection) ==
         DBUS_DISPATCH_NEED_MEMORY)
    _dbus_wait_for_memory ();

  return dbus_connection_borrow_message (connection);
}

static void
warn_unexpected_real (DBusConnection *connection,
                      DBusMessage    *message,
                      const char     *expected,
                      const char     *function,
                      int             line)
{
  if (message)
    _dbus_warn ("%s:%d received message interface \"%s\" member \"%s\" error name \"%s\" on %p, expecting %s\n",
                function, line,
                dbus_message_get_interface (message) ?
                dbus_message_get_interface (message) : "(unset)",
                dbus_message_get_member (message) ?
                dbus_message_get_member (message) : "(unset)",
                dbus_message_get_error_name (message) ?
                dbus_message_get_error_name (message) : "(unset)",
                connection,
                expected);
  else
    _dbus_warn ("%s:%d received no message on %p, expecting %s\n",
                function, line, connection, expected);
}

#define warn_unexpected(connection, message, expected) \
  warn_unexpected_real (connection, message, expected, _DBUS_FUNCTION_NAME, __LINE__)

static void
verbose_message_received (DBusConnection *connection,
                          DBusMessage    *message)
{
  _dbus_verbose ("Received message interface \"%s\" member \"%s\" error name \"%s\" on %p\n",
                 dbus_message_get_interface (message) ?
                 dbus_message_get_interface (message) : "(unset)",
                 dbus_message_get_member (message) ?
                 dbus_message_get_member (message) : "(unset)",
                 dbus_message_get_error_name (message) ?
                 dbus_message_get_error_name (message) : "(unset)",
                 connection);
}

typedef enum
{
  SERVICE_CREATED,
  OWNER_CHANGED,
  SERVICE_DELETED
} ServiceInfoKind;

typedef struct
{
  ServiceInfoKind expected_kind;
  const char *expected_service_name;
  dbus_bool_t failed;
  DBusConnection *skip_connection;
} CheckServiceOwnerChangedData;

static dbus_bool_t
check_service_owner_changed_foreach (DBusConnection *connection,
                                     void           *data)
{
  CheckServiceOwnerChangedData *d = data;
  DBusMessage *message;
  DBusError error;
  const char *service_name, *old_owner, *new_owner;

  if (d->expected_kind == SERVICE_CREATED
      && connection == d->skip_connection)
    return TRUE;

  dbus_error_init (&error);
  d->failed = TRUE;

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Did not receive a message on %p, expecting %s\n",
                  connection, "NameOwnerChanged");
      goto out;
    }
  else if (!dbus_message_is_signal (message,
                                    DBUS_INTERFACE_DBUS,
                                    "NameOwnerChanged"))
    {
      warn_unexpected (connection, message, "NameOwnerChanged");

      goto out;
    }
  else
    {
    reget_service_info_data:
      service_name = NULL;
      old_owner = NULL;
      new_owner = NULL;

      dbus_message_get_args (message, &error,
                             DBUS_TYPE_STRING, &service_name,
                             DBUS_TYPE_STRING, &old_owner,
                             DBUS_TYPE_STRING, &new_owner,
                             DBUS_TYPE_INVALID);

      if (dbus_error_is_set (&error))
        {
          if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
            {
              dbus_error_free (&error);
              _dbus_wait_for_memory ();
              goto reget_service_info_data;
            }
          else
            {
              _dbus_warn ("Did not get the expected arguments\n");
              goto out;
            }
        }

      if ((d->expected_kind == SERVICE_CREATED    && ( old_owner[0] || !new_owner[0]))
          || (d->expected_kind == OWNER_CHANGED   && (!old_owner[0] || !new_owner[0]))
          || (d->expected_kind == SERVICE_DELETED && (!old_owner[0] ||  new_owner[0])))
        {
          _dbus_warn ("inconsistent NameOwnerChanged arguments\n");
          goto out;
        }

      if (strcmp (service_name, d->expected_service_name) != 0)
        {
          _dbus_warn ("expected info on service %s, got info on %s\n",
                      d->expected_service_name,
                      service_name);
          goto out;
        }

      if (*service_name == ':' && new_owner[0]
          && strcmp (service_name, new_owner) != 0)
        {
          _dbus_warn ("inconsistent ServiceOwnedChanged message (\"%s\" [ %s -> %s ])\n",
                      service_name, old_owner, new_owner);
          goto out;
        }
    }

  d->failed = FALSE;

 out:
  dbus_error_free (&error);

  if (message)
    dbus_message_unref (message);

  return !d->failed;
}


static void
kill_client_connection (BusContext     *context,
                        DBusConnection *connection)
{
  char *base_service;
  const char *s;
  CheckServiceOwnerChangedData socd;

  _dbus_verbose ("killing connection %p\n", connection);

  s = dbus_bus_get_unique_name (connection);
  _dbus_assert (s != NULL);

  while ((base_service = _dbus_strdup (s)) == NULL)
    _dbus_wait_for_memory ();

  dbus_connection_ref (connection);

  /* kick in the disconnect handler that unrefs the connection */
  dbus_connection_close (connection);

  bus_test_run_everything (context);

  _dbus_assert (bus_test_client_listed (connection));

  /* Run disconnect handler in test.c */
  if (bus_connection_dispatch_one_message (connection))
    _dbus_assert_not_reached ("something received on connection being killed other than the disconnect");

  _dbus_assert (!dbus_connection_get_is_connected (connection));
  dbus_connection_unref (connection);
  connection = NULL;
  _dbus_assert (!bus_test_client_listed (connection));

  socd.expected_kind = SERVICE_DELETED;
  socd.expected_service_name = base_service;
  socd.failed = FALSE;
  socd.skip_connection = NULL;

  bus_test_clients_foreach (check_service_owner_changed_foreach,
                            &socd);

  dbus_free (base_service);

  if (socd.failed)
    _dbus_assert_not_reached ("didn't get the expected NameOwnerChanged (deletion) messages");

  if (!check_no_leftovers (context))
    _dbus_assert_not_reached ("stuff left in message queues after disconnecting a client");
}

static void
kill_client_connection_unchecked (DBusConnection *connection)
{
  /* This kills the connection without expecting it to affect
   * the rest of the bus.
   */
  _dbus_verbose ("Unchecked kill of connection %p\n", connection);

  dbus_connection_ref (connection);
  dbus_connection_close (connection);
  /* dispatching disconnect handler will unref once */
  if (bus_connection_dispatch_one_message (connection))
    _dbus_assert_not_reached ("message other than disconnect dispatched after failure to register");

  _dbus_assert (!bus_test_client_listed (connection));
  dbus_connection_unref (connection);
}

typedef struct
{
  dbus_bool_t failed;
} CheckNoMessagesData;

static dbus_bool_t
check_no_messages_foreach (DBusConnection *connection,
                           void           *data)
{
  CheckNoMessagesData *d = data;
  DBusMessage *message;

  message = pop_message_waiting_for_memory (connection);
  if (message != NULL)
    {
      warn_unexpected (connection, message, "no messages");

      d->failed = TRUE;
    }

  if (message)
    dbus_message_unref (message);
  return !d->failed;
}

static dbus_bool_t
check_no_leftovers (BusContext *context)
{
  CheckNoMessagesData nmd;

  nmd.failed = FALSE;
  bus_test_clients_foreach (check_no_messages_foreach,
                            &nmd);

  if (nmd.failed)
    {
      _dbus_verbose ("leftover message found\n");
      return FALSE;
    }
  else
    return TRUE;
}

/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_hello_message (BusContext     *context,
                     DBusConnection *connection)
{
  DBusMessage *message;
  DBusMessage *name_message;
  dbus_uint32_t serial;
  dbus_bool_t retval;
  DBusError error;
  const char *name;
  const char *acquired;

  retval = FALSE;
  dbus_error_init (&error);
  name = NULL;
  acquired = NULL;
  message = NULL;
  name_message = NULL;

  _dbus_verbose ("check_hello_message for %p\n", connection);

  message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
                                          DBUS_PATH_DBUS,
                                          DBUS_INTERFACE_DBUS,
                                          "Hello");

  if (message == NULL)
    return TRUE;

  dbus_connection_ref (connection); /* because we may get disconnected */

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      dbus_connection_unref (connection);
      return TRUE;
    }

  _dbus_assert (dbus_message_has_signature (message, ""));

  dbus_message_unref (message);
  message = NULL;

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_verbose ("connection was disconnected (presumably auth failed)\n");

      dbus_connection_unref (connection);

      return TRUE;
    }

  /* send our message */
  bus_test_run_clients_loop (SEND_PENDING (connection));

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_verbose ("connection was disconnected (presumably auth failed)\n");

      dbus_connection_unref (connection);

      return TRUE;
    }

  block_connection_until_message_from_bus (context, connection, "reply to Hello");

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_verbose ("connection was disconnected (presumably auth failed)\n");

      dbus_connection_unref (connection);

      return TRUE;
    }

  dbus_connection_unref (connection);

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Did not receive a reply to %s %d on %p\n",
                  "Hello", serial, connection);
      goto out;
    }

  verbose_message_received (connection, message);

  if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
    {
      _dbus_warn ("Message has wrong sender %s\n",
                  dbus_message_get_sender (message) ?
                  dbus_message_get_sender (message) : "(none)");
      goto out;
    }

  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
    {
      if (dbus_message_is_error (message,
                                 DBUS_ERROR_NO_MEMORY))
        {
          ; /* good, this is a valid response */
        }
      else
        {
          warn_unexpected (connection, message, "not this error");

          goto out;
        }
    }
  else
    {
      CheckServiceOwnerChangedData socd;

      if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
        {
          ; /* good, expected */
        }
      else
        {
          warn_unexpected (connection, message, "method return for Hello");

          goto out;
        }

    retry_get_hello_name:
      if (!dbus_message_get_args (message, &error,
                                  DBUS_TYPE_STRING, &name,
                                  DBUS_TYPE_INVALID))
        {
          if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
            {
              _dbus_verbose ("no memory to get service name arg from hello\n");
              dbus_error_free (&error);
              _dbus_wait_for_memory ();
              goto retry_get_hello_name;
            }
          else
            {
              _dbus_assert (dbus_error_is_set (&error));
              _dbus_warn ("Did not get the expected single string argument to hello\n");
              goto out;
            }
        }

      _dbus_verbose ("Got hello name: %s\n", name);

      while (!dbus_bus_set_unique_name (connection, name))
        _dbus_wait_for_memory ();

      socd.expected_kind = SERVICE_CREATED;
      socd.expected_service_name = name;
      socd.failed = FALSE;
      socd.skip_connection = connection; /* we haven't done AddMatch so won't get it ourselves */
      bus_test_clients_foreach (check_service_owner_changed_foreach,
                                &socd);

      if (socd.failed)
        goto out;

      name_message = message;
      /* Client should also have gotten ServiceAcquired */

      message = pop_message_waiting_for_memory (connection);
      if (message == NULL)
        {
          _dbus_warn ("Expecting %s, got nothing\n",
                      "NameAcquired");
          goto out;
        }
      if (! dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
                                    "NameAcquired"))
        {
          _dbus_warn ("Expecting %s, got smthg else\n",
                      "NameAcquired");
          goto out;
        }

    retry_get_acquired_name:
      if (!dbus_message_get_args (message, &error,
                                  DBUS_TYPE_STRING, &acquired,
                                  DBUS_TYPE_INVALID))
        {
          if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
            {
              _dbus_verbose ("no memory to get service name arg from acquired\n");
              dbus_error_free (&error);
              _dbus_wait_for_memory ();
              goto retry_get_acquired_name;
            }
          else
            {
              _dbus_assert (dbus_error_is_set (&error));
              _dbus_warn ("Did not get the expected single string argument to ServiceAcquired\n");
              goto out;
            }
        }

      _dbus_verbose ("Got acquired name: %s\n", acquired);

      if (strcmp (acquired, name) != 0)
        {
          _dbus_warn ("Acquired name is %s but expected %s\n",
                      acquired, name);
          goto out;
        }
      acquired = NULL;
    }

  if (!check_no_leftovers (context))
    goto out;

  retval = TRUE;

 out:
  _dbus_verbose ("ending - retval = %d\n", retval);

  dbus_error_free (&error);

  if (message)
    dbus_message_unref (message);

  if (name_message)
    dbus_message_unref (name_message);

  return retval;
}

/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_double_hello_message (BusContext     *context,
                            DBusConnection *connection)
{
  DBusMessage *message;
  dbus_uint32_t serial;
  dbus_bool_t retval;
  DBusError error;

  retval = FALSE;
  dbus_error_init (&error);
  message = NULL;

  _dbus_verbose ("check_double_hello_message for %p\n", connection);

  message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
                                          DBUS_PATH_DBUS,
                                          DBUS_INTERFACE_DBUS,
                                          "Hello");

  if (message == NULL)
    return TRUE;

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  dbus_message_unref (message);
  message = NULL;

  /* send our message */
  bus_test_run_clients_loop (SEND_PENDING (connection));

  dbus_connection_ref (connection); /* because we may get disconnected */
  block_connection_until_message_from_bus (context, connection, "reply to Hello");

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_verbose ("connection was disconnected\n");

      dbus_connection_unref (connection);

      return TRUE;
    }

  dbus_connection_unref (connection);

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Did not receive a reply to %s %d on %p\n",
                  "Hello", serial, connection);
      goto out;
    }

  verbose_message_received (connection, message);

  if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
    {
      _dbus_warn ("Message has wrong sender %s\n",
                  dbus_message_get_sender (message) ?
                  dbus_message_get_sender (message) : "(none)");
      goto out;
    }

  if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
    {
      warn_unexpected (connection, message, "method return for Hello");
      goto out;
    }

  if (!check_no_leftovers (context))
    goto out;

  retval = TRUE;

 out:
  dbus_error_free (&error);

  if (message)
    dbus_message_unref (message);

  return retval;
}

/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_get_connection_unix_user (BusContext     *context,
                                DBusConnection *connection)
{
  DBusMessage *message;
  dbus_uint32_t serial;
  dbus_bool_t retval;
  DBusError error;
  const char *base_service_name;
  dbus_uint32_t uid;

  retval = FALSE;
  dbus_error_init (&error);
  message = NULL;

  _dbus_verbose ("check_get_connection_unix_user for %p\n", connection);

  message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
                                          DBUS_PATH_DBUS,
                                          DBUS_INTERFACE_DBUS,
                                          "GetConnectionUnixUser");

  if (message == NULL)
    return TRUE;

  base_service_name = dbus_bus_get_unique_name (connection);

  if (!dbus_message_append_args (message,
                                 DBUS_TYPE_STRING, &base_service_name,
                                 DBUS_TYPE_INVALID))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  /* send our message */
  bus_test_run_clients_loop (SEND_PENDING (connection));

  dbus_message_unref (message);
  message = NULL;

  dbus_connection_ref (connection); /* because we may get disconnected */
  block_connection_until_message_from_bus (context, connection, "reply to GetConnectionUnixUser");

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_verbose ("connection was disconnected\n");

      dbus_connection_unref (connection);

      return TRUE;
    }

  dbus_connection_unref (connection);

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Did not receive a reply to %s %d on %p\n",
                  "GetConnectionUnixUser", serial, connection);
      goto out;
    }

  verbose_message_received (connection, message);

  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
    {
      if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY))
        {
          ; /* good, this is a valid response */
        }
      else
        {
          warn_unexpected (connection, message, "not this error");

          goto out;
        }
    }
  else
    {
      if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
        {
          ; /* good, expected */
        }
      else
        {
          warn_unexpected (connection, message,
                           "method_return for GetConnectionUnixUser");

          goto out;
        }

    retry_get_property:

      if (!dbus_message_get_args (message, &error,
                                  DBUS_TYPE_UINT32, &uid,
                                  DBUS_TYPE_INVALID))
        {
          if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
            {
              _dbus_verbose ("no memory to get uid by GetConnectionUnixUser\n");
              dbus_error_free (&error);
              _dbus_wait_for_memory ();
              goto retry_get_property;
            }
          else
            {
              _dbus_assert (dbus_error_is_set (&error));
              _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetConnectionUnixUser\n");
              goto out;
            }
        }
    }

  if (!check_no_leftovers (context))
    goto out;

  retval = TRUE;

 out:
  dbus_error_free (&error);

  if (message)
    dbus_message_unref (message);

  return retval;
}

/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_get_connection_unix_process_id (BusContext     *context,
                                      DBusConnection *connection)
{
  DBusMessage *message;
  dbus_uint32_t serial;
  dbus_bool_t retval;
  DBusError error;
  const char *base_service_name;
  dbus_uint32_t pid;

  retval = FALSE;
  dbus_error_init (&error);
  message = NULL;

  _dbus_verbose ("check_get_connection_unix_process_id for %p\n", connection);

  message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
                                          DBUS_PATH_DBUS,
                                          DBUS_INTERFACE_DBUS,
                                          "GetConnectionUnixProcessID");

  if (message == NULL)
    return TRUE;

  base_service_name = dbus_bus_get_unique_name (connection);

  if (!dbus_message_append_args (message,
                                 DBUS_TYPE_STRING, &base_service_name,
                                 DBUS_TYPE_INVALID))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  /* send our message */
  bus_test_run_clients_loop (SEND_PENDING (connection));

  dbus_message_unref (message);
  message = NULL;

  dbus_connection_ref (connection); /* because we may get disconnected */
  block_connection_until_message_from_bus (context, connection, "reply to GetConnectionUnixProcessID");

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_verbose ("connection was disconnected\n");

      dbus_connection_unref (connection);

      return TRUE;
    }

  dbus_connection_unref (connection);

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Did not receive a reply to %s %d on %p\n",
                  "GetConnectionUnixProcessID", serial, connection);
      goto out;
    }

  verbose_message_received (connection, message);

  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
    {
      if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY))
        {
          ; /* good, this is a valid response */
        }
#ifdef DBUS_WIN
      else if (dbus_message_is_error (message, DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN))
        {
          /* We are expecting this error, since we know in the test suite we aren't
           * talking to a client running on UNIX
           */
          _dbus_verbose ("Windows correctly does not support GetConnectionUnixProcessID\n");
        }
#endif
      else
        {
          warn_unexpected (connection, message, "not this error");

          goto out;
        }
    }
  else
    {
#ifdef DBUS_WIN
      warn_unexpected (connection, message, "GetConnectionUnixProcessID to fail on Windows");
      goto out;
#else
      if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
        {
          ; /* good, expected */
        }
      else
        {
          warn_unexpected (connection, message,
                           "method_return for GetConnectionUnixProcessID");

          goto out;
        }

    retry_get_property:

      if (!dbus_message_get_args (message, &error,
                                  DBUS_TYPE_UINT32, &pid,
                                  DBUS_TYPE_INVALID))
        {
          if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
            {
              _dbus_verbose ("no memory to get pid by GetConnectionUnixProcessID\n");
              dbus_error_free (&error);
              _dbus_wait_for_memory ();
              goto retry_get_property;
            }
          else
            {
              _dbus_assert (dbus_error_is_set (&error));
              _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetConnectionUnixProcessID\n");
              goto out;
            }
        }
      else
        {
          /* test if returned pid is the same as our own pid
           *
           * @todo It would probably be good to restructure the tests
           *       in a way so our parent is the bus that we're testing
           *       cause then we can test that the pid returned matches
           *       getppid()
           */
          if (pid != (dbus_uint32_t) _dbus_getpid ())
            {
              _dbus_assert (dbus_error_is_set (&error));
              _dbus_warn ("Result from GetConnectionUnixProcessID is not our own pid\n");
              goto out;
            }
        }
#endif /* !DBUS_WIN */
    }

  if (!check_no_leftovers (context))
    goto out;

  retval = TRUE;

 out:
  dbus_error_free (&error);

  if (message)
    dbus_message_unref (message);

  return retval;
}

/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_add_match_all (BusContext     *context,
                     DBusConnection *connection)
{
  DBusMessage *message;
  dbus_bool_t retval;
  dbus_uint32_t serial;
  DBusError error;
  const char *empty = "";

  retval = FALSE;
  dbus_error_init (&error);
  message = NULL;

  _dbus_verbose ("check_add_match_all for %p\n", connection);

  message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
                                          DBUS_PATH_DBUS,
                                          DBUS_INTERFACE_DBUS,
                                          "AddMatch");

  if (message == NULL)
    return TRUE;

  /* empty string match rule matches everything */
  if (!dbus_message_append_args (message, DBUS_TYPE_STRING, &empty,
                                 DBUS_TYPE_INVALID))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  dbus_message_unref (message);
  message = NULL;

  dbus_connection_ref (connection); /* because we may get disconnected */

  /* send our message */
  bus_test_run_clients_loop (SEND_PENDING (connection));

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_verbose ("connection was disconnected\n");

      dbus_connection_unref (connection);

      return TRUE;
    }

  block_connection_until_message_from_bus (context, connection, "reply to AddMatch");

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_verbose ("connection was disconnected\n");

      dbus_connection_unref (connection);

      return TRUE;
    }

  dbus_connection_unref (connection);

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Did not receive a reply to %s %d on %p\n",
                  "AddMatch", serial, connection);
      goto out;
    }

  verbose_message_received (connection, message);

  if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
    {
      _dbus_warn ("Message has wrong sender %s\n",
                  dbus_message_get_sender (message) ?
                  dbus_message_get_sender (message) : "(none)");
      goto out;
    }

  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
    {
      if (dbus_message_is_error (message,
                                 DBUS_ERROR_NO_MEMORY))
        {
          ; /* good, this is a valid response */
        }
      else
        {
          warn_unexpected (connection, message, "not this error");

          goto out;
        }
    }
  else
    {
      if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
        {
          ; /* good, expected */
          _dbus_assert (dbus_message_get_reply_serial (message) == serial);
        }
      else
        {
          warn_unexpected (connection, message, "method return for AddMatch");

          goto out;
        }
    }

  if (!check_no_leftovers (context))
    goto out;

  retval = TRUE;

 out:
  dbus_error_free (&error);

  if (message)
    dbus_message_unref (message);

  return retval;
}

/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_hello_connection (BusContext *context)
{
  DBusConnection *connection;
  DBusError error;

  dbus_error_init (&error);

  connection = dbus_connection_open_private (TEST_CONNECTION, &error);
  if (connection == NULL)
    {
      _DBUS_ASSERT_ERROR_IS_SET (&error);
      dbus_error_free (&error);
      return TRUE;
    }

  if (!bus_setup_debug_client (connection))
    {
      dbus_connection_close (connection);
      dbus_connection_unref (connection);
      return TRUE;
    }

  spin_connection_until_authenticated (context, connection);

  if (!check_hello_message (context, connection))
    return FALSE;

  if (dbus_bus_get_unique_name (connection) == NULL)
    {
      /* We didn't successfully register, so we can't
       * do the usual kill_client_connection() checks
       */
      kill_client_connection_unchecked (connection);
    }
  else
    {
      if (!check_add_match_all (context, connection))
        return FALSE;

      kill_client_connection (context, connection);
    }

  return TRUE;
}

#define NONEXISTENT_SERVICE_NAME "test.this.service.does.not.exist.ewuoiurjdfxcvn"

/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_nonexistent_service_no_auto_start (BusContext     *context,
                                         DBusConnection *connection)
{
  DBusMessage *message;
  dbus_uint32_t serial;
  dbus_bool_t retval;
  const char *nonexistent = NONEXISTENT_SERVICE_NAME;
  dbus_uint32_t flags;

  message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
                                          DBUS_PATH_DBUS,
                                          DBUS_INTERFACE_DBUS,
                                          "StartServiceByName");

  if (message == NULL)
    return TRUE;

  dbus_message_set_auto_start (message, FALSE);

  flags = 0;
  if (!dbus_message_append_args (message,
                                 DBUS_TYPE_STRING, &nonexistent,
                                 DBUS_TYPE_UINT32, &flags,
                                 DBUS_TYPE_INVALID))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  dbus_message_unref (message);
  message = NULL;

  bus_test_run_everything (context);
  block_connection_until_message_from_bus (context, connection, "reply to ActivateService on nonexistent");
  bus_test_run_everything (context);

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_verbose ("connection was disconnected\n");
      return TRUE;
    }

  retval = FALSE;

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Did not receive a reply to %s %d on %p\n",
                  "StartServiceByName", serial, connection);
      goto out;
    }

  verbose_message_received (connection, message);

  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
    {
      if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
        {
          _dbus_warn ("Message has wrong sender %s\n",
                      dbus_message_get_sender (message) ?
                      dbus_message_get_sender (message) : "(none)");
          goto out;
        }

      if (dbus_message_is_error (message,
                                 DBUS_ERROR_NO_MEMORY))
        {
          ; /* good, this is a valid response */
        }
      else if (dbus_message_is_error (message,
                                      DBUS_ERROR_SERVICE_UNKNOWN))
        {
          ; /* good, this is expected also */
        }
      else
        {
          warn_unexpected (connection, message, "not this error");
          goto out;
        }
    }
  else
    {
      _dbus_warn ("Did not expect to successfully activate %s\n",
                  NONEXISTENT_SERVICE_NAME);
      goto out;
    }

  retval = TRUE;

 out:
  if (message)
    dbus_message_unref (message);

  return retval;
}

/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_nonexistent_service_auto_start (BusContext     *context,
                                      DBusConnection *connection)
{
  DBusMessage *message;
  dbus_uint32_t serial;
  dbus_bool_t retval;

  message = dbus_message_new_method_call (NONEXISTENT_SERVICE_NAME,
                                          "/org/freedesktop/TestSuite",
                                          "org.freedesktop.TestSuite",
                                          "Echo");

  if (message == NULL)
    return TRUE;

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  dbus_message_unref (message);
  message = NULL;

  bus_test_run_everything (context);
  block_connection_until_message_from_bus (context, connection, "reply to Echo");
  bus_test_run_everything (context);

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_verbose ("connection was disconnected\n");
      return TRUE;
    }

  retval = FALSE;

  message = pop_message_waiting_for_memory (connection);

  if (message == NULL)
    {
      _dbus_warn ("Did not receive a reply to %s %d on %p\n",
                  "Echo message (auto activation)", serial, connection);
      goto out;
    }

  verbose_message_received (connection, message);

  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
    {
      if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
        {
          _dbus_warn ("Message has wrong sender %s\n",
                      dbus_message_get_sender (message) ?
                      dbus_message_get_sender (message) : "(none)");
          goto out;
        }

      if (dbus_message_is_error (message,
                                 DBUS_ERROR_NO_MEMORY))
        {
          ; /* good, this is a valid response */
        }
      else if (dbus_message_is_error (message,
                                      DBUS_ERROR_SERVICE_UNKNOWN))
        {
          ; /* good, this is expected also */
        }
      else
        {
          warn_unexpected (connection, message, "not this error");
          goto out;
        }
    }
  else
    {
      _dbus_warn ("Did not expect to successfully activate %s\n",
                  NONEXISTENT_SERVICE_NAME);
      goto out;
    }

  retval = TRUE;

 out:
  if (message)
    dbus_message_unref (message);

  return retval;
}

static dbus_bool_t
check_base_service_activated (BusContext     *context,
                              DBusConnection *connection,
                              DBusMessage    *initial_message,
                              const char    **base_service_p)
{
  DBusMessage *message;
  dbus_bool_t retval;
  DBusError error;
  const char *base_service, *base_service_from_bus, *old_owner;

  retval = FALSE;

  dbus_error_init (&error);
  base_service = NULL;
  old_owner = NULL;
  base_service_from_bus = NULL;

  message = initial_message;
  dbus_message_ref (message);

  if (dbus_message_is_signal (message,
                              DBUS_INTERFACE_DBUS,
                              "NameOwnerChanged"))
    {
      CheckServiceOwnerChangedData socd;

    reget_service_name_arg:
      base_service = NULL;
      old_owner = NULL;
      base_service_from_bus = NULL;

      if (!dbus_message_get_args (message, &error,
                                  DBUS_TYPE_STRING, &base_service,
                                  DBUS_TYPE_STRING, &old_owner,
                                  DBUS_TYPE_STRING, &base_service_from_bus,
                                  DBUS_TYPE_INVALID))
        {
          if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
            {
              dbus_error_free (&error);
              _dbus_wait_for_memory ();
              goto reget_service_name_arg;
            }
          else
            {
              _dbus_warn ("Message %s doesn't have a service name: %s\n",
                          "NameOwnerChanged (creation)",
                          error.message);
              goto out;
            }
        }

      if (*base_service != ':')
        {
          _dbus_warn ("Expected base service activation, got \"%s\" instead\n",
                      base_service);
          goto out;
        }

      if (strcmp (base_service, base_service_from_bus) != 0)
        {
          _dbus_warn ("Expected base service activation, got \"%s\" instead with owner \"%s\"\n",
                      base_service, base_service_from_bus);
          goto out;
        }

      if (old_owner[0])
        {
          _dbus_warn ("Received an old_owner argument during base service activation, \"%s\"\n",
                      old_owner);
          goto out;
        }

      socd.expected_kind = SERVICE_CREATED;
      socd.expected_service_name = base_service;
      socd.failed = FALSE;
      socd.skip_connection = connection;
      bus_test_clients_foreach (check_service_owner_changed_foreach,
                                &socd);

      if (socd.failed)
        goto out;
    }
  else
    {
      warn_unexpected (connection, message, "NameOwnerChanged (creation) for base service");

      goto out;
    }

  if (base_service_p)
    *base_service_p = base_service;

  retval = TRUE;

 out:
  if (message)
    dbus_message_unref (message);
  dbus_error_free (&error);

  return retval;
}

static dbus_bool_t
check_service_activated (BusContext     *context,
                         DBusConnection *connection,
                         const char     *activated_name,
                         const char     *base_service_name,
                         DBusMessage    *initial_message)
{
  DBusMessage *message;
  dbus_bool_t retval;
  DBusError error;
  dbus_uint32_t activation_result;

  retval = FALSE;

  dbus_error_init (&error);

  message = initial_message;
  dbus_message_ref (message);

  if (dbus_message_is_signal (message,
                              DBUS_INTERFACE_DBUS,
                              "NameOwnerChanged"))
    {
      CheckServiceOwnerChangedData socd;
      const char *service_name, *base_service_from_bus, *old_owner;

    reget_service_name_arg:
      service_name = NULL;
      old_owner = NULL;
      base_service_from_bus = NULL;

      if (!dbus_message_get_args (message, &error,
                                  DBUS_TYPE_STRING, &service_name,
                                   DBUS_TYPE_STRING, &old_owner,
                                  DBUS_TYPE_STRING, &base_service_from_bus,
                                  DBUS_TYPE_INVALID))
        {
          if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
            {
              dbus_error_free (&error);
              _dbus_wait_for_memory ();
              goto reget_service_name_arg;
            }
          else
            {
              _dbus_warn ("Message %s doesn't have a service name: %s\n",
                          "NameOwnerChanged (creation)",
                          error.message);
              goto out;
            }
        }

      if (strcmp (service_name, activated_name) != 0)
        {
          _dbus_warn ("Expected to see service %s created, saw %s instead\n",
                      activated_name, service_name);
          goto out;
        }

      if (strcmp (base_service_name, base_service_from_bus) != 0)
        {
          _dbus_warn ("NameOwnerChanged reports wrong base service: %s owner, expected %s instead\n",
                      base_service_from_bus, base_service_name);
          goto out;
        }

      if (old_owner[0])
        {
          _dbus_warn ("expected a %s, got a %s\n",
                      "NameOwnerChanged (creation)",
                      "NameOwnerChanged (change)");
          goto out;
        }

      socd.expected_kind = SERVICE_CREATED;
      socd.skip_connection = connection;
      socd.failed = FALSE;
      socd.expected_service_name = service_name;
      bus_test_clients_foreach (check_service_owner_changed_foreach,
                                &socd);

      if (socd.failed)
        goto out;

      dbus_message_unref (message);
      service_name = NULL;
      old_owner = NULL;
      base_service_from_bus = NULL;

      message = pop_message_waiting_for_memory (connection);
      if (message == NULL)
        {
          _dbus_warn ("Expected a reply to %s, got nothing\n",
                      "StartServiceByName");
          goto out;
        }
    }
  else
    {
      warn_unexpected (connection, message, "NameOwnerChanged for the activated name");

      goto out;
    }

  if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
    {
      warn_unexpected (connection, message, "reply to StartServiceByName");

      goto out;
    }

  activation_result = 0;
  if (!dbus_message_get_args (message, &error,
                              DBUS_TYPE_UINT32, &activation_result,
                              DBUS_TYPE_INVALID))
    {
      if (!dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
        {
          _dbus_warn ("Did not have activation result first argument to %s: %s\n",
                      "StartServiceByName", error.message);
          goto out;
        }

      dbus_error_free (&error);
    }
  else
    {
      if (activation_result == DBUS_START_REPLY_SUCCESS)
        ; /* Good */
      else if (activation_result == DBUS_START_REPLY_ALREADY_RUNNING)
        ; /* Good also */
      else
        {
          _dbus_warn ("Activation result was %u, no good.\n",
                      activation_result);
          goto out;
        }
    }

  dbus_message_unref (message);
  message = NULL;

  if (!check_no_leftovers (context))
    {
      _dbus_warn ("Messages were left over after verifying existent activation results\n");
      goto out;
    }

  retval = TRUE;

 out:
  if (message)
    dbus_message_unref (message);
  dbus_error_free (&error);

  return retval;
}

static dbus_bool_t
check_service_auto_activated (BusContext     *context,
                              DBusConnection *connection,
                              const char     *activated_name,
                              const char     *base_service_name,
                              DBusMessage    *initial_message)
{
  DBusMessage *message;
  dbus_bool_t retval;
  DBusError error;

  retval = FALSE;

  dbus_error_init (&error);

  message = initial_message;
  dbus_message_ref (message);

  if (dbus_message_is_signal (message,
                              DBUS_INTERFACE_DBUS,
                              "NameOwnerChanged"))
    {
      const char *service_name;
      CheckServiceOwnerChangedData socd;

    reget_service_name_arg:
      if (!dbus_message_get_args (message, &error,
                                  DBUS_TYPE_STRING, &service_name,
                                  DBUS_TYPE_INVALID))
        {
          if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
            {
              dbus_error_free (&error);
              _dbus_wait_for_memory ();
              goto reget_service_name_arg;
            }
          else
            {
              _dbus_warn ("Message %s doesn't have a service name: %s\n",
                          "NameOwnerChanged",
                          error.message);
              dbus_error_free (&error);
              goto out;
            }
        }

      if (strcmp (service_name, activated_name) != 0)
        {
          _dbus_warn ("Expected to see service %s created, saw %s instead\n",
                      activated_name, service_name);
          goto out;
        }

      socd.expected_kind = SERVICE_CREATED;
      socd.expected_service_name = service_name;
      socd.failed = FALSE;
      socd.skip_connection = connection;
      bus_test_clients_foreach (check_service_owner_changed_foreach,
                                &socd);

      if (socd.failed)
        goto out;

      /* Note that this differs from regular activation in that we don't get a
       * reply to ActivateService here.
       */

      dbus_message_unref (message);
      message = NULL;
      service_name = NULL;
    }
  else
    {
      warn_unexpected (connection, message, "NameOwnerChanged for the activated name");

      goto out;
    }

  retval = TRUE;

 out:
  if (message)
    dbus_message_unref (message);

  return retval;
}

static dbus_bool_t
check_service_deactivated (BusContext     *context,
                           DBusConnection *connection,
                           const char     *activated_name,
                           const char     *base_service)
{
  dbus_bool_t retval;
  CheckServiceOwnerChangedData socd;

  retval = FALSE;

  /* Now we are expecting ServiceOwnerChanged (deletion) messages for the base
   * service and the activated_name.  The base service
   * notification is required to come last.
   */
  socd.expected_kind = SERVICE_DELETED;
  socd.expected_service_name = activated_name;
  socd.failed = FALSE;
  socd.skip_connection = NULL;
  bus_test_clients_foreach (check_service_owner_changed_foreach,
                            &socd);

  if (socd.failed)
    goto out;

  socd.expected_kind = SERVICE_DELETED;
  socd.expected_service_name = base_service;
  socd.failed = FALSE;
  socd.skip_connection = NULL;
  bus_test_clients_foreach (check_service_owner_changed_foreach,
                            &socd);

  if (socd.failed)
    goto out;

  retval = TRUE;

 out:
  return retval;
}

static dbus_bool_t
check_send_exit_to_service (BusContext     *context,
                            DBusConnection *connection,
                            const char     *service_name,
                            const char     *base_service)
{
  dbus_bool_t got_error;
  DBusMessage *message;
  dbus_uint32_t serial;
  dbus_bool_t retval;

  _dbus_verbose ("Sending exit message to the test service\n");

  retval = FALSE;

  /* Kill off the test service by sending it a quit message */
  message = dbus_message_new_method_call (service_name,
                                          "/org/freedesktop/TestSuite",
                                          "org.freedesktop.TestSuite",
                                          "Exit");

  if (message == NULL)
    {
      /* Do this again; we still need the service to exit... */
      if (!check_send_exit_to_service (context, connection,
                                       service_name, base_service))
        goto out;

      return TRUE;
    }

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);

      /* Do this again; we still need the service to exit... */
      if (!check_send_exit_to_service (context, connection,
                                       service_name, base_service))
        goto out;

      return TRUE;
    }

  dbus_message_unref (message);
  message = NULL;

  /* send message */
  bus_test_run_clients_loop (SEND_PENDING (connection));

  /* read it in and write it out to test service */
  bus_test_run_bus_loop (context, FALSE);

  /* see if we got an error during message bus dispatching */
  bus_test_run_clients_loop (FALSE);
  message = borrow_message_waiting_for_memory (connection);
  got_error = message != NULL && dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR;
  if (message)
    {
      dbus_connection_return_message (connection, message);
      message = NULL;
    }

  if (!got_error)
    {
      /* If no error, wait for the test service to exit */
      block_connection_until_message_from_bus (context, connection, "test service to exit");

      bus_test_run_everything (context);
    }

  if (got_error)
    {
      message = pop_message_waiting_for_memory (connection);
      _dbus_assert (message != NULL);

      if (dbus_message_get_reply_serial (message) != serial)
        {
          warn_unexpected (connection, message,
                           "error with the correct reply serial");
          goto out;
        }

      if (!dbus_message_is_error (message,
                                  DBUS_ERROR_NO_MEMORY))
        {
          warn_unexpected (connection, message,
                           "a no memory error from asking test service to exit");
          goto out;
        }

      _dbus_verbose ("Got error %s when asking test service to exit\n",
                     dbus_message_get_error_name (message));

      /* Do this again; we still need the service to exit... */
      if (!check_send_exit_to_service (context, connection,
                                       service_name, base_service))
        goto out;
    }
  else
    {
      if (!check_service_deactivated (context, connection,
                                      service_name, base_service))
        goto out;

      /* Should now have a NoReply error from the Exit() method
       * call; it should have come after all the deactivation
       * stuff.
       */
      message = pop_message_waiting_for_memory (connection);

      if (message == NULL)
        {
          warn_unexpected (connection, NULL,
                           "reply to Exit() method call");
          goto out;
        }
      if (!dbus_message_is_error (message,
                                  DBUS_ERROR_NO_REPLY))
        {
          warn_unexpected (connection, message,
                           "NoReply error from Exit() method call");
          goto out;
        }

      if (dbus_message_get_reply_serial (message) != serial)
        {
          warn_unexpected (connection, message,
                           "error with the correct reply serial");
          goto out;
        }

      _dbus_verbose ("Got error %s after test service exited\n",
                     dbus_message_get_error_name (message));

      if (!check_no_leftovers (context))
        {
          _dbus_warn ("Messages were left over after %s\n",
                      _DBUS_FUNCTION_NAME);
          goto out;
        }
    }

  retval = TRUE;

 out:
  if (message)
    dbus_message_unref (message);

  return retval;
}

static dbus_bool_t
check_got_error (BusContext     *context,
                 DBusConnection *connection,
                 const char     *first_error_name,
                 ...)
{
  DBusMessage *message;
  dbus_bool_t retval;
  va_list ap;
  dbus_bool_t error_found;
  const char *error_name;

  retval = FALSE;

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Did not get an expected error\n");
      goto out;
    }

  if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
    {
      warn_unexpected (connection, message, "an error");

      goto out;
    }

  error_found = FALSE;

  va_start (ap, first_error_name);
  error_name = first_error_name;
  while (error_name != NULL)
    {
      if (dbus_message_is_error (message, error_name))
        {
          error_found = TRUE;
          break;
        }
      error_name = va_arg (ap, char*);
    }
  va_end (ap);

  if (!error_found)
    {
      _dbus_warn ("Expected error %s or other, got %s instead\n",
                  first_error_name,
                  dbus_message_get_error_name (message));
      goto out;
    }

  retval = TRUE;

 out:
  if (message)
    dbus_message_unref (message);

  return retval;
}

typedef enum
{
  GOT_SERVICE_CREATED,
  GOT_SERVICE_DELETED,
  GOT_ERROR,
  GOT_SOMETHING_ELSE
} GotServiceInfo;

static GotServiceInfo
check_got_service_info (DBusMessage *message)
{
  GotServiceInfo message_kind;

  if (dbus_message_is_signal (message,
                              DBUS_INTERFACE_DBUS,
                              "NameOwnerChanged"))
    {
      DBusError error;
      const char *service_name, *old_owner, *new_owner;
      dbus_error_init (&error);

    reget_service_info_data:
      service_name = NULL;
      old_owner = NULL;
      new_owner = NULL;

      dbus_message_get_args (message, &error,
                             DBUS_TYPE_STRING, &service_name,
                             DBUS_TYPE_STRING, &old_owner,
                             DBUS_TYPE_STRING, &new_owner,
                             DBUS_TYPE_INVALID);
      if (dbus_error_is_set (&error))
        {
          if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
            {
              dbus_error_free (&error);
              goto reget_service_info_data;
            }
          else
            {
              _dbus_warn ("unexpected arguments for NameOwnerChanged message\n");
              message_kind = GOT_SOMETHING_ELSE;
            }
        }
      else if (!old_owner[0])
        message_kind = GOT_SERVICE_CREATED;
      else if (!new_owner[0])
        message_kind = GOT_SERVICE_DELETED;
      else
        message_kind = GOT_SOMETHING_ELSE;

      dbus_error_free (&error);
    }
  else if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
    message_kind = GOT_ERROR;
  else
    message_kind = GOT_SOMETHING_ELSE;

  return message_kind;
}

#define EXISTENT_SERVICE_NAME "org.freedesktop.DBus.TestSuiteEchoService"

/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_existent_service_no_auto_start (BusContext     *context,
                                      DBusConnection *connection)
{
  DBusMessage *message;
  DBusMessage *base_service_message;
  const char *base_service;
  dbus_uint32_t serial;
  dbus_bool_t retval;
  const char *existent = EXISTENT_SERVICE_NAME;
  dbus_uint32_t flags;

  base_service_message = NULL;

  message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
                                          DBUS_PATH_DBUS,
                                          DBUS_INTERFACE_DBUS,
                                          "StartServiceByName");

  if (message == NULL)
    return TRUE;

  dbus_message_set_auto_start (message, FALSE);

  flags = 0;
  if (!dbus_message_append_args (message,
                                 DBUS_TYPE_STRING, &existent,
                                 DBUS_TYPE_UINT32, &flags,
                                 DBUS_TYPE_INVALID))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  dbus_message_unref (message);
  message = NULL;

  bus_test_run_everything (context);

  /* now wait for the message bus to hear back from the activated
   * service.
   */
  block_connection_until_message_from_bus (context, connection, "activated service to connect");

  bus_test_run_everything (context);

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_verbose ("connection was disconnected\n");
      return TRUE;
    }

  retval = FALSE;

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Did not receive any messages after %s %d on %p\n",
                  "StartServiceByName", serial, connection);
      goto out;
    }

  verbose_message_received (connection, message);
  _dbus_verbose ("  (after sending %s)\n", "StartServiceByName");

  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
    {
      if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
        {
          _dbus_warn ("Message has wrong sender %s\n",
                      dbus_message_get_sender (message) ?
                      dbus_message_get_sender (message) : "(none)");
          goto out;
        }

      if (dbus_message_is_error (message,
                                 DBUS_ERROR_NO_MEMORY))
        {
          ; /* good, this is a valid response */
        }
      else if (dbus_message_is_error (message,
                                      DBUS_ERROR_SPAWN_CHILD_EXITED) ||
               dbus_message_is_error (message,
                                      DBUS_ERROR_SPAWN_CHILD_SIGNALED) ||
               dbus_message_is_error (message,
                                      DBUS_ERROR_SPAWN_EXEC_FAILED))
        {
          ; /* good, this is expected also */
        }
      else
        {
          _dbus_warn ("Did not expect error %s\n",
                      dbus_message_get_error_name (message));
          goto out;
        }
    }
  else
    {
      GotServiceInfo message_kind;

      if (!check_base_service_activated (context, connection,
                                         message, &base_service))
        goto out;

      base_service_message = message;
      message = NULL;

      /* We may need to block here for the test service to exit or finish up */
      block_connection_until_message_from_bus (context, connection, "test service to exit or finish up");

      message = dbus_connection_borrow_message (connection);
      if (message == NULL)
        {
          _dbus_warn ("Did not receive any messages after base service creation notification\n");
          goto out;
        }

      message_kind = check_got_service_info (message);

      dbus_connection_return_message (connection, message);
      message = NULL;

      switch (message_kind)
        {
        case GOT_SOMETHING_ELSE:
          _dbus_warn ("Unexpected message after ActivateService "
                      "(should be an error or a service announcement");
          goto out;

        case GOT_ERROR:
          if (!check_got_error (context, connection,
                                DBUS_ERROR_SPAWN_CHILD_EXITED,
                                DBUS_ERROR_NO_MEMORY,
                                NULL))
            goto out;
          /* A service deleted should be coming along now after this error.
           * We can also get the error *after* the service deleted.
           */

          /* fall through */

        case GOT_SERVICE_DELETED:
          {
            /* The service started up and got a base address, but then
             * failed to register under EXISTENT_SERVICE_NAME
             */
            CheckServiceOwnerChangedData socd;

            socd.expected_kind = SERVICE_DELETED;
            socd.expected_service_name = base_service;
            socd.failed = FALSE;
            socd.skip_connection = NULL;

            bus_test_clients_foreach (check_service_owner_changed_foreach,
                                      &socd);

            if (socd.failed)
              goto out;

            /* Now we should get an error about the service exiting
             * if we didn't get it before.
             */
            if (message_kind != GOT_ERROR)
              {
                block_connection_until_message_from_bus (context, connection, "error about service exiting");

                /* and process everything again */
                bus_test_run_everything (context);

                if (!check_got_error (context, connection,
                                      DBUS_ERROR_SPAWN_CHILD_EXITED,
				      DBUS_ERROR_NO_MEMORY,
                                      NULL))
                  goto out;
              }
            break;
          }

        case GOT_SERVICE_CREATED:
          message = pop_message_waiting_for_memory (connection);
          if (message == NULL)
            {
              _dbus_warn ("Failed to pop message we just put back! "
                          "should have been a NameOwnerChanged (creation)\n");
              goto out;
            }

          if (!check_service_activated (context, connection, EXISTENT_SERVICE_NAME,
                                        base_service, message))
            goto out;

          dbus_message_unref (message);
          message = NULL;

          if (!check_no_leftovers (context))
            {
              _dbus_warn ("Messages were left over after successful activation\n");
              goto out;
            }

	  if (!check_send_exit_to_service (context, connection,
                                           EXISTENT_SERVICE_NAME, base_service))
	    goto out;

          break;
        }
    }

  retval = TRUE;

 out:
  if (message)
    dbus_message_unref (message);

  if (base_service_message)
    dbus_message_unref (base_service_message);

  return retval;
}

#ifndef DBUS_WIN_FIXME
/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_segfault_service_no_auto_start (BusContext     *context,
                                      DBusConnection *connection)
{
  DBusMessage *message;
  dbus_uint32_t serial;
  dbus_bool_t retval;
  const char *segv_service;
  dbus_uint32_t flags;

  message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
                                          DBUS_PATH_DBUS,
                                          DBUS_INTERFACE_DBUS,
                                          "StartServiceByName");

  if (message == NULL)
    return TRUE;

  dbus_message_set_auto_start (message, FALSE);

  segv_service = "org.freedesktop.DBus.TestSuiteSegfaultService";
  flags = 0;
  if (!dbus_message_append_args (message,
                                 DBUS_TYPE_STRING, &segv_service,
                                 DBUS_TYPE_UINT32, &flags,
                                 DBUS_TYPE_INVALID))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  dbus_message_unref (message);
  message = NULL;

  bus_test_run_everything (context);
  block_connection_until_message_from_bus (context, connection, "reply to activating segfault service");
  bus_test_run_everything (context);

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_verbose ("connection was disconnected\n");
      return TRUE;
    }

  retval = FALSE;

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Did not receive a reply to %s %d on %p\n",
                  "StartServiceByName", serial, connection);
      goto out;
    }

  verbose_message_received (connection, message);

  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
    {
      if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
        {
          _dbus_warn ("Message has wrong sender %s\n",
                      dbus_message_get_sender (message) ?
                      dbus_message_get_sender (message) : "(none)");
          goto out;
        }

      if (dbus_message_is_error (message,
                                 DBUS_ERROR_NO_MEMORY))
        {
          ; /* good, this is a valid response */
        }
      else if (dbus_message_is_error (message,
                                      DBUS_ERROR_FAILED))
        {
          const char *servicehelper;
          servicehelper = bus_context_get_servicehelper (context);
          /* make sure this only happens with the launch helper */
          _dbus_assert (servicehelper != NULL);
        }
      else if (dbus_message_is_error (message,
                                      DBUS_ERROR_SPAWN_CHILD_SIGNALED))
        {
          ; /* good, this is expected also */
        }
      else
        {
          warn_unexpected (connection, message, "not this error");

          goto out;
        }
    }
  else
    {
      _dbus_warn ("Did not expect to successfully activate segfault service\n");
      goto out;
    }

  retval = TRUE;

 out:
  if (message)
    dbus_message_unref (message);

  return retval;
}


/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_segfault_service_auto_start (BusContext     *context,
                                   DBusConnection *connection)
{
  DBusMessage *message;
  dbus_uint32_t serial;
  dbus_bool_t retval;

  message = dbus_message_new_method_call ("org.freedesktop.DBus.TestSuiteSegfaultService",
                                          "/org/freedesktop/TestSuite",
                                          "org.freedesktop.TestSuite",
                                          "Echo");

  if (message == NULL)
    return TRUE;

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  dbus_message_unref (message);
  message = NULL;

  bus_test_run_everything (context);
  block_connection_until_message_from_bus (context, connection, "reply to Echo on segfault service");
  bus_test_run_everything (context);

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_verbose ("connection was disconnected\n");
      return TRUE;
    }

  retval = FALSE;

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Did not receive a reply to %s %d on %p\n",
                  "Echo message (auto activation)", serial, connection);
      goto out;
    }

  verbose_message_received (connection, message);

  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
    {
      if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
        {
          _dbus_warn ("Message has wrong sender %s\n",
                      dbus_message_get_sender (message) ?
                      dbus_message_get_sender (message) : "(none)");
          goto out;
        }

      if (dbus_message_is_error (message,
                                 DBUS_ERROR_NO_MEMORY))
        {
          ; /* good, this is a valid response */
        }
      else if (dbus_message_is_error (message,
                                      DBUS_ERROR_SPAWN_CHILD_SIGNALED))
        {
          ; /* good, this is expected also */
        }
      else
        {
          warn_unexpected (connection, message, "not this error");

          goto out;
        }
    }
  else
    {
      _dbus_warn ("Did not expect to successfully activate segfault service\n");
      goto out;
    }

  retval = TRUE;

 out:
  if (message)
    dbus_message_unref (message);

  return retval;
}
#endif

#define TEST_ECHO_MESSAGE "Test echo message"
#define TEST_RUN_HELLO_FROM_SELF_MESSAGE "Test sending message to self"

/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_existent_hello_from_self (BusContext     *context,
                                DBusConnection *connection)
{
  DBusMessage *message;
  dbus_uint32_t serial;
  const char *text;

  message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME,
                                          "/org/freedesktop/TestSuite",
                                          "org.freedesktop.TestSuite",
                                          "RunHelloFromSelf");

  if (message == NULL)
    return TRUE;

  text = TEST_RUN_HELLO_FROM_SELF_MESSAGE;
  if (!dbus_message_append_args (message,
                                 DBUS_TYPE_STRING, &text,
                                 DBUS_TYPE_INVALID))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  dbus_message_unref (message);
  message = NULL;

  bus_test_run_everything (context);

  /* Note: if this test is run in OOM mode, it will block when the bus
   * doesn't send a reply due to OOM.
   */
  block_connection_until_message_from_bus (context, connection, "reply from running hello from self");

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Failed to pop message! Should have been reply from RunHelloFromSelf message\n");
      return FALSE;
    }

  if (dbus_message_get_reply_serial (message) != serial)
    {
      _dbus_warn ("Wrong reply serial\n");
      dbus_message_unref (message);
      return FALSE;
    }

  dbus_message_unref (message);
  message = NULL;

  return TRUE;
}

/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_existent_ping (BusContext     *context,
                     DBusConnection *connection)
{
  DBusMessage *message;
  dbus_uint32_t serial;
  message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME,
                                          "/org/freedesktop/TestSuite",
                                          "org.freedesktop.DBus.Peer",
                                          "Ping");

  if (message == NULL)
    return TRUE;

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  dbus_message_unref (message);
  message = NULL;

  bus_test_run_everything (context);

  /* Note: if this test is run in OOM mode, it will block when the bus
   * doesn't send a reply due to OOM.
   */
  block_connection_until_message_from_bus (context, connection, "reply from running Ping");

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Failed to pop message! Should have been reply from Ping message\n");
      return FALSE;
    }

  if (dbus_message_get_reply_serial (message) != serial)
    {
      _dbus_warn ("Wrong reply serial\n");
      dbus_message_unref (message);
      return FALSE;
    }

  if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
    {
      _dbus_warn ("Unexpected message return during Ping\n");
      dbus_message_unref (message);
      return FALSE;
    }

  dbus_message_unref (message);
  message = NULL;

  return TRUE;
}

/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_existent_get_machine_id (BusContext     *context,
                               DBusConnection *connection)
{
  DBusMessage *message;
  dbus_uint32_t serial;
  const char *machine_id;

  message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME,
                                          "/org/freedesktop/TestSuite",
                                          "org.freedesktop.DBus.Peer",
                                          "GetMachineId");

  if (message == NULL)
    return TRUE;

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  dbus_message_unref (message);
  message = NULL;

  bus_test_run_everything (context);

  /* Note: if this test is run in OOM mode, it will block when the bus
   * doesn't send a reply due to OOM.
   */
  block_connection_until_message_from_bus (context, connection, "reply from running GetMachineId");

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Failed to pop message! Should have been reply from GetMachineId message\n");
      return FALSE;
    }

  if (dbus_message_get_reply_serial (message) != serial)
    {
      _dbus_warn ("Wrong reply serial\n");
      dbus_message_unref (message);
      return FALSE;
    }

  if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
    {
      _dbus_warn ("Unexpected message return during GetMachineId\n");
      dbus_message_unref (message);
      return FALSE;
    }

  machine_id = NULL;
  if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &machine_id, DBUS_TYPE_INVALID))
    {
      _dbus_warn ("Did not get a machine ID in reply to GetMachineId\n");
      dbus_message_unref (message);
      return FALSE;
    }

  if (machine_id == NULL || strlen (machine_id) != 32)
    {
      _dbus_warn ("Machine id looks bogus: '%s'\n", machine_id ? machine_id : "null");
      dbus_message_unref (message);
      return FALSE;
    }

  /* We can't check that the machine id is correct because during make check it is
   * just made up for each process separately
   */

  dbus_message_unref (message);
  message = NULL;

  return TRUE;
}

/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_existent_service_auto_start (BusContext     *context,
                                   DBusConnection *connection)
{
  DBusMessage *message;
  DBusMessage *base_service_message;
  dbus_uint32_t serial;
  dbus_bool_t retval;
  const char *base_service;
  const char *text;

  base_service_message = NULL;

  message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME,
                                          "/org/freedesktop/TestSuite",
                                          "org.freedesktop.TestSuite",
                                          "Echo");

  if (message == NULL)
    return TRUE;

  text = TEST_ECHO_MESSAGE;
  if (!dbus_message_append_args (message,
                                 DBUS_TYPE_STRING, &text,
                                 DBUS_TYPE_INVALID))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  dbus_message_unref (message);
  message = NULL;

  bus_test_run_everything (context);

  /* now wait for the message bus to hear back from the activated
   * service.
   */
  block_connection_until_message_from_bus (context, connection, "reply to Echo on existent service");
  bus_test_run_everything (context);

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_verbose ("connection was disconnected\n");
      return TRUE;
    }

  retval = FALSE;

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Did not receive any messages after auto start %d on %p\n",
                  serial, connection);
      goto out;
    }

  verbose_message_received (connection, message);
  _dbus_verbose ("  (after sending %s)\n", "auto start");

  /* we should get zero or two ServiceOwnerChanged signals */
  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL)
    {
      GotServiceInfo message_kind;

      if (!check_base_service_activated (context, connection,
                                         message, &base_service))
        goto out;

      base_service_message = message;
      message = NULL;

      /* We may need to block here for the test service to exit or finish up */
      block_connection_until_message_from_bus (context, connection, "service to exit");

      /* Should get a service creation notification for the activated
       * service name, or a service deletion on the base service name
       */
      message = dbus_connection_borrow_message (connection);
      if (message == NULL)
        {
          _dbus_warn ("No message after auto activation "
                      "(should be a service announcement)\n");
          dbus_connection_return_message (connection, message);
          message = NULL;
          goto out;
        }

      message_kind = check_got_service_info (message);

      dbus_connection_return_message (connection, message);
      message = NULL;

      switch (message_kind)
        {
        case GOT_SERVICE_CREATED:
          message = pop_message_waiting_for_memory (connection);
          if (message == NULL)
            {
              _dbus_warn ("Failed to pop message we just put back! "
                          "should have been a NameOwnerChanged (creation)\n");
              goto out;
            }

          /* Check that ServiceOwnerChanged (creation) was correctly received */
          if (!check_service_auto_activated (context, connection, EXISTENT_SERVICE_NAME,
                                             base_service, message))
            goto out;

          dbus_message_unref (message);
          message = NULL;

          break;

        case GOT_SERVICE_DELETED:
          {
            /* The service started up and got a base address, but then
             * failed to register under EXISTENT_SERVICE_NAME
             */
            CheckServiceOwnerChangedData socd;

            socd.expected_kind = SERVICE_DELETED;
            socd.expected_service_name = base_service;
            socd.failed = FALSE;
            socd.skip_connection = NULL;
            bus_test_clients_foreach (check_service_owner_changed_foreach,
                                      &socd);

            if (socd.failed)
              goto out;

            break;
          }

        case GOT_ERROR:
        case GOT_SOMETHING_ELSE:
          _dbus_warn ("Unexpected message after auto activation\n");
          goto out;
        }
    }

  /* OK, now we've dealt with ServiceOwnerChanged signals, now should
   * come the method reply (or error) from the initial method call
   */

  /* Note: if this test is run in OOM mode, it will block when the bus
   * doesn't send a reply due to OOM.
   */
  block_connection_until_message_from_bus (context, connection, "reply from echo message after auto-activation");

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Failed to pop message! Should have been reply from echo message\n");
      goto out;
    }

  if (dbus_message_get_reply_serial (message) != serial)
    {
      _dbus_warn ("Wrong reply serial\n");
      goto out;
    }

  dbus_message_unref (message);
  message = NULL;

  if (!check_existent_ping (context, connection))
    goto out;

  if (!check_existent_get_machine_id (context, connection))
    goto out;

  if (!check_existent_hello_from_self (context, connection))
    goto out;

  if (!check_send_exit_to_service (context, connection,
                                   EXISTENT_SERVICE_NAME,
                                   base_service))
    goto out;

  retval = TRUE;

 out:
  if (message)
    dbus_message_unref (message);

  if (base_service_message)
    dbus_message_unref (base_service_message);

  return retval;
}

#define SERVICE_FILE_MISSING_NAME "org.freedesktop.DBus.TestSuiteEchoServiceDotServiceFileDoesNotExist"

/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_launch_service_file_missing (BusContext     *context,
                                   DBusConnection *connection)
{
  DBusMessage *message;
  dbus_uint32_t serial;
  dbus_bool_t retval;

  message = dbus_message_new_method_call (SERVICE_FILE_MISSING_NAME,
                                          "/org/freedesktop/TestSuite",
                                          "org.freedesktop.TestSuite",
                                          "Echo");

  if (message == NULL)
    return TRUE;

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  dbus_message_unref (message);
  message = NULL;

  bus_test_run_everything (context);
  block_connection_until_message_from_bus (context, connection, "reply to service file missing should fail to auto-start");
  bus_test_run_everything (context);

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_verbose ("connection was disconnected\n");
      return TRUE;
    }

  retval = FALSE;

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Did not receive a reply to %s %d on %p\n",
                  "Echo message (auto activation)", serial, connection);
      goto out;
    }

  verbose_message_received (connection, message);

  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
    {
      if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
        {
          _dbus_warn ("Message has wrong sender %s\n",
                      dbus_message_get_sender (message) ?
                      dbus_message_get_sender (message) : "(none)");
          goto out;
        }

      if (dbus_message_is_error (message,
                                 DBUS_ERROR_NO_MEMORY))
        {
          ; /* good, this is a valid response */
        }
      else if (dbus_message_is_error (message,
                                      DBUS_ERROR_SERVICE_UNKNOWN))
        {
          _dbus_verbose("got service unknown\n");
          ; /* good, this is expected (only valid when using launch helper) */
        }
      else
        {
          warn_unexpected (connection, message, "not this error");

          goto out;
        }
    }
  else
    {
      _dbus_warn ("Did not expect to successfully auto-start missing service\n");
      goto out;
    }

  retval = TRUE;

 out:
  if (message)
    dbus_message_unref (message);

  return retval;
}

#define SERVICE_USER_MISSING_NAME "org.freedesktop.DBus.TestSuiteNoUser"

/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_launch_service_user_missing (BusContext     *context,
                                   DBusConnection *connection)
{
  DBusMessage *message;
  dbus_uint32_t serial;
  dbus_bool_t retval;

  message = dbus_message_new_method_call (SERVICE_USER_MISSING_NAME,
                                          "/org/freedesktop/TestSuite",
                                          "org.freedesktop.TestSuite",
                                          "Echo");

  if (message == NULL)
    return TRUE;

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  dbus_message_unref (message);
  message = NULL;

  bus_test_run_everything (context);
  block_connection_until_message_from_bus (context, connection,
  					   "reply to service which should fail to auto-start (missing User)");
  bus_test_run_everything (context);

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_warn ("connection was disconnected\n");
      return TRUE;
    }

  retval = FALSE;

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Did not receive a reply to %s %d on %p\n",
                  "Echo message (auto activation)", serial, connection);
      goto out;
    }

  verbose_message_received (connection, message);

  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
    {
      if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
        {
          _dbus_warn ("Message has wrong sender %s\n",
                      dbus_message_get_sender (message) ?
                      dbus_message_get_sender (message) : "(none)");
          goto out;
        }

      if (dbus_message_is_error (message,
                                 DBUS_ERROR_NO_MEMORY))
        {
          ; /* good, this is a valid response */
        }
      else if (dbus_message_is_error (message,
                                      DBUS_ERROR_SPAWN_FILE_INVALID))
        {
          _dbus_verbose("got service file invalid\n");
          ; /* good, this is expected (only valid when using launch helper) */
        }
      else
        {
          warn_unexpected (connection, message, "not this error");

          goto out;
        }
    }
  else
    {
      _dbus_warn ("Did not expect to successfully auto-start missing service\n");
      goto out;
    }

  retval = TRUE;

 out:
  if (message)
    dbus_message_unref (message);

  return retval;
}

#define SERVICE_EXEC_MISSING_NAME "org.freedesktop.DBus.TestSuiteNoExec"

/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_launch_service_exec_missing (BusContext     *context,
                                   DBusConnection *connection)
{
  DBusMessage *message;
  dbus_uint32_t serial;
  dbus_bool_t retval;

  message = dbus_message_new_method_call (SERVICE_EXEC_MISSING_NAME,
                                          "/org/freedesktop/TestSuite",
                                          "org.freedesktop.TestSuite",
                                          "Echo");

  if (message == NULL)
    return TRUE;

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  dbus_message_unref (message);
  message = NULL;

  bus_test_run_everything (context);
  block_connection_until_message_from_bus (context, connection,
  					   "reply to service which should fail to auto-start (missing Exec)");
  bus_test_run_everything (context);

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_warn ("connection was disconnected\n");
      return TRUE;
    }

  retval = FALSE;

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Did not receive a reply to %s %d on %p\n",
                  "Echo message (auto activation)", serial, connection);
      goto out;
    }

  verbose_message_received (connection, message);

  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
    {
      if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
        {
          _dbus_warn ("Message has wrong sender %s\n",
                      dbus_message_get_sender (message) ?
                      dbus_message_get_sender (message) : "(none)");
          goto out;
        }

      if (dbus_message_is_error (message,
                                 DBUS_ERROR_NO_MEMORY))
        {
          ; /* good, this is a valid response */
        }
      else if (dbus_message_is_error (message,
                                      DBUS_ERROR_SERVICE_UNKNOWN))
        {
          _dbus_verbose("could not activate as invalid service file was not added\n");
          ; /* good, this is expected as we shouldn't have been added to
             * the activation list with a missing Exec key */
        }
      else if (dbus_message_is_error (message,
                                      DBUS_ERROR_SPAWN_FILE_INVALID))
        {
          _dbus_verbose("got service file invalid\n");
          ; /* good, this is allowed, and is the message passed back from the
             * launch helper */
        }
      else
        {
          warn_unexpected (connection, message, "not this error");

          goto out;
        }
    }
  else
    {
      _dbus_warn ("Did not expect to successfully auto-start missing service\n");
      goto out;
    }

  retval = TRUE;

 out:
  if (message)
    dbus_message_unref (message);

  return retval;
}

#define SERVICE_SERVICE_MISSING_NAME "org.freedesktop.DBus.TestSuiteNoService"

/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_launch_service_service_missing (BusContext     *context,
                                      DBusConnection *connection)
{
  DBusMessage *message;
  dbus_uint32_t serial;
  dbus_bool_t retval;

  message = dbus_message_new_method_call (SERVICE_SERVICE_MISSING_NAME,
                                          "/org/freedesktop/TestSuite",
                                          "org.freedesktop.TestSuite",
                                          "Echo");

  if (message == NULL)
    return TRUE;

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  dbus_message_unref (message);
  message = NULL;

  bus_test_run_everything (context);
  block_connection_until_message_from_bus (context, connection,
  					   "reply to service which should fail to auto-start (missing Service)");
  bus_test_run_everything (context);

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_warn ("connection was disconnected\n");
      return TRUE;
    }

  retval = FALSE;

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Did not receive a reply to %s %d on %p\n",
                  "Echo message (auto activation)", serial, connection);
      goto out;
    }

  verbose_message_received (connection, message);

  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
    {
      if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
        {
          _dbus_warn ("Message has wrong sender %s\n",
                      dbus_message_get_sender (message) ?
                      dbus_message_get_sender (message) : "(none)");
          goto out;
        }

      if (dbus_message_is_error (message,
                                 DBUS_ERROR_NO_MEMORY))
        {
          ; /* good, this is a valid response */
        }
      else if (dbus_message_is_error (message,
                                      DBUS_ERROR_SERVICE_UNKNOWN))
        {
          _dbus_verbose("could not activate as invalid service file was not added\n");
          ; /* good, this is expected as we shouldn't have been added to
             * the activation list with a missing Exec key */
        }
      else if (dbus_message_is_error (message,
                                      DBUS_ERROR_SPAWN_FILE_INVALID))
        {
          _dbus_verbose("got service file invalid\n");
          ; /* good, this is allowed, and is the message passed back from the
             * launch helper */
        }
      else
        {
          warn_unexpected (connection, message, "not this error");

          goto out;
        }
    }
  else
    {
      _dbus_warn ("Did not expect to successfully auto-start missing service\n");
      goto out;
    }

  retval = TRUE;

 out:
  if (message)
    dbus_message_unref (message);

  return retval;
}

#define SHELL_FAIL_SERVICE_NAME "org.freedesktop.DBus.TestSuiteShellEchoServiceFail"

/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_shell_fail_service_auto_start (BusContext     *context,
                                     DBusConnection *connection)
{
  DBusMessage *message;
  dbus_uint32_t serial;
  dbus_bool_t retval;

  message = dbus_message_new_method_call (SHELL_FAIL_SERVICE_NAME,
                                          "/org/freedesktop/TestSuite",
                                          "org.freedesktop.TestSuite",
                                          "Echo");

  if (message == NULL)
    return TRUE;

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  dbus_message_unref (message);
  message = NULL;

  bus_test_run_everything (context);
  block_connection_until_message_from_bus (context, connection, "reply to shell Echo on service which should fail to auto-start");
  bus_test_run_everything (context);

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_verbose ("connection was disconnected\n");
      return TRUE;
    }

  retval = FALSE;

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Did not receive a reply to %s %d on %p\n",
                  "Echo message (auto activation)", serial, connection);
      goto out;
    }

  verbose_message_received (connection, message);

  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
    {
      if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
        {
          _dbus_warn ("Message has wrong sender %s\n",
                      dbus_message_get_sender (message) ?
                      dbus_message_get_sender (message) : "(none)");
          goto out;
        }

      if (dbus_message_is_error (message,
                                 DBUS_ERROR_NO_MEMORY))
        {
          ; /* good, this is a valid response */
        }
      else if (dbus_message_is_error (message,
                                      DBUS_ERROR_INVALID_ARGS))
        {
          _dbus_verbose("got invalid args\n");
          ; /* good, this is expected also */
        }
      else
        {
          warn_unexpected (connection, message, "not this error");

          goto out;
        }
    }
  else
    {
      _dbus_warn ("Did not expect to successfully auto-start shell fail service\n");
      goto out;
    }

  retval = TRUE;

 out:
  if (message)
    dbus_message_unref (message);

  return retval;
}

#define SHELL_SUCCESS_SERVICE_NAME "org.freedesktop.DBus.TestSuiteShellEchoServiceSuccess"

/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_shell_service_success_auto_start (BusContext     *context,
                                        DBusConnection *connection)
{
  DBusMessage *message;
  DBusMessage *base_service_message;
  dbus_uint32_t serial;
  dbus_bool_t retval;
  const char *base_service;
  const char *argv[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};

  base_service_message = NULL;

  message = dbus_message_new_method_call (SHELL_SUCCESS_SERVICE_NAME,
                                          "/org/freedesktop/TestSuite",
                                          "org.freedesktop.TestSuite",
                                          "Echo");

  if (message == NULL)
    return TRUE;

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  dbus_message_unref (message);
  message = NULL;

  bus_test_run_everything (context);

  /* now wait for the message bus to hear back from the activated
   * service.
   */
  block_connection_until_message_from_bus (context, connection, "reply to Echo on shell success service");
  bus_test_run_everything (context);

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_verbose ("connection was disconnected\n");
      return TRUE;
    }

  retval = FALSE;

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Did not receive any messages after auto start %d on %p\n",
                  serial, connection);
      goto out;
    }

  verbose_message_received (connection, message);
  _dbus_verbose ("  (after sending %s)\n", "auto start");

  /* we should get zero or two ServiceOwnerChanged signals */
  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL)
    {
      GotServiceInfo message_kind;

      if (!check_base_service_activated (context, connection,
                                         message, &base_service))
        goto out;

      base_service_message = message;
      message = NULL;

      /* We may need to block here for the test service to exit or finish up */
      block_connection_until_message_from_bus (context, connection, "service to exit");

      /* Should get a service creation notification for the activated
       * service name, or a service deletion on the base service name
       */
      message = dbus_connection_borrow_message (connection);
      if (message == NULL)
        {
          _dbus_warn ("No message after auto activation "
                      "(should be a service announcement)\n");
          dbus_connection_return_message (connection, message);
          message = NULL;
          goto out;
        }

      message_kind = check_got_service_info (message);

      dbus_connection_return_message (connection, message);
      message = NULL;

      switch (message_kind)
        {
        case GOT_SERVICE_CREATED:
          message = pop_message_waiting_for_memory (connection);
          if (message == NULL)
            {
              _dbus_warn ("Failed to pop message we just put back! "
                          "should have been a NameOwnerChanged (creation)\n");
              goto out;
            }

          /* Check that ServiceOwnerChanged (creation) was correctly received */
          if (!check_service_auto_activated (context, connection, SHELL_SUCCESS_SERVICE_NAME,
                                             base_service, message))
            goto out;

          dbus_message_unref (message);
          message = NULL;

          break;

        case GOT_SERVICE_DELETED:
          {
            /* The service started up and got a base address, but then
             * failed to register under SHELL_SUCCESS_SERVICE_NAME
             */
            CheckServiceOwnerChangedData socd;

            socd.expected_kind = SERVICE_DELETED;
            socd.expected_service_name = base_service;
            socd.failed = FALSE;
            socd.skip_connection = NULL;
            bus_test_clients_foreach (check_service_owner_changed_foreach,
                                      &socd);

            if (socd.failed)
              goto out;

            break;
          }

        case GOT_ERROR:
        case GOT_SOMETHING_ELSE:
          _dbus_warn ("Unexpected message after auto activation\n");
          goto out;
        }
    }

  /* OK, now we've dealt with ServiceOwnerChanged signals, now should
   * come the method reply (or error) from the initial method call
   */

  /* Note: if this test is run in OOM mode, it will block when the bus
   * doesn't send a reply due to OOM.
   */
  block_connection_until_message_from_bus (context, connection, "reply from echo message after auto-activation");

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Failed to pop message! Should have been reply from echo message\n");
      goto out;
    }

  if (dbus_message_get_reply_serial (message) != serial)
    {
      _dbus_warn ("Wrong reply serial\n");
      goto out;
    }

  if (!dbus_message_get_args (message, NULL,
                                       DBUS_TYPE_STRING, &argv[0],
                                       DBUS_TYPE_STRING, &argv[1],
                                       DBUS_TYPE_STRING, &argv[2],
                                       DBUS_TYPE_STRING, &argv[3],
                                       DBUS_TYPE_STRING, &argv[4],
                                       DBUS_TYPE_STRING, &argv[5],
                                       DBUS_TYPE_STRING, &argv[6],
                                       DBUS_TYPE_INVALID))
    {
      _dbus_warn ("Error getting arguments from return\n");
      goto out;
    }

   /* don't worry about arg[0] as it may be different
      depending on the path to the tests
   */
  if (strcmp("-test", argv[1]) != 0)
    {
      _dbus_warn ("Unexpected argv[1] in shell success service test (expected: %s, got: %s)\n",
                  "-test", argv[1]);
      goto out;
    }

  if (strcmp("that", argv[2]) != 0)
    {
      _dbus_warn ("Unexpected argv[2] in shell success service test (expected: %s, got: %s)\n",
                   "that", argv[2]);
      goto out;
    }

  if (strcmp("we get", argv[3]) != 0)
    {
      _dbus_warn ("Unexpected argv[3] in shell success service test (expected: %s, got: %s)\n",
                   "we get", argv[3]);
      goto out;
    }

  if (strcmp("back", argv[4]) != 0)
    {
      _dbus_warn ("Unexpected argv[4] in shell success service test (expected: %s, got: %s)\n",
                   "back", argv[4]);
      goto out;
    }

  if (strcmp("--what", argv[5]) != 0)
    {
      _dbus_warn ("Unexpected argv[5] in shell success service test (expected: %s, got: %s)\n",
                   "--what", argv[5]);
      goto out;
    }

  if (strcmp("we put in", argv[6]) != 0)
    {
      _dbus_warn ("Unexpected argv[6] in shell success service test (expected: %s, got: %s)\n",
                   "we put in", argv[6]);
      goto out;
    }

  dbus_message_unref (message);
  message = NULL;

  if (!check_send_exit_to_service (context, connection,
                                   SHELL_SUCCESS_SERVICE_NAME,
                                   base_service))
    goto out;

  retval = TRUE;

 out:
  if (message)
    dbus_message_unref (message);

  if (base_service_message)
    dbus_message_unref (base_service_message);

  return retval;
}

typedef struct
{
  Check1Func func;
  BusContext *context;
} Check1Data;

static dbus_bool_t
check_oom_check1_func (void *data)
{
  Check1Data *d = data;

  if (! (* d->func) (d->context))
    return FALSE;

  if (!check_no_leftovers (d->context))
    {
      _dbus_warn ("Messages were left over, should be covered by test suite\n");
      return FALSE;
    }

  return TRUE;
}

static void
check1_try_iterations (BusContext *context,
                       const char *description,
                       Check1Func  func)
{
  Check1Data d;

  d.func = func;
  d.context = context;

  if (!_dbus_test_oom_handling (description, check_oom_check1_func,
                                &d))
    _dbus_assert_not_reached ("test failed");
}

static dbus_bool_t
check_get_services (BusContext     *context,
		    DBusConnection *connection,
		    const char     *method,
		    char         ***services,
		    int            *len)
{
  DBusMessage *message;
  dbus_uint32_t serial;
  dbus_bool_t retval;
  DBusError error;
  char **srvs;
  int l;

  retval = FALSE;
  dbus_error_init (&error);
  message = NULL;

  message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
					  DBUS_PATH_DBUS,
					  DBUS_INTERFACE_DBUS,
					  method);

  if (message == NULL)
    return TRUE;

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  /* send our message */
  bus_test_run_clients_loop (SEND_PENDING (connection));

  dbus_message_unref (message);
  message = NULL;

  dbus_connection_ref (connection); /* because we may get disconnected */
  block_connection_until_message_from_bus (context, connection, "reply to ListActivatableNames/ListNames");

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_verbose ("connection was disconnected\n");

      dbus_connection_unref (connection);

      return TRUE;
    }

  dbus_connection_unref (connection);

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Did not receive a reply to %s %d on %p\n",
		  method, serial, connection);
      goto out;
    }

  verbose_message_received (connection, message);

  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
    {
      if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY))
	{
	  ; /* good, this is a valid response */
	}
      else
	{
	  warn_unexpected (connection, message, "not this error");

	  goto out;
	}
    }
  else
    {
      if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
	{
	  ; /* good, expected */
	}
      else
	{
	  warn_unexpected (connection, message,
			   "method_return for ListActivatableNames/ListNames");

	  goto out;
	}

    retry_get_property:

      if (!dbus_message_get_args (message, &error,
				  DBUS_TYPE_ARRAY,
				  DBUS_TYPE_STRING,
				  &srvs, &l,
				  DBUS_TYPE_INVALID))
	{
	  if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
	    {
	      _dbus_verbose ("no memory to list services by %s\n", method);
	      dbus_error_free (&error);
	      _dbus_wait_for_memory ();
	      goto retry_get_property;
	    }
	  else
	    {
	      _dbus_assert (dbus_error_is_set (&error));
	      _dbus_warn ("Did not get the expected DBUS_TYPE_ARRAY from %s\n", method);
	      goto out;
	    }
	} else {
	  *services = srvs;
	  *len = l;
	}
    }

  if (!check_no_leftovers (context))
    goto out;

  retval = TRUE;

 out:
  dbus_error_free (&error);

  if (message)
    dbus_message_unref (message);

  return retval;
}

/* returns TRUE if the correct thing happens,
 * but the correct thing may include OOM errors.
 */
static dbus_bool_t
check_list_services (BusContext     *context,
		     DBusConnection *connection)
{
  DBusMessage  *message;
  DBusMessage  *base_service_message;
  const char   *base_service;
  dbus_uint32_t serial;
  dbus_bool_t   retval;
  const char   *existent = EXISTENT_SERVICE_NAME;
  dbus_uint32_t flags;
  char        **services;
  int           len;

  _dbus_verbose ("check_list_services for %p\n", connection);

  if (!check_get_services (context, connection, "ListActivatableNames", &services, &len))
    {
      return TRUE;
    }

  if (!_dbus_string_array_contains ((const char **)services, existent))
    {
      _dbus_warn ("Did not get the expected %s from ListActivatableNames\n", existent);
      dbus_free_string_array (services);
      return FALSE;
    }

  dbus_free_string_array (services);

  base_service_message = NULL;

  message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
					  DBUS_PATH_DBUS,
					  DBUS_INTERFACE_DBUS,
					  "StartServiceByName");

  if (message == NULL)
    return TRUE;

  dbus_message_set_auto_start (message, FALSE);

  flags = 0;
  if (!dbus_message_append_args (message,
				 DBUS_TYPE_STRING, &existent,
				 DBUS_TYPE_UINT32, &flags,
				 DBUS_TYPE_INVALID))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  if (!dbus_connection_send (connection, message, &serial))
    {
      dbus_message_unref (message);
      return TRUE;
    }

  dbus_message_unref (message);
  message = NULL;

  bus_test_run_everything (context);

  /* now wait for the message bus to hear back from the activated
   * service.
   */
  block_connection_until_message_from_bus (context, connection, "activated service to connect");

  bus_test_run_everything (context);

  if (!dbus_connection_get_is_connected (connection))
    {
      _dbus_verbose ("connection was disconnected\n");
      return TRUE;
    }

  retval = FALSE;

  message = pop_message_waiting_for_memory (connection);
  if (message == NULL)
    {
      _dbus_warn ("Did not receive any messages after %s %d on %p\n",
		  "StartServiceByName", serial, connection);
      goto out;
    }

  verbose_message_received (connection, message);
  _dbus_verbose ("  (after sending %s)\n", "StartServiceByName");

  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
    {
      if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
	{
	  _dbus_warn ("Message has wrong sender %s\n",
		      dbus_message_get_sender (message) ?
		      dbus_message_get_sender (message) : "(none)");
	  goto out;
	}

      if (dbus_message_is_error (message,
				 DBUS_ERROR_NO_MEMORY))
	{
	  ; /* good, this is a valid response */
	}
      else if (dbus_message_is_error (message,
				      DBUS_ERROR_SPAWN_CHILD_EXITED) ||
	       dbus_message_is_error (message,
				      DBUS_ERROR_SPAWN_CHILD_SIGNALED) ||
	       dbus_message_is_error (message,
				      DBUS_ERROR_SPAWN_EXEC_FAILED))
	{
	  ; /* good, this is expected also */
	}
      else
	{
	  _dbus_warn ("Did not expect error %s\n",
		      dbus_message_get_error_name (message));
	  goto out;
	}
    }
  else
    {
      GotServiceInfo message_kind;

      if (!check_base_service_activated (context, connection,
					 message, &base_service))
	goto out;

      base_service_message = message;
      message = NULL;

      /* We may need to block here for the test service to exit or finish up */
      block_connection_until_message_from_bus (context, connection, "test service to exit or finish up");

      message = dbus_connection_borrow_message (connection);
      if (message == NULL)
	{
	  _dbus_warn ("Did not receive any messages after base service creation notification\n");
	  goto out;
	}

      message_kind = check_got_service_info (message);

      dbus_connection_return_message (connection, message);
      message = NULL;

      switch (message_kind)
	{
	case GOT_SOMETHING_ELSE:
	case GOT_ERROR:
	case GOT_SERVICE_DELETED:
	  _dbus_warn ("Unexpected message after ActivateService "
		      "(should be an error or a service announcement)\n");
	  goto out;

	case GOT_SERVICE_CREATED:
	  message = pop_message_waiting_for_memory (connection);
	  if (message == NULL)
	    {
	      _dbus_warn ("Failed to pop message we just put back! "
			  "should have been a NameOwnerChanged (creation)\n");
	      goto out;
	    }

	  if (!check_service_activated (context, connection, EXISTENT_SERVICE_NAME,
					base_service, message))
	    goto out;

	  dbus_message_unref (message);
	  message = NULL;

	  if (!check_no_leftovers (context))
	    {
	      _dbus_warn ("Messages were left over after successful activation\n");
	      goto out;
	    }

	  break;
	}
    }

  if (!check_get_services (context, connection, "ListNames", &services, &len))
    {
      return TRUE;
    }

  if (!_dbus_string_array_contains ((const char **)services, existent))
    {
      _dbus_warn ("Did not get the expected %s from ListNames\n", existent);
      goto out;
    }

  dbus_free_string_array (services);

  if (!check_send_exit_to_service (context, connection,
				   EXISTENT_SERVICE_NAME, base_service))
    goto out;

  retval = TRUE;

 out:
  if (message)
    dbus_message_unref (message);

  if (base_service_message)
    dbus_message_unref (base_service_message);

  return retval;
}

typedef struct
{
  Check2Func func;
  BusContext *context;
  DBusConnection *connection;
} Check2Data;

static dbus_bool_t
check_oom_check2_func (void *data)
{
  Check2Data *d = data;

  if (! (* d->func) (d->context, d->connection))
    return FALSE;

  if (!check_no_leftovers (d->context))
    {
      _dbus_warn ("Messages were left over, should be covered by test suite\n");
      return FALSE;
    }

  return TRUE;
}

static void
check2_try_iterations (BusContext     *context,
                       DBusConnection *connection,
                       const char     *description,
                       Check2Func      func)
{
  Check2Data d;

  d.func = func;
  d.context = context;
  d.connection = connection;

  if (!_dbus_test_oom_handling (description, check_oom_check2_func,
                                &d))
    {
      _dbus_warn ("%s failed during oom\n", description);
      _dbus_assert_not_reached ("test failed");
    }
}

static dbus_bool_t
setenv_TEST_LAUNCH_HELPER_CONFIG(const DBusString *test_data_dir,
                                 const char       *filename)
{
  DBusString full;
  DBusString file;

  if (!_dbus_string_init (&full))
    return FALSE;

  if (!_dbus_string_copy (test_data_dir, 0, &full, 0))
    {
      _dbus_string_free (&full);
      return FALSE;
    }

  _dbus_string_init_const (&file, filename);

  if (!_dbus_concat_dir_and_file (&full, &file))
    {
      _dbus_string_free (&full);
      return FALSE;
    }

  _dbus_verbose ("Setting TEST_LAUNCH_HELPER_CONFIG to '%s'\n",
                 _dbus_string_get_const_data (&full));

  _dbus_setenv ("TEST_LAUNCH_HELPER_CONFIG", _dbus_string_get_const_data (&full));

  _dbus_string_free (&full);

  return TRUE;
}

static dbus_bool_t
bus_dispatch_test_conf (const DBusString *test_data_dir,
		        const char       *filename,
		        dbus_bool_t       use_launcher)
{
  BusContext *context;
  DBusConnection *foo;
  DBusConnection *bar;
  DBusConnection *baz;
  DBusError error;

  /* save the config name for the activation helper */
  if (!setenv_TEST_LAUNCH_HELPER_CONFIG (test_data_dir, filename))
    _dbus_assert_not_reached ("no memory setting TEST_LAUNCH_HELPER_CONFIG");

  dbus_error_init (&error);

  context = bus_context_new_test (test_data_dir, filename);
  if (context == NULL)
    return FALSE;

  foo = dbus_connection_open_private (TEST_CONNECTION, &error);
  if (foo == NULL)
    _dbus_assert_not_reached ("could not alloc connection");

  if (!bus_setup_debug_client (foo))
    _dbus_assert_not_reached ("could not set up connection");

  spin_connection_until_authenticated (context, foo);

  if (!check_hello_message (context, foo))
    _dbus_assert_not_reached ("hello message failed");

  if (!check_double_hello_message (context, foo))
    _dbus_assert_not_reached ("double hello message failed");

  if (!check_add_match_all (context, foo))
    _dbus_assert_not_reached ("AddMatch message failed");

  bar = dbus_connection_open_private (TEST_CONNECTION, &error);
  if (bar == NULL)
    _dbus_assert_not_reached ("could not alloc connection");

  if (!bus_setup_debug_client (bar))
    _dbus_assert_not_reached ("could not set up connection");

  spin_connection_until_authenticated (context, bar);

  if (!check_hello_message (context, bar))
    _dbus_assert_not_reached ("hello message failed");

  if (!check_add_match_all (context, bar))
    _dbus_assert_not_reached ("AddMatch message failed");

  baz = dbus_connection_open_private (TEST_CONNECTION, &error);
  if (baz == NULL)
    _dbus_assert_not_reached ("could not alloc connection");

  if (!bus_setup_debug_client (baz))
    _dbus_assert_not_reached ("could not set up connection");

  spin_connection_until_authenticated (context, baz);

  if (!check_hello_message (context, baz))
    _dbus_assert_not_reached ("hello message failed");

  if (!check_add_match_all (context, baz))
    _dbus_assert_not_reached ("AddMatch message failed");

#ifdef DBUS_WIN_FIXME
  _dbus_warn("TODO: testing of GetConnectionUnixUser message skipped for now\n");
  _dbus_warn("TODO: testing of GetConnectionUnixProcessID message skipped for now\n");
#else
  if (!check_get_connection_unix_user (context, baz))
    _dbus_assert_not_reached ("GetConnectionUnixUser message failed");

  if (!check_get_connection_unix_process_id (context, baz))
    _dbus_assert_not_reached ("GetConnectionUnixProcessID message failed");
#endif

  if (!check_list_services (context, baz))
    _dbus_assert_not_reached ("ListActivatableNames message failed");

  if (!check_no_leftovers (context))
    {
      _dbus_warn ("Messages were left over after setting up initial connections\n");
      _dbus_assert_not_reached ("initial connection setup failed");
    }

  check1_try_iterations (context, "create_and_hello",
                         check_hello_connection);

  check2_try_iterations (context, foo, "nonexistent_service_no_auto_start",
                         check_nonexistent_service_no_auto_start);

#ifdef DBUS_WIN_FIXME
  _dbus_warn("TODO: dispatch.c segfault_service_no_auto_start test\n");
#else
  check2_try_iterations (context, foo, "segfault_service_no_auto_start",
                         check_segfault_service_no_auto_start);
#endif

  check2_try_iterations (context, foo, "existent_service_no_auto_start",
                         check_existent_service_no_auto_start);

  check2_try_iterations (context, foo, "nonexistent_service_auto_start",
                         check_nonexistent_service_auto_start);


#ifdef DBUS_WIN_FIXME
  _dbus_warn("TODO: dispatch.c segfault_service_auto_start test\n");
#else
  /* only do the segfault test if we are not using the launcher */
  check2_try_iterations (context, foo, "segfault_service_auto_start",
                         check_segfault_service_auto_start);
#endif

  /* only do the shell fail test if we are not using the launcher */
  check2_try_iterations (context, foo, "shell_fail_service_auto_start",
                         check_shell_fail_service_auto_start);

  /* specific to launcher */
  if (use_launcher)
    if (!check_launch_service_file_missing (context, foo))
      _dbus_assert_not_reached ("did not get service file not found error");

#if 0
  /* Note: need to resolve some issues with the testing code in order to run
   * this in oom (handle that we sometimes don't get replies back from the bus
   * when oom happens, without blocking the test).
   */
  check2_try_iterations (context, foo, "existent_service_auto_auto_start",
                         check_existent_service_auto_start);
#endif

  if (!check_existent_service_auto_start (context, foo))
    _dbus_assert_not_reached ("existent service auto start failed");

  if (!check_shell_service_success_auto_start (context, foo))
    _dbus_assert_not_reached ("shell success service auto start failed");

  _dbus_verbose ("Disconnecting foo, bar, and baz\n");

  kill_client_connection_unchecked (foo);
  kill_client_connection_unchecked (bar);
  kill_client_connection_unchecked (baz);

  bus_context_unref (context);

  return TRUE;
}

static dbus_bool_t
bus_dispatch_test_conf_fail (const DBusString *test_data_dir,
		             const char       *filename)
{
  BusContext *context;
  DBusConnection *foo;
  DBusError error;

  /* save the config name for the activation helper */
  if (!setenv_TEST_LAUNCH_HELPER_CONFIG (test_data_dir, filename))
    _dbus_assert_not_reached ("no memory setting TEST_LAUNCH_HELPER_CONFIG");

  dbus_error_init (&error);

  context = bus_context_new_test (test_data_dir, filename);
  if (context == NULL)
    return FALSE;

  foo = dbus_connection_open_private (TEST_CONNECTION, &error);
  if (foo == NULL)
    _dbus_assert_not_reached ("could not alloc connection");

  if (!bus_setup_debug_client (foo))
    _dbus_assert_not_reached ("could not set up connection");

  spin_connection_until_authenticated (context, foo);

  if (!check_hello_message (context, foo))
    _dbus_assert_not_reached ("hello message failed");

  if (!check_double_hello_message (context, foo))
    _dbus_assert_not_reached ("double hello message failed");

  if (!check_add_match_all (context, foo))
    _dbus_assert_not_reached ("AddMatch message failed");

  /* this only tests the activation.c user check */
  if (!check_launch_service_user_missing (context, foo))
    _dbus_assert_not_reached ("user missing did not trigger error");

  /* this only tests the desktop.c exec check */
  if (!check_launch_service_exec_missing (context, foo))
    _dbus_assert_not_reached ("exec missing did not trigger error");

  /* this only tests the desktop.c service check */
  if (!check_launch_service_service_missing (context, foo))
    _dbus_assert_not_reached ("service missing did not trigger error");

  _dbus_verbose ("Disconnecting foo\n");

  kill_client_connection_unchecked (foo);

  bus_context_unref (context);

  return TRUE;
}

dbus_bool_t
bus_dispatch_test (const DBusString *test_data_dir)
{
  /* run normal activation tests */
  _dbus_verbose ("Normal activation tests\n");
  if (!bus_dispatch_test_conf (test_data_dir,
  			       "valid-config-files/debug-allow-all.conf", FALSE))
    return FALSE;

#ifdef DBUS_WIN
  _dbus_warn("Info: Launch helper activation tests skipped because launch-helper is not supported yet\n");
#else
  /* run launch-helper activation tests */
  _dbus_verbose ("Launch helper activation tests\n");
  if (!bus_dispatch_test_conf (test_data_dir,
  			       "valid-config-files-system/debug-allow-all-pass.conf", TRUE))
    return FALSE;

  /* run select launch-helper activation tests on broken service files */
  if (!bus_dispatch_test_conf_fail (test_data_dir,
  			            "valid-config-files-system/debug-allow-all-fail.conf"))
    return FALSE;
#endif

  return TRUE;
}

dbus_bool_t
bus_dispatch_sha1_test (const DBusString *test_data_dir)
{
  BusContext *context;
  DBusConnection *foo;
  DBusError error;

  dbus_error_init (&error);

  /* Test SHA1 authentication */
  _dbus_verbose ("Testing SHA1 context\n");

  context = bus_context_new_test (test_data_dir,
                                  "valid-config-files/debug-allow-all-sha1.conf");
  if (context == NULL)
    return FALSE;

  foo = dbus_connection_open_private (TEST_CONNECTION, &error);
  if (foo == NULL)
    _dbus_assert_not_reached ("could not alloc connection");

  if (!bus_setup_debug_client (foo))
    _dbus_assert_not_reached ("could not set up connection");

  spin_connection_until_authenticated (context, foo);

  if (!check_hello_message (context, foo))
    _dbus_assert_not_reached ("hello message failed");

  if (!check_add_match_all (context, foo))
    _dbus_assert_not_reached ("addmatch message failed");

  if (!check_no_leftovers (context))
    {
      _dbus_warn ("Messages were left over after setting up initial SHA-1 connection\n");
      _dbus_assert_not_reached ("initial connection setup failed");
    }

  check1_try_iterations (context, "create_and_hello_sha1",
                         check_hello_connection);

  kill_client_connection_unchecked (foo);

  bus_context_unref (context);

  return TRUE;
}

#ifdef HAVE_UNIX_FD_PASSING

dbus_bool_t
bus_unix_fds_passing_test(const DBusString *test_data_dir)
{
  BusContext *context;
  DBusConnection *foo, *bar;
  DBusError error;
  DBusMessage *m;
  dbus_bool_t b;
  int one[2], two[2], x, y, z;
  char r;

  dbus_error_init (&error);

  context = bus_context_new_test (test_data_dir, "valid-config-files/debug-allow-all.conf");
  if (context == NULL)
    _dbus_assert_not_reached ("could not alloc context");

  foo = dbus_connection_open_private (TEST_CONNECTION, &error);
  if (foo == NULL)
    _dbus_assert_not_reached ("could not alloc connection");

  if (!bus_setup_debug_client (foo))
    _dbus_assert_not_reached ("could not set up connection");

  spin_connection_until_authenticated (context, foo);

  if (!check_hello_message (context, foo))
    _dbus_assert_not_reached ("hello message failed");

  if (!check_add_match_all (context, foo))
    _dbus_assert_not_reached ("AddMatch message failed");

  bar = dbus_connection_open_private (TEST_CONNECTION, &error);
  if (bar == NULL)
    _dbus_assert_not_reached ("could not alloc connection");

  if (!bus_setup_debug_client (bar))
    _dbus_assert_not_reached ("could not set up connection");

  spin_connection_until_authenticated (context, bar);

  if (!check_hello_message (context, bar))
    _dbus_assert_not_reached ("hello message failed");

  if (!check_add_match_all (context, bar))
    _dbus_assert_not_reached ("AddMatch message failed");

  if (!(m = dbus_message_new_signal("/", "a.b.c", "d")))
    _dbus_assert_not_reached ("could not alloc message");

  if (!(_dbus_full_duplex_pipe(one, one+1, TRUE, &error)))
    _dbus_assert_not_reached("Failed to allocate pipe #1");

  if (!(_dbus_full_duplex_pipe(two, two+1, TRUE, &error)))
    _dbus_assert_not_reached("Failed to allocate pipe #2");

  if (!dbus_message_append_args(m,
                                DBUS_TYPE_UNIX_FD, one,
                                DBUS_TYPE_UNIX_FD, two,
                                DBUS_TYPE_UNIX_FD, two,
                                DBUS_TYPE_INVALID))
    _dbus_assert_not_reached("Failed to attach fds.");

  if (!_dbus_close(one[0], &error))
    _dbus_assert_not_reached("Failed to close pipe #1 ");
  if (!_dbus_close(two[0], &error))
    _dbus_assert_not_reached("Failed to close pipe #2 ");

  if (!(dbus_connection_can_send_type(foo, DBUS_TYPE_UNIX_FD)))
    _dbus_assert_not_reached("Connection cannot do fd passing");

  if (!(dbus_connection_can_send_type(bar, DBUS_TYPE_UNIX_FD)))
    _dbus_assert_not_reached("Connection cannot do fd passing");

  if (!dbus_connection_send (foo, m, NULL))
    _dbus_assert_not_reached("Failed to send fds");

  dbus_message_unref(m);

  bus_test_run_clients_loop (SEND_PENDING (foo));

  bus_test_run_everything (context);

  block_connection_until_message_from_bus (context, foo, "unix fd reception on foo");

  if (!(m = pop_message_waiting_for_memory (foo)))
    _dbus_assert_not_reached("Failed to receive msg");

  if (!dbus_message_is_signal(m, "a.b.c", "d"))
    _dbus_assert_not_reached("bogus message received");

  dbus_message_unref(m);

  block_connection_until_message_from_bus (context, bar, "unix fd reception on bar");

  if (!(m = pop_message_waiting_for_memory (bar)))
    _dbus_assert_not_reached("Failed to receive msg");

  if (!dbus_message_is_signal(m, "a.b.c", "d"))
    _dbus_assert_not_reached("bogus message received");

  if (!dbus_message_get_args(m,
                             &error,
                             DBUS_TYPE_UNIX_FD, &x,
                             DBUS_TYPE_UNIX_FD, &y,
                             DBUS_TYPE_UNIX_FD, &z,
                             DBUS_TYPE_INVALID))
    _dbus_assert_not_reached("Failed to parse fds.");

  dbus_message_unref(m);

  if (write(x, "X", 1) != 1)
    _dbus_assert_not_reached("Failed to write to pipe #1");
  if (write(y, "Y", 1) != 1)
    _dbus_assert_not_reached("Failed to write to pipe #2");
  if (write(z, "Z", 1) != 1)
    _dbus_assert_not_reached("Failed to write to pipe #2/2nd fd");

  if (!_dbus_close(x, &error))
    _dbus_assert_not_reached("Failed to close pipe #1/other side ");
  if (!_dbus_close(y, &error))
    _dbus_assert_not_reached("Failed to close pipe #2/other side ");
  if (!_dbus_close(z, &error))
    _dbus_assert_not_reached("Failed to close pipe #2/other size 2nd fd ");

  if (read(one[1], &r, 1) != 1 || r != 'X')
    _dbus_assert_not_reached("Failed to read value from pipe.");
  if (read(two[1], &r, 1) != 1 || r != 'Y')
    _dbus_assert_not_reached("Failed to read value from pipe.");
  if (read(two[1], &r, 1) != 1 || r != 'Z')
    _dbus_assert_not_reached("Failed to read value from pipe.");

  if (!_dbus_close(one[1], &error))
    _dbus_assert_not_reached("Failed to close pipe #1 ");
  if (!_dbus_close(two[1], &error))
    _dbus_assert_not_reached("Failed to close pipe #2 ");

  _dbus_verbose ("Disconnecting foo\n");
  kill_client_connection_unchecked (foo);

  _dbus_verbose ("Disconnecting bar\n");
  kill_client_connection_unchecked (bar);

  bus_context_unref (context);

  return TRUE;
}
#endif

#endif /* DBUS_BUILD_TESTS */
