summary refs log tree commit diff
path: root/src/tests
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests')
-rw-r--r--src/tests/config/NetworkManager-warn.conf26
-rw-r--r--src/tests/config/NetworkManager.conf6
-rw-r--r--src/tests/config/meson.build5
-rw-r--r--src/tests/config/nm-test-device.c3
-rw-r--r--src/tests/config/test-config.c77
-rw-r--r--src/tests/meson.build14
-rw-r--r--src/tests/test-dcb.c2
-rw-r--r--src/tests/test-general-with-expect.c5
-rw-r--r--src/tests/test-general.c210
-rw-r--r--src/tests/test-ip4-config.c1
-rw-r--r--src/tests/test-ip6-config.c3
-rw-r--r--src/tests/test-systemd.c125
-rw-r--r--src/tests/test-utils.c14
13 files changed, 381 insertions, 110 deletions
diff --git a/src/tests/config/NetworkManager-warn.conf b/src/tests/config/NetworkManager-warn.conf
new file mode 100644
index 00000000..80df7c52
--- /dev/null
+++ b/src/tests/config/NetworkManager-warn.conf
@@ -0,0 +1,26 @@
+[main]
+dhcp=dhclient
+plugin=foo,bar,baz
+no-auto-default=11:11:11:11:11:11
+rc-managed=unmanaged
+dns=none
+
+[logging]
+level=INFO
+
+[connectivity]
+uri=http://example.com
+interval=100
+response=Hello
+audit=true
+
+[connection]
+ipv4.route-metric=50
+ipv4.addresses=1.2.3.4
+ipv4.dad-timeout=100
+
+[connection-wifi]
+match-device=type:wifi
+wifi.powersave=2
+ipv6.ip6-privacy=1
+wifi.tx-power=99
diff --git a/src/tests/config/NetworkManager.conf b/src/tests/config/NetworkManager.conf
index da7b1fd4..a447b6d6 100644
--- a/src/tests/config/NetworkManager.conf
+++ b/src/tests/config/NetworkManager.conf
@@ -19,8 +19,8 @@ extra-key=some value
 [connection]
 ipv4.route-metric=50
 ipv6.ip6_privacy=0
-dummy.test1=no
-dummy.test2=no
+ethernet.mtu=1400
+ipv4.dns-priority=60
 
 ord.key00=A-0.0.00
 ord.key01=A-0.0.01
@@ -37,7 +37,7 @@ ord.key09=A-0.0.09
 match-device=mac:00:00:00:00:00:51
 stop-match=yes
 ipv4.route-metric=51
-dummy.test1=yes
+ethernet.mtu=9000
 
 [connection.dev52]
 match-device=mac:00:00:00:00:00:52
diff --git a/src/tests/config/meson.build b/src/tests/config/meson.build
index fd6c89b7..f65f90bb 100644
--- a/src/tests/config/meson.build
+++ b/src/tests/config/meson.build
@@ -2,7 +2,7 @@ test_unit = 'test-config'
 
 sources = files(
   'nm-test-device.c',
-  'test-config.c'
+  'test-config.c',
 )
 
 test_config_dir = meson.current_source_dir()
@@ -16,5 +16,6 @@ exe = executable(
 test(
   'config/' + test_unit,
   test_script,
-  args: test_args + [exe.full_path()]
+  args: test_args + [exe.full_path()],
+  timeout: default_test_timeout,
 )
diff --git a/src/tests/config/nm-test-device.c b/src/tests/config/nm-test-device.c
index 49631583..3a8ef266 100644
--- a/src/tests/config/nm-test-device.c
+++ b/src/tests/config/nm-test-device.c
@@ -22,8 +22,6 @@
 
 #include "nm-test-device.h"
 
-#include <string.h>
-
 #include "devices/nm-device-private.h"
 #include "nm-utils.h"
 
@@ -77,6 +75,7 @@ nm_test_device_new (const char *hwaddr)
 	return g_object_new (NM_TYPE_TEST_DEVICE,
 	                     NM_DEVICE_IFACE, "dummy",
 	                     NM_DEVICE_PERM_HW_ADDRESS, hwaddr,
+	                     NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_ETHERNET,
 	                     NULL);
 }
 
diff --git a/src/tests/config/test-config.c b/src/tests/config/test-config.c
index 20a05df1..10084b7f 100644
--- a/src/tests/config/test-config.c
+++ b/src/tests/config/test-config.c
@@ -206,20 +206,20 @@ test_config_simple (void)
 	g_assert_cmpstr (value, ==, "52");
 	g_free (value);
 
-	value = nm_config_data_get_connection_default (nm_config_get_data_orig (config), "dummy.test1", dev51);
-	g_assert_cmpstr (value, ==, "yes");
+	value = nm_config_data_get_connection_default (nm_config_get_data_orig (config), "ethernet.mtu", dev51);
+	g_assert_cmpstr (value, ==, "9000");
 	g_free (value);
 
-	value = nm_config_data_get_connection_default (nm_config_get_data_orig (config), "dummy.test1", dev50);
-	g_assert_cmpstr (value, ==, "no");
+	value = nm_config_data_get_connection_default (nm_config_get_data_orig (config), "ethernet.mtu", dev50);
+	g_assert_cmpstr (value, ==, "1400");
 	g_free (value);
 
-	value = nm_config_data_get_connection_default (nm_config_get_data_orig (config), "dummy.test2", dev51);
+	value = nm_config_data_get_connection_default (nm_config_get_data_orig (config), "ipv4.dns-priority", dev51);
 	g_assert_cmpstr (value, ==, NULL);
 	g_free (value);
 
-	value = nm_config_data_get_connection_default (nm_config_get_data_orig (config), "dummy.test2", dev50);
-	g_assert_cmpstr (value, ==, "no");
+	value = nm_config_data_get_connection_default (nm_config_get_data_orig (config), "ipv4.dns-priority", dev50);
+	g_assert_cmpstr (value, ==, "60");
 	g_free (value);
 }
 
@@ -506,17 +506,17 @@ test_config_confdir (void)
 		gs_free char *_value = nm_config_data_get_connection_default (nm_config_get_data_orig (xconfig), (xname), NULL); \
 		g_assert_cmpstr (_value, ==, (xvalue)); \
 	} G_STMT_END
-	ASSERT_GET_CONN_DEFAULT (config, "ord.key00", "A-0.0.00");
-	ASSERT_GET_CONN_DEFAULT (config, "ord.key01", "A-0.3.01");
-	ASSERT_GET_CONN_DEFAULT (config, "ord.key02", "A-0.2.02");
-	ASSERT_GET_CONN_DEFAULT (config, "ord.key03", "A-0.1.03");
-	ASSERT_GET_CONN_DEFAULT (config, "ord.key04", "B-1.3.04");
-	ASSERT_GET_CONN_DEFAULT (config, "ord.key05", "B-1.2.05");
-	ASSERT_GET_CONN_DEFAULT (config, "ord.key06", "B-1.1.06");
-	ASSERT_GET_CONN_DEFAULT (config, "ord.key07", "C-2.3.07");
-	ASSERT_GET_CONN_DEFAULT (config, "ord.key08", "C-2.2.08");
-	ASSERT_GET_CONN_DEFAULT (config, "ord.key09", "C-2.1.09");
-	ASSERT_GET_CONN_DEFAULT (config, "ord.ovw01", "C-0.1.ovw01");
+	ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.key00"), "A-0.0.00");
+	ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.key01"), "A-0.3.01");
+	ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.key02"), "A-0.2.02");
+	ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.key03"), "A-0.1.03");
+	ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.key04"), "B-1.3.04");
+	ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.key05"), "B-1.2.05");
+	ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.key06"), "B-1.1.06");
+	ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.key07"), "C-2.3.07");
+	ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.key08"), "C-2.2.08");
+	ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.key09"), "C-2.1.09");
+	ASSERT_GET_CONN_DEFAULT (config, NM_CON_DEFAULT ("ord.ovw01"), "C-0.1.ovw01");
 
 	value = nm_config_data_get_value (nm_config_get_data_orig (config), NM_CONFIG_KEYFILE_GROUPPREFIX_TEST_APPEND_STRINGLIST".1", "val1", NM_CONFIG_GET_VALUE_NONE);
 	g_assert_cmpstr (value, ==, "a,c");
@@ -552,6 +552,36 @@ test_config_confdir_parse_error (void)
 	g_clear_error (&error);
 }
 
+static void
+test_config_warnings (void)
+{
+	gs_unref_object NMConfig *config = NULL;
+	const char *const *warnings;
+
+	config = setup_config (NULL, TEST_DIR "/NetworkManager-warn.conf", "", NULL, "/no/such/dir", "", NULL);
+
+	warnings = nm_config_get_warnings (config);
+
+#define check_warning(str, group, key) \
+	{ \
+		gs_free char *expected = NULL; \
+		\
+		expected = g_strdup_printf ("unknown key '%s' in section [%s] of file '" TEST_DIR "/NetworkManager-warn.conf'", \
+		                            key, group); \
+		g_assert_cmpstr (str, ==, expected); \
+	}
+
+	g_assert (warnings);
+	g_assert_cmpint (g_strv_length ((char **) warnings), ==, 5);
+	check_warning (warnings[0], "main", "plugin");
+	check_warning (warnings[1], "main", "rc-managed");
+	check_warning (warnings[2], "connectivity", "audit");
+	check_warning (warnings[3], "connection-wifi", "wifi.tx-power");
+	check_warning (warnings[4], "connection", "ipv4.addresses");
+
+#undef check_warning
+}
+
 /*****************************************************************************/
 
 typedef void (*TestSetValuesUserSetFcn) (NMConfig *config, gboolean is_user, GKeyFile *keyfile_user, NMConfigChangeFlags *out_expected_changes);
@@ -622,7 +652,7 @@ _set_values_user (NMConfig *config,
 	else
 		NMTST_EXPECT_NM_INFO ("config: signal: SIGHUP (no changes from disk)*");
 
-	nm_config_reload (config, NM_CONFIG_CHANGE_CAUSE_SIGHUP);
+	nm_config_reload (config, NM_CONFIG_CHANGE_CAUSE_SIGHUP, FALSE);
 
 	g_test_assert_expected_messages ();
 
@@ -926,15 +956,15 @@ test_config_signal (void)
 
 	expected = NM_CONFIG_CHANGE_CAUSE_SIGUSR1;
 	NMTST_EXPECT_NM_INFO ("config: signal: SIGUSR1");
-	nm_config_reload (config, expected);
+	nm_config_reload (config, expected, FALSE);
 
 	expected = NM_CONFIG_CHANGE_CAUSE_SIGUSR2;
 	NMTST_EXPECT_NM_INFO ("config: signal: SIGUSR2");
-	nm_config_reload (config, expected);
+	nm_config_reload (config, expected, FALSE);
 
 	expected = NM_CONFIG_CHANGE_CAUSE_SIGHUP;
 	NMTST_EXPECT_NM_INFO ("config: signal: SIGHUP (no changes from disk)*");
-	nm_config_reload (config, expected);
+	nm_config_reload (config, expected, FALSE);
 
 	/* test with subscribing two signals...
 	 *
@@ -946,7 +976,7 @@ test_config_signal (void)
 	                  &expected);
 	expected = NM_CONFIG_CHANGE_CAUSE_SIGUSR2;
 	NMTST_EXPECT_NM_INFO ("config: signal: SIGUSR2");
-	nm_config_reload (config, NM_CONFIG_CHANGE_CAUSE_SIGUSR2);
+	nm_config_reload (config, NM_CONFIG_CHANGE_CAUSE_SIGUSR2, FALSE);
 	g_signal_handlers_disconnect_by_func (config, _test_signal_config_changed_cb2, &expected);
 
 	g_signal_handlers_disconnect_by_func (config, _test_signal_config_changed_cb, &expected);
@@ -1064,6 +1094,7 @@ main (int argc, char **argv)
 	g_test_add_func ("/config/no-auto-default", test_config_no_auto_default);
 	g_test_add_func ("/config/confdir", test_config_confdir);
 	g_test_add_func ("/config/confdir-parse-error", test_config_confdir_parse_error);
+	g_test_add_func ("/config/warnings", test_config_warnings);
 
 	g_test_add_func ("/config/set-values", test_config_set_values);
 	g_test_add_func ("/config/global-dns", test_config_global_dns);
diff --git a/src/tests/meson.build b/src/tests/meson.build
index 430ffe43..153128f2 100644
--- a/src/tests/meson.build
+++ b/src/tests/meson.build
@@ -7,20 +7,21 @@ test_units = [
   'test-ip6-config',
   'test-dcb',
   'test-wired-defname',
-  'test-utils'
+  'test-utils',
 ]
 
 foreach test_unit: test_units
   exe = executable(
     test_unit,
     test_unit + '.c',
-    dependencies: test_nm_dep
+    dependencies: test_nm_dep,
   )
 
   test(
     'src/' + test_unit,
     test_script,
-    args: test_args + [exe.full_path()]
+    args: test_args + [exe.full_path()],
+    timeout: default_test_timeout,
   )
 endforeach
 
@@ -37,11 +38,14 @@ exe = executable(
   include_directories: src_inc,
   dependencies: nm_core_dep,
   c_args: cflags,
-  link_with: libsystemd_nm
+  link_with: [
+    libnm_systemd_core,
+    libnm_systemd_shared,
+  ],
 )
 
 test(
   'src/' + test_unit,
   test_script,
-  args: test_args + [exe.full_path()]
+  args: test_args + [exe.full_path()],
 )
diff --git a/src/tests/test-dcb.c b/src/tests/test-dcb.c
index 2ab0f890..6291f254 100644
--- a/src/tests/test-dcb.c
+++ b/src/tests/test-dcb.c
@@ -20,8 +20,6 @@
 
 #include "nm-default.h"
 
-#include <string.h>
-
 #include "nm-dcb.h"
 
 #include "nm-test-utils-core.h"
diff --git a/src/tests/test-general-with-expect.c b/src/tests/test-general-with-expect.c
index ba8e3ce4..8339fa5d 100644
--- a/src/tests/test-general-with-expect.c
+++ b/src/tests/test-general-with-expect.c
@@ -20,8 +20,6 @@
 
 #include "nm-default.h"
 
-#include <string.h>
-#include <errno.h>
 #include <time.h>
 #include <netinet/ether.h>
 #include <sys/types.h>
@@ -42,7 +40,8 @@ test_nm_utils_monotonic_timestamp_as_boottime (void)
 	clockid_t clockid;
 	guint i;
 
-	if (clock_gettime (CLOCK_BOOTTIME, &tp) != 0 && errno == EINVAL)
+	if (   clock_gettime (CLOCK_BOOTTIME, &tp) != 0
+	    && errno == EINVAL)
 		clockid = CLOCK_MONOTONIC;
 	else
 		clockid = CLOCK_BOOTTIME;
diff --git a/src/tests/test-general.c b/src/tests/test-general.c
index 9dce9435..0dee566e 100644
--- a/src/tests/test-general.c
+++ b/src/tests/test-general.c
@@ -20,8 +20,6 @@
 
 #include "nm-default.h"
 
-#include <string.h>
-#include <errno.h>
 #include <net/if.h>
 #include <byteswap.h>
 
@@ -31,7 +29,7 @@
 #include "NetworkManagerUtils.h"
 #include "nm-core-internal.h"
 #include "nm-core-utils.h"
-#include "systemd/nm-sd-utils.h"
+#include "systemd/nm-sd-utils-core.h"
 
 #include "dns/nm-dns-manager.h"
 #include "nm-connectivity.h"
@@ -352,13 +350,13 @@ _match_connection (GSList *connections,
                    gint64 default_v4_metric,
                    gint64 default_v6_metric)
 {
-	NMConnection **list;
+	gs_free NMConnection **list = NULL;
 	guint i, len;
 
 	len = g_slist_length (connections);
 	g_assert (len < 10);
 
-	list = g_alloca ((len + 1) * sizeof (NMConnection *));
+	list = g_malloc ((len + 1) * sizeof (NMConnection *));
 	for (i = 0; i < len; i++, connections = connections->next) {
 		g_assert (connections);
 		g_assert (connections->data);
@@ -1116,7 +1114,10 @@ _test_match_spec_device (const GSList *specs, const char *match_str)
 }
 
 static void
-_do_test_match_spec_device (const char *spec_str, const char **matches, const char **no_matches, const char **neg_matches)
+_do_test_match_spec_device (const char *spec_str,
+                            const char *const *matches,
+                            const char *const *no_matches,
+                            const char *const *neg_matches)
 {
 	GSList *specs, *specs_randperm = NULL, *specs_resplit, *specs_i, *specs_j;
 	guint i;
@@ -1188,102 +1189,100 @@ _do_test_match_spec_device (const char *spec_str, const char **matches, const ch
 static void
 test_match_spec_device (void)
 {
-#define S(...) ((const char *[]) { __VA_ARGS__, NULL } )
 	_do_test_match_spec_device ("em1",
-	                            S ("em1"),
+	                            NM_MAKE_STRV ("em1"),
 	                            NULL,
 	                            NULL);
 	_do_test_match_spec_device ("em1,em2",
-	                            S ("em1", "em2"),
+	                            NM_MAKE_STRV ("em1", "em2"),
 	                            NULL,
 	                            NULL);
 	_do_test_match_spec_device ("em1,em2,interface-name:em2",
-	                            S ("em1", "em2"),
+	                            NM_MAKE_STRV ("em1", "em2"),
 	                            NULL,
 	                            NULL);
 	_do_test_match_spec_device ("interface-name:em1",
-	                            S ("em1"),
+	                            NM_MAKE_STRV ("em1"),
 	                            NULL,
 	                            NULL);
 	_do_test_match_spec_device ("interface-name:em*",
-	                            S ("em", "em*", "em\\", "em\\*", "em\\1", "em\\11", "em\\2", "em1", "em11", "em2", "em3"),
+	                            NM_MAKE_STRV ("em", "em*", "em\\", "em\\*", "em\\1", "em\\11", "em\\2", "em1", "em11", "em2", "em3"),
 	                            NULL,
 	                            NULL);
 	_do_test_match_spec_device ("interface-name:em\\*",
-	                            S ("em\\", "em\\*", "em\\1", "em\\11", "em\\2"),
+	                            NM_MAKE_STRV ("em\\", "em\\*", "em\\1", "em\\11", "em\\2"),
 	                            NULL,
 	                            NULL);
 	_do_test_match_spec_device ("interface-name:~em\\*",
-	                            S ("em\\", "em\\*", "em\\1", "em\\11", "em\\2"),
+	                            NM_MAKE_STRV ("em\\", "em\\*", "em\\1", "em\\11", "em\\2"),
 	                            NULL,
 	                            NULL);
 	_do_test_match_spec_device ("except:*",
 	                            NULL,
-	                            S (NULL),
-	                            S ("a"));
+	                            NM_MAKE_STRV (NULL),
+	                            NM_MAKE_STRV ("a"));
 	_do_test_match_spec_device ("interface-name:=em*",
-	                            S ("em*"),
+	                            NM_MAKE_STRV ("em*"),
 	                            NULL,
 	                            NULL);
 	_do_test_match_spec_device ("interface-name:em*,except:interface-name:em1*",
-	                            S ("em", "em*", "em\\", "em\\*", "em\\1", "em\\11", "em\\2", "em2", "em3"),
+	                            NM_MAKE_STRV ("em", "em*", "em\\", "em\\*", "em\\1", "em\\11", "em\\2", "em2", "em3"),
 	                            NULL,
-	                            S ("em1", "em11"));
+	                            NM_MAKE_STRV ("em1", "em11"));
 	_do_test_match_spec_device ("interface-name:em*,except:interface-name:=em*",
-	                            S ("em", "em\\", "em\\*", "em\\1", "em\\11", "em\\2", "em1", "em11", "em2", "em3"),
+	                            NM_MAKE_STRV ("em", "em\\", "em\\*", "em\\1", "em\\11", "em\\2", "em1", "em11", "em2", "em3"),
 	                            NULL,
-	                            S ("em*"));
+	                            NM_MAKE_STRV ("em*"));
 	_do_test_match_spec_device ("except:interface-name:em*",
-	                            S ("", "eth", "eth1", "e1"),
-	                            S (NULL),
-	                            S ("em", "em\\", "em\\*", "em\\1", "em\\11", "em\\2", "em1", "em11", "em2", "em3"));
+	                            NM_MAKE_STRV ("", "eth", "eth1", "e1"),
+	                            NM_MAKE_STRV (NULL),
+	                            NM_MAKE_STRV ("em", "em\\", "em\\*", "em\\1", "em\\11", "em\\2", "em1", "em11", "em2", "em3"));
 	_do_test_match_spec_device ("aa,bb,cc\\,dd,e,,",
-	                            S ("aa", "bb", "cc,dd", "e"),
+	                            NM_MAKE_STRV ("aa", "bb", "cc,dd", "e"),
 	                            NULL,
 	                            NULL);
 	_do_test_match_spec_device ("aa;bb;cc\\;dd;e,;",
-	                            S ("aa", "bb", "cc;dd", "e"),
+	                            NM_MAKE_STRV ("aa", "bb", "cc;dd", "e"),
 	                            NULL,
 	                            NULL);
 	_do_test_match_spec_device ("interface-name:em\\;1,em\\,2,\\,,\\\\,,em\\\\x",
-	                            S ("em;1", "em,2", ",", "\\", "em\\x"),
+	                            NM_MAKE_STRV ("em;1", "em,2", ",", "\\", "em\\x"),
 	                            NULL,
 	                            NULL);
 	_do_test_match_spec_device ("\\s\\s,\\sinterface-name:a,\\s,",
-	                            S ("  ", " ", " interface-name:a"),
+	                            NM_MAKE_STRV ("  ", " ", " interface-name:a"),
 	                            NULL,
 	                            NULL);
 	_do_test_match_spec_device (" aa ;  bb   ; cc\\;dd  ;e , ; \t\\t  , ",
-	                            S ("aa", "bb", "cc;dd", "e", "\t"),
+	                            NM_MAKE_STRV ("aa", "bb", "cc;dd", "e", "\t"),
 	                            NULL,
 	                            NULL);
 
 	_do_test_match_spec_device ("s390-subchannels:0.0.1000\\,0.0.1001",
-	                            S (MATCH_S390"0.0.1000", MATCH_S390"0.0.1000,deadbeef", MATCH_S390"0.0.1000,0.0.1001", MATCH_S390"0.0.1000,0.0.1002"),
-	                            S (MATCH_S390"0.0.1001"),
+	                            NM_MAKE_STRV (MATCH_S390"0.0.1000", MATCH_S390"0.0.1000,deadbeef", MATCH_S390"0.0.1000,0.0.1001", MATCH_S390"0.0.1000,0.0.1002"),
+	                            NM_MAKE_STRV (MATCH_S390"0.0.1001"),
 	                            NULL);
 	_do_test_match_spec_device ("*,except:s390-subchannels:0.0.1000\\,0.0.1001",
 	                            NULL,
-	                            S (NULL),
-	                            S (MATCH_S390"0.0.1000", MATCH_S390"0.0.1000,deadbeef", MATCH_S390"0.0.1000,0.0.1001", MATCH_S390"0.0.1000,0.0.1002"));
+	                            NM_MAKE_STRV (NULL),
+	                            NM_MAKE_STRV (MATCH_S390"0.0.1000", MATCH_S390"0.0.1000,deadbeef", MATCH_S390"0.0.1000,0.0.1001", MATCH_S390"0.0.1000,0.0.1002"));
 
 	_do_test_match_spec_device ("driver:DRV",
-	                            S (MATCH_DRIVER"DRV", MATCH_DRIVER"DRV|1.6"),
-	                            S (MATCH_DRIVER"DR", MATCH_DRIVER"DR*"),
+	                            NM_MAKE_STRV (MATCH_DRIVER"DRV", MATCH_DRIVER"DRV|1.6"),
+	                            NM_MAKE_STRV (MATCH_DRIVER"DR", MATCH_DRIVER"DR*"),
 	                            NULL);
 	_do_test_match_spec_device ("driver:DRV//",
-	                            S (MATCH_DRIVER"DRV/"),
-	                            S (MATCH_DRIVER"DRV/|1.6", MATCH_DRIVER"DR", MATCH_DRIVER"DR*"),
+	                            NM_MAKE_STRV (MATCH_DRIVER"DRV/"),
+	                            NM_MAKE_STRV (MATCH_DRIVER"DRV/|1.6", MATCH_DRIVER"DR", MATCH_DRIVER"DR*"),
 	                            NULL);
 	_do_test_match_spec_device ("driver:DRV//*",
-	                            S (MATCH_DRIVER"DRV/", MATCH_DRIVER"DRV/|1.6"),
-	                            S (MATCH_DRIVER"DR", MATCH_DRIVER"DR*"),
+	                            NM_MAKE_STRV (MATCH_DRIVER"DRV/", MATCH_DRIVER"DRV/|1.6"),
+	                            NM_MAKE_STRV (MATCH_DRIVER"DR", MATCH_DRIVER"DR*"),
 	                            NULL);
 	_do_test_match_spec_device ("driver:DRV//1.5*",
-	                            S (MATCH_DRIVER"DRV/|1.5", MATCH_DRIVER"DRV/|1.5.2"),
-	                            S (MATCH_DRIVER"DRV/", MATCH_DRIVER"DRV/|1.6", MATCH_DRIVER"DR", MATCH_DRIVER"DR*"),
+	                            NM_MAKE_STRV (MATCH_DRIVER"DRV/|1.5", MATCH_DRIVER"DRV/|1.5.2"),
+	                            NM_MAKE_STRV (MATCH_DRIVER"DRV/", MATCH_DRIVER"DRV/|1.6", MATCH_DRIVER"DR", MATCH_DRIVER"DR*"),
 	                            NULL);
-#undef S
 }
 
 /*****************************************************************************/
@@ -1307,7 +1306,7 @@ _do_test_match_spec_config (const char *file, int line, const char *spec_str, gu
 	match_result = nm_match_spec_config (specs, version, NULL);
 
 	if (expected != match_result)
-		g_error ("%s:%d: faild comparing \"%s\" with %u.%u.%u. Expected %d, but got %d", file, line, spec_str, v_maj, v_min, v_mic, (int) expected, (int) match_result);
+		g_error ("%s:%d: failed comparing \"%s\" with %u.%u.%u. Expected %d, but got %d", file, line, spec_str, v_maj, v_min, v_mic, (int) expected, (int) match_result);
 
 	if (   g_slist_length (specs) == 1
 	    && !g_str_has_prefix (specs->data, "except:")) {
@@ -1439,6 +1438,82 @@ test_nm_utils_strbuf_append (void)
 	char buf[NM_STRLEN (BUF_ORIG) + 1];
 	char str[NM_STRLEN (BUF_ORIG) + 1];
 
+#define _strbuf_append(buf, len, format, ...) \
+	G_STMT_START { \
+		char **_buf = (buf); \
+		gsize *_len = (len); \
+		const char *_str_iter; \
+		gs_free char *_str = NULL; \
+		\
+		switch (nmtst_get_rand_int () % 4) { \
+		case 0: \
+			nm_utils_strbuf_append (_buf, _len, (format), __VA_ARGS__); \
+			break; \
+		case 1: \
+			_str = g_strdup_printf ((format), __VA_ARGS__); \
+			nm_utils_strbuf_append_str (_buf, _len, _str); \
+			break; \
+		case 2: \
+			_str = g_strdup_printf ((format), __VA_ARGS__); \
+			nm_utils_strbuf_append_bin (_buf, _len, _str, strlen (_str)); \
+			break; \
+		case 3: \
+			_str = g_strdup_printf ((format), __VA_ARGS__); \
+			if (!_str[0]) \
+				nm_utils_strbuf_append_str (_buf, _len, _str); \
+			for (_str_iter = _str; _str_iter[0]; _str_iter++) \
+				nm_utils_strbuf_append_c (_buf, _len, _str_iter[0]); \
+			break; \
+		} \
+	} G_STMT_END
+
+#define _strbuf_append_str(buf, len, str) \
+	G_STMT_START { \
+		char **_buf = (buf); \
+		gsize *_len = (len); \
+		const char *_str = (str); \
+		\
+		switch (nmtst_get_rand_int () % 4) { \
+		case 0: \
+			nm_utils_strbuf_append (_buf, _len, "%s", _str ?: ""); \
+			break; \
+		case 1: \
+			nm_utils_strbuf_append_str (_buf, _len, _str); \
+			break; \
+		case 2: \
+			nm_utils_strbuf_append_bin (_buf, _len, _str, _str ? strlen (_str) : 0); \
+			break; \
+		case 3: \
+			if (!_str || !_str[0]) \
+				nm_utils_strbuf_append_str (_buf, _len, _str); \
+			for (; _str && _str[0]; _str++) \
+				nm_utils_strbuf_append_c (_buf, _len, _str[0]); \
+			break; \
+		} \
+	} G_STMT_END
+
+#define _strbuf_append_c(buf, len, ch) \
+	G_STMT_START { \
+		char **_buf = (buf); \
+		gsize *_len = (len); \
+		char _ch = (ch); \
+		\
+		switch (nmtst_get_rand_int () % 4) { \
+		case 0: \
+			nm_utils_strbuf_append (_buf, _len, "%c", _ch); \
+			break; \
+		case 1: \
+			nm_utils_strbuf_append_str (_buf, _len, ((char[2]) { _ch, 0 })); \
+			break; \
+		case 2: \
+			nm_utils_strbuf_append_bin (_buf, _len, &_ch, 1); \
+			break; \
+		case 3: \
+			nm_utils_strbuf_append_c (_buf, _len, _ch); \
+			break; \
+		} \
+	} G_STMT_END
+
 	for (buf_len = 0; buf_len < 10; buf_len++) {
 		for (rep = 0; rep < 50; rep++) {
 			const int s_len = nmtst_get_rand_int () % (sizeof (str) - 5);
@@ -1462,21 +1537,21 @@ test_nm_utils_strbuf_append (void)
 			switch (test_mode) {
 			case 0:
 				if (s_len == 1) {
-					nm_utils_strbuf_append_c (&t_buf, &t_len, str[0]);
+					_strbuf_append_c (&t_buf, &t_len, str[0]);
 					break;
 				}
 				/* fall through */
 			case 1:
-				nm_utils_strbuf_append_str (&t_buf, &t_len, str);
+				_strbuf_append_str (&t_buf, &t_len, str);
 				break;
 			case 2:
 				if (s_len == 1) {
-					nm_utils_strbuf_append (&t_buf, &t_len, "%c", str[0]);
+					_strbuf_append (&t_buf, &t_len, "%c", str[0]);
 					break;
 				}
 				/* fall through */
 			case 3:
-				nm_utils_strbuf_append (&t_buf, &t_len, "%s", str);
+				_strbuf_append (&t_buf, &t_len, "%s", str);
 				break;
 			case 4:
 				g_snprintf (t_buf, t_len, "%s", str);
@@ -1589,7 +1664,7 @@ test_duplicate_decl_specifier (void)
 	/* have some static variables, so that the result is certainly not optimized out. */
 	static const int v_const[1] = { 1 };
 	static int v_result[1] = { };
-	const const int v2 = 3;
+	const int v2 = 3;
 
 	/* Test that we don't get a compiler warning about duplicate const specifier.
 	 * C99 allows that and it can easily happen in macros. */
@@ -1858,6 +1933,25 @@ test_nm_utils_exp10 (void)
 
 /*****************************************************************************/
 
+static void
+test_utils_file_is_in_path (void)
+{
+	g_assert (!nm_utils_file_is_in_path ("/", "/"));
+	g_assert (!nm_utils_file_is_in_path ("//", "/"));
+	g_assert (!nm_utils_file_is_in_path ("/a/", "/"));
+	g_assert ( nm_utils_file_is_in_path ("/a", "/"));
+	g_assert ( nm_utils_file_is_in_path ("///a", "/"));
+	g_assert ( nm_utils_file_is_in_path ("//b/a", "/b//"));
+	g_assert ( nm_utils_file_is_in_path ("//b///a", "/b//"));
+	g_assert (!nm_utils_file_is_in_path ("//b///a/", "/b//"));
+	g_assert (!nm_utils_file_is_in_path ("//b///a/", "/b/a/"));
+	g_assert (!nm_utils_file_is_in_path ("//b///a", "/b/a/"));
+	g_assert ( nm_utils_file_is_in_path ("//b///a/.", "/b/a/"));
+	g_assert ( nm_utils_file_is_in_path ("//b///a/..", "/b/a/"));
+}
+
+/*****************************************************************************/
+
 #define _TEST_RC(searches, nameservers, options, expected) \
 	G_STMT_START { \
 		const char *const*const _searches = (searches); \
@@ -1918,11 +2012,11 @@ test_machine_id_read (void)
 	nmtst_logging_reenable (logstate);
 
 	g_assert (machine_id);
-	g_assert (_nm_utils_bin2hexstr_full (machine_id,
-	                                     sizeof (NMUuid),
-	                                     '\0',
-	                                     FALSE,
-	                                     machine_id_str) == machine_id_str);
+	g_assert (nm_utils_bin2hexstr_full (machine_id,
+	                                    sizeof (NMUuid),
+	                                    '\0',
+	                                    FALSE,
+	                                    machine_id_str) == machine_id_str);
 	g_assert (strlen (machine_id_str) == 32);
 	g_assert_cmpstr (machine_id_str, ==, nm_utils_machine_id_str ());
 
@@ -1959,14 +2053,14 @@ test_nm_utils_dhcp_client_id_systemd_node_specific (gconstpointer test_data)
 		guint64 duid_id;
 	} d_array[] = {
 		[0] = {
-			.machine_id = { 0xcb, 0xc2, 0x2e, 0x47, 0x41, 0x8e, 0x40, 0x2a, 0xa7, 0xb3, 0x0d, 0xea, 0x92, 0x83, 0x94, 0xef },
+			.machine_id.uuid = { 0xcb, 0xc2, 0x2e, 0x47, 0x41, 0x8e, 0x40, 0x2a, 0xa7, 0xb3, 0x0d, 0xea, 0x92, 0x83, 0x94, 0xef },
 			.ifname = "lo",
 			.ifname_hash_1 = 0x7297085c2b12c911llu,
 			.iaid_ifname = htobe32 (0x5985c14du),
 			.duid_id = htobe64 (0x3d769bb2c14d29e1u),
 		},
 		[1] = {
-			.machine_id = { 0x11, 0x4e, 0xb4, 0xda, 0xd3, 0x22, 0x4a, 0xff, 0x9f, 0xc3, 0x30, 0x83, 0x38, 0xa0, 0xeb, 0xb7 },
+			.machine_id.uuid = { 0x11, 0x4e, 0xb4, 0xda, 0xd3, 0x22, 0x4a, 0xff, 0x9f, 0xc3, 0x30, 0x83, 0x38, 0xa0, 0xeb, 0xb7 },
 			.ifname = "eth0",
 			.ifname_hash_1 = 0x9e1cb083b54cd7b6llu,
 			.iaid_ifname = htobe32 (0x2b506735u),
@@ -2016,6 +2110,10 @@ test_nm_utils_dhcp_client_id_systemd_node_specific (gconstpointer test_data)
 		g_assert_cmpmem (&cid[5], 2, &duid_type_en, sizeof (duid_type_en));
 		g_assert_cmpmem (&cid[7], 4, &systemd_pen, sizeof (systemd_pen));
 		g_assert_cmpmem (&cid[11], 8, &d->duid_id, sizeof (d->duid_id));
+
+		g_assert_cmpint (iaid, ==, htonl (nm_utils_create_dhcp_iaid (legacy_unstable_byteorder,
+		                                                             (const guint8 *) d->ifname,
+		                                                             strlen (d->ifname))));
 	}
 }
 
@@ -2123,6 +2221,8 @@ main (int argc, char **argv)
 
 	g_test_add_func ("/general/machine-id/read", test_machine_id_read);
 
+	g_test_add_func ("/general/test_utils_file_is_in_path", test_utils_file_is_in_path);
+
 	g_test_add_func ("/general/test_dns_create_resolv_conf", test_dns_create_resolv_conf);
 
 	g_test_add_data_func ("/general/nm_utils_dhcp_client_id_systemd_node_specific/0", GINT_TO_POINTER (0), test_nm_utils_dhcp_client_id_systemd_node_specific);
diff --git a/src/tests/test-ip4-config.c b/src/tests/test-ip4-config.c
index 9fea6af5..f98c84c3 100644
--- a/src/tests/test-ip4-config.c
+++ b/src/tests/test-ip4-config.c
@@ -20,7 +20,6 @@
 
 #include "nm-default.h"
 
-#include <string.h>
 #include <arpa/inet.h>
 
 #include "nm-ip4-config.h"
diff --git a/src/tests/test-ip6-config.c b/src/tests/test-ip6-config.c
index 5b255068..8f5f41d7 100644
--- a/src/tests/test-ip6-config.c
+++ b/src/tests/test-ip6-config.c
@@ -20,7 +20,6 @@
 
 #include "nm-default.h"
 
-#include <string.h>
 #include <arpa/inet.h>
 #include <linux/if_addr.h>
 
@@ -252,7 +251,7 @@ test_nm_ip6_config_addresses_sort_check (NMIP6Config *config, NMSettingIP6Config
 	copy2 = nm_ip6_config_clone (config);
 	g_assert (copy2);
 
-	/* initialize the array of indeces, and keep shuffling them for every @repeat iteration. */
+	/* initialize the array of indices, and keep shuffling them for every @repeat iteration. */
 	for (i = 0; i < addr_count; i++)
 		idx[i] = i;
 
diff --git a/src/tests/test-systemd.c b/src/tests/test-systemd.c
index 4660bd0d..91edcab2 100644
--- a/src/tests/test-systemd.c
+++ b/src/tests/test-systemd.c
@@ -20,7 +20,7 @@
 #include "nm-default.h"
 
 #include "systemd/nm-sd.h"
-#include "systemd/nm-sd-utils.h"
+#include "systemd/nm-sd-utils-shared.h"
 
 #include "nm-test-utils-core.h"
 
@@ -48,10 +48,19 @@ nm_utils_get_monotonic_timestamp_s (void)
 
 NMLogDomain _nm_logging_enabled_state[_LOGL_N_REAL];
 
+gboolean
+_nm_log_enabled_impl (gboolean mt_require_locking,
+                      NMLogLevel level,
+                      NMLogDomain domain)
+{
+	return FALSE;
+}
+
 void
 _nm_log_impl (const char *file,
               guint line,
               const char *func,
+              gboolean mt_require_locking,
               NMLogLevel level,
               NMLogDomain domain,
               int error,
@@ -71,6 +80,12 @@ nm_logging_setup (const char  *level,
 	return TRUE;
 }
 
+const char *
+nm_strerror_native (int errsv)
+{
+	return g_strerror (errsv);
+}
+
 /*****************************************************************************/
 
 static void
@@ -201,16 +216,16 @@ test_path_equal (void)
 	} G_STMT_END
 
 	_path_equal_check ("",                  "",                NULL);
-	_path_equal_check (".",                 ".",               "");
+	_path_equal_check (".",                 ".",               NULL);
 	_path_equal_check ("..",                "..",              NULL);
 	_path_equal_check ("/..",               "/..",             NULL);
 	_path_equal_check ("//..",              "/..",             NULL);
 	_path_equal_check ("/.",                "/.",              "/");
-	_path_equal_check ("./",                ".",               "");
-	_path_equal_check ("./.",               "./.",             "");
-	_path_equal_check (".///.",             "./.",             "");
-	_path_equal_check (".///./",            "./.",             "");
-	_path_equal_check (".////",             ".",               "");
+	_path_equal_check ("./",                ".",               ".");
+	_path_equal_check ("./.",               "./.",             ".");
+	_path_equal_check (".///.",             "./.",             ".");
+	_path_equal_check (".///./",            "./.",             ".");
+	_path_equal_check (".////",             ".",               ".");
 	_path_equal_check ("//..//foo/",        "/../foo",         NULL);
 	_path_equal_check ("///foo//./bar/.",   "/foo/./bar/.",    "/foo/bar");
 	_path_equal_check (".//./foo//./bar/.", "././foo/./bar/.", "foo/bar");
@@ -218,6 +233,101 @@ test_path_equal (void)
 
 /*****************************************************************************/
 
+static void
+_test_unbase64char (char ch, gboolean maybe_invalid)
+{
+	int r;
+
+	r = nm_sd_utils_unbase64char (ch, FALSE);
+
+	if (ch == '=') {
+		g_assert (!maybe_invalid);
+		g_assert_cmpint (r, <, 0);
+		g_assert_cmpint (nm_sd_utils_unbase64char (ch, TRUE), ==, G_MAXINT);
+	} else {
+		g_assert_cmpint (r, ==, nm_sd_utils_unbase64char (ch, TRUE));
+		if (r >= 0)
+			g_assert_cmpint (r, <=, 255);
+		if (!maybe_invalid)
+			g_assert_cmpint (r, >=, 0);
+	}
+}
+
+static void
+_test_unbase64mem_mem (const char *base64, const guint8 *expected_arr, gsize expected_len)
+{
+	gs_free char *expected_base64 = NULL;
+	int r;
+	gs_free guint8 *exp2_arr = NULL;
+	gs_free guint8 *exp3_arr = NULL;
+	gsize exp2_len;
+	gsize exp3_len;
+	gsize i;
+
+	expected_base64 = g_base64_encode (expected_arr, expected_len);
+
+	for (i = 0; expected_base64[i]; i++)
+		_test_unbase64char (expected_base64[i], FALSE);
+
+	r = nm_sd_utils_unbase64mem (expected_base64, strlen (expected_base64), &exp2_arr, &exp2_len);
+	g_assert_cmpint (r, ==, 0);
+	g_assert_cmpmem (expected_arr, expected_len, exp2_arr, exp2_len);
+
+	if (!nm_streq (base64, expected_base64)) {
+		r = nm_sd_utils_unbase64mem (base64, strlen (base64), &exp3_arr, &exp3_len);
+		g_assert_cmpint (r, ==, 0);
+		g_assert_cmpmem (expected_arr, expected_len, exp3_arr, exp3_len);
+	}
+}
+
+#define _test_unbase64mem(base64, expected_str) _test_unbase64mem_mem (base64, (const guint8 *) ""expected_str"", NM_STRLEN (expected_str))
+
+static void
+_test_unbase64mem_inval (const char *base64)
+{
+	gs_free guint8 *exp_arr = NULL;
+	gsize exp_len = 0;
+	int r;
+
+	r = nm_sd_utils_unbase64mem (base64, strlen (base64), &exp_arr, &exp_len);
+	g_assert_cmpint (r, <, 0);
+	g_assert (!exp_arr);
+	g_assert (exp_len == 0);
+}
+
+static void
+test_nm_sd_utils_unbase64mem (void)
+{
+	gs_free char *rnd_base64 = NULL;
+	guint8 rnd_buf[30];
+	guint i, rnd_len;
+
+	_test_unbase64mem ("", "");
+	_test_unbase64mem ("  ", "");
+	_test_unbase64mem (" Y Q == ", "a");
+	_test_unbase64mem (" Y   WJjZGV mZ 2g = ", "abcdefgh");
+	_test_unbase64mem_inval (" Y   %WJjZGV mZ 2g = ");
+	_test_unbase64mem_inval (" Y   %WJjZGV mZ 2g = a");
+	_test_unbase64mem ("YQ==", "a");
+	_test_unbase64mem_inval ("YQ==a");
+
+	rnd_len = nmtst_get_rand_int () % sizeof (rnd_buf);
+	for (i = 0; i < rnd_len; i++)
+		rnd_buf[i] = nmtst_get_rand_int () % 256;
+	rnd_base64 = g_base64_encode (rnd_buf, rnd_len);
+	_test_unbase64mem_mem (rnd_base64, rnd_buf, rnd_len);
+
+	_test_unbase64char ('=', FALSE);
+	for (i = 0; i < 10; i++) {
+		char ch = nmtst_get_rand_int () % 256;
+
+		if (ch != '=')
+			_test_unbase64char (ch, TRUE);
+	}
+}
+
+/*****************************************************************************/
+
 NMTST_DEFINE ();
 
 int
@@ -229,6 +339,7 @@ main (int argc, char **argv)
 	g_test_add_func ("/systemd/lldp/create", test_lldp_create);
 	g_test_add_func ("/systemd/sd-event", test_sd_event);
 	g_test_add_func ("/systemd/test_path_equal", test_path_equal);
+	g_test_add_func ("/systemd/test_nm_sd_utils_unbase64mem", test_nm_sd_utils_unbase64mem);
 
 	return g_test_run ();
 }
diff --git a/src/tests/test-utils.c b/src/tests/test-utils.c
index 16eb3aec..c326f790 100644
--- a/src/tests/test-utils.c
+++ b/src/tests/test-utils.c
@@ -20,8 +20,6 @@
 
 #include "nm-default.h"
 
-#include <string.h>
-#include <errno.h>
 #include <arpa/inet.h>
 
 #include "nm-test-utils-core.h"
@@ -64,10 +62,10 @@ _do_test_hw_addr (NMUtilsStableType stable_type,
                   const char *ifname,
                   const char *current_mac_address,
                   const char *generate_mac_address_mask,
-                  const char **expected)
+                  const char *const *expected)
 {
 	gs_free char *generated = NULL;
-	const char **e;
+	const char *const *e;
 	gboolean found = FALSE;
 
 	for (e = expected; *e; e++) {
@@ -95,7 +93,13 @@ _do_test_hw_addr (NMUtilsStableType stable_type,
 	g_assert (found);
 }
 #define do_test_hw_addr(stable_type, stable_id, secret_key, ifname, current_mac_address, generate_mac_address_mask, ...) \
-	_do_test_hw_addr ((stable_type), (stable_id), (const guint8 *) ""secret_key"", NM_STRLEN (secret_key), (ifname), ""current_mac_address"", generate_mac_address_mask, (const char *[]) { __VA_ARGS__, NULL })
+	_do_test_hw_addr ((stable_type), \
+	                  (stable_id), \
+	                  (const guint8 *) ""secret_key"", \
+	                  NM_STRLEN (secret_key), (ifname), \
+	                  ""current_mac_address"", \
+	                  generate_mac_address_mask, \
+	                  NM_MAKE_STRV (__VA_ARGS__))
 
 static void
 test_hw_addr_gen_stable_eth (void)