summary refs log tree commit diff
path: root/libnm/tests
diff options
context:
space:
mode:
Diffstat (limited to 'libnm/tests')
-rw-r--r--libnm/tests/meson.build2
-rw-r--r--libnm/tests/test-libnm.c45
-rw-r--r--libnm/tests/test-nm-client.c4
-rw-r--r--libnm/tests/test-remote-settings-client.c16
-rw-r--r--libnm/tests/test-secret-agent.c313
5 files changed, 252 insertions, 128 deletions
diff --git a/libnm/tests/meson.build b/libnm/tests/meson.build
index 76c3b287..59fb771d 100644
--- a/libnm/tests/meson.build
+++ b/libnm/tests/meson.build
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1+
+
 test_units = [
   ['test-libnm', 30],
   ['test-nm-client', 90],
diff --git a/libnm/tests/test-libnm.c b/libnm/tests/test-libnm.c
index 345fbb07..90d0cf0d 100644
--- a/libnm/tests/test-libnm.c
+++ b/libnm/tests/test-libnm.c
@@ -22,6 +22,7 @@
 #include "nm-libnm-utils.h"
 #include "nm-object.h"
 #include "nm-vpn-service-plugin.h"
+#include "nm-libnm-core-intern/nm-libnm-core-utils.h"
 
 #include "nm-utils/nm-test-utils.h"
 
@@ -3064,6 +3065,49 @@ test_dbus_meta_types (void)
 		g_assert (meta_iface->get_type_fcn() == d->gtype);
 	}
 }
+
+/*****************************************************************************/
+
+static void
+test_nm_auth_permissions (void)
+{
+	int i, j;
+
+	G_STATIC_ASSERT (G_N_ELEMENTS (nm_auth_permission_names_by_idx) == NM_CLIENT_PERMISSION_LAST);
+	G_STATIC_ASSERT (G_N_ELEMENTS (nm_auth_permission_sorted) == NM_CLIENT_PERMISSION_LAST);
+
+	for (i = 0; i < NM_CLIENT_PERMISSION_LAST; i++) {
+		g_assert (nm_auth_permission_names_by_idx[i]);
+		g_assert (NM_STR_HAS_PREFIX (nm_auth_permission_names_by_idx[i], "org.freedesktop.NetworkManager."));
+		g_assert_cmpint (nm_auth_permission_sorted[i], >, 0);
+		g_assert_cmpint (nm_auth_permission_sorted[i], <=, NM_CLIENT_PERMISSION_LAST);
+		for (j = i + 1; j < NM_CLIENT_PERMISSION_LAST; j++) {
+			g_assert_cmpint (nm_auth_permission_sorted[i], !=, nm_auth_permission_sorted[j]);
+			g_assert_cmpstr (nm_auth_permission_names_by_idx[i], !=, nm_auth_permission_names_by_idx[j]);
+		}
+	}
+	for (i = 1; i < NM_CLIENT_PERMISSION_LAST; i++) {
+		NMClientPermission a = nm_auth_permission_sorted[i - 1];
+		NMClientPermission b = nm_auth_permission_sorted[i];
+		const char *s_a = nm_auth_permission_names_by_idx[a - 1];
+		const char *s_b = nm_auth_permission_names_by_idx[b - 1];
+
+		g_assert_cmpstr (s_a, <, s_b);
+		g_assert (a != b);
+		g_assert (s_a != s_b);
+	}
+	for (i = 1; i <= NM_CLIENT_PERMISSION_LAST; i++) {
+		const char *s = nm_auth_permission_to_string (i);
+
+		g_assert_cmpstr (s, ==, nm_auth_permission_names_by_idx[i - 1]);
+		g_assert (s == nm_auth_permission_names_by_idx[i - 1]);
+		g_assert_cmpint (nm_auth_permission_from_string (s), ==, i);
+	}
+	return;
+	for (i = 0; i < NM_CLIENT_PERMISSION_LAST; i++)
+		g_assert_cmpint (nm_auth_permission_from_string (nm_auth_permission_names_by_idx[i]), ==, i + 1);
+}
+
 /*****************************************************************************/
 
 NMTST_DEFINE ();
@@ -3078,6 +3122,7 @@ int main (int argc, char **argv)
 	g_test_add_func ("/libnm/general/test_types", test_types);
 	g_test_add_func ("/libnm/general/test_nml_dbus_meta", test_nml_dbus_meta);
 	g_test_add_func ("/libnm/general/test_dbus_meta_types", test_dbus_meta_types);
+	g_test_add_func ("/libnm/general/test_nm_auth_permissions", test_nm_auth_permissions);
 
 	return g_test_run ();
 }
diff --git a/libnm/tests/test-nm-client.c b/libnm/tests/test-nm-client.c
index afcc4962..3d63e1ce 100644
--- a/libnm/tests/test-nm-client.c
+++ b/libnm/tests/test-nm-client.c
@@ -364,7 +364,7 @@ test_wifi_ap_added_removed (void)
 	                              NULL,
 	                              &error);
 	g_assert_no_error (error);
-	g_clear_pointer (&ret, g_variant_unref);
+	nm_clear_pointer (&ret, g_variant_unref);
 
 	g_signal_connect (wifi,
 	                  "access-point-removed",
@@ -590,7 +590,7 @@ test_client_nm_running (void)
 	g_source_remove (quit_id);
 
 	/* And kill it */
-	g_clear_pointer (&sinfo, nmtstc_service_cleanup);
+	nm_clear_pointer (&sinfo, nmtstc_service_cleanup);
 
 	g_assert (nm_client_get_nm_running (client1));
 
diff --git a/libnm/tests/test-remote-settings-client.c b/libnm/tests/test-remote-settings-client.c
index 8483eca8..f8771a98 100644
--- a/libnm/tests/test-remote-settings-client.c
+++ b/libnm/tests/test-remote-settings-client.c
@@ -62,7 +62,7 @@ test_add_connection (void)
 	                                add_cb,
 	                                &done);
 
-	nmtst_main_context_iterate_until (NULL, 5000, done);
+	nmtst_main_context_iterate_until_assert (NULL, 5000, done);
 
 	g_assert (gl.remote != NULL);
 
@@ -151,7 +151,7 @@ test_make_invisible (void)
 	                   set_visible_cb, NULL);
 
 	/* Wait for the connection to be removed */
-	nmtst_main_context_iterate_until (NULL, 5000, visible_changed && connection_removed);
+	nmtst_main_context_iterate_until_assert (NULL, 5000, visible_changed && connection_removed);
 
 	g_signal_handlers_disconnect_by_func (gl.remote, G_CALLBACK (visible_changed_cb), &visible_changed);
 	g_signal_handlers_disconnect_by_func (gl.client, G_CALLBACK (connection_removed_cb), &connection_removed);
@@ -225,7 +225,7 @@ test_make_visible (void)
 	                   set_visible_cb, NULL);
 
 	/* Wait for the settings service to announce the connection again */
-	nmtst_main_context_iterate_until (NULL, 5000, new);
+	nmtst_main_context_iterate_until_assert (NULL, 5000, new);
 
 	/* Ensure the new connection is the same as the one we made visible again */
 	g_assert (new == gl.remote);
@@ -313,7 +313,7 @@ test_remove_connection (void)
 	                   NULL,
 	                   deleted_cb, NULL);
 
-	nmtst_main_context_iterate_until (NULL, 5000, done && !gl.remote);
+	nmtst_main_context_iterate_until_assert (NULL, 5000, done && !gl.remote);
 
 	/* Ensure NMClient no longer has the connection */
 	conns = nm_client_get_connections (gl.client);
@@ -378,7 +378,7 @@ test_add_remove_connection (void)
 	                                add_remove_cb,
 	                                &done);
 
-	nmtst_main_context_iterate_until (NULL, 5000, done);
+	nmtst_main_context_iterate_until_assert (NULL, 5000, done);
 }
 
 /*****************************************************************************/
@@ -417,7 +417,7 @@ test_add_bad_connection (void)
 	                                &done);
 	g_clear_object (&connection);
 
-	nmtst_main_context_iterate_until (NULL, 5000, done);
+	nmtst_main_context_iterate_until_assert (NULL, 5000, done);
 	g_assert (gl.remote == NULL);
 }
 
@@ -454,12 +454,12 @@ test_save_hostname (void)
 
 	nm_client_save_hostname_async (gl.client, "example.com", NULL, save_hostname_cb, &done);
 
-	until_ts = nm_utils_get_monotonic_timestamp_ms () + 5000;
+	until_ts = nm_utils_get_monotonic_timestamp_msec () + 5000;
 	while (TRUE) {
 		g_main_context_iteration (NULL, FALSE);
 		if (done)
 			break;
-		if (nm_utils_get_monotonic_timestamp_ms () >= until_ts)
+		if (nm_utils_get_monotonic_timestamp_msec () >= until_ts)
 			g_assert_not_reached ();
 	}
 
diff --git a/libnm/tests/test-secret-agent.c b/libnm/tests/test-secret-agent.c
index fef6071d..97953b6d 100644
--- a/libnm/tests/test-secret-agent.c
+++ b/libnm/tests/test-secret-agent.c
@@ -16,22 +16,17 @@
 
 enum {
 	SECRET_REQUESTED,
-
-	LAST_SIGNAL
+	LAST_SIGNAL,
 };
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
-typedef NMSecretAgentOld TestSecretAgent;
+typedef NMSecretAgentOld      TestSecretAgent;
 typedef NMSecretAgentOldClass TestSecretAgentClass;
 
 GType test_secret_agent_get_type (void);
-G_DEFINE_TYPE (TestSecretAgent, test_secret_agent, NM_TYPE_SECRET_AGENT_OLD)
 
-static void
-test_secret_agent_init (TestSecretAgent *agent)
-{
-}
+G_DEFINE_TYPE (TestSecretAgent, test_secret_agent, NM_TYPE_SECRET_AGENT_OLD)
 
 static void
 test_secret_agent_get_secrets (NMSecretAgentOld                 *agent,
@@ -89,7 +84,7 @@ test_secret_agent_get_secrets (NMSecretAgentOld                 *agent,
 done:
 	callback (agent, connection, secrets, error, callback_data);
 	g_clear_error (&error);
-	g_clear_pointer (&secrets, g_variant_unref);
+	nm_clear_pointer (&secrets, g_variant_unref);
 	g_free (secret);
 }
 
@@ -122,42 +117,41 @@ test_secret_agent_delete_secrets (NMSecretAgentOld                  *agent,
 }
 
 static void
+test_secret_agent_init (TestSecretAgent *agent)
+{
+}
+
+static NMSecretAgentOld *
+test_secret_agent_new (gboolean auto_register)
+{
+	return nmtstc_context_object_new (test_secret_agent_get_type (),
+	                                  TRUE,
+	                                  NM_SECRET_AGENT_OLD_IDENTIFIER, "test-secret-agent",
+	                                  NM_SECRET_AGENT_OLD_AUTO_REGISTER, auto_register,
+	                                  NULL);
+}
+
+static void
 test_secret_agent_class_init (TestSecretAgentClass *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 	NMSecretAgentOldClass *agent_class = NM_SECRET_AGENT_OLD_CLASS (klass);
 
-	agent_class->get_secrets = test_secret_agent_get_secrets;
+	agent_class->get_secrets =        test_secret_agent_get_secrets;
 	agent_class->cancel_get_secrets = test_secret_agent_cancel_get_secrets;
-	agent_class->save_secrets = test_secret_agent_save_secrets;
-	agent_class->delete_secrets = test_secret_agent_delete_secrets;
+	agent_class->save_secrets =       test_secret_agent_save_secrets;
+	agent_class->delete_secrets =     test_secret_agent_delete_secrets;
 
 	signals[SECRET_REQUESTED] =
-		g_signal_new ("secret-requested",
-		              G_OBJECT_CLASS_TYPE (object_class),
-		              G_SIGNAL_RUN_LAST,
-		              0, NULL, NULL, NULL,
-		              G_TYPE_STRING, 4,
-		              NM_TYPE_CONNECTION,
-		              G_TYPE_STRING,
-		              G_TYPE_STRING,
-		              G_TYPE_STRING);
-
-}
-
-static NMSecretAgentOld *
-test_secret_agent_new (void)
-{
-	NMSecretAgentOld *agent;
-	GError *error = NULL;
-
-	agent = g_initable_new (test_secret_agent_get_type (), NULL, &error,
-	                        NM_SECRET_AGENT_OLD_IDENTIFIER, "test-secret-agent",
-	                        NM_SECRET_AGENT_OLD_AUTO_REGISTER, FALSE,
-	                        NULL);
-	g_assert_no_error (error);
-
-	return agent;
+	    g_signal_new ("secret-requested",
+	                  G_OBJECT_CLASS_TYPE (object_class),
+	                  G_SIGNAL_RUN_LAST,
+	                  0, NULL, NULL, NULL,
+	                  G_TYPE_STRING, 4,
+	                  NM_TYPE_CONNECTION,
+	                  G_TYPE_STRING,
+	                  G_TYPE_STRING,
+	                  G_TYPE_STRING);
 }
 
 /*****************************************************************************/
@@ -171,7 +165,7 @@ typedef struct {
 	NMConnection *connection;
 
 	GMainLoop *loop;
-	guint timeout_id;
+	GSource *timeout_source;
 
 	char *ifname;
 	char *con_id;
@@ -179,12 +173,6 @@ typedef struct {
 	int secrets_requested;
 } TestSecretAgentData;
 
-static gboolean
-timeout_assert (gpointer user_data)
-{
-	g_assert_not_reached ();
-}
-
 static void
 connection_added_cb (GObject *s,
                      GAsyncResult *result,
@@ -221,33 +209,40 @@ register_cb (GObject *object, GAsyncResult *result, gpointer user_data)
 static void
 test_setup (TestSecretAgentData *sadata, gconstpointer test_data)
 {
-	static int counter = 0;
-	const char *agent_notes = test_data;
+	static int static_counter = 0;
+	const int counter = static_counter++;
+	const char *create_agent = test_data;
 	NMConnection *connection;
 	NMSettingConnection *s_con;
 	NMSettingWireless *s_wireless;
 	GBytes *ssid;
 	NMSetting *s_wsec;
-	GError *error = NULL;
+	gs_free_error GError *error = NULL;
 
 	sadata->sinfo = nmtstc_service_init ();
 	if (!sadata->sinfo)
 		return;
 
-	g_assert (g_main_context_get_thread_default () == NULL);
+	g_assert (nm_g_main_context_is_thread_default (NULL));
 
 	sadata->client = nmtstc_client_new (TRUE);
 
+	g_assert (nm_g_main_context_is_thread_default (NULL));
+	g_assert (nm_g_main_context_is_thread_default (nm_client_get_main_context (sadata->client)));
+
 	sadata->loop = g_main_loop_new (NULL, FALSE);
-	sadata->timeout_id = g_timeout_add_seconds (5, timeout_assert, NULL);
+
+	sadata->timeout_source = g_timeout_source_new_seconds (5);
+	g_source_set_callback (sadata->timeout_source, nmtst_g_source_assert_not_called, NULL, NULL);
+	g_source_attach (sadata->timeout_source, NULL);
 
 	sadata->ifname = g_strdup_printf ("wlan%d", counter);
 	sadata->con_id = g_strdup_printf ("%s-%d", TEST_CON_ID_PREFIX, counter);
-	counter++;
 
-	/* Create the device */
-	sadata->device = nmtstc_service_add_device (sadata->sinfo, sadata->client,
-	                                            "AddWifiDevice", sadata->ifname);
+	sadata->device = nmtstc_service_add_device (sadata->sinfo,
+	                                            sadata->client,
+	                                            "AddWifiDevice",
+	                                            sadata->ifname);
 
 	/* Create the connection */
 	connection = nmtst_create_minimal_connection (sadata->con_id, NULL, NM_SETTING_WIRELESS_SETTING_NAME, &s_con);
@@ -278,18 +273,25 @@ test_setup (TestSecretAgentData *sadata, gconstpointer test_data)
 	g_main_loop_run (sadata->loop);
 	g_assert (sadata->connection);
 
-	if (agent_notes) {
-		sadata->agent = test_secret_agent_new ();
+	if (nm_streq (create_agent, "1")) {
+		gboolean auto_register = nmtst_get_rand_bool ();
+
+		sadata->agent = test_secret_agent_new (auto_register);
 
-		if (!strcmp (agent_notes, "sync")) {
+		if (auto_register) {
+			g_assert (nm_secret_agent_old_get_registered (sadata->agent));
 			nm_secret_agent_old_register (sadata->agent, NULL, &error);
 			g_assert_no_error (error);
-			g_assert (nm_secret_agent_old_get_registered (sadata->agent));
 		} else {
-			nm_secret_agent_old_register_async (sadata->agent, NULL,
-			                                register_cb, sadata);
+			g_assert (!nm_secret_agent_old_get_registered (sadata->agent));
+			nm_secret_agent_old_register_async (sadata->agent,
+			                                    NULL,
+			                                    register_cb,
+			                                    sadata);
 			g_main_loop_run (sadata->loop);
 		}
+
+		g_assert (nm_secret_agent_old_get_registered (sadata->agent));
 	}
 }
 
@@ -298,11 +300,22 @@ test_cleanup (TestSecretAgentData *sadata, gconstpointer test_data)
 {
 	GVariant *ret;
 	GError *error = NULL;
+	NMTstContextBusyWatcherData watcher_data = { };
+
+	g_assert (nm_g_main_context_is_thread_default (NULL));
 
 	if (!sadata->sinfo)
 		return;
 
+	g_assert (nm_g_main_context_is_thread_default (nm_client_get_main_context (sadata->client)));
+
+	nmtst_context_busy_watcher_add (&watcher_data,
+	                                nm_client_get_context_busy_watcher (sadata->client));
+
 	if (sadata->agent) {
+		nmtst_context_busy_watcher_add (&watcher_data,
+		                                nm_secret_agent_old_get_context_busy_watcher (sadata->agent));
+
 		if (nm_secret_agent_old_get_registered (sadata->agent)) {
 			nm_secret_agent_old_unregister (sadata->agent, NULL, &error);
 			g_assert_no_error (error);
@@ -325,11 +338,21 @@ test_cleanup (TestSecretAgentData *sadata, gconstpointer test_data)
 
 	nmtstc_service_cleanup (sadata->sinfo);
 
-	g_source_remove (sadata->timeout_id);
+	nm_clear_g_source_inst (&sadata->timeout_source);
+
 	g_main_loop_unref (sadata->loop);
 
 	g_free (sadata->ifname);
 	g_free (sadata->con_id);
+
+	*sadata = (TestSecretAgentData) { };
+
+	nmtst_context_busy_watcher_wait (&watcher_data);
+
+	while (g_main_context_iteration (NULL, FALSE)) {
+	}
+
+	nmtst_main_context_assert_no_dispatch (NULL, nmtst_get_rand_uint32 () % 500);
 }
 
 /*****************************************************************************/
@@ -529,17 +552,18 @@ test_secret_agent_good (TestSecretAgentData *sadata, gconstpointer test_data)
 	g_assert_cmpint (sadata->secrets_requested, ==, 1);
 }
 
+/*****************************************************************************/
+
 static void
 async_init_cb (GObject *object, GAsyncResult *result, gpointer user_data)
 {
 	GMainLoop *loop = user_data;
-	GError *error = NULL;
-	GObject *agent;
+	gs_free_error GError *error = NULL;
+	gs_unref_object GObject *agent = NULL;
 
 	agent = g_async_initable_new_finish (G_ASYNC_INITABLE (object), result, &error);
-	g_assert_error (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_FAILED);
-	g_assert (agent == NULL);
-	g_clear_error (&error);
+	nmtst_assert_success (NM_IS_SECRET_AGENT_OLD (agent), error);
+	g_assert (!nm_secret_agent_old_get_registered (NM_SECRET_AGENT_OLD (agent)));
 
 	g_main_loop_quit (loop);
 }
@@ -547,89 +571,151 @@ async_init_cb (GObject *object, GAsyncResult *result, gpointer user_data)
 static void
 test_secret_agent_nm_not_running (void)
 {
-	NMSecretAgentOld *agent;
-	GMainLoop *loop;
+	gs_unref_object NMSecretAgentOld *agent = NULL;
+	nm_auto_unref_gmainloop GMainLoop *loop = NULL;
 	GError *error = NULL;
 
-	agent = g_initable_new (test_secret_agent_get_type (), NULL, &error,
+	agent = g_initable_new (test_secret_agent_get_type (),
+	                        NULL,
+	                        &error,
 	                        NM_SECRET_AGENT_OLD_IDENTIFIER, "test-secret-agent",
 	                        NULL);
-	g_assert_error (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_FAILED);
-	g_assert (agent == NULL);
-	g_clear_error (&error);
+	nmtst_assert_success (NM_IS_SECRET_AGENT_OLD (agent), error);
+	g_assert (!nm_secret_agent_old_get_registered (agent));
+	g_clear_object (&agent);
 
 	loop = g_main_loop_new (NULL, FALSE);
 	g_async_initable_new_async (test_secret_agent_get_type (),
 	                            G_PRIORITY_DEFAULT,
-	                            NULL, async_init_cb, loop,
+	                            NULL,
+	                            async_init_cb,
+	                            loop,
 	                            NM_SECRET_AGENT_OLD_IDENTIFIER, "test-secret-agent",
 	                            NULL);
 	g_main_loop_run (loop);
-	g_main_loop_unref (loop);
 }
 
+/*****************************************************************************/
+
+typedef struct {
+	int step;
+	int invoke_count;
+} AutoRegisterData;
+
 static void
 registered_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
 {
-	GMainLoop *loop = user_data;
-
-	g_main_loop_quit (loop);
+	NMSecretAgentOld *agent = NM_SECRET_AGENT_OLD (object);
+	AutoRegisterData *data = user_data;
+
+	g_assert (data);
+	g_assert (NM_IS_SECRET_AGENT_OLD (agent));
+
+	data->invoke_count++;
+	g_assert_cmpint (data->invoke_count, ==, data->step);
+
+	switch (data->step) {
+	case 1:
+	case 3:
+		g_assert (nm_secret_agent_old_get_registered (agent));
+		break;
+	case 2:
+	case 4:
+		g_assert (!nm_secret_agent_old_get_registered (agent));
+		break;
+	default:
+		g_assert_not_reached ();
+	}
 }
 
 static void
 test_secret_agent_auto_register (void)
 {
 	NMTstcServiceInfo *sinfo;
-	NMSecretAgentOld *agent;
-	GMainLoop *loop;
+	gs_unref_object NMSecretAgentOld *agent = NULL;
 	GError *error = NULL;
+	AutoRegisterData auto_register_data = {
+		.step         = 0,
+		.invoke_count = 0,
+	};
+	gulong signal_id;
+	NMTstContextBusyWatcherData watcher_data = { };
 
 	sinfo = nmtstc_service_init ();
 	if (!nmtstc_service_available (sinfo))
 		return;
 
-	loop = g_main_loop_new (NULL, FALSE);
+	agent = test_secret_agent_new (FALSE);
+	g_assert (!nm_secret_agent_old_get_registered (agent));
 
-	agent = test_secret_agent_new ();
-	g_object_set (agent,
-	              NM_SECRET_AGENT_OLD_AUTO_REGISTER, TRUE,
-	              NULL);
-	g_signal_connect (agent, "notify::" NM_SECRET_AGENT_OLD_REGISTERED,
-	                  G_CALLBACK (registered_changed), loop);
+	signal_id = g_signal_connect (agent, "notify::" NM_SECRET_AGENT_OLD_REGISTERED,
+	                              G_CALLBACK (registered_changed), &auto_register_data);
 
+	if (nmtst_get_rand_bool ()) {
+		g_object_set (agent,
+		              NM_SECRET_AGENT_OLD_AUTO_REGISTER, TRUE,
+		              NULL);
+	} else
+		nm_secret_agent_old_enable (agent, TRUE);
 	g_assert (!nm_secret_agent_old_get_registered (agent));
+
 	nm_secret_agent_old_register (agent, NULL, &error);
 	g_assert_no_error (error);
-	g_assert (nm_secret_agent_old_get_registered (agent));
+	g_assert (!nm_secret_agent_old_get_registered (agent));
 
-	/* The GLib ObjectManager doesn't like when we drop the service
-	 * in between it sees the service disappear and the call to
-	 * GetManagedObjects. Give it a chance to do its business.
-	 * Arguably a bug. */
-	g_main_context_iteration (NULL, FALSE);
+	auto_register_data.step = 1;
+	nmtst_main_context_iterate_until_assert (NULL,
+	                                         1000,
+	                                         nm_secret_agent_old_get_registered (agent));
+
+	auto_register_data.step = 2;
+	nm_secret_agent_old_enable (agent, FALSE);
+	g_assert (!nm_secret_agent_old_get_registered (agent));
+
+	nmtst_main_context_iterate_until (NULL,
+	                                  nmtst_get_rand_uint32 () % 200,
+	                                  FALSE);
+
+	g_assert (!nm_secret_agent_old_get_registered (agent));
 
-	/* Shut down test service */
 	nmtstc_service_cleanup (sinfo);
-	g_main_loop_run (loop);
+
+	g_assert (!nm_secret_agent_old_get_registered (agent));
+
+	nm_secret_agent_old_enable (agent, TRUE);
+
+	g_assert (!nm_secret_agent_old_get_registered (agent));
+
+	nmtst_main_context_iterate_until (NULL,
+	                                  nmtst_get_rand_uint32 () % 200,
+	                                  FALSE);
+
 	g_assert (!nm_secret_agent_old_get_registered (agent));
 
-	/* Restart test service */
 	sinfo = nmtstc_service_init ();
 	g_assert (nmtstc_service_available (sinfo));
 
-	g_main_loop_run (loop);
-	g_assert (nm_secret_agent_old_get_registered (agent));
-
-	/* Let ObjectManager initialize (see above). */
-	g_main_context_iteration (NULL, FALSE);
+	auto_register_data.step = 3;
+	nmtst_main_context_iterate_until_assert (NULL,
+	                                         1000,
+	                                         nm_secret_agent_old_get_registered (agent));
 
-	/* Shut down test service again */
 	nmtstc_service_cleanup (sinfo);
-	g_main_loop_run (loop);
-	g_assert (!nm_secret_agent_old_get_registered (agent));
 
-	g_object_unref (agent);
-	g_main_loop_unref (loop);
+	auto_register_data.step = 4;
+	nmtst_main_context_iterate_until_assert (NULL,
+	                                         1000,
+	                                         !nm_secret_agent_old_get_registered (agent));
+
+	nm_clear_g_signal_handler (agent, &signal_id);
+
+	nmtst_context_busy_watcher_add (&watcher_data, nm_secret_agent_old_get_context_busy_watcher (agent));
+
+	g_clear_object (&agent);
+
+	nmtst_context_busy_watcher_wait (&watcher_data);
+
+	nmtst_main_context_assert_no_dispatch (NULL, nmtst_get_rand_uint32 () % 500);
 }
 
 /*****************************************************************************/
@@ -639,25 +725,16 @@ NMTST_DEFINE ();
 int
 main (int argc, char **argv)
 {
-	int ret;
-
 	g_setenv ("LIBNM_USE_SESSION_BUS", "1", TRUE);
 
 	nmtst_init (&argc, &argv, TRUE);
 
-	g_test_add ("/libnm/secret-agent/none", TestSecretAgentData, NULL,
-	            test_setup, test_secret_agent_none, test_cleanup);
-	g_test_add ("/libnm/secret-agent/no-secrets", TestSecretAgentData, "sync",
-	            test_setup, test_secret_agent_no_secrets, test_cleanup);
-	g_test_add ("/libnm/secret-agent/cancel", TestSecretAgentData, "async",
-	            test_setup, test_secret_agent_cancel, test_cleanup);
-	g_test_add ("/libnm/secret-agent/good", TestSecretAgentData, "async",
-	            test_setup, test_secret_agent_good, test_cleanup);
+	g_test_add ("/libnm/secret-agent/none",       TestSecretAgentData, "0", test_setup, test_secret_agent_none,       test_cleanup);
+	g_test_add ("/libnm/secret-agent/no-secrets", TestSecretAgentData, "1", test_setup, test_secret_agent_no_secrets, test_cleanup);
+	g_test_add ("/libnm/secret-agent/cancel",     TestSecretAgentData, "1", test_setup, test_secret_agent_cancel,     test_cleanup);
+	g_test_add ("/libnm/secret-agent/good",       TestSecretAgentData, "1", test_setup, test_secret_agent_good,       test_cleanup);
 	g_test_add_func ("/libnm/secret-agent/nm-not-running", test_secret_agent_nm_not_running);
 	g_test_add_func ("/libnm/secret-agent/auto-register", test_secret_agent_auto_register);
 
-	ret = g_test_run ();
-
-	return ret;
+	return g_test_run ();
 }
-