summary refs log tree commit diff
path: root/libnm/tests/test-secret-agent.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm/tests/test-secret-agent.c')
-rw-r--r--libnm/tests/test-secret-agent.c313
1 files changed, 195 insertions, 118 deletions
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 ();
 }
-