]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blobdiff - tests/src/test-runner.c
Fix warning when tests complete
[sojka/lightdm.git] / tests / src / test-runner.c
index fec53eae71a440be555a673909d40e2929261fb3..bcb6f8eea1d7a5a86018c4d9b7ffd91f30bd54be 100644 (file)
@@ -81,7 +81,6 @@ static const GDBusInterfaceVTable user_vtable =
     handle_user_call,
     handle_user_get_property,
 };
-static GDBusConnection *ck_connection = NULL;
 static GDBusNodeInfo *ck_session_info;
 typedef struct
 {
@@ -107,6 +106,22 @@ static const GDBusInterfaceVTable ck_session_vtable =
 
 typedef struct
 {
+    gchar *id;
+    gchar *path;
+    gboolean can_graphical;
+    gboolean can_multi_session;
+    gchar *active_session;
+} Login1Seat;
+
+static GList *login1_seats = NULL;
+
+static Login1Seat *add_login1_seat (GDBusConnection *connection, const gchar *id, gboolean emit_signal);
+static Login1Seat *find_login1_seat (const gchar *id);
+static void remove_login1_seat (GDBusConnection *connection, const gchar *id);
+
+typedef struct
+{
+    gchar *id;
     gchar *path;
     guint pid;
     gboolean locked;
@@ -122,21 +137,26 @@ typedef struct
 } StatusClient;
 static GList *status_clients = NULL;
 
-static void run_lightdm (void);
+static void ready (void);
 static void quit (int status);
+static gboolean status_timeout_cb (gpointer data);
 static void check_status (const gchar *status);
 static AccountsUser *get_accounts_user_by_uid (guint uid);
 static AccountsUser *get_accounts_user_by_name (const gchar *username);
 static void accounts_user_set_hidden (AccountsUser *user, gboolean hidden, gboolean emit_signal);
+static Login1Session *find_login1_session (const gchar *id);
 
 static gboolean
 kill_timeout_cb (gpointer data)
 {
     Process *process = data;
 
+    process->kill_timeout = 0;
+
     if (getenv ("DEBUG"))
         g_print ("Sending SIGKILL to process %d\n", process->pid);
     kill (process->pid, SIGKILL);
+
     return FALSE;
 }
 
@@ -326,6 +346,71 @@ stop_loop (gpointer user_data)
     return G_SOURCE_REMOVE;
 }
 
+static void
+switch_to_greeter_done_cb (GObject *bus, GAsyncResult *result, gpointer data)
+{
+    GVariant *r;
+    GError *error = NULL;
+
+    r = g_dbus_connection_call_finish (G_DBUS_CONNECTION (bus), result, &error);
+    if (error)
+        g_warning ("Failed to switch to greeter: %s\n", error->message);
+    g_clear_error (&error);
+
+    if (r)
+    {
+        check_status ("RUNNER SWITCH-TO-GREETER");
+        g_variant_unref (r);
+    }
+    else
+        check_status ("RUNNER SWITCH-TO-GREETER FAILED");
+}
+
+static void
+switch_to_user_done_cb (GObject *bus, GAsyncResult *result, gpointer data)
+{
+    GVariant *r;
+    GError *error = NULL;
+    gchar *username = data, *status_text;
+
+    r = g_dbus_connection_call_finish (G_DBUS_CONNECTION (bus), result, &error);
+    if (error)
+        g_warning ("Failed to switch to user: %s\n", error->message);
+    g_clear_error (&error);
+
+    if (r)
+    {
+        status_text = g_strdup_printf ("RUNNER SWITCH-TO-USER USERNAME=%s", username);
+        g_variant_unref (r);
+    }
+    else
+        status_text = g_strdup_printf ("RUNNER SWITCH-TO-USER USERNAME=%s FAILED", username);
+    check_status (status_text);
+
+    g_free (status_text);
+    g_free (username);
+}
+
+static void
+switch_to_guest_done_cb (GObject *bus, GAsyncResult *result, gpointer data)
+{
+    GVariant *r;
+    GError *error = NULL;
+
+    r = g_dbus_connection_call_finish (G_DBUS_CONNECTION (bus), result, &error);
+    if (error)
+        g_warning ("Failed to switch to guest: %s\n", error->message);
+    g_clear_error (&error);
+
+    if (r)
+    {
+        check_status ("RUNNER SWITCH-TO-GUEST");
+        g_variant_unref (r);
+    }
+    else
+        check_status ("RUNNER SWITCH-TO-GUEST FAILED");
+}
+
 static void
 handle_command (const gchar *command)
 {
@@ -403,52 +488,147 @@ handle_command (const gchar *command)
         g_hash_table_insert (params, param_name, param_value);
     }
 
-    if (strcmp (name, "WAIT") == 0)
+    if (strcmp (name, "START-DAEMON") == 0)
     {
+        GString *command_line;
+        gchar **lightdm_argv;
+        pid_t lightdm_pid;
+        GError *error = NULL;
+
+        command_line = g_string_new ("lightdm");
+        if (getenv ("DEBUG"))
+            g_string_append (command_line, " --debug");
+        g_string_append_printf (command_line, " --cache-dir %s/cache", temp_dir);
+
+        test_runner_command = g_strdup_printf ("PATH=%s LD_PRELOAD=%s LD_LIBRARY_PATH=%s LIGHTDM_TEST_ROOT=%s DBUS_SESSION_BUS_ADDRESS=%s %s\n",
+                                               g_getenv ("PATH"), g_getenv ("LD_PRELOAD"), g_getenv ("LD_LIBRARY_PATH"), g_getenv ("LIGHTDM_TEST_ROOT"), g_getenv ("DBUS_SESSION_BUS_ADDRESS"),
+                                               command_line->str);
+
+        if (!g_shell_parse_argv (command_line->str, NULL, &lightdm_argv, &error))
+        {
+            g_warning ("Error parsing command line: %s", error->message);
+            quit (EXIT_FAILURE);
+        }
+        g_clear_error (&error);
+
+        if (!g_spawn_async (NULL, lightdm_argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, NULL, NULL, &lightdm_pid, &error))
+        {
+            g_warning ("Error launching LightDM: %s", error->message);
+            quit (EXIT_FAILURE);
+        }
+        g_clear_error (&error);
+        lightdm_process = watch_process (lightdm_pid);
+
+        check_status ("RUNNER DAEMON-START");
+    }
+    else if (strcmp (name, "WAIT") == 0)
+    {
+        const gchar *v;
+        int duration;
+
+        /* Stop status timeout */
+        if (status_timeout)
+            g_source_remove (status_timeout);
+        status_timeout = 0;
+
         /* Use a main loop so that our DBus functions are still responsive */
         GMainLoop *loop = g_main_loop_new (NULL, FALSE);
-        g_timeout_add_seconds (1, stop_loop, loop);
+        v = g_hash_table_lookup (params, "DURATION");
+        duration = v ? atoi (v) : 1;
+        if (duration < 1)
+            duration = 1;
+        g_timeout_add_seconds (duration, stop_loop, loop);
         g_main_loop_run (loop);
         g_main_loop_unref (loop);
+
+        /* Restart status timeout */
+        status_timeout = g_timeout_add (status_timeout_ms, status_timeout_cb, NULL);
     }
-    else if (strcmp (name, "LIST-SHARED-DATA-DIRS") == 0)
+    else if (strcmp (name, "ADD-SEAT") == 0)
     {
-        gchar *shared_dir;
-        GDir *dir;
-        const gchar *path;
-        GList *paths = NULL, *link;
-        GString *status;
+        const gchar *id, *v;
+        Login1Seat *seat;
 
-        shared_dir = g_strdup_printf ("%s/var/lib/lightdm-data", temp_dir);
-        dir = g_dir_open (shared_dir, 0, NULL);
-        while ((path = g_dir_read_name (dir)))
-        {
-            gchar *full_path = g_build_filename (shared_dir, path, NULL);
-            paths = g_list_insert_sorted (paths, full_path, (GCompareFunc)g_strcmp0);
-        }
-        g_dir_close (dir);
-        g_free (shared_dir);
+        id = g_hash_table_lookup (params, "ID");
+        seat = add_login1_seat (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL), id, TRUE);
+        v = g_hash_table_lookup (params, "CAN-GRAPHICAL");
+        if (v)
+            seat->can_graphical = strcmp (v, "TRUE") == 0;
+        v = g_hash_table_lookup (params, "CAN-MULTI-SESSION");
+        if (v)
+            seat->can_multi_session = strcmp (v, "TRUE") == 0;
+    }
+    else if (strcmp (name, "ADD-LOCAL-X-SEAT") == 0)
+    {
+        GVariant *result;
+        const gchar *v;
+
+        v = g_hash_table_lookup (params, "DISPLAY");
+        result = g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
+                                              "org.freedesktop.DisplayManager",
+                                              "/org/freedesktop/DisplayManager",
+                                              "org.freedesktop.DisplayManager",
+                                              "AddLocalXSeat",
+                                              g_variant_new ("(i)", v ? atoi (v) : -1),
+                                              G_VARIANT_TYPE ("(o)"),
+                                              G_DBUS_CALL_FLAGS_NONE,
+                                              G_MAXINT,
+                                              NULL,
+                                              NULL);
+        g_variant_unref (result);
+    }
+    else if (strcmp (name, "UPDATE-SEAT") == 0)
+    {
+        Login1Seat *seat;
+        const gchar *id;
 
-        status = g_string_new ("RUNNER LIST-SHARED-DATA-DIRS DIRS=");
-        for (link = paths; link; link = link->next)
+        id = g_hash_table_lookup (params, "ID");
+        seat = find_login1_seat (id);
+        if (seat)
         {
-            path = (const gchar *)link->data;
-            GStatBuf buf;
-            if (g_stat (path, &buf) != 0)
-                continue;
+            const gchar *v;
+            GVariantBuilder invalidated_properties;
+            GError *error = NULL;
 
-            if (link != paths)
-                g_string_append (status, ",");
-            gchar *basename = g_path_get_basename (path);
-            g_string_append_printf (status, "%s:%u:%u:0%o", basename,
-                                    buf.st_uid, buf.st_gid,
-                                    buf.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO));
-            g_free (basename);
-        }
-        g_list_free_full (paths, g_free);
+            g_variant_builder_init (&invalidated_properties, G_VARIANT_TYPE_ARRAY);
 
-        check_status (status->str);
-        g_string_free (status, TRUE);
+            v = g_hash_table_lookup (params, "CAN-GRAPHICAL");
+            if (v)
+            {
+                seat->can_graphical = strcmp (v, "TRUE") == 0;
+                g_variant_builder_add (&invalidated_properties, "s", "CanGraphical");
+            }
+            v = g_hash_table_lookup (params, "CAN-MULTI-SESSION");
+            if (v)
+            {
+                seat->can_multi_session = strcmp (v, "TRUE") == 0;
+                g_variant_builder_add (&invalidated_properties, "s", "CanMultiSession");
+            }
+            v = g_hash_table_lookup (params, "ACTIVE-SESSION");
+            if (v)
+            {
+                g_free (seat->active_session);
+                seat->active_session = g_strdup (v);
+                g_variant_builder_add (&invalidated_properties, "s", "ActiveSession");
+            }
+
+            g_dbus_connection_emit_signal (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
+                                           NULL,
+                                           seat->path,
+                                           "org.freedesktop.DBus.Properties",
+                                           "PropertiesChanged",
+                                           g_variant_new ("(sa{sv}as)", "org.freedesktop.login1.Seat", NULL, &invalidated_properties),
+                                           &error);
+            if (error)
+                g_warning ("Failed to emit PropertiesChanged: %s", error->message);
+            g_clear_error (&error);
+        }
+    }
+    else if (strcmp (name, "REMOVE-SEAT") == 0)
+    {
+        const gchar *id;
+        id = g_hash_table_lookup (params, "ID");
+        remove_login1_seat (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL), id);
     }
     else if (strcmp (name, "LIST-SEATS") == 0)
     {
@@ -466,7 +646,7 @@ handle_command (const gchar *command)
                                               g_variant_new ("(ss)", "org.freedesktop.DisplayManager", "Seats"),
                                               G_VARIANT_TYPE ("(v)"),
                                               G_DBUS_CALL_FLAGS_NONE,
-                                              1000,
+                                              G_MAXINT,
                                               NULL,
                                               NULL);
 
@@ -502,7 +682,7 @@ handle_command (const gchar *command)
                                               g_variant_new ("(ss)", "org.freedesktop.DisplayManager", "Sessions"),
                                               G_VARIANT_TYPE ("(v)"),
                                               G_DBUS_CALL_FLAGS_NONE,
-                                              1000,
+                                              G_MAXINT,
                                               NULL,
                                               NULL);
 
@@ -522,55 +702,101 @@ handle_command (const gchar *command)
         check_status (status->str);
         g_string_free (status, TRUE);
     }
+    else if (strcmp (name, "SEAT-CAN-SWITCH") == 0)
+    {
+        GVariant *result, *value;
+        gchar *status;
+
+        result = g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
+                                              "org.freedesktop.DisplayManager",
+                                              "/org/freedesktop/DisplayManager/Seat0",
+                                              "org.freedesktop.DBus.Properties",
+                                              "Get",
+                                              g_variant_new ("(ss)", "org.freedesktop.DisplayManager.Seat", "CanSwitch"),
+                                              G_VARIANT_TYPE ("(v)"),
+                                              G_DBUS_CALL_FLAGS_NONE,
+                                              G_MAXINT,
+                                              NULL,
+                                              NULL);
+
+        g_variant_get (result, "(v)", &value);
+        status = g_strdup_printf ("RUNNER SEAT-CAN-SWITCH CAN-SWITCH=%s", g_variant_get_boolean (value) ? "TRUE" : "FALSE");
+        g_variant_unref (value);
+        g_variant_unref (result);
+        check_status (status);
+        g_free (status);
+    }
+    else if (strcmp (name, "SEAT-HAS-GUEST-ACCOUNT") == 0)
+    {
+        GVariant *result, *value;
+        gchar *status;
+
+        result = g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
+                                              "org.freedesktop.DisplayManager",
+                                              "/org/freedesktop/DisplayManager/Seat0",
+                                              "org.freedesktop.DBus.Properties",
+                                              "Get",
+                                              g_variant_new ("(ss)", "org.freedesktop.DisplayManager.Seat", "HasGuestAccount"),
+                                              G_VARIANT_TYPE ("(v)"),
+                                              G_DBUS_CALL_FLAGS_NONE,
+                                              G_MAXINT,
+                                              NULL,
+                                              NULL);
+
+        g_variant_get (result, "(v)", &value);
+        status = g_strdup_printf ("RUNNER SEAT-HAS-GUEST-ACCOUNT HAS-GUEST-ACCOUNT=%s", g_variant_get_boolean (value) ? "TRUE" : "FALSE");
+        g_variant_unref (value);
+        g_variant_unref (result);
+        check_status (status);
+        g_free (status);
+    }
     else if (strcmp (name, "SWITCH-TO-GREETER") == 0)
     {
-        g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
-                                     "org.freedesktop.DisplayManager",
-                                     "/org/freedesktop/DisplayManager/Seat0",
-                                     "org.freedesktop.DisplayManager.Seat",
-                                     "SwitchToGreeter",
-                                     g_variant_new ("()"),
-                                     G_VARIANT_TYPE ("()"),
-                                     G_DBUS_CALL_FLAGS_NONE,
-                                     1000,
-                                     NULL,
-                                     NULL);
-        check_status ("RUNNER SWITCH-TO-GREETER");
+        g_dbus_connection_call (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
+                                "org.freedesktop.DisplayManager",
+                                "/org/freedesktop/DisplayManager/Seat0",
+                                "org.freedesktop.DisplayManager.Seat",
+                                "SwitchToGreeter",
+                                g_variant_new ("()"),
+                                G_VARIANT_TYPE ("()"),
+                                G_DBUS_CALL_FLAGS_NONE,
+                                G_MAXINT,
+                                NULL,
+                                switch_to_greeter_done_cb,
+                                NULL);
     }
     else if (strcmp (name, "SWITCH-TO-USER") == 0)
     {
-        gchar *status_text, *username;
+        const gchar *username;
 
         username = g_hash_table_lookup (params, "USERNAME");
-        g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
-                                     "org.freedesktop.DisplayManager",
-                                     "/org/freedesktop/DisplayManager/Seat0",
-                                     "org.freedesktop.DisplayManager.Seat",
-                                     "SwitchToUser",
-                                     g_variant_new ("(ss)", username, ""),
-                                     G_VARIANT_TYPE ("()"),
-                                     G_DBUS_CALL_FLAGS_NONE,
-                                     1000,
-                                     NULL,
-                                     NULL);
-        status_text = g_strdup_printf ("RUNNER SWITCH-TO-USER USERNAME=%s", username);
-        check_status (status_text);
-        g_free (status_text);
+        g_dbus_connection_call (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
+                                "org.freedesktop.DisplayManager",
+                                "/org/freedesktop/DisplayManager/Seat0",
+                                "org.freedesktop.DisplayManager.Seat",
+                                "SwitchToUser",
+                                g_variant_new ("(ss)", username, ""),
+                                G_VARIANT_TYPE ("()"),
+                                G_DBUS_CALL_FLAGS_NONE,
+                                G_MAXINT,
+                                NULL,
+                                switch_to_user_done_cb,
+                                g_strdup (username));
     }
     else if (strcmp (name, "SWITCH-TO-GUEST") == 0)
     {
-        g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
-                                     "org.freedesktop.DisplayManager",
-                                     "/org/freedesktop/DisplayManager/Seat0",
-                                     "org.freedesktop.DisplayManager.Seat",
-                                     "SwitchToGuest",
-                                     g_variant_new ("(s)", ""),
-                                     G_VARIANT_TYPE ("()"),
-                                     G_DBUS_CALL_FLAGS_NONE,
-                                     1000,
-                                     NULL,
-                                     NULL);
-        check_status ("RUNNER SWITCH-TO-GUEST");
+        g_dbus_connection_call (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
+                                "org.freedesktop.DisplayManager",
+                                "/org/freedesktop/DisplayManager/Seat0",
+                                "org.freedesktop.DisplayManager.Seat",
+                                "SwitchToGuest",
+                                g_variant_new ("(s)", ""),
+                                G_VARIANT_TYPE ("()"),
+                                G_DBUS_CALL_FLAGS_NONE,
+                                G_MAXINT,
+                                NULL,
+                                switch_to_guest_done_cb,
+                                NULL);
     }
     else if (strcmp (name, "STOP-DAEMON") == 0)
         stop_process (lightdm_process);
@@ -701,17 +927,18 @@ handle_command (const gchar *command)
                 user->xsession = g_strdup (g_hash_table_lookup (params, "SESSION"));
                 g_string_append_printf (status_text, " SESSION=%s", user->xsession);
             }
+
+            g_dbus_connection_emit_signal (accounts_connection,
+                                           NULL,
+                                           user->path,
+                                           "org.freedesktop.Accounts.User",
+                                           "Changed",
+                                           g_variant_new ("()"),
+                                           &error);
         }
         else
             g_warning ("Unknown user %s", username);
 
-        g_dbus_connection_emit_signal (accounts_connection,
-                                       NULL,
-                                       user->path,
-                                       "org.freedesktop.Accounts.User",
-                                       "Changed",
-                                       g_variant_new ("()"),
-                                       &error);
         if (error)
             g_warning ("Failed to emit Changed: %s", error->message);
         g_clear_error (&error);
@@ -735,10 +962,32 @@ handle_command (const gchar *command)
         check_status (status_text);
         g_free (status_text);
     }
+    else if (strcmp (name, "UNLOCK-SESSION") == 0)
+    {
+        gchar *status_text, *id;
+        Login1Session *session;
+        
+        id = g_hash_table_lookup (params, "SESSION");
+        session = find_login1_session (id);
+        if (session)
+        {
+            if (!session->locked)
+                g_warning ("Session %s is not locked", id);
+            session->locked = FALSE;
+        }
+        else
+            g_warning ("Unknown session %s", id);
+
+        status_text = g_strdup_printf ("RUNNER UNLOCK-SESSION SESSION=%s", id);
+        check_status (status_text);
+        g_free (status_text);
+    }
     /* Forward to external processes */
     else if (g_str_has_prefix (name, "SESSION-") ||
              g_str_has_prefix (name, "GREETER-") ||
              g_str_has_prefix (name, "XSERVER-") ||
+             g_str_has_prefix (name, "XMIR-") ||
+             g_str_has_prefix (name, "XVNC-") ||
              strcmp (name, "UNITY-SYSTEM-COMPOSITOR") == 0)
     {
         GList *link;
@@ -794,10 +1043,12 @@ status_timeout_cb (gpointer data)
 {
     ScriptLine *line;
 
+    status_timeout = 0;
+
     line = get_script_line (NULL);
     fail ("(timeout)", line ? line->text : NULL);
 
-    return FALSE;
+    return G_SOURCE_REMOVE;
 }
 
 static void
@@ -837,7 +1088,8 @@ check_status (const gchar *status)
     line->done = TRUE;
 
     /* Restart timeout */
-    g_source_remove (status_timeout);
+    if (status_timeout)
+        g_source_remove (status_timeout);
     status_timeout = g_timeout_add (status_timeout_ms, status_timeout_cb, NULL);
 
     run_commands ();
@@ -855,7 +1107,12 @@ status_message_cb (GSocket *socket, GIOCondition condition, StatusClient *client
     if (n_read > 0)
         n_read = g_socket_receive (socket, buffer, length, NULL, &error);
     if (error)
-        g_warning ("Error reading from socket: %s", error->message);
+    {
+        if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED))
+            n_read = 0;
+        else
+            g_warning ("Error reading from socket: %s", error->message);
+    }
     g_clear_error (&error);
     if (n_read == 0)
     {
@@ -1008,7 +1265,7 @@ upower_name_acquired_cb (GDBusConnection *connection,
 
     service_count--;
     if (service_count == 0)
-        run_lightdm ();
+        ready ();
 }
 
 static void
@@ -1026,7 +1283,7 @@ start_upower_daemon (void)
 }
 
 static CKSession *
-open_ck_session (GVariant *params)
+open_ck_session (GDBusConnection *connection, GVariant *params)
 {
     CKSession *session;
     GString *cookie;
@@ -1053,7 +1310,7 @@ open_ck_session (GVariant *params)
     session->cookie = cookie->str;
     g_string_free (cookie, FALSE);
     session->path = g_strdup_printf ("/org/freedesktop/ConsoleKit/Session%d", ck_session_index++);
-    session->id = g_dbus_connection_register_object (ck_connection,
+    session->id = g_dbus_connection_register_object (connection,
                                                      session->path,
                                                      ck_session_info->interfaces[0],
                                                      &ck_session_vtable,
@@ -1093,12 +1350,12 @@ handle_ck_call (GDBusConnection       *connection,
     {
         GVariantBuilder params;
         g_variant_builder_init (&params, G_VARIANT_TYPE ("a(sv)"));
-        CKSession *session = open_ck_session (g_variant_builder_end (&params));
+        CKSession *session = open_ck_session (connection, g_variant_builder_end (&params));
         g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", session->cookie));
     }
     else if (strcmp (method_name, "OpenSessionWithParameters") == 0)
     {
-        CKSession *session = open_ck_session (g_variant_get_child_value (parameters, 0));
+        CKSession *session = open_ck_session (connection, g_variant_get_child_value (parameters, 0));
         g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", session->cookie));
     }
     else if (strcmp (method_name, "GetSessionForCookie") == 0)
@@ -1111,7 +1368,7 @@ handle_ck_call (GDBusConnection       *connection,
         for (link = ck_sessions; link; link = link->next)
         {
             CKSession *session = link->data;
-            if (strcmp (session->cookie, cookie) != 0)
+            if (strcmp (session->cookie, cookie) == 0)
             {
                 g_dbus_method_invocation_return_value (invocation, g_variant_new ("(o)", session->path));
                 return;
@@ -1146,8 +1403,12 @@ handle_ck_session_call (GDBusConnection       *connection,
 {
     CKSession *session = user_data;
 
-    if (strcmp (method_name, "Lock") == 0)
-    { 
+    if (strcmp (method_name, "GetXDGRuntimeDir") == 0 && !g_key_file_get_boolean (config, "test-runner-config", "ck-no-xdg-runtime", NULL))
+    {
+        g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "/run/console-kit"));
+    }
+    else if (strcmp (method_name, "Lock") == 0)
+    {
         if (!session->locked)
             check_status ("CONSOLE-KIT LOCK-SESSION");
         session->locked = TRUE;
@@ -1160,6 +1421,14 @@ handle_ck_session_call (GDBusConnection       *connection,
         session->locked = FALSE;
         g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
     }
+    else if (strcmp (method_name, "Activate") == 0)
+    {
+        gchar *status = g_strdup_printf ("CONSOLE-KIT ACTIVATE-SESSION SESSION=%s", session->cookie);
+        check_status (status);
+        g_free (status);
+
+        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
+    }
     else
         g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such method: %s", method_name);
 }
@@ -1207,25 +1476,38 @@ ck_name_acquired_cb (GDBusConnection *connection,
     {
         handle_ck_call,
     };
+    const gchar *ck_session_interface_old =
+        "<node>"
+        "  <interface name='org.freedesktop.ConsoleKit.Session'>"
+        "    <method name='Lock'/>"
+        "    <method name='Unlock'/>"
+        "    <method name='Activate'/>"
+        "  </interface>"
+        "</node>";
     const gchar *ck_session_interface =
         "<node>"
         "  <interface name='org.freedesktop.ConsoleKit.Session'>"
+        "    <method name='GetXDGRuntimeDir'>"
+        "      <arg name='dir' direction='out' type='s'/>"
+        "    </method>"
         "    <method name='Lock'/>"
         "    <method name='Unlock'/>"
+        "    <method name='Activate'/>"
         "  </interface>"
         "</node>";
     GDBusNodeInfo *ck_info;
     GError *error = NULL;
 
-    ck_connection = connection;
-
     ck_info = g_dbus_node_info_new_for_xml (ck_interface, &error);
     if (error)
         g_warning ("Failed to parse D-Bus interface: %s", error->message);
     g_clear_error (&error);
     if (!ck_info)
         return;
-    ck_session_info = g_dbus_node_info_new_for_xml (ck_session_interface, &error);
+    if (g_key_file_get_boolean (config, "test-runner-config", "ck-no-xdg-runtime", NULL))
+        ck_session_info = g_dbus_node_info_new_for_xml (ck_session_interface_old, &error);
+    else
+        ck_session_info = g_dbus_node_info_new_for_xml (ck_session_interface, &error);  
     if (error)
         g_warning ("Failed to parse D-Bus interface: %s", error->message);
     g_clear_error (&error);
@@ -1244,7 +1526,7 @@ ck_name_acquired_cb (GDBusConnection *connection,
 
     service_count--;
     if (service_count == 0)
-        run_lightdm ();
+        ready ();
 }
 
 static void
@@ -1254,13 +1536,173 @@ start_console_kit_daemon (void)
     g_bus_own_name (G_BUS_TYPE_SYSTEM,
                     "org.freedesktop.ConsoleKit",
                     G_BUS_NAME_OWNER_FLAGS_NONE,
-                    ck_name_acquired_cb,
                     NULL,
+                    ck_name_acquired_cb,
                     NULL,
                     NULL,
                     NULL);
 }
 
+static void
+handle_login1_seat_call (GDBusConnection       *connection,
+                         const gchar           *sender,
+                         const gchar           *object_path,
+                         const gchar           *interface_name,
+                         const gchar           *method_name,
+                         GVariant              *parameters,
+                         GDBusMethodInvocation *invocation,
+                         gpointer               user_data)
+{
+    g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such method: %s", method_name);
+}
+
+static GVariant *
+handle_login1_seat_get_property (GDBusConnection       *connection,
+                                 const gchar           *sender,
+                                 const gchar           *object_path,
+                                 const gchar           *interface_name,
+                                 const gchar           *property_name,
+                                 GError               **error,
+                                 gpointer               user_data)
+{
+    Login1Seat *seat = user_data;
+
+    if (strcmp (property_name, "CanGraphical") == 0)
+        return g_variant_new_boolean (seat->can_graphical);
+    else if (strcmp (property_name, "CanMultiSession") == 0)
+        return g_variant_new_boolean (seat->can_multi_session);
+    else if (strcmp (property_name, "Id") == 0)
+        return g_variant_new_string (seat->id);
+    else if (strcmp (property_name, "ActiveSession") == 0)
+    {
+        if (seat->active_session)
+        {
+            gchar *path;
+            GVariant *ret;
+            
+            path = g_strdup_printf ("/org/freedesktop/login1/session/%s", seat->active_session);
+            ret = g_variant_new ("(so)", seat->active_session, path);
+            g_free (path);
+
+            return ret;
+        }
+        else 
+            return NULL;
+    }
+    else
+        return NULL;
+}
+
+static Login1Seat *
+add_login1_seat (GDBusConnection *connection, const gchar *id, gboolean emit_signal)
+{
+    Login1Seat *seat;
+    GError *error = NULL;
+    GDBusNodeInfo *login1_seat_info;
+
+    const gchar *login1_seat_interface =
+        "<node>"
+        "  <interface name='org.freedesktop.login1.Seat'>"
+        "    <property name='CanGraphical' type='b' access='read'/>"
+        "    <property name='CanMultiSession' type='b' access='read'/>"
+        "    <property name='ActiveSession' type='(so)' access='read'/>"
+        "    <property name='Id' type='s' access='read'/>"
+        "  </interface>"
+        "</node>";
+    static const GDBusInterfaceVTable login1_seat_vtable =
+    {
+        handle_login1_seat_call,
+        handle_login1_seat_get_property,
+    };
+
+    seat = g_malloc0 (sizeof (Login1Seat));
+    login1_seats = g_list_append (login1_seats, seat);
+    seat->id = g_strdup (id);
+    seat->path = g_strdup_printf ("/org/freedesktop/login1/seat/%s", seat->id);
+    seat->can_graphical = TRUE;
+    seat->can_multi_session = TRUE;
+    seat->active_session = NULL;
+
+    login1_seat_info = g_dbus_node_info_new_for_xml (login1_seat_interface, &error);
+    if (error)
+        g_warning ("Failed to parse login1 seat D-Bus interface: %s", error->message);
+    g_clear_error (&error);
+    if (!login1_seat_info)
+        return NULL;
+
+    g_dbus_connection_register_object (connection,
+                                       seat->path,
+                                       login1_seat_info->interfaces[0],
+                                       &login1_seat_vtable,
+                                       seat,
+                                       NULL,
+                                       &error);
+    if (error)
+        g_warning ("Failed to register login1 seat: %s", error->message);
+    g_clear_error (&error);
+    g_dbus_node_info_unref (login1_seat_info);
+
+    if (emit_signal)
+    {
+        g_dbus_connection_emit_signal (connection,
+                                       NULL,
+                                       "/org/freedesktop/login1",
+                                       "org.freedesktop.login1.Manager",
+                                       "SeatNew",
+                                       g_variant_new ("(so)", seat->id, seat->path),
+                                       &error);
+        if (error)
+            g_warning ("Failed to emit SeatNew: %s", error->message);
+        g_clear_error (&error);
+    }
+
+    return seat;
+}
+
+static Login1Seat *
+find_login1_seat (const gchar *id)
+{
+    Login1Seat *seat;
+    GList *link;
+
+    for (link = login1_seats; link; link = link->next)
+    {
+        seat = link->data;
+        if (strcmp (seat->id, id) == 0)
+            return seat;
+    }
+
+    return NULL;
+}
+
+static void
+remove_login1_seat (GDBusConnection *connection, const gchar *id)
+{
+    Login1Seat *seat;
+    GError *error = NULL;
+
+    seat = find_login1_seat (id);
+    if (!seat)
+        return;
+
+    g_dbus_connection_emit_signal (connection,
+                                   NULL,
+                                   "/org/freedesktop/login1",
+                                   "org.freedesktop.login1.Manager",
+                                   "SeatRemoved",
+                                   g_variant_new ("(so)", seat->id, seat->path),
+                                   &error);
+    if (error)
+        g_warning ("Failed to emit SeatNew: %s", error->message);
+    g_clear_error (&error);
+
+    login1_seats = g_list_remove (login1_seats, seat);
+    g_free (seat->id);
+    g_free (seat->path);
+    g_free (seat->active_session);
+    g_free (seat);
+}
+
 static void
 handle_login1_session_call (GDBusConnection       *connection,
                             const gchar           *sender,
@@ -1271,29 +1713,12 @@ handle_login1_session_call (GDBusConnection       *connection,
                             GDBusMethodInvocation *invocation,
                             gpointer               user_data)
 {
-    Login1Session *session = user_data;
-
-    if (strcmp (method_name, "Lock") == 0)
-    {
-        if (!session->locked)
-            check_status ("LOGIN1 LOCK-SESSION");
-        session->locked = TRUE;
-        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
-    }
-    else if (strcmp (method_name, "Unlock") == 0)
-    {
-        if (session->locked)
-            check_status ("LOGIN1 UNLOCK-SESSION");
-        session->locked = FALSE;
-        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
-    }
-    else
-        g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such method: %s", method_name);
+    /*Login1Session *session = user_data;*/
+    g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such method: %s", method_name);
 }
 
 static Login1Session *
-open_login1_session (GDBusConnection *connection,
-                     GVariant *params)
+create_login1_session (GDBusConnection *connection)
 {
     Login1Session *session;
     GError *error = NULL;
@@ -1302,8 +1727,6 @@ open_login1_session (GDBusConnection *connection,
     const gchar *login1_session_interface =
         "<node>"
         "  <interface name='org.freedesktop.login1.Session'>"
-        "    <method name='Lock'/>"
-        "    <method name='Unlock'/>"
         "  </interface>"
         "</node>";
     static const GDBusInterfaceVTable login1_session_vtable =
@@ -1314,16 +1737,12 @@ open_login1_session (GDBusConnection *connection,
     session = g_malloc0 (sizeof (Login1Session));
     login1_sessions = g_list_append (login1_sessions, session);
 
-    session->path = g_strdup_printf("/org/freedesktop/login1/Session/c%d",
-                                    login1_session_index++);
-
+    session->id = g_strdup_printf ("c%d", login1_session_index++);
+    session->path = g_strdup_printf ("/org/freedesktop/login1/Session/%s", session->id);
 
-
-    login1_session_info = g_dbus_node_info_new_for_xml (login1_session_interface,
-                                                        &error);
+    login1_session_info = g_dbus_node_info_new_for_xml (login1_session_interface, &error);
     if (error)
-        g_warning ("Failed to parse login1 session D-Bus interface: %s",
-                   error->message);
+        g_warning ("Failed to parse login1 session D-Bus interface: %s", error->message);
     g_clear_error (&error);
     if (!login1_session_info)
         return NULL;
@@ -1343,6 +1762,20 @@ open_login1_session (GDBusConnection *connection,
     return session;
 }
 
+static Login1Session *
+find_login1_session (const gchar *id)
+{
+    GList *link;
+
+    for (link = login1_sessions; link; link = link->next)
+    {
+        Login1Session *session = link->data;
+        if (strcmp (session->id, id) == 0)
+            return session;
+    }
+
+    return NULL;
+}
 
 static void
 handle_login1_call (GDBusConnection       *connection,
@@ -1354,34 +1787,89 @@ handle_login1_call (GDBusConnection       *connection,
                     GDBusMethodInvocation *invocation,
                     gpointer               user_data)
 {
-
-    if (strcmp (method_name, "GetSessionByPID") == 0)
+    if (strcmp (method_name, "ListSeats") == 0)
     {
-        /* Look for a session with our PID, and create one if we don't have one
-           already. */
+        GVariantBuilder seats;
         GList *link;
-        guint pid;
-        Login1Session *ret = NULL;
 
-        g_variant_get (parameters, "(u)", &pid);
+        g_variant_builder_init (&seats, G_VARIANT_TYPE ("a(so)"));
+        for (link = login1_seats; link; link = link->next)
+        {
+            Login1Seat *seat = link->data;
+            g_variant_builder_add (&seats, "(so)", seat->id, seat->path);
+        }
+        g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a(so))", &seats));
+    }
+    else if (strcmp (method_name, "CreateSession") == 0)
+    {
+        /* Note: this is not the full CreateSession as used by logind, we just
+           need one so our fake PAM stack can communicate with this service */
+        Login1Session *session = create_login1_session (connection);
+        g_dbus_method_invocation_return_value (invocation, g_variant_new ("(so)", session->id, session->path));
 
-        for (link = login1_sessions; link; link = link->next)
+    }
+    else if (strcmp (method_name, "LockSession") == 0)
+    {
+        const gchar *id;
+        Login1Session *session;
+
+        g_variant_get (parameters, "(&s)", &id);
+        session = find_login1_session (id);
+        if (!session)
         {
-            Login1Session *session;
-            session = link->data;
-            if (session->pid == pid)
-            {
-                ret = session;
-                break;
-            }
+            g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such session: %s", id);
+            return;
         }
-        /* Not found */
-        if (!ret)
-            ret = open_login1_session (connection, parameters);
 
-        g_dbus_method_invocation_return_value (invocation,
-                                               g_variant_new("(o)", ret->path));
+        if (!session->locked)
+        {
+            gchar *status = g_strdup_printf ("LOGIN1 LOCK-SESSION SESSION=%s", id);
+            check_status (status);
+            g_free (status);
+        }
+        session->locked = TRUE;
+        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
+    }
+    else if (strcmp (method_name, "UnlockSession") == 0)
+    {
+        const gchar *id;
+        Login1Session *session;
 
+        g_variant_get (parameters, "(&s)", &id);
+        session = find_login1_session (id);
+        if (!session)
+        {
+            g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such session: %s", id);
+            return;
+        }
+
+        if (session->locked)
+        {
+            gchar *status = g_strdup_printf ("LOGIN1 UNLOCK-SESSION SESSION=%s", id);
+            check_status (status);
+            g_free (status);
+        }
+        session->locked = FALSE;
+        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
+    }
+    else if (strcmp (method_name, "ActivateSession") == 0)
+    {
+        const gchar *id;
+        Login1Session *session;
+
+        g_variant_get (parameters, "(&s)", &id);
+        session = find_login1_session (id);
+        if (!session)
+        {
+            g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such session: %s", id);
+            return;
+        }
+
+        gchar *status = g_strdup_printf ("LOGIN1 ACTIVATE-SESSION SESSION=%s", id);
+        check_status (status);
+        g_free (status);
+
+        g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
     }
     else if (strcmp (method_name, "CanReboot") == 0)
     {
@@ -1443,9 +1931,21 @@ login1_name_acquired_cb (GDBusConnection *connection,
     const gchar *login1_interface =
         "<node>"
         "  <interface name='org.freedesktop.login1.Manager'>"
-        "    <method name='GetSessionByPID'>"
-        "      <arg name='pid' type='u' direction='in'/>"
-        "      <arg name='session' type='o' direction='out'/>"
+        "    <method name='ListSeats'>"
+        "      <arg name='seats' type='a(so)' direction='out'/>"
+        "    </method>"
+        "    <method name='CreateSession'>"
+        "      <arg name='id' type='s' direction='out'/>"
+        "      <arg name='path' type='o' direction='out'/>"
+        "    </method>"
+        "    <method name='LockSession'>"
+        "      <arg name='id' type='s' direction='in'/>"
+        "    </method>"
+        "    <method name='UnlockSession'>"
+        "      <arg name='id' type='s' direction='in'/>"
+        "    </method>"
+        "    <method name='ActivateSession'>"
+        "      <arg name='id' type='s' direction='in'/>"
         "    </method>"
         "    <method name='CanReboot'>"
         "      <arg name='result' direction='out' type='s'/>"
@@ -1471,6 +1971,12 @@ login1_name_acquired_cb (GDBusConnection *connection,
         "    <method name='Hibernate'>"
         "      <arg name='interactive' direction='in' type='b'/>"
         "    </method>"
+        "    <signal name='SeatNew'>"
+        "      <arg name='seat' type='so'/>"
+        "    </signal>"
+        "    <signal name='SeatRemoved'>"
+        "      <arg name='seat' type='so'/>"
+        "    </signal>"
         "  </interface>"
         "</node>";
     static const GDBusInterfaceVTable login1_vtable =
@@ -1478,6 +1984,7 @@ login1_name_acquired_cb (GDBusConnection *connection,
         handle_login1_call,
     };
     GDBusNodeInfo *login1_info;
+    Login1Seat *seat0;
     GError *error = NULL;
 
     login1_info = g_dbus_node_info_new_for_xml (login1_interface, &error);
@@ -1497,9 +2004,16 @@ login1_name_acquired_cb (GDBusConnection *connection,
     g_clear_error (&error);
     g_dbus_node_info_unref (login1_info);
 
+    /* We always have seat0 */
+    seat0 = add_login1_seat (connection, "seat0", FALSE);
+    if (g_key_file_has_key (config, "test-runner-config", "seat0-can-graphical", NULL))
+        seat0->can_graphical = g_key_file_get_boolean (config, "test-runner-config", "seat0-can-graphical", NULL);
+    if (g_key_file_has_key (config, "test-runner-config", "seat0-can-multi-session", NULL))
+        seat0->can_multi_session = g_key_file_get_boolean (config, "test-runner-config", "seat0-can-multi-session", NULL);
+
     service_count--;
     if (service_count == 0)
-        run_lightdm ();
+        ready ();
 }
 
 static void
@@ -1509,8 +2023,8 @@ start_login1_daemon (void)
     g_bus_own_name (G_BUS_TYPE_SYSTEM,
                     "org.freedesktop.login1",
                     G_BUS_NAME_OWNER_FLAGS_NONE,
-                    login1_name_acquired_cb,
                     NULL,
+                    login1_name_acquired_cb,
                     NULL,
                     NULL,
                     NULL);
@@ -1527,7 +2041,7 @@ get_accounts_user_by_uid (guint uid)
         if (u->uid == uid)
             return u;
     }
-  
+
     return NULL;
 }
 
@@ -1901,7 +2415,7 @@ accounts_name_acquired_cb (GDBusConnection *connection,
 
     service_count--;
     if (service_count == 0)
-        run_lightdm ();
+        ready ();
 }
 
 static void
@@ -1919,50 +2433,87 @@ start_accounts_service_daemon (void)
 }
 
 static void
-run_lightdm (void)
+ready (void)
 {
-    GString *command_line;
-    gchar **lightdm_argv;
-    pid_t lightdm_pid;
-    GError *error = NULL;
-
     run_commands ();
+}
 
-    status_timeout = g_timeout_add (status_timeout_ms, status_timeout_cb, NULL);
+static gboolean
+signal_cb (gpointer user_data)
+{
+    g_print ("Caught signal, quitting\n");
+    quit (EXIT_FAILURE);
+    return FALSE;
+}
 
-    command_line = g_string_new ("lightdm");
-    if (getenv ("DEBUG"))
-        g_string_append (command_line, " --debug");
-    g_string_append_printf (command_line, " --cache-dir %s/cache", temp_dir);
+static void
+properties_changed_cb (GDBusConnection *connection,
+                       const gchar *sender_name,
+                       const gchar *object_path,
+                       const gchar *interface_name,
+                       const gchar *signal_name,
+                       GVariant *parameters,
+                       gpointer user_data)
+{
+    const gchar *interface, *name;
+    GString *status;
+    GVariant *value;
+    GVariantIter *changed_properties, *invalidated_properties;
+    int i;
 
-    test_runner_command = g_strdup_printf ("PATH=%s LD_PRELOAD=%s LD_LIBRARY_PATH=%s LIGHTDM_TEST_ROOT=%s DBUS_SESSION_BUS_ADDRESS=%s %s\n",
-                                           g_getenv ("PATH"), g_getenv ("LD_PRELOAD"), g_getenv ("LD_LIBRARY_PATH"), g_getenv ("LIGHTDM_TEST_ROOT"), g_getenv ("DBUS_SESSION_BUS_ADDRESS"),
-                                           command_line->str);
+    g_variant_get (parameters, "(&sa{sv}as)", &interface, &changed_properties, &invalidated_properties);
 
-    if (!g_shell_parse_argv (command_line->str, NULL, &lightdm_argv, &error))
+    status = g_string_new ("RUNNER DBUS-PROPERTIES-CHANGED");
+    g_string_append_printf (status, " PATH=%s", object_path);
+    g_string_append_printf (status, " INTERFACE=%s", interface);
+    for (i = 0; g_variant_iter_loop (changed_properties, "{&sv}", &name, &value); i++)
     {
-        g_warning ("Error parsing command line: %s", error->message);
-        quit (EXIT_FAILURE);
-    }
-    g_clear_error (&error);
+        if (i == 0)
+            g_string_append (status, " CHANGED=");
+        else
+            g_string_append (status, ",");
+        g_string_append (status, name);
+        if (g_variant_is_of_type (value, G_VARIANT_TYPE ("ao")))
+        {
+            GVariantIter iter;
+            const gchar *path;
 
-    if (!g_spawn_async (NULL, lightdm_argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, NULL, NULL, &lightdm_pid, &error))
+            g_variant_iter_init (&iter, value);
+            while (g_variant_iter_loop (&iter, "&o", &path))
+                g_string_append_printf (status, ":%s", path);
+        }
+    }
+    for (i = 0; g_variant_iter_loop (invalidated_properties, "&s", &name); i++)
     {
-        g_warning ("Error launching LightDM: %s", error->message);
-        quit (EXIT_FAILURE);
+        if (i == 0)
+            g_string_append (status, " INVALIDATED=");
+        else
+            g_string_append (status, ",");
+        g_string_append (status, name);
     }
-    g_clear_error (&error);
-    lightdm_process = watch_process (lightdm_pid);
 
-    check_status ("RUNNER DAEMON-START");
+    check_status (status->str);
+    g_string_free (status, TRUE);
 }
 
-static gboolean
-signal_cb (gpointer user_data)
+static void
+dbus_signal_cb (GDBusConnection *connection,
+                const gchar *sender_name,
+                const gchar *object_path,
+                const gchar *interface_name,
+                const gchar *signal_name,
+                GVariant *parameters,
+                gpointer user_data)
 {
-    g_print ("Caught signal, quitting\n");
-    quit (EXIT_FAILURE);
-    return FALSE;
+    GString *status;
+
+    status = g_string_new ("RUNNER DBUS-SIGNAL");
+    g_string_append_printf (status, " PATH=%s", object_path);
+    g_string_append_printf (status, " INTERFACE=%s", interface_name);
+    g_string_append_printf (status, " NAME=%s", signal_name);
+
+    check_status (status->str);
+    g_string_free (status, TRUE);
 }
 
 int
@@ -2012,6 +2563,10 @@ main (int argc, char **argv)
     /* Don't contact our X server */
     g_unsetenv ("DISPLAY");
 
+    /* Don't let XDG vars from system affect tests */
+    g_unsetenv ("XDG_CONFIG_DIRS");
+    g_unsetenv ("XDG_DATA_DIRS");
+
     /* Override system calls */
     ld_preload = g_build_filename (BUILDDIR, "tests", "src", ".libs", "libsystem.so", NULL);
     g_setenv ("LD_PRELOAD", ld_preload, TRUE);
@@ -2047,7 +2602,7 @@ main (int argc, char **argv)
         if (!g_file_test (temp_dir, G_FILE_TEST_EXISTS))
             break;
         i++;
-    }  
+    }
     g_mkdir_with_parents (temp_dir, 0755);
     g_setenv ("LIGHTDM_TEST_ROOT", temp_dir, TRUE);
 
@@ -2091,6 +2646,7 @@ main (int argc, char **argv)
 
     /* Set up a skeleton file system */
     g_mkdir_with_parents (g_strdup_printf ("%s/etc", temp_dir), 0755);
+    g_mkdir_with_parents (g_strdup_printf ("%s/run", temp_dir), 0755);
     g_mkdir_with_parents (g_strdup_printf ("%s/usr/share", temp_dir), 0755);
     g_mkdir_with_parents (g_strdup_printf ("%s/usr/share/lightdm/sessions", temp_dir), 0755);
     g_mkdir_with_parents (g_strdup_printf ("%s/usr/share/lightdm/remote-sessions", temp_dir), 0755);
@@ -2105,6 +2661,8 @@ main (int argc, char **argv)
     if (!g_key_file_has_key (config, "test-runner-config", "have-config", NULL) || g_key_file_get_boolean (config, "test-runner-config", "have-config", NULL))
         if (system (g_strdup_printf ("cp %s %s/etc/lightdm/lightdm.conf", config_path, temp_dir)))
             perror ("Failed to copy configuration");
+    if (system (g_strdup_printf ("cp %s/tests/data/keys.conf %s/etc/lightdm/", SRCDIR, temp_dir)))
+        perror ("Failed to copy key configuration");
 
     additional_system_config = g_key_file_get_string (config, "test-runner-config", "additional-system-config", NULL);
     if (additional_system_config)
@@ -2125,11 +2683,11 @@ main (int argc, char **argv)
     {
         gchar **files;
 
-        g_mkdir_with_parents (g_strdup_printf ("%s/etc/lightdm/lightdm.conf.d", temp_dir), 0755);
+        g_mkdir_with_parents (g_strdup_printf ("%s/etc/xdg/lightdm/lightdm.conf.d", temp_dir), 0755);
 
         files = g_strsplit (additional_config, " ", -1);
         for (i = 0; files[i]; i++)
-            if (system (g_strdup_printf ("cp %s/tests/scripts/%s %s/etc/lightdm/lightdm.conf.d", SRCDIR, files[i], temp_dir)))
+            if (system (g_strdup_printf ("cp %s/tests/scripts/%s %s/etc/xdg/lightdm/lightdm.conf.d", SRCDIR, files[i], temp_dir)))
                 perror ("Failed to copy configuration");
         g_strfreev (files);
     }
@@ -2361,6 +2919,31 @@ main (int argc, char **argv)
     if (!g_key_file_get_boolean (config, "test-runner-config", "disable-accounts-service", NULL))
         start_accounts_service_daemon ();
 
+    /* Listen for daemon bus events */
+    if (g_key_file_get_boolean (config, "test-runner-config", "log-dbus", NULL))
+    {
+        g_dbus_connection_signal_subscribe (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
+                                            "org.freedesktop.DisplayManager",
+                                            "org.freedesktop.DBus.Properties",
+                                            "PropertiesChanged",
+                                            NULL,
+                                            NULL,
+                                            G_DBUS_SIGNAL_FLAGS_NONE,
+                                            properties_changed_cb,
+                                            NULL,
+                                            NULL);
+        g_dbus_connection_signal_subscribe (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
+                                            "org.freedesktop.DisplayManager",
+                                            "org.freedesktop.DisplayManager",
+                                            NULL,
+                                            NULL,
+                                            NULL,
+                                            G_DBUS_SIGNAL_FLAGS_NONE,
+                                            dbus_signal_cb,
+                                            NULL,
+                                            NULL);
+    }
+
     g_main_loop_run (loop);
 
     return EXIT_FAILURE;