summary refs log tree commit diff
path: root/shared/nm-test-utils-impl.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2020-04-11 21:28:04 +0200
committerMichael Biebl <biebl@debian.org>2020-04-11 21:28:04 +0200
commit1e5977b62f896e844b548c3007ace9e1dfa7f9ed (patch)
tree7a7416ed410e72b6200f3d860fd315ec11cc106b /shared/nm-test-utils-impl.c
parentb012fa6e1d808e0736c009799c62d835cbfcc1dd (diff)
New upstream version 1.23.90 upstream/1.23.90
Diffstat (limited to 'shared/nm-test-utils-impl.c')
-rw-r--r--shared/nm-test-utils-impl.c276
1 files changed, 158 insertions, 118 deletions
diff --git a/shared/nm-test-utils-impl.c b/shared/nm-test-utils-impl.c
index 0805d0b9..0ef6591f 100644
--- a/shared/nm-test-utils-impl.c
+++ b/shared/nm-test-utils-impl.c
@@ -127,7 +127,7 @@ nmtstc_service_init (void)
 		g_source_attach (timeout_source, context);
 
 		child_source = g_child_watch_source_new (info->pid);
-		g_source_set_callback (child_source, (GSourceFunc)(void (*) (void)) _service_init_wait_child_wait, &data, NULL);
+		g_source_set_callback (child_source, G_SOURCE_FUNC (_service_init_wait_child_wait), &data, NULL);
 		g_source_attach (child_source, context);
 
 		had_timeout = !nmtst_main_loop_run (data.mainloop, 30000);
@@ -216,7 +216,7 @@ again_wait:
 typedef struct {
 	GMainLoop *loop;
 	const char *ifname;
-	char *path;
+	const char *path;
 	NMDevice *device;
 } AddDeviceInfo;
 
@@ -227,21 +227,17 @@ device_added_cb (NMClient *client,
 {
 	AddDeviceInfo *info = user_data;
 
-	g_assert (device);
+	g_assert (info);
+	g_assert (!info->device);
+
+	g_assert (NM_IS_DEVICE (device));
 	g_assert_cmpstr (nm_object_get_path (NM_OBJECT (device)), ==, info->path);
 	g_assert_cmpstr (nm_device_get_iface (device), ==, info->ifname);
 
-	info->device = device;
+	info->device = g_object_ref (device);
 	g_main_loop_quit (info->loop);
 }
 
-static gboolean
-timeout (gpointer user_data)
-{
-	g_assert_not_reached ();
-	return G_SOURCE_REMOVE;
-}
-
 static GVariant *
 call_add_wired_device (GDBusProxy *proxy, const char *ifname, const char *hwaddr,
                        const char **subchannels, GError **error)
@@ -275,39 +271,53 @@ call_add_device (GDBusProxy *proxy, const char *method, const char *ifname, GErr
 }
 
 static NMDevice *
-add_device_common (NMTstcServiceInfo *sinfo, NMClient *client,
-                   const char *method, const char *ifname,
-                   const char *hwaddr, const char **subchannels)
+add_device_common (NMTstcServiceInfo *sinfo,
+                   NMClient *client,
+                   const char *method,
+                   const char *ifname,
+                   const char *hwaddr,
+                   const char **subchannels)
 {
+	nm_auto_unref_gmainloop GMainLoop *loop = NULL;
+	gs_unref_variant GVariant *ret = NULL;
+	gs_free_error GError *error = NULL;
 	AddDeviceInfo info;
-	GError *error = NULL;
-	GVariant *ret;
-	guint timeout_id;
 
-	if (g_strcmp0 (method, "AddWiredDevice") == 0)
+	g_assert (sinfo);
+	g_assert (NM_IS_CLIENT (client));
+
+	if (nm_streq0 (method, "AddWiredDevice"))
 		ret = call_add_wired_device (sinfo->proxy, ifname, hwaddr, subchannels, &error);
 	else
 		ret = call_add_device (sinfo->proxy, method, ifname, &error);
 
-	g_assert_no_error (error);
-	g_assert (ret);
+	nmtst_assert_success (ret, error);
 	g_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)");
-	g_variant_get (ret, "(o)", &info.path);
-	g_variant_unref (ret);
-
-	/* Wait for libnm to find the device */
-	info.ifname = ifname;
-	info.loop = g_main_loop_new (NULL, FALSE);
-	g_signal_connect (client, "device-added",
-	                  G_CALLBACK (device_added_cb), &info);
-	timeout_id = g_timeout_add_seconds (5, timeout, NULL);
-	g_main_loop_run (info.loop);
-
-	g_source_remove (timeout_id);
+
+	/* Wait for NMClient to find the device */
+
+	loop = g_main_loop_new (nm_client_get_main_context (client), FALSE);
+
+	info = (AddDeviceInfo) {
+		.ifname = ifname,
+		.loop   = loop,
+	};
+	g_variant_get (ret, "(&o)", &info.path);
+
+	g_signal_connect (client,
+	                  NM_CLIENT_DEVICE_ADDED,
+	                  G_CALLBACK (device_added_cb),
+	                  &info);
+
+	if (!nmtst_main_loop_run (loop, 5000))
+		g_assert_not_reached ();
+
 	g_signal_handlers_disconnect_by_func (client, device_added_cb, &info);
-	g_free (info.path);
-	g_main_loop_unref (info.loop);
 
+	g_assert (NM_IS_DEVICE (info.device));
+
+	g_assert (info.device == nm_client_get_device_by_path (client, nm_object_get_path (NM_OBJECT (info.device))));
+	g_object_unref (info.device);
 	return info.device;
 }
 
@@ -410,35 +420,47 @@ nmtstc_service_update_connection_variant (NMTstcServiceInfo *sinfo,
 /*****************************************************************************/
 
 typedef struct {
+	GType gtype;
 	GMainLoop *loop;
-	NMClient *client;
-} NMTstcClientNewData;
+	GObject *obj;
+	bool call_nm_client_new_async:1;
+} NMTstcObjNewData;
 
 static void
-_nmtstc_client_new_cb (GObject *source_object,
-                       GAsyncResult *res,
-                       gpointer user_data)
+_context_object_new_do_cb (GObject *source_object,
+                           GAsyncResult *res,
+                           gpointer user_data)
 {
-	NMTstcClientNewData *d = user_data;
+	NMTstcObjNewData *d = user_data;
 	gs_free_error GError *error = NULL;
 
-	g_assert (!d->client);
+	g_assert (!d->obj);
 
-	d->client = nm_client_new_finish (res,
-	                                  nmtst_get_rand_bool () ? &error : NULL);
+	if (d->call_nm_client_new_async) {
+		d->obj = G_OBJECT (nm_client_new_finish (res,
+		                                         nmtst_get_rand_bool () ? &error : NULL));
+	} else {
+		d->obj = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
+		                                      res,
+		                                      nmtst_get_rand_bool () ? &error : NULL);
+	}
 
-	nmtst_assert_success (NM_IS_CLIENT (d->client), error);
+	nmtst_assert_success (G_IS_OBJECT (d->obj), error);
+	g_assert (G_OBJECT_TYPE (d->obj) == d->gtype);
 
 	g_main_loop_quit (d->loop);
 }
 
-static NMClient *
-_nmtstc_client_new (gboolean sync)
+static GObject *
+_context_object_new_do (GType gtype,
+                        gboolean sync,
+                        const gchar *first_property_name,
+                        va_list var_args)
 {
 	gs_free_error GError *error = NULL;
-	NMClient *client;
+	GObject *obj;
 
-	/* Create a NMClient instance synchronously, and arbitrarily use either
+	/* Create a GObject instance synchronously, and arbitrarily use either
 	 * the sync or async constructor.
 	 *
 	 * Note that the sync and async construct differ in one important aspect:
@@ -456,125 +478,128 @@ _nmtstc_client_new (gboolean sync)
 			g_source_attach (source, g_main_context_get_thread_default ());
 		}
 
-		if (nmtst_get_rand_bool ()) {
+		if (   gtype != NM_TYPE_CLIENT
+		    || first_property_name
+		    || nmtst_get_rand_bool ()) {
 			gboolean success;
 
-			client = g_object_new (NM_TYPE_CLIENT, NULL);
-			g_assert (NM_IS_CLIENT (client));
+			if (   first_property_name
+			    || nmtst_get_rand_bool ())
+				obj = g_object_new_valist (gtype, first_property_name, var_args);
+			else
+				obj = g_object_new (gtype, NULL);
 
-			success = g_initable_init (G_INITABLE (client),
+			success = g_initable_init (G_INITABLE (obj),
 			                           NULL,
 			                           nmtst_get_rand_bool () ? &error : NULL);
 			nmtst_assert_success (success, error);
 		} else {
-			client = nm_client_new (NULL,
-			                        nmtst_get_rand_bool () ? &error : NULL);
+			obj = G_OBJECT (nm_client_new (NULL,
+			                               nmtst_get_rand_bool () ? &error : NULL));
 		}
 	} else {
 		nm_auto_unref_gmainloop GMainLoop *loop = NULL;
-		NMTstcClientNewData d = { .loop = NULL, };
+		NMTstcObjNewData d = {
+			.gtype                    = gtype,
+			.loop                     = NULL,
+		};
+		gs_unref_object GObject *obj2 = NULL;
 
 		loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
-
 		d.loop = loop;
-		nm_client_new_async (NULL,
-		                     _nmtstc_client_new_cb,
-		                     &d);
+
+		if (   gtype != NM_TYPE_CLIENT
+		    || first_property_name
+		    || nmtst_get_rand_bool ()) {
+			if (   first_property_name
+			    || nmtst_get_rand_bool ())
+				obj2 = g_object_new_valist (gtype, first_property_name, var_args);
+			else
+				obj2 = g_object_new (gtype, NULL);
+
+			g_async_initable_init_async (G_ASYNC_INITABLE (obj2),
+			                             G_PRIORITY_DEFAULT,
+			                             NULL,
+			                             _context_object_new_do_cb,
+			                             &d);
+		} else {
+			d.call_nm_client_new_async = TRUE;
+			nm_client_new_async (NULL,
+			                     _context_object_new_do_cb,
+			                     &d);
+		}
 		g_main_loop_run (loop);
-		g_assert (NM_IS_CLIENT (d.client));
-		client = d.client;
+		obj = d.obj;
+		g_assert (!obj2 || obj == obj2);
 	}
 
-	nmtst_assert_success (NM_IS_CLIENT (client), error);
-	return client;
+	nmtst_assert_success (G_IS_OBJECT (obj), error);
+	g_assert (G_OBJECT_TYPE (obj) == gtype);
+	return obj;
 }
 
 typedef struct {
+	GType gtype;
+	const char *first_property_name;
+	va_list var_args;
 	GMainLoop *loop;
-	NMClient *client;
+	GObject *obj;
 	bool sync;
 } NewSyncInsideDispatchedData;
 
 static gboolean
-_nmtstc_client_new_inside_loop_do (gpointer user_data)
+_context_object_new_inside_loop_do (gpointer user_data)
 {
 	NewSyncInsideDispatchedData *d = user_data;
 
 	g_assert (d->loop);
-	g_assert (!d->client);
+	g_assert (!d->obj);
 
-	d->client = nmtstc_client_new (d->sync);
+	d->obj = nmtstc_context_object_new_valist (d->gtype, d->sync, d->first_property_name, d->var_args);
 	g_main_loop_quit (d->loop);
 	return G_SOURCE_CONTINUE;
 }
 
-static NMClient *
-_nmtstc_client_new_inside_loop (gboolean sync)
+static GObject *
+_context_object_new_inside_loop (GType gtype,
+                                 gboolean sync,
+                                 const char *first_property_name,
+                                 va_list var_args)
 {
 	GMainContext *context = g_main_context_get_thread_default ();
 	nm_auto_unref_gmainloop GMainLoop *loop = g_main_loop_new (context, FALSE);
 	NewSyncInsideDispatchedData d = {
-		.sync = sync,
-		.loop = loop,
+		.gtype               = gtype,
+		.first_property_name = first_property_name,
+		.sync                = sync,
+		.loop                = loop,
 	};
 	nm_auto_destroy_and_unref_gsource GSource *source = NULL;
 
+	va_copy (d.var_args, var_args);
+
 	source = g_idle_source_new ();
-	g_source_set_callback (source, _nmtstc_client_new_inside_loop_do, &d, NULL);
+	g_source_set_callback (source, _context_object_new_inside_loop_do, &d, NULL);
 	g_source_attach (source, context);
 
 	g_main_loop_run (loop);
-	g_assert (NM_IS_CLIENT (d.client));
-	return d.client;
-}
-
-static NMClient *
-_nmtstc_client_new_extra_context (void)
-{
-	GMainContext *inner_context;
-	NMClient *client;
-	GSource *source;
-	guint key_idx;
-
-	inner_context = g_main_context_new ();
-	g_main_context_push_thread_default (inner_context);
-
-	client = nmtstc_client_new (TRUE);
 
-	source = nm_utils_g_main_context_create_integrate_source (inner_context);
+	va_end (d.var_args);
 
-	g_main_context_pop_thread_default (inner_context);
-	g_main_context_unref (inner_context);
-
-	g_source_attach (source, g_main_context_get_thread_default ());
-
-	for (key_idx = 0; TRUE; key_idx++) {
-		char s[100];
-
-		/* nmtstc_client_new() may call _nmtstc_client_new_extra_context() repeatedly. We
-		 * need to attach the source to a previously unused key. */
-		nm_sprintf_buf (s, "nm-test-extra-context-%u", key_idx);
-		if (!g_object_get_data (G_OBJECT (client), s)) {
-			g_object_set_data_full (G_OBJECT (client),
-			                        s,
-			                        source,
-			                        (GDestroyNotify) nm_g_source_destroy_and_unref);
-			break;
-		}
-	}
-
-	return client;
+	g_assert (G_IS_OBJECT (d.obj));
+	g_assert (G_OBJECT_TYPE (d.obj) == gtype);
+	return d.obj;
 }
 
-NMClient *
-nmtstc_client_new (gboolean allow_iterate_main_context)
+gpointer
+nmtstc_context_object_new_valist (GType gtype,
+                                  gboolean allow_iterate_main_context,
+                                  const char *first_property_name,
+                                  va_list var_args)
 {
 	gboolean inside_loop;
 	gboolean sync;
 
-	if (nmtst_get_rand_uint32 () % 5 == 0)
-		return _nmtstc_client_new_extra_context ();
-
 	if (!allow_iterate_main_context) {
 		sync = TRUE;
 		inside_loop = FALSE;
@@ -587,11 +612,26 @@ nmtstc_client_new (gboolean allow_iterate_main_context)
 	}
 
 	if (inside_loop) {
-		/* Create the client on an idle handler of the current context.
+		/* Create the obj on an idle handler of the current context.
 		 * In practice, it should make no difference, which this check
 		 * tries to prove. */
-		return _nmtstc_client_new_inside_loop (sync);
+		return _context_object_new_inside_loop (gtype, sync, first_property_name, var_args);
 	}
 
-	return _nmtstc_client_new (sync);
+	return _context_object_new_do (gtype, sync, first_property_name, var_args);
+}
+
+gpointer
+nmtstc_context_object_new (GType gtype,
+                           gboolean allow_iterate_main_context,
+                           const char *first_property_name,
+                           ...)
+{
+	GObject *obj;
+	va_list var_args;
+
+	va_start (var_args, first_property_name);
+	obj = nmtstc_context_object_new_valist (gtype, allow_iterate_main_context, first_property_name, var_args);
+	va_end (var_args);
+	return obj;
 }