summary refs log tree commit diff
path: root/src/platform/tests
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2019-07-31 10:51:42 +0200
committerMichael Biebl <biebl@debian.org>2019-07-31 10:51:42 +0200
commit2e5fa45ddfbb5cffa1e78221f1cea706e2f298af (patch)
tree86f69d36c56de3074280456eddc854a780b8e04b /src/platform/tests
parent85563b7fc7ec2cd21e38debb9b28db342e2e8e7c (diff)
New upstream version 1.19.90 upstream/1.19.90
Diffstat (limited to 'src/platform/tests')
-rw-r--r--src/platform/tests/meson.build29
-rw-r--r--src/platform/tests/monitor.c1
-rw-r--r--src/platform/tests/test-address.c1
-rw-r--r--src/platform/tests/test-cleanup.c1
-rw-r--r--src/platform/tests/test-common.c9
-rw-r--r--src/platform/tests/test-link.c155
-rw-r--r--src/platform/tests/test-nmp-object.c5
-rw-r--r--src/platform/tests/test-platform-general.c (renamed from src/platform/tests/test-general.c)28
-rw-r--r--src/platform/tests/test-route.c84
9 files changed, 209 insertions, 104 deletions
diff --git a/src/platform/tests/meson.build b/src/platform/tests/meson.build
index 8086a46c..aaee8964 100644
--- a/src/platform/tests/meson.build
+++ b/src/platform/tests/meson.build
@@ -1,23 +1,22 @@
 test_units = [
-  ['test-link-fake',     'test-link.c',       test_nm_dep_fake,  default_test_timeout],
-  ['test-link-linux',    'test-link.c',       test_nm_dep_linux, 900],
-  ['test-address-fake',  'test-address.c',    test_nm_dep_fake,  default_test_timeout],
-  ['test-address-linux', 'test-address.c',    test_nm_dep_linux, default_test_timeout],
-  ['test-general',       'test-general.c',    test_nm_dep,       default_test_timeout],
-  ['test-nmp-object',    'test-nmp-object.c', test_nm_dep,       default_test_timeout],
-  ['test-route-fake',    'test-route.c',      test_nm_dep_fake,  default_test_timeout],
-  ['test-route-linux',   'test-route.c',      test_nm_dep_linux, default_test_timeout],
-  ['test-cleanup-fake',  'test-cleanup.c',    test_nm_dep_fake,  default_test_timeout],
-  ['test-cleanup-linux', 'test-cleanup.c',    test_nm_dep_linux, default_test_timeout],
+  [ 'test-address-fake',     'test-address.c',          test_nm_dep_fake,  default_test_timeout ],
+  [ 'test-address-linux',    'test-address.c',          test_nm_dep_linux, default_test_timeout ],
+  [ 'test-cleanup-fake',     'test-cleanup.c',          test_nm_dep_fake,  default_test_timeout ],
+  [ 'test-cleanup-linux',    'test-cleanup.c',          test_nm_dep_linux, default_test_timeout ],
+  [ 'test-link-fake',        'test-link.c',             test_nm_dep_fake,  default_test_timeout ],
+  [ 'test-link-linux',       'test-link.c',             test_nm_dep_linux, 900                  ],
+  [ 'test-nmp-object',       'test-nmp-object.c',       test_nm_dep,       default_test_timeout ],
+  [ 'test-platform-general', 'test-platform-general.c', test_nm_dep,       default_test_timeout ],
+  [ 'test-route-fake',       'test-route.c',            test_nm_dep_fake,  default_test_timeout ],
+  [ 'test-route-linux',      'test-route.c',            test_nm_dep_linux, default_test_timeout ],
 ]
 
 foreach test_unit: test_units
   exe = executable(
-    'platform-' + test_unit[0],
+    test_unit[0],
     test_unit[1],
     dependencies: test_unit[2],
   )
-
   test(
     'platform/' + test_unit[0],
     test_script,
@@ -26,10 +25,8 @@ foreach test_unit: test_units
   )
 endforeach
 
-test = 'monitor'
-
 executable(
-  test,
-  test + '.c',
+  'monitor',
+  'monitor.c',
   dependencies: test_nm_dep,
 )
diff --git a/src/platform/tests/monitor.c b/src/platform/tests/monitor.c
index fff5967b..6a5e0e16 100644
--- a/src/platform/tests/monitor.c
+++ b/src/platform/tests/monitor.c
@@ -1,4 +1,3 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 /*
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/platform/tests/test-address.c b/src/platform/tests/test-address.c
index d84a806d..3a3e9009 100644
--- a/src/platform/tests/test-address.c
+++ b/src/platform/tests/test-address.c
@@ -1,4 +1,3 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 /*
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/platform/tests/test-cleanup.c b/src/platform/tests/test-cleanup.c
index 6c73a63e..70d64c15 100644
--- a/src/platform/tests/test-cleanup.c
+++ b/src/platform/tests/test-cleanup.c
@@ -1,4 +1,3 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 /*
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c
index 7ebda9ff..cd0bef45 100644
--- a/src/platform/tests/test-common.c
+++ b/src/platform/tests/test-common.c
@@ -1,4 +1,3 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 /*
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -679,7 +678,7 @@ nmtstp_run_command_check_external_global (void)
 {
 	if (!nmtstp_is_root_test ())
 		return FALSE;
-	switch (nmtst_get_rand_int () % 3) {
+	switch (nmtst_get_rand_uint32 () % 3) {
 	case 0:
 		return -1;
 	case 1:
@@ -699,7 +698,7 @@ nmtstp_run_command_check_external (int external_command)
 	}
 	if (!nmtstp_is_root_test ())
 		return FALSE;
-	return (nmtst_get_rand_int () % 2) == 0;
+	return (nmtst_get_rand_uint32 () % 2) == 0;
 }
 
 /*****************************************************************************/
@@ -843,7 +842,7 @@ _ip_address_add (NMPlatform *platform,
 			g_assert (flags == 0);
 
 			if (   peer_address->addr4 != address->addr4
-			    || nmtst_get_rand_int () % 2) {
+			    || nmtst_get_rand_uint32 () % 2) {
 				/* If the peer is the same as the local address, we can omit it. The result should be identical */
 				nm_sprintf_buf (s_peer, " peer %s", nm_utils_inet4_ntop (peer_address->addr4, b2));
 			} else
@@ -1994,7 +1993,7 @@ nmtstp_netns_select_random (NMPlatform **platforms, gsize n_platforms, NMPNetns
 	for (i = 0; i < n_platforms; i++)
 		g_assert (NM_IS_PLATFORM (platforms[i]));
 
-	i = nmtst_get_rand_int () % (n_platforms + 1);
+	i = nmtst_get_rand_uint32 () % (n_platforms + 1);
 	if (i == 0)
 		return;
 	g_assert (nm_platform_netns_push (platforms[i - 1], netns));
diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c
index a0650cc1..5926dac1 100644
--- a/src/platform/tests/test-link.c
+++ b/src/platform/tests/test-link.c
@@ -1,4 +1,3 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 /*
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -241,7 +240,7 @@ test_slave (int master, int type, SignalData *master_changed)
 	/* Set master up */
 	g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, master, NULL));
 	g_assert (nm_platform_link_is_up (NM_PLATFORM_GET, master));
-	accept_signals (master_changed, 1, 2);
+	accept_signals (master_changed, 1, 3);
 
 	g_signal_handlers_disconnect_by_func (NM_PLATFORM_GET, G_CALLBACK (test_link_changed_signal_cb), &test_link_changed_signal_arg1);
 	g_signal_handlers_disconnect_by_func (NM_PLATFORM_GET, G_CALLBACK (test_link_changed_signal_cb), &test_link_changed_signal_arg2);
@@ -287,7 +286,7 @@ test_slave (int master, int type, SignalData *master_changed)
 	g_assert (nm_platform_link_is_connected (NM_PLATFORM_GET, master));
 	accept_signals (link_changed, 1, 3);
 	/* NM running, can cause additional change of addrgenmode */
-	accept_signals (master_changed, 0, 2);
+	accept_signals (master_changed, 0, 3);
 
 	/* Enslave again
 	 *
@@ -329,7 +328,7 @@ test_slave (int master, int type, SignalData *master_changed)
 		ensure_no_signal (link_changed);
 		accept_signal (link_removed);
 	}
-	accept_signals (master_changed, 0, 2);
+	accept_signals (master_changed, 0, 3);
 
 	ensure_no_signal (master_changed);
 
@@ -515,8 +514,8 @@ test_bridge_addr (void)
 	link = *plink;
 	g_assert_cmpstr (link.name, ==, DEVICE_NAME);
 
-	g_assert_cmpint (link.addr.len, ==, sizeof (addr));
-	g_assert (!memcmp (link.addr.data, addr, sizeof (addr)));
+	g_assert_cmpint (link.l_address.len, ==, sizeof (addr));
+	g_assert (!memcmp (link.l_address.data, addr, sizeof (addr)));
 
 	plink = nm_platform_link_get (NM_PLATFORM_GET, link.ifindex);
 	g_assert (plink);
@@ -538,8 +537,8 @@ test_bridge_addr (void)
 		g_assert_cmpint (_nm_platform_uint8_inv (plink->inet6_addr_gen_mode_inv), ==, NM_IN6_ADDR_GEN_MODE_EUI64);
 	}
 
-	g_assert_cmpint (plink->addr.len, ==, sizeof (addr));
-	g_assert (!memcmp (plink->addr.data, addr, sizeof (addr)));
+	g_assert_cmpint (plink->l_address.len, ==, sizeof (addr));
+	g_assert (!memcmp (plink->l_address.data, addr, sizeof (addr)));
 
 	nmtstp_link_delete (NULL, -1, link.ifindex, link.name, TRUE);
 }
@@ -2100,7 +2099,7 @@ test_create_many_links_do (guint n_devices)
 	char name[64];
 	const NMPlatformLink *pllink;
 	gs_unref_array GArray *ifindexes = g_array_sized_new (FALSE, FALSE, sizeof (int), n_devices);
-	const int EX = ((int) (nmtst_get_rand_int () % 4)) - 1;
+	const int EX = ((int) (nmtst_get_rand_uint32 () % 4)) - 1;
 
 	g_assert (EX >= -1 && EX <= 2);
 
@@ -2459,17 +2458,17 @@ test_netns_general (gpointer fixture, gconstpointer test_data)
 		NMPlatform *p = (k == 0 ? platform_1 : platform_2);
 		const char *id = (k == 0 ? "a" : "b");
 
-		for (i = 0, j = nmtst_get_rand_int () % 5; i < j; i++)
+		for (i = 0, j = nmtst_get_rand_uint32 () % 5; i < j; i++)
 			_ADD_DUMMY (p, nm_sprintf_buf (sbuf, "other-a-%s-%02d", id, i));
 
 		_ADD_DUMMY (p, "dummy1_");
 
-		for (i = 0, j = nmtst_get_rand_int () % 5; i < j; i++)
+		for (i = 0, j = nmtst_get_rand_uint32 () % 5; i < j; i++)
 			_ADD_DUMMY (p, nm_sprintf_buf (sbuf, "other-b-%s-%02d", id, i));
 
 		_ADD_DUMMY (p, nm_sprintf_buf (sbuf, "dummy2%s", id));
 
-		for (i = 0, j = nmtst_get_rand_int () % 5; i < j; i++)
+		for (i = 0, j = nmtst_get_rand_uint32 () % 5; i < j; i++)
 			_ADD_DUMMY (p, nm_sprintf_buf (sbuf, "other-c-%s-%02d", id, i));
 	}
 
@@ -2491,17 +2490,17 @@ test_netns_general (gpointer fixture, gconstpointer test_data)
 		NMPlatform *pl;
 		const char *path;
 
-		j = nmtst_get_rand_int () % 2;
+		j = nmtst_get_rand_uint32 () % 2;
 
-		if (nmtst_get_rand_int () % 2) {
+		if (nmtst_get_rand_uint32 () % 2) {
 			pl = platform_1;
-			if (nmtst_get_rand_int () % 2)
+			if (nmtst_get_rand_uint32 () % 2)
 				path = "/proc/sys/net/ipv6/conf/dummy1_/disable_ipv6";
 			else
 				path = "/proc/sys/net/ipv6/conf/dummy2a/disable_ipv6";
 		} else {
 			pl = platform_2;
-			if (nmtst_get_rand_int () % 2)
+			if (nmtst_get_rand_uint32 () % 2)
 				path = "/proc/sys/net/ipv6/conf/dummy1_/disable_ipv6";
 			else
 				path = "/proc/sys/net/ipv6/conf/dummy2b/disable_ipv6";
@@ -2654,7 +2653,7 @@ test_netns_push (gpointer fixture, gconstpointer test_data)
 	pl[2].platform = platform_2 = _test_netns_create_platform ();
 
 	pl_base = &pl[0];
-	i = nmtst_get_rand_int () % (G_N_ELEMENTS (pl) + 1);
+	i = nmtst_get_rand_uint32 () % (G_N_ELEMENTS (pl) + 1);
 	if (i < G_N_ELEMENTS (pl)) {
 		pl_base = &pl[i];
 		g_assert (nm_platform_netns_push (pl[i].platform, &netns_pop));
@@ -2674,7 +2673,7 @@ test_netns_push (gpointer fixture, gconstpointer test_data)
 		g_ptr_array_add (device_names, tmp);
 		pl[i].sysctl_path = tmp;
 
-		pl[i].sysctl_value = nmtst_get_rand_int () % 2 ? "1" : "0";
+		pl[i].sysctl_value = nmtst_get_rand_uint32 () % 2 ? "1" : "0";
 
 		_ADD_DUMMY (pl[i].platform, pl[i].device_name);
 
@@ -2689,16 +2688,16 @@ test_netns_push (gpointer fixture, gconstpointer test_data)
 		pl[i].ns_mnt = tmp;
 	}
 
-	nstack = nmtst_get_rand_int () % (G_N_ELEMENTS (stack) + 1);
+	nstack = nmtst_get_rand_uint32 () % (G_N_ELEMENTS (stack) + 1);
 	for (i = 0; i < nstack; i++) {
-		stack[i].pl = &pl[nmtst_get_rand_int () % G_N_ELEMENTS (pl)];
-		stack[i].ns_types = ns_types_list[nmtst_get_rand_int () % G_N_ELEMENTS (ns_types_list)];
+		stack[i].pl = &pl[nmtst_get_rand_uint32 () % G_N_ELEMENTS (pl)];
+		stack[i].ns_types = ns_types_list[nmtst_get_rand_uint32 () % G_N_ELEMENTS (ns_types_list)];
 
 		nmp_netns_push_type (nm_platform_netns_get (stack[i].pl->platform), stack[i].ns_types);
 	}
 
 	/* pop some again. */
-	for (i = nmtst_get_rand_int () % (nstack + 1); i > 0; i--) {
+	for (i = nmtst_get_rand_uint32 () % (nstack + 1); i > 0; i--) {
 		g_assert (nstack > 0);
 		nstack--;
 		nmp_netns_pop (nm_platform_netns_get (stack[nstack].pl->platform));
@@ -2765,9 +2764,9 @@ test_netns_push (gpointer fixture, gconstpointer test_data)
 static void
 test_netns_bind_to_path (gpointer fixture, gconstpointer test_data)
 {
-#define P_VAR_RUN                "/var/run"
-#define P_VAR_RUN_NETNS          "/var/run/netns"
-#define P_VAR_RUN_NETNS_BINDNAME "/var/run/netns/"P_NETNS_BINDNAME
+#define P_VAR_RUN                "/run"
+#define P_VAR_RUN_NETNS          "/run/netns"
+#define P_VAR_RUN_NETNS_BINDNAME "/run/netns/"P_NETNS_BINDNAME
 #define P_NETNS_BINDNAME         "nmtst-iproute2-netns"
 	gs_unref_object NMPlatform *platform_0 = NULL;
 	gs_unref_object NMPlatform *platform_1 = NULL;
@@ -2789,7 +2788,7 @@ test_netns_bind_to_path (gpointer fixture, gconstpointer test_data)
 	g_assert_cmpint (mount ("tmpfs", P_VAR_RUN, "tmpfs", MS_NOATIME | MS_NODEV | MS_NOSUID, "mode=0755,size=32K"), ==, 0);
 	g_assert_cmpint (mkdir (P_VAR_RUN_NETNS, 755), ==, 0);
 
-	i = (nmtst_get_rand_int () % 2) + 1;
+	i = (nmtst_get_rand_uint32 () % 2) + 1;
 	netns = nm_platform_netns_get (platforms[i]);
 
 	_ADD_DUMMY (platforms[i], "dummy2b");
@@ -2832,9 +2831,9 @@ test_sysctl_rename (void)
 	ifindex[0] = nmtstp_link_dummy_add (PL, -1, IFNAME[0])->ifindex;
 	ifindex[1] = nmtstp_link_dummy_add (PL, -1, IFNAME[1])->ifindex;
 
-	s = (nmtst_get_rand_int () % 2) ? NULL : ifname_buf;
+	s = (nmtst_get_rand_uint32 () % 2) ? NULL : ifname_buf;
 
-	if (nmtst_get_rand_int () % 2) {
+	if (nmtst_get_rand_uint32 () % 2) {
 		/* bring the platform cache out of sync */
 		nmtstp_run_command_check ("ip link set %s name %s", IFNAME[0], IFNAME[2]);
 		nm_platform_process_events (PL);
@@ -2847,7 +2846,7 @@ test_sysctl_rename (void)
 	}
 
 	/* open dirfd for IFNAME[0] */
-	i = nmtst_get_rand_int () % (2 + G_N_ELEMENTS (IFNAME));
+	i = nmtst_get_rand_uint32 () % (2 + G_N_ELEMENTS (IFNAME));
 	if (i == 0) {
 		dirfd = nm_platform_sysctl_open_netdir (PL,
 		                                        ifindex[0],
@@ -2866,7 +2865,7 @@ test_sysctl_rename (void)
 		g_assert_cmpstr (s, ==, IFNAME[0]);
 
 	/* possibly rename the interfaces. */
-	switch (nmtst_get_rand_int () % 4) {
+	switch (nmtst_get_rand_uint32 () % 4) {
 	case 0:
 		break;
 	case 1:
@@ -2879,11 +2878,11 @@ test_sysctl_rename (void)
 	}
 
 	/* possibly, resync platform cache (should make no difference). */
-	if (nmtst_get_rand_int () % 2)
+	if (nmtst_get_rand_uint32 () % 2)
 		nm_platform_process_events (PL);
 
 	/* check that we still read the same file. */
-	switch (nmtst_get_rand_int () % 2) {
+	switch (nmtst_get_rand_uint32 () % 2) {
 	case 0: {
 		gs_free char *c = NULL;
 
@@ -2930,7 +2929,7 @@ test_sysctl_netns_switch (void)
 	platforms[0] = platform_0 = nm_linux_platform_new (TRUE, TRUE);
 	platforms[1] = platform_1 = _test_netns_create_platform ();
 	platforms[2] = platform_2 = _test_netns_create_platform ();
-	PL = platforms[nmtst_get_rand_int () % 3];
+	PL = platforms[nmtst_get_rand_uint32 () % 3];
 
 	nmtstp_netns_select_random (platforms, G_N_ELEMENTS (platforms), &netns_pop_1);
 
@@ -2938,7 +2937,7 @@ test_sysctl_netns_switch (void)
 
 	nmtstp_netns_select_random (platforms, G_N_ELEMENTS (platforms), &netns_pop_2);
 
-	s = (nmtst_get_rand_int () % 2) ? NULL : ifname_buf;
+	s = (nmtst_get_rand_uint32 () % 2) ? NULL : ifname_buf;
 	dirfd = nm_platform_sysctl_open_netdir (PL,
 	                                        ifindex,
 	                                        s);
@@ -3015,6 +3014,92 @@ test_sysctl_netns_switch (void)
 	nmtstp_link_delete (PL, FALSE, ifindex, NULL, TRUE);
 }
 
+static void
+sysctl_set_async_cb_assert_success (GError *error, gpointer data)
+{
+	g_assert_no_error (error);
+	g_main_loop_quit (data);
+}
+
+static void
+sysctl_set_async_cb_assert_failure (GError *error, gpointer data)
+{
+	g_assert (error);
+	g_main_loop_quit (data);
+}
+
+static void
+test_sysctl_set_async (void)
+{
+	NMPlatform *const PL = NM_PLATFORM_GET;
+	const char *const IFNAME = "nm-dummy-0";
+	const char *const PATH = "/proc/sys/net/ipv4/conf/nm-dummy-0/rp_filter";
+	gs_free GMainLoop *loop = NULL;
+	gs_unref_object GCancellable *cancellable = NULL;
+	int ifindex;
+
+	ifindex = nmtstp_link_dummy_add (PL, -1, IFNAME)->ifindex;
+	loop = g_main_loop_new (NULL, FALSE);
+	cancellable = g_cancellable_new ();
+
+	nm_platform_sysctl_set_async (PL,
+	                              NMP_SYSCTL_PATHID_ABSOLUTE (PATH),
+	                              (const char *[]) { "2", NULL},
+	                              sysctl_set_async_cb_assert_success,
+	                              loop,
+	                              cancellable);
+
+	if (!nmtst_main_loop_run (loop, 1000))
+		g_assert_not_reached ();
+
+	g_assert_cmpint (nm_platform_sysctl_get_int32 (PL, NMP_SYSCTL_PATHID_ABSOLUTE (PATH), -1),
+	                 ==,
+	                 2);
+
+	nm_platform_sysctl_set_async (PL,
+	                              NMP_SYSCTL_PATHID_ABSOLUTE (PATH),
+	                              (const char *[]) { "2", "0", "1", "0", "1", NULL},
+	                              sysctl_set_async_cb_assert_success,
+	                              loop,
+	                              cancellable);
+
+	if (!nmtst_main_loop_run (loop, 2000))
+		g_assert_not_reached ();
+
+	g_assert_cmpint (nm_platform_sysctl_get_int32 (PL, NMP_SYSCTL_PATHID_ABSOLUTE (PATH), -1),
+	                 ==,
+	                 1);
+
+	nmtstp_link_delete (NULL, -1, ifindex, IFNAME, TRUE);
+}
+
+static void
+test_sysctl_set_async_fail (void)
+{
+	NMPlatform *const PL = NM_PLATFORM_GET;
+	const char *const IFNAME = "nm-dummy-0";
+	const char *const PATH = "/proc/sys/net/ipv4/conf/nm-dummy-0/does-not-exist";
+	gs_free GMainLoop *loop = NULL;
+	gs_unref_object GCancellable *cancellable = NULL;
+	int ifindex;
+
+	ifindex = nmtstp_link_dummy_add (PL, -1, IFNAME)->ifindex;
+	loop = g_main_loop_new (NULL, FALSE);
+	cancellable = g_cancellable_new ();
+
+	nm_platform_sysctl_set_async (PL,
+	                              NMP_SYSCTL_PATHID_ABSOLUTE (PATH),
+	                              (const char *[]) { "2", NULL},
+	                              sysctl_set_async_cb_assert_failure,
+	                              loop,
+	                              cancellable);
+
+	if (!nmtst_main_loop_run (loop, 1000))
+		g_assert_not_reached ();
+
+	nmtstp_link_delete (NULL, -1, ifindex, IFNAME, TRUE);
+}
+
 /*****************************************************************************/
 
 static gpointer
@@ -3238,6 +3323,8 @@ _nmtstp_setup_tests (void)
 
 		g_test_add_func ("/general/sysctl/rename", test_sysctl_rename);
 		g_test_add_func ("/general/sysctl/netns-switch", test_sysctl_netns_switch);
+		g_test_add_func ("/general/sysctl/set-async", test_sysctl_set_async);
+		g_test_add_func ("/general/sysctl/set-async-fail", test_sysctl_set_async_fail);
 
 		g_test_add_func ("/link/ethtool/features/get", test_ethtool_features_get);
 	}
diff --git a/src/platform/tests/test-nmp-object.c b/src/platform/tests/test-nmp-object.c
index e2019e96..08bde437 100644
--- a/src/platform/tests/test-nmp-object.c
+++ b/src/platform/tests/test-nmp-object.c
@@ -1,4 +1,3 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 /* nm-platform.c - Handle runtime kernel networking configuration
  *
  * This program is free software; you can redistribute it and/or modify
@@ -267,7 +266,7 @@ test_cache_link (void)
 	struct udev_device *udev_device_3 = g_list_nth_data (global.udev_devices, 0);
 	NMPCacheOpsType ops_type;
 	nm_auto_unref_dedup_multi_index NMDedupMultiIndex *multi_idx = NULL;
-	gboolean use_udev = nmtst_get_rand_int () % 2;
+	gboolean use_udev = nmtst_get_rand_uint32 () % 2;
 
 	multi_idx = nm_dedup_multi_index_new ();
 
@@ -503,7 +502,7 @@ test_cache_qdisc (void)
 	nm_auto_nmpobj NMPObject *obj2 = nmp_object_new (NMP_OBJECT_TYPE_QDISC, (NMPlatformObject *) &pl_qdisc_2);
 
 	multi_idx = nm_dedup_multi_index_new ();
-	cache = nmp_cache_new (multi_idx, nmtst_get_rand_int () % 2);
+	cache = nmp_cache_new (multi_idx, nmtst_get_rand_uint32 () % 2);
 
 	g_assert (nmp_cache_lookup_obj (cache, obj1a) == NULL);
 
diff --git a/src/platform/tests/test-general.c b/src/platform/tests/test-platform-general.c
index eebc15d8..2b723810 100644
--- a/src/platform/tests/test-general.c
+++ b/src/platform/tests/test-platform-general.c
@@ -1,4 +1,3 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 /* nm-platform.c - Handle runtime kernel networking configuration
  *
  * This program is free software; you can redistribute it and/or modify
@@ -52,6 +51,31 @@ test_link_get_all (void)
 
 /*****************************************************************************/
 
+static void
+test_nm_platform_link_flags2str (void)
+{
+	int i;
+
+	for (i = 0; i < 100; i++) {
+		char buf[NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN + 100];
+		const char *s;
+		const guint flags = ((i == 0) ? ~0u : nmtst_get_rand_uint ());
+		gsize l;
+
+		s = nm_platform_link_flags2str (flags, buf, sizeof (buf));
+		g_assert (s);
+
+		l = strlen (s);
+		if (l > NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN)
+			g_error ("nm_platform_link_flags2str(%x) produced a longer output than %zu chars: \"%s\"", flags, NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN, s);
+		if (   flags == ~0u
+		    && l != NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN)
+			g_error ("nm_platform_link_flags2str(%x) is expected to produce %zu chars, but produced %zu: \"%s\"", flags, NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN, l, s);
+	}
+}
+
+/*****************************************************************************/
+
 NMTST_DEFINE ();
 
 int
@@ -61,7 +85,7 @@ main (int argc, char **argv)
 
 	g_test_add_func ("/general/init_linux_platform", test_init_linux_platform);
 	g_test_add_func ("/general/link_get_all", test_link_get_all);
+	g_test_add_func ("/general/nm_platform_link_flags2str", test_nm_platform_link_flags2str);
 
 	return g_test_run ();
 }
-
diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c
index e6ffe1ae..44bfbc58 100644
--- a/src/platform/tests/test-route.c
+++ b/src/platform/tests/test-route.c
@@ -1,4 +1,3 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 /*
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -445,7 +444,7 @@ test_ip4_route_get (void)
 	result = nm_platform_ip_route_get (NM_PLATFORM_GET,
 	                                   AF_INET,
 	                                   &a,
-	                                   nmtst_get_rand_int () % 2 ? 0 : ifindex,
+	                                   nmtst_get_rand_uint32 () % 2 ? 0 : ifindex,
 	                                   &route);
 
 	g_assert (NMTST_NM_ERR_SUCCESS (result));
@@ -607,7 +606,7 @@ test_ip6_route_get (void)
 	result = nm_platform_ip_route_get (NM_PLATFORM_GET,
 	                                   AF_INET6,
 	                                   a,
-	                                   nmtst_get_rand_int () % 2 ? 0 : ifindex,
+	                                   nmtst_get_rand_uint32 () % 2 ? 0 : ifindex,
 	                                   &route);
 
 	g_assert (NMTST_NM_ERR_SUCCESS (result));
@@ -815,9 +814,9 @@ test_ip (gconstpointer test_data)
 
 		if (   order_len == 0
 		    || (   order_len < G_N_ELEMENTS (order_idx)
-		        && nmtst_get_rand_int () % 2)) {
+		        && nmtst_get_rand_uint32 () % 2)) {
 again_find_idx:
-			idx = nmtst_get_rand_int () % G_N_ELEMENTS (iface_data);
+			idx = nmtst_get_rand_uint32 () % G_N_ELEMENTS (iface_data);
 			for (i = 0; i < order_len; i++) {
 				if (order_idx[i] == idx)
 					goto again_find_idx;
@@ -827,7 +826,7 @@ again_find_idx:
 			r->ifindex = iface_data[idx].ifindex;
 			g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_ip4_route_add (platform, NMP_NLM_FLAG_APPEND, r)));
 		} else {
-			i = nmtst_get_rand_int () % order_len;
+			i = nmtst_get_rand_uint32 () % order_len;
 			idx = order_idx[i];
 			for (i++; i < order_len; i++)
 				order_idx[i - 1] = order_idx[i];
@@ -1129,17 +1128,17 @@ _rule_create_random (NMPlatform *platform)
 
 	addr_size = nm_utils_addr_family_to_size (rr->addr_family);
 
-	p = nmtst_get_rand_int ();
+	p = nmtst_get_rand_uint32 ();
 	if ((p % 1000u) < 50)
 		rr->priority = 10000 + ((~p) % 20u);
 
-	p = nmtst_get_rand_int ();
+	p = nmtst_get_rand_uint32 ();
 	if ((p % 1000u) < 40)
 		nm_sprintf_buf (rr->iifname, "t-iif-%u", (~p) % 20);
 	else if ((p % 1000u) < 80)
 		nm_sprintf_buf (rr->iifname, "%s", DEVICE_NAME);
 
-	p = nmtst_get_rand_int ();
+	p = nmtst_get_rand_uint32 ();
 	if ((p % 1000u) < 40)
 		nm_sprintf_buf (rr->oifname, "t-oif-%d", (~p) % 20);
 	else if ((p % 1000u) < 80)
@@ -1149,14 +1148,14 @@ _rule_create_random (NMPlatform *platform)
 		NMIPAddr *p_addr = i ? &rr->src     : &rr->dst;
 		guint8 *p_len    = i ? &rr->src_len : &rr->dst_len;
 
-		p = nmtst_get_rand_int ();
+		p = nmtst_get_rand_uint32 ();
 		if ((p % 1000u) < 100) {
 			/* if we set src_len/dst_len to zero, the src/dst is actually ignored.
 			 *
 			 * For fuzzying, still set the address. It shall have no further effect.
 			 * */
 			*p_len = (~p) % (addr_size * 8 + 1);
-			p = nmtst_get_rand_int ();
+			p = nmtst_get_rand_uint32 ();
 			if ((p % 3u) == 0) {
 				if (rr->addr_family == AF_INET)
 					p_addr->addr4 = nmtst_inet4_from_string (nm_sprintf_buf (saddr, "192.192.5.%u", (~p) % 256u));
@@ -1167,12 +1166,12 @@ _rule_create_random (NMPlatform *platform)
 		}
 	}
 
-	p = nmtst_get_rand_int ();
+	p = nmtst_get_rand_uint32 ();
 	if ((p % 1000u) < 50)
 		rr->tun_id = 10000 + ((~p) % 20);
 
 again_action:
-	p = nmtst_get_rand_int ();
+	p = nmtst_get_rand_uint32 ();
 	if ((p % 1000u) < 500)
 		rr->action = FR_ACT_UNSPEC;
 	else if ((p % 1000u) < 750)
@@ -1180,22 +1179,22 @@ again_action:
 	else
 		rr->action = (~p) % 0x100u;
 
-	rr->priority = _rr_rand_choose_u32 (nmtst_get_rand_int ());
+	rr->priority = _rr_rand_choose_u32 (nmtst_get_rand_uint32 ());
 
 	if (   rr->action == FR_ACT_GOTO
 	    && rr->priority == G_MAXINT32)
 		goto again_action;
 
-	p = nmtst_get_rand_int ();
+	p = nmtst_get_rand_uint32 ();
 	if ((p % 10000u) < 100)
 		rr->goto_target = rr->priority + 1;
 	else
-		rr->goto_target = _rr_rand_choose_u32 (nmtst_get_rand_int ());
+		rr->goto_target = _rr_rand_choose_u32 (nmtst_get_rand_uint32 ());
 	if (   rr->action == FR_ACT_GOTO
 	    && rr->goto_target <= rr->priority)
 		goto again_action;
 
-	p = nmtst_get_rand_int ();
+	p = nmtst_get_rand_uint32 ();
 	if ((p % 1000u) < 25) {
 		if (_rule_check_kernel_support (platform, FRA_L3MDEV)) {
 			rr->l3mdev = TRUE;
@@ -1205,7 +1204,7 @@ again_action:
 
 again_table:
 	if (!rr->l3mdev) {
-		p = nmtst_get_rand_int ();
+		p = nmtst_get_rand_uint32 ();
 		if ((p % 1000u) < 700)
 			rr->table = RT_TABLE_UNSPEC;
 		else if ((p % 1000u) < 850)
@@ -1217,33 +1216,33 @@ again_table:
 			goto again_table;
 	}
 
-	rr->fwmark = _rr_rand_choose_u32 (nmtst_get_rand_int ());
-	rr->fwmask = _rr_rand_choose_u32 (nmtst_get_rand_int ());
+	rr->fwmark = _rr_rand_choose_u32 (nmtst_get_rand_uint32 ());
+	rr->fwmask = _rr_rand_choose_u32 (nmtst_get_rand_uint32 ());
 
-	rr->flow = _rr_rand_choose_u32 (nmtst_get_rand_int ());
+	rr->flow = _rr_rand_choose_u32 (nmtst_get_rand_uint32 ());
 
 	if (_rule_check_kernel_support (platform, FRA_PROTOCOL))
-		rr->protocol = _rr_rand_choose_u8 (nmtst_get_rand_int ());
+		rr->protocol = _rr_rand_choose_u8 (nmtst_get_rand_uint32 ());
 
 #define IPTOS_TOS_MASK 0x1E
 
 again_tos:
-	rr->tos = _rr_rand_choose_u8 (nmtst_get_rand_int ());
+	rr->tos = _rr_rand_choose_u8 (nmtst_get_rand_uint32 ());
 	if (   rr->addr_family == AF_INET
 	    && rr->tos & ~IPTOS_TOS_MASK)
 		goto again_tos;
 
 	if (_rule_check_kernel_support (platform, FRA_IP_PROTO))
-		rr->ip_proto = _rr_rand_choose_u8 (nmtst_get_rand_int ());
+		rr->ip_proto = _rr_rand_choose_u8 (nmtst_get_rand_uint32 ());
 
 	if (_rule_check_kernel_support (platform, FRA_SUPPRESS_PREFIXLEN))
-		rr->suppress_prefixlen_inverse = ~_rr_rand_choose_u32 (nmtst_get_rand_int ());
+		rr->suppress_prefixlen_inverse = ~_rr_rand_choose_u32 (nmtst_get_rand_uint32 ());
 
 	if (_rule_check_kernel_support (platform, FRA_SUPPRESS_IFGROUP))
-		rr->suppress_ifgroup_inverse = ~_rr_rand_choose_u32 (nmtst_get_rand_int ());
+		rr->suppress_ifgroup_inverse = ~_rr_rand_choose_u32 (nmtst_get_rand_uint32 ());
 
 	if (_rule_check_kernel_support (platform, FRA_UID_RANGE)) {
-		p = nmtst_get_rand_int ();
+		p = nmtst_get_rand_uint32 ();
 		rr->uid_range_has = (p % 10000u) < 200;
 	}
 
@@ -1265,10 +1264,10 @@ again_uid_range:
 		if (!_rule_check_kernel_support (platform, attribute))
 			continue;
 
-		p = nmtst_get_rand_int ();
+		p = nmtst_get_rand_uint32 ();
 		if ((p % 10000u) < 300) {
 			while (range->start == 0) {
-				p = p ^ nmtst_get_rand_int ();
+				p = p ^ nmtst_get_rand_uint32 ();
 				range->start = nmtst_rand_select (1u, 0xFFFEu, ((p      ) % 0xFFFEu) + 1);
 				range->end   = nmtst_rand_select (1u, 0xFFFEu, ((p >> 16) % 0xFFFEu) + 1, range->start);
 				if (range->end < range->start)
@@ -1277,7 +1276,7 @@ again_uid_range:
 		}
 	}
 
-	p = nmtst_get_rand_int () % 1000u;
+	p = nmtst_get_rand_uint32 () % 1000u;
 	if (p < 100)
 		rr->flags |= FIB_RULE_INVERT;
 
@@ -1345,8 +1344,7 @@ _rule_fuzzy_equal (const NMPObject *obj,
 			rr_co.tos = 0;
 		if (rr->ip_proto == 0)
 			rr_co.ip_proto = 0;
-		if (rr->suppress_prefixlen_inverse == 0)
-			rr_co.suppress_prefixlen_inverse = 0;
+		rr_co.suppress_prefixlen_inverse = rr->suppress_prefixlen_inverse;
 		if (rr->suppress_ifgroup_inverse == 0)
 			rr_co.suppress_ifgroup_inverse = 0;
 		if (!rr->uid_range_has)
@@ -1483,10 +1481,10 @@ test_rule (gconstpointer test_data)
 
 	if (TEST_IDX != 1) {
 		nmtst_rand_perm (NULL, objs->pdata, NULL, sizeof (gpointer), objs->len);
-		g_ptr_array_set_size (objs, nmtst_get_rand_int () % (objs->len + 1));
+		g_ptr_array_set_size (objs, nmtst_get_rand_uint32 () % (objs->len + 1));
 	}
 
-	n = (TEST_IDX != 1) ? nmtst_get_rand_int () % 50u : 0u;
+	n = (TEST_IDX != 1) ? nmtst_get_rand_uint32 () % 50u : 0u;
 	for (i = 0; i < n; i++) {
 		nm_auto_nmpobj const NMPObject *o = NULL;
 		guint try = 0;
@@ -1536,16 +1534,18 @@ again:
 			nmp_rules_manager_track (rules_manager,
 			                         NMP_OBJECT_CAST_ROUTING_RULE (objs_sync->pdata[i]),
 			                         1,
-			                         USER_TAG_1);
+			                         USER_TAG_1,
+			                         NULL);
 			if (nmtst_get_rand_bool ()) {
 				/* this has no effect, because a negative priority (of same absolute value)
 				 * has lower priority than the positive priority above. */
 				nmp_rules_manager_track (rules_manager,
 				                         NMP_OBJECT_CAST_ROUTING_RULE (objs_sync->pdata[i]),
 				                         -1,
-				                         USER_TAG_2);
+				                         USER_TAG_2,
+				                         NULL);
 			}
-			if (nmtst_get_rand_int () % objs_sync->len == 0) {
+			if (nmtst_get_rand_uint32 () % objs_sync->len == 0) {
 				nmp_rules_manager_sync (rules_manager, FALSE);
 				g_assert_cmpint (nmtstp_platform_routing_rules_get_count (platform, AF_UNSPEC), ==, i + 1);
 			}
@@ -1555,7 +1555,7 @@ again:
 		g_assert_cmpint (nmtstp_platform_routing_rules_get_count (platform, AF_UNSPEC), ==, objs_sync->len);
 
 		for (i = 0; i < objs_sync->len; i++) {
-			switch (nmtst_get_rand_int () % 3) {
+			switch (nmtst_get_rand_uint32 () % 3) {
 			case 0:
 				nmp_rules_manager_untrack (rules_manager,
 				                           NMP_OBJECT_CAST_ROUTING_RULE (objs_sync->pdata[i]),
@@ -1568,16 +1568,18 @@ again:
 				nmp_rules_manager_track (rules_manager,
 				                         NMP_OBJECT_CAST_ROUTING_RULE (objs_sync->pdata[i]),
 				                         -1,
-				                         USER_TAG_1);
+				                         USER_TAG_1,
+				                         NULL);
 				break;
 			case 2:
 				nmp_rules_manager_track (rules_manager,
 				                         NMP_OBJECT_CAST_ROUTING_RULE (objs_sync->pdata[i]),
 				                         -2,
-				                         USER_TAG_2);
+				                         USER_TAG_2,
+				                         NULL);
 				break;
 			}
-			if (nmtst_get_rand_int () % objs_sync->len == 0) {
+			if (nmtst_get_rand_uint32 () % objs_sync->len == 0) {
 				nmp_rules_manager_sync (rules_manager, FALSE);
 				g_assert_cmpint (nmtstp_platform_routing_rules_get_count (platform, AF_UNSPEC), ==, objs_sync->len - i - 1);
 			}