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/meson.build26
-rw-r--r--src/tests/config/nm-test-device.c2
-rw-r--r--src/tests/config/test-config.c39
-rw-r--r--src/tests/meson.build47
-rw-r--r--src/tests/test-general-with-expect.c126
-rw-r--r--src/tests/test-general.c25
-rw-r--r--src/tests/test-ip6-config.c18
-rw-r--r--src/tests/test-resolvconf-capture.c298
8 files changed, 390 insertions, 191 deletions
diff --git a/src/tests/config/meson.build b/src/tests/config/meson.build
deleted file mode 100644
index fb40d9a9..00000000
--- a/src/tests/config/meson.build
+++ /dev/null
@@ -1,26 +0,0 @@
-test_unit = 'test-config'
-
-sources = files(
-  'nm-test-device.c',
-  'test-config.c'
-)
-
-test_config_dir = meson.current_source_dir()
-
-cflags = [
-  '-DSRCDIR="@0@"'.format(test_config_dir),
-  '-DBUILDDIR="@0@"'.format(test_config_dir)
-]
-
-exe = executable(
-  test_unit,
-  sources,
-  dependencies: test_nm_dep,
-  c_args: cflags
-)
-
-test(
-  'config/' + test_unit,
-  test_script,
-  args: test_args + [exe.full_path()]
-)
diff --git a/src/tests/config/nm-test-device.c b/src/tests/config/nm-test-device.c
index 49631583..3ec866f5 100644
--- a/src/tests/config/nm-test-device.c
+++ b/src/tests/config/nm-test-device.c
@@ -57,7 +57,7 @@ nm_test_device_init (NMTestDevice *self)
 }
 
 /* We jump over NMDevice's construct/destruct methods, which require NMPlatform
- * and NMSettings to be initialized.
+ * and NMConnectionProvider to be initialized.
  */
 static void
 constructed (GObject *object)
diff --git a/src/tests/config/test-config.c b/src/tests/config/test-config.c
index 50215756..89b22a9f 100644
--- a/src/tests/config/test-config.c
+++ b/src/tests/config/test-config.c
@@ -25,7 +25,7 @@
 #include "nm-config.h"
 #include "nm-test-device.h"
 #include "platform/nm-fake-platform.h"
-#include "nm-dbus-manager.h"
+#include "nm-bus-manager.h"
 #include "nm-connectivity.h"
 
 #include "nm-test-utils-core.h"
@@ -254,7 +254,7 @@ test_config_global_dns (void)
 	NMConfig *config;
 	const NMGlobalDnsConfig *dns;
 	NMGlobalDnsDomain *domain;
-	const char *const*strv;
+	const char *const *strv;
 
 	config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL,
 	                       "/no/such/dir", "", NULL);
@@ -318,10 +318,10 @@ test_config_global_dns (void)
 	g_object_unref (config);
 }
 
+#if WITH_CONCHECK
 static void
 test_config_connectivity_check (void)
 {
-#if WITH_CONCHECK
 	const char *CONFIG_INTERN = BUILDDIR"/test-connectivity-check-intern.conf";
 	NMConfig *config;
 	NMConnectivity *connectivity;
@@ -334,14 +334,14 @@ test_config_connectivity_check (void)
 	g_assert (nm_connectivity_check_enabled (connectivity));
 
 	/* disable connectivity checking */
-	NMTST_EXPECT_NM_INFO ("config: signal: *");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, "*config: signal *");
 	nm_config_set_connectivity_check_enabled (config, FALSE);
 	g_test_assert_expected_messages ();
 
 	g_assert (!nm_connectivity_check_enabled (connectivity));
 
 	/* re-enable connectivity checking */
-	NMTST_EXPECT_NM_INFO ("config: signal: *");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, "*config: signal *");
 	nm_config_set_connectivity_check_enabled (config, TRUE);
 	g_test_assert_expected_messages ();
 
@@ -351,10 +351,8 @@ test_config_connectivity_check (void)
 	g_object_unref (config);
 
 	g_assert (remove (CONFIG_INTERN) == 0);
-#else
-	g_test_skip ("concheck disabled");
-#endif
 }
+#endif
 
 static void
 test_config_no_auto_default (void)
@@ -388,7 +386,7 @@ test_config_no_auto_default (void)
 	g_assert (!nm_config_get_no_auto_default_for_device (config, dev3));
 	g_assert (nm_config_get_no_auto_default_for_device (config, dev4));
 
-	NMTST_EXPECT_NM_INFO ("config: signal: NO_AUTO_DEFAULT,no-auto-default *");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, "*config: signal NO_AUTO_DEFAULT,no-auto-default *");
 	nm_config_set_no_auto_default_for_device (config, dev3);
 	g_test_assert_expected_messages ();
 
@@ -599,9 +597,9 @@ _set_values_user (NMConfig *config,
 	config_data_before = g_object_ref (nm_config_get_data (config));
 
 	if (expected_changes != NM_CONFIG_CHANGE_NONE)
-		NMTST_EXPECT_NM_INFO ("config: signal: *");
+		g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, "*config: signal *");
 	else
-		NMTST_EXPECT_NM_INFO ("config: signal: SIGHUP (no changes from disk)*");
+		g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, "*config: signal SIGHUP (no changes from disk)*");
 
 	nm_config_reload (config, NM_CONFIG_CHANGE_CAUSE_SIGHUP);
 
@@ -643,7 +641,7 @@ _set_values_intern (NMConfig *config,
 	                  &config_changed_data);
 
 	if (expected_changes != NM_CONFIG_CHANGE_NONE)
-		NMTST_EXPECT_NM_INFO ("config: signal: *");
+		g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, "*config: signal *");
 
 	nm_config_set_values (config, keyfile_intern, TRUE, FALSE);
 
@@ -906,15 +904,15 @@ test_config_signal (void)
 	                  &expected);
 
 	expected = NM_CONFIG_CHANGE_CAUSE_SIGUSR1;
-	NMTST_EXPECT_NM_INFO ("config: signal: SIGUSR1");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, "*config: signal SIGUSR1");
 	nm_config_reload (config, expected);
 
 	expected = NM_CONFIG_CHANGE_CAUSE_SIGUSR2;
-	NMTST_EXPECT_NM_INFO ("config: signal: SIGUSR2");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, "*config: signal SIGUSR2");
 	nm_config_reload (config, expected);
 
 	expected = NM_CONFIG_CHANGE_CAUSE_SIGHUP;
-	NMTST_EXPECT_NM_INFO ("config: signal: SIGHUP (no changes from disk)*");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, "*config: signal SIGHUP (no changes from disk)*");
 	nm_config_reload (config, expected);
 
 
@@ -927,7 +925,7 @@ test_config_signal (void)
 	                  G_CALLBACK (_test_signal_config_changed_cb2),
 	                  &expected);
 	expected = NM_CONFIG_CHANGE_CAUSE_SIGUSR2;
-	NMTST_EXPECT_NM_INFO ("config: signal: SIGUSR2");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, "*config: signal SIGUSR2");
 	nm_config_reload (config, NM_CONFIG_CHANGE_CAUSE_SIGUSR2);
 	g_signal_handlers_disconnect_by_func (config, _test_signal_config_changed_cb2, &expected);
 
@@ -1039,6 +1037,13 @@ main (int argc, char **argv)
 {
 	nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT");
 
+	/* Initialize the DBus manager singleton explicitly, because it is accessed by
+	 * the class initializer of NMDevice (used by the NMTestDevice stub).
+	 * This way, we skip calling nm_bus_manager_init_bus() which would
+	 * either fail and/or cause unexpected actions in the test.
+	 * */
+	nm_bus_manager_setup (g_object_new (NM_TYPE_BUS_MANAGER, NULL));
+
 	nm_fake_platform_setup ();
 
 	g_test_add_func ("/config/simple", test_config_simple);
@@ -1050,7 +1055,9 @@ main (int argc, char **argv)
 
 	g_test_add_func ("/config/set-values", test_config_set_values);
 	g_test_add_func ("/config/global-dns", test_config_global_dns);
+#if WITH_CONCHECK
 	g_test_add_func ("/config/connectivity-check", test_config_connectivity_check);
+#endif
 
 	g_test_add_func ("/config/signal", test_config_signal);
 
diff --git a/src/tests/meson.build b/src/tests/meson.build
deleted file mode 100644
index 386ede87..00000000
--- a/src/tests/meson.build
+++ /dev/null
@@ -1,47 +0,0 @@
-subdir('config')
-
-test_units = [
-  'test-general',
-  'test-general-with-expect',
-  'test-ip4-config',
-  'test-ip6-config',
-  'test-dcb',
-  'test-wired-defname',
-  'test-utils'
-]
-
-foreach test_unit: test_units
-  exe = executable(
-    test_unit,
-    test_unit + '.c',
-    dependencies: test_nm_dep
-  )
-
-  test(
-    'src/' + test_unit,
-    test_script,
-    args: test_args + [exe.full_path()]
-  )
-endforeach
-
-test_unit = 'test-systemd'
-
-cflags = [
-  '-DNETWORKMANAGER_COMPILATION_TEST',
-  '-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_SYSTEMD',
-]
-
-exe = executable(
-  test_unit,
-  [test_unit + '.c'] + shared_siphash,
-  include_directories: src_inc,
-  dependencies: nm_core_dep,
-  c_args: cflags,
-  link_with: libsystemd_nm
-)
-
-test(
-  'src/' + test_unit,
-  test_script,
-  args: test_args + [exe.full_path()]
-)
diff --git a/src/tests/test-general-with-expect.c b/src/tests/test-general-with-expect.c
index f67c332b..2911d84d 100644
--- a/src/tests/test-general-with-expect.c
+++ b/src/tests/test-general-with-expect.c
@@ -167,7 +167,7 @@ test_nm_utils_kill_child_spawn (char **argv, gboolean do_not_reap_child)
 }
 
 static pid_t
-do_test_nm_utils_kill_child_create_and_join_pgroup (void)
+test_nm_utils_kill_child_create_and_join_pgroup (void)
 {
 	int err, tmp = 0;
 	int pipefd[2];
@@ -177,7 +177,10 @@ do_test_nm_utils_kill_child_create_and_join_pgroup (void)
 	g_assert (err == 0);
 
 	pgid = fork();
-	g_assert (pgid >= 0);
+	if (pgid < 0) {
+		g_assert_not_reached ();
+		return pgid;
+	}
 
 	if (pgid == 0) {
 		/* child process... */
@@ -203,6 +206,7 @@ do_test_nm_utils_kill_child_create_and_join_pgroup (void)
 	err = setpgid (0, pgid);
 	g_assert (err == 0);
 
+
 	do {
 		err = waitpid (pgid, &tmp, 0);
 	} while (err == -1 && errno == EINTR);
@@ -215,8 +219,9 @@ do_test_nm_utils_kill_child_create_and_join_pgroup (void)
 #define TEST_TOKEN  "nm_test_kill_child_process"
 
 static void
-do_test_nm_utils_kill_child (void)
+test_nm_utils_kill_child (void)
 {
+	int err;
 	GLogLevelFlags fatal_mask;
 	char *argv_watchdog[] = {
 			"bash",
@@ -250,6 +255,7 @@ do_test_nm_utils_kill_child (void)
 			"trap \"while true; do :; done\" TERM; while true; do :; done; #" TEST_TOKEN,
 			NULL,
 		};
+	pid_t gpid;
 	pid_t pid1a_1, pid1a_2, pid1a_3, pid2a, pid3a, pid4a;
 	pid_t pid1s_1, pid1s_2, pid1s_3, pid2s, pid3s, pid4s;
 
@@ -257,6 +263,8 @@ do_test_nm_utils_kill_child (void)
 	const int expected_signal_TERM = SIGTERM;
 	const int expected_signal_KILL = SIGKILL;
 
+	gpid = test_nm_utils_kill_child_create_and_join_pgroup ();
+
 	test_nm_utils_kill_child_spawn (argv_watchdog, FALSE);
 
 	pid1s_1 = test_nm_utils_kill_child_spawn (argv1, TRUE);
@@ -276,122 +284,90 @@ do_test_nm_utils_kill_child (void)
 	/* give processes time to start (and potentially block signals) ... */
 	g_usleep (G_USEC_PER_SEC / 10);
 
+
 	fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
 
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-s-1-1' (*): waiting up to 3000 milliseconds for process to terminate normally after sending SIGTERM (15)...");
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-s-1-1' (*): after sending SIGTERM (15), process * exited by signal 15 (* usec elapsed)");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-1-1' (*): waiting up to 3000 milliseconds for process to terminate normally after sending SIGTERM (15)...");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-1-1' (*): after sending SIGTERM (15), process * exited by signal 15 (* usec elapsed)");
 	test_nm_utils_kill_child_sync_do ("test-s-1-1", pid1s_1, SIGTERM, 3000, TRUE,  &expected_signal_TERM);
 
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-s-1-2' (*): waiting for process to terminate after sending SIGKILL (9)...");
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-s-1-2' (*): after sending SIGKILL (9), process * exited by signal 9 (* usec elapsed)");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-1-2' (*): waiting for process to terminate after sending SIGKILL (9)...");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-1-2' (*): after sending SIGKILL (9), process * exited by signal 9 (* usec elapsed)");
 	test_nm_utils_kill_child_sync_do ("test-s-1-2", pid1s_2, SIGKILL, 1000 / 2, TRUE,  &expected_signal_KILL);
 
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-s-1-3' (*): waiting up to 1 milliseconds for process to terminate normally after sending no signal (0)...");
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-s-1-3' (*): sending SIGKILL...");
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-s-1-3' (*): after sending no signal (0) and SIGKILL, process * exited by signal 9 (* usec elapsed)");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-1-3' (*): waiting up to 1 milliseconds for process to terminate normally after sending no signal (0)...");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-1-3' (*): sending SIGKILL...");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-1-3' (*): after sending no signal (0) and SIGKILL, process * exited by signal 9 (* usec elapsed)");
 	test_nm_utils_kill_child_sync_do ("test-s-1-3", pid1s_3, 0, 1, TRUE,  &expected_signal_KILL);
 
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-s-2' (*): process * already terminated normally with status 47");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-2' (*): process * already terminated normally with status 47");
 	test_nm_utils_kill_child_sync_do ("test-s-2", pid2s, SIGTERM, 3000, TRUE,  &expected_exit_47);
 
 	/* send invalid signal. */
-	NMTST_EXPECT_NM_ERROR ("kill child process 'test-s-3-0' (*): failed to send Unexpected signal: Invalid argument (22)");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*kill child process 'test-s-3-0' (*): failed to send Unexpected signal: Invalid argument (22)");
 	test_nm_utils_kill_child_sync_do ("test-s-3-0", pid3s, -1, 0, FALSE, NULL);
 
 	/* really kill pid3s */
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-s-3-1' (*): waiting up to 3000 milliseconds for process to terminate normally after sending SIGTERM (15)...");
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-s-3-1' (*): after sending SIGTERM (15), process * exited normally with status 47 (* usec elapsed)");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-3-1' (*): waiting up to 3000 milliseconds for process to terminate normally after sending SIGTERM (15)...");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-3-1' (*): after sending SIGTERM (15), process * exited normally with status 47 (* usec elapsed)");
 	test_nm_utils_kill_child_sync_do ("test-s-3-1", pid3s, SIGTERM, 3000, TRUE,  &expected_exit_47);
 
 	/* pid3s should not be a valid process, hence the call should fail. Note, that there
 	 * is a race here. */
-	NMTST_EXPECT_NM_ERROR ("kill child process 'test-s-3-2' (*): failed due to unexpected return value -1 by waitpid (No child processes, 10) after sending no signal (0)");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*kill child process 'test-s-3-2' (*): failed due to unexpected return value -1 by waitpid (No child processes, 10) after sending no signal (0)");
 	test_nm_utils_kill_child_sync_do ("test-s-3-2", pid3s, 0, 0, FALSE, NULL);
 
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-s-4' (*): waiting up to 1 milliseconds for process to terminate normally after sending SIGTERM (15)...");
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-s-4' (*): sending SIGKILL...");
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-s-4' (*): after sending SIGTERM (15) and SIGKILL, process * exited by signal 9 (* usec elapsed)");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-4' (*): waiting up to 1 milliseconds for process to terminate normally after sending SIGTERM (15)...");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-4' (*): sending SIGKILL...");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-4' (*): after sending SIGTERM (15) and SIGKILL, process * exited by signal 9 (* usec elapsed)");
 	test_nm_utils_kill_child_sync_do ("test-s-4", pid4s, SIGTERM, 1, TRUE, &expected_signal_KILL);
 
 
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-a-1-1' (*): wait for process to terminate after sending SIGTERM (15) (send SIGKILL in 3000 milliseconds)...");
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-a-1-1' (*): terminated by signal 15 (* usec elapsed)");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-1-1' (*): wait for process to terminate after sending SIGTERM (15) (send SIGKILL in 3000 milliseconds)...");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-1-1' (*): terminated by signal 15 (* usec elapsed)");
 	test_nm_utils_kill_child_async_do ("test-a-1-1", pid1a_1, SIGTERM, 3000, TRUE, &expected_signal_TERM);
 
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-a-1-2' (*): wait for process to terminate after sending SIGKILL (9)...");
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-a-1-2' (*): terminated by signal 9 (* usec elapsed)");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-1-2' (*): wait for process to terminate after sending SIGKILL (9)...");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-1-2' (*): terminated by signal 9 (* usec elapsed)");
 	test_nm_utils_kill_child_async_do ("test-a-1-2", pid1a_2, SIGKILL, 1000 / 2, TRUE, &expected_signal_KILL);
 
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-a-1-3' (*): wait for process to terminate after sending no signal (0) (send SIGKILL in 1 milliseconds)...");
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-a-1-3' (*): process not terminated after * usec. Sending SIGKILL signal");
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-a-1-3' (*): terminated by signal 9 (* usec elapsed)");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-1-3' (*): wait for process to terminate after sending no signal (0) (send SIGKILL in 1 milliseconds)...");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-1-3' (*): process not terminated after * usec. Sending SIGKILL signal");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-1-3' (*): terminated by signal 9 (* usec elapsed)");
 	test_nm_utils_kill_child_async_do ("test-a-1-3", pid1a_3, 0, 1, TRUE, &expected_signal_KILL);
 
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-a-2' (*): process * already terminated normally with status 47");
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-a-2' (*): invoke callback: terminated normally with status 47");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-2' (*): process * already terminated normally with status 47");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-2' (*): invoke callback: terminated normally with status 47");
 	test_nm_utils_kill_child_async_do ("test-a-2", pid2a, SIGTERM, 3000, TRUE, &expected_exit_47);
 
-	NMTST_EXPECT_NM_ERROR ("kill child process 'test-a-3-0' (*): unexpected error sending Unexpected signal: Invalid argument (22)");
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-a-3-0' (*): invoke callback: killing child failed");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*kill child process 'test-a-3-0' (*): unexpected error sending Unexpected signal: Invalid argument (22)");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-3-0' (*): invoke callback: killing child failed");
 	/* coverity[negative_returns] */
 	test_nm_utils_kill_child_async_do ("test-a-3-0", pid3a, -1, 1000 / 2, FALSE, NULL);
 
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-a-3-1' (*): wait for process to terminate after sending SIGTERM (15) (send SIGKILL in 3000 milliseconds)...");
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-a-3-1' (*): terminated normally with status 47 (* usec elapsed)");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-3-1' (*): wait for process to terminate after sending SIGTERM (15) (send SIGKILL in 3000 milliseconds)...");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-3-1' (*): terminated normally with status 47 (* usec elapsed)");
 	test_nm_utils_kill_child_async_do ("test-a-3-1", pid3a, SIGTERM, 3000, TRUE, &expected_exit_47);
 
 	/* pid3a should not be a valid process, hence the call should fail. Note, that there
 	 * is a race here. */
-	NMTST_EXPECT_NM_ERROR ("kill child process 'test-a-3-2' (*): failed due to unexpected return value -1 by waitpid (No child processes, 10) after sending no signal (0)");
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-a-3-2' (*): invoke callback: killing child failed");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*kill child process 'test-a-3-2' (*): failed due to unexpected return value -1 by waitpid (No child processes, 10) after sending no signal (0)");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-3-2' (*): invoke callback: killing child failed");
 	test_nm_utils_kill_child_async_do ("test-a-3-2", pid3a, 0, 0, FALSE, NULL);
 
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-a-4' (*): wait for process to terminate after sending SIGTERM (15) (send SIGKILL in 1 milliseconds)...");
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-a-4' (*): process not terminated after * usec. Sending SIGKILL signal");
-	NMTST_EXPECT_NM_DEBUG ("kill child process 'test-a-4' (*): terminated by signal 9 (* usec elapsed)");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-4' (*): wait for process to terminate after sending SIGTERM (15) (send SIGKILL in 1 milliseconds)...");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-4' (*): process not terminated after * usec. Sending SIGKILL signal");
+	g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-4' (*): terminated by signal 9 (* usec elapsed)");
 	test_nm_utils_kill_child_async_do ("test-a-4", pid4a, SIGTERM, 1, TRUE, &expected_signal_KILL);
 
-	g_log_set_always_fatal (fatal_mask);
-
-	g_test_assert_expected_messages ();
-}
-
-static void
-test_nm_utils_kill_child (void)
-{
-	int err;
-	int exit_status;
-	pid_t gpid;
-	pid_t child_pid;
-
-	/* the tests spawns several processes, we want to clean them up
-	 * by sending a SIGKILL to the process group.
-	 *
-	 * The current process might be a session leader, which prevents it from
-	 * creating a new process group. Hence, first fork and let the child
-	 * create a new process group, run the tests, and kill all pending
-	 * processes. */
-	child_pid = fork ();
-	g_assert (child_pid >= 0);
-
-	if (child_pid == 0) {
-		gpid = do_test_nm_utils_kill_child_create_and_join_pgroup ();
-
-		do_test_nm_utils_kill_child ();
-
-		err = setpgid (0, 0);
-		g_assert (err == 0);
+	err = setpgid (0, 0);
+	g_assert (err == 0);
 
-		kill (-gpid, SIGKILL);
+	kill (-gpid, SIGKILL);
 
-		exit (0);
-	};
+	g_log_set_always_fatal (fatal_mask);
 
-	do {
-		err = waitpid (child_pid, &exit_status, 0);
-	} while (err == -1 && errno == EINTR);
-	g_assert (err == child_pid);
-	g_assert (WIFEXITED (exit_status) && WEXITSTATUS(exit_status) == 0);
+	g_test_assert_expected_messages ();
 }
 
 /*****************************************************************************/
@@ -456,7 +432,7 @@ test_nm_utils_array_remove_at_indexes (void)
 
 	idx = g_array_new (FALSE, FALSE, sizeof (guint));
 	array = g_array_new (FALSE, FALSE, sizeof (gssize));
-	unique = g_hash_table_new (nm_direct_hash, NULL);
+	unique = g_hash_table_new (NULL, NULL);
 	for (i_len = 1; i_len < 20; i_len++) {
 		for (i_idx_len = 1; i_idx_len <= i_len; i_idx_len++) {
 			for (i_rnd = 0; i_rnd < 20; i_rnd++) {
diff --git a/src/tests/test-general.c b/src/tests/test-general.c
index 38eaf25e..bfa2ea73 100644
--- a/src/tests/test-general.c
+++ b/src/tests/test-general.c
@@ -232,13 +232,13 @@ test_nm_utils_log_connection_diff (void)
 
 	connection = nm_simple_connection_new ();
 	nm_connection_add_setting (connection, nm_setting_connection_new ());
-	nm_utils_log_connection_diff (connection, NULL, LOGL_DEBUG, LOGD_CORE, "test1", ">>> ", NULL);
+	nm_utils_log_connection_diff (connection, NULL, LOGL_DEBUG, LOGD_CORE, "test1", ">>> ");
 
 	nm_connection_add_setting (connection, nm_setting_wired_new ());
-	nm_utils_log_connection_diff (connection, NULL, LOGL_DEBUG, LOGD_CORE, "test2", ">>> ", NULL);
+	nm_utils_log_connection_diff (connection, NULL, LOGL_DEBUG, LOGD_CORE, "test2", ">>> ");
 
 	connection2 = nm_simple_connection_new_clone (connection);
-	nm_utils_log_connection_diff (connection, connection2, LOGL_DEBUG, LOGD_CORE, "test3", ">>> ", NULL);
+	nm_utils_log_connection_diff (connection, connection2, LOGL_DEBUG, LOGD_CORE, "test3", ">>> ");
 
 	g_object_set (nm_connection_get_setting_connection (connection),
 	              NM_SETTING_CONNECTION_ID, "id",
@@ -248,24 +248,24 @@ test_nm_utils_log_connection_diff (void)
 	              NM_SETTING_CONNECTION_ID, "id2",
 	              NM_SETTING_CONNECTION_MASTER, "master2",
 	              NULL);
-	nm_utils_log_connection_diff (connection, connection2, LOGL_DEBUG, LOGD_CORE, "test4", ">>> ", NULL);
+	nm_utils_log_connection_diff (connection, connection2, LOGL_DEBUG, LOGD_CORE, "test4", ">>> ");
 
 	nm_connection_add_setting (connection, nm_setting_802_1x_new ());
-	nm_utils_log_connection_diff (connection, connection2, LOGL_DEBUG, LOGD_CORE, "test5", ">>> ", NULL);
+	nm_utils_log_connection_diff (connection, connection2, LOGL_DEBUG, LOGD_CORE, "test5", ">>> ");
 
 	g_object_set (nm_connection_get_setting_802_1x (connection),
 	              NM_SETTING_802_1X_PASSWORD, "id2",
 	              NM_SETTING_802_1X_PASSWORD_FLAGS, NM_SETTING_SECRET_FLAG_NOT_SAVED,
 	              NULL);
-	nm_utils_log_connection_diff (connection, NULL, LOGL_DEBUG, LOGD_CORE, "test6", ">>> ", NULL);
-	nm_utils_log_connection_diff (connection, connection2, LOGL_DEBUG, LOGD_CORE, "test7", ">>> ", NULL);
-	nm_utils_log_connection_diff (connection2, connection, LOGL_DEBUG, LOGD_CORE, "test8", ">>> ", NULL);
+	nm_utils_log_connection_diff (connection, NULL, LOGL_DEBUG, LOGD_CORE, "test6", ">>> ");
+	nm_utils_log_connection_diff (connection, connection2, LOGL_DEBUG, LOGD_CORE, "test7", ">>> ");
+	nm_utils_log_connection_diff (connection2, connection, LOGL_DEBUG, LOGD_CORE, "test8", ">>> ");
 
 	g_clear_object (&connection);
 	g_clear_object (&connection2);
 
 	connection = nmtst_create_minimal_connection ("id-vpn-1", NULL, NM_SETTING_VPN_SETTING_NAME, NULL);
-	nm_utils_log_connection_diff (connection, NULL, LOGL_DEBUG, LOGD_CORE, "test-vpn-1", ">>> ", NULL);
+	nm_utils_log_connection_diff (connection, NULL, LOGL_DEBUG, LOGD_CORE, "test-vpn-1", ">>> ");
 
 	g_clear_object (&connection);
 }
@@ -1460,11 +1460,6 @@ test_nm_utils_strbuf_append (void)
 static void
 test_duplicate_decl_specifier (void)
 {
-	/* We're intentionally assigning values to static arrays v_const
-	 * and v_result without using it afterwards just so that valgrind
-	 * doesn't complain about the leak. */
-	NM_PRAGMA_WARNING_DISABLE("-Wunused-but-set-variable")
-
 	/* 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] = { };
@@ -1482,8 +1477,6 @@ test_duplicate_decl_specifier (void)
 	})
 
 	v_result[0] = TEST_MAX (v_const[0], nmtst_get_rand_int () % 5) + v2;
-
-	NM_PRAGMA_WARNING_REENABLE
 }
 
 static void
diff --git a/src/tests/test-ip6-config.c b/src/tests/test-ip6-config.c
index 816a816f..bcbeee3e 100644
--- a/src/tests/test-ip6-config.c
+++ b/src/tests/test-ip6-config.c
@@ -246,10 +246,8 @@ test_nm_ip6_config_addresses_sort_check (NMIP6Config *config, NMSettingIP6Config
 	int *idx = g_new (int, addr_count);
 
 	nm_ip6_config_set_privacy (config, use_tempaddr);
-	copy = nm_ip6_config_clone (config);
-	g_assert (copy);
-	copy2 = nm_ip6_config_clone (config);
-	g_assert (copy2);
+	copy = nmtst_ip6_config_clone (config);
+	copy2 = nmtst_ip6_config_clone (config);
 
 	/* initialize the array of indeces, and keep shuffling them for every @repeat iteration. */
 	for (i = 0; i < addr_count; i++)
@@ -298,9 +296,9 @@ test_nm_ip6_config_addresses_sort (void)
 	ADDR_ADD("2607:f0d0:1002:51::4",     NULL,  64, 0, NM_IP_CONFIG_SOURCE_USER,   0, 0, 0, 0);
 	ADDR_ADD("2607:f0d0:1002:51::5",     NULL,  64, 0, NM_IP_CONFIG_SOURCE_USER,   0, 0, 0, 0);
 	ADDR_ADD("2607:f0d0:1002:51::6",     NULL,  64, 0, NM_IP_CONFIG_SOURCE_NDISC,  0, 0, 0, IFA_F_MANAGETEMPADDR);
-	ADDR_ADD("2607:f0d0:1002:51::3",     NULL,  64, 0, NM_IP_CONFIG_SOURCE_USER,   0, 0, 0, IFA_F_TEMPORARY);
-	ADDR_ADD("2607:f0d0:1002:51::8",     NULL,  64, 0, NM_IP_CONFIG_SOURCE_USER,   0, 0, 0, IFA_F_TEMPORARY);
-	ADDR_ADD("2607:f0d0:1002:51::0",     NULL,  64, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, IFA_F_TEMPORARY);
+	ADDR_ADD("2607:f0d0:1002:51::3",     NULL,  64, 0, NM_IP_CONFIG_SOURCE_USER,   0, 0, 0, IFA_F_SECONDARY);
+	ADDR_ADD("2607:f0d0:1002:51::8",     NULL,  64, 0, NM_IP_CONFIG_SOURCE_USER,   0, 0, 0, IFA_F_SECONDARY);
+	ADDR_ADD("2607:f0d0:1002:51::0",     NULL,  64, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, IFA_F_SECONDARY);
 	ADDR_ADD("fec0::1",                  NULL, 128, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, 0);
 	ADDR_ADD("fe80::208:74ff:feda:625c", NULL, 128, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, 0);
 	ADDR_ADD("fe80::208:74ff:feda:625d", NULL, 128, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, 0);
@@ -311,11 +309,11 @@ test_nm_ip6_config_addresses_sort (void)
 	test_nm_ip6_config_addresses_sort_check (config, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR, 8);
 
 	nm_ip6_config_reset_addresses (config);
-	ADDR_ADD("2607:f0d0:1002:51::3",     NULL,  64, 0, NM_IP_CONFIG_SOURCE_USER,   0, 0, 0, IFA_F_TEMPORARY);
+	ADDR_ADD("2607:f0d0:1002:51::3",     NULL,  64, 0, NM_IP_CONFIG_SOURCE_USER,   0, 0, 0, IFA_F_SECONDARY);
 	ADDR_ADD("2607:f0d0:1002:51::4",     NULL,  64, 0, NM_IP_CONFIG_SOURCE_USER,   0, 0, 0, 0);
 	ADDR_ADD("2607:f0d0:1002:51::5",     NULL,  64, 0, NM_IP_CONFIG_SOURCE_USER,   0, 0, 0, 0);
-	ADDR_ADD("2607:f0d0:1002:51::8",     NULL,  64, 0, NM_IP_CONFIG_SOURCE_USER,   0, 0, 0, IFA_F_TEMPORARY);
-	ADDR_ADD("2607:f0d0:1002:51::0",     NULL,  64, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, IFA_F_TEMPORARY);
+	ADDR_ADD("2607:f0d0:1002:51::8",     NULL,  64, 0, NM_IP_CONFIG_SOURCE_USER,   0, 0, 0, IFA_F_SECONDARY);
+	ADDR_ADD("2607:f0d0:1002:51::0",     NULL,  64, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, IFA_F_SECONDARY);
 	ADDR_ADD("2607:f0d0:1002:51::6",     NULL,  64, 0, NM_IP_CONFIG_SOURCE_NDISC,  0, 0, 0, IFA_F_MANAGETEMPADDR);
 	ADDR_ADD("fec0::1",                  NULL, 128, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, 0);
 	ADDR_ADD("fe80::208:74ff:feda:625c", NULL, 128, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, 0);
diff --git a/src/tests/test-resolvconf-capture.c b/src/tests/test-resolvconf-capture.c
new file mode 100644
index 00000000..2c34ff74
--- /dev/null
+++ b/src/tests/test-resolvconf-capture.c
@@ -0,0 +1,298 @@
+/* -*- 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
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ */
+
+#include "nm-default.h"
+
+#include <string.h>
+#include <arpa/inet.h>
+
+#include "NetworkManagerUtils.h"
+#include "nm-ip4-config.h"
+#include "nm-ip6-config.h"
+#include "platform/nm-platform.h"
+
+#include "nm-test-utils-core.h"
+
+static void
+test_capture_empty (void)
+{
+	GArray *ns4 = g_array_new (FALSE, FALSE, sizeof (guint32));
+	GArray *ns6 = g_array_new (FALSE, FALSE, sizeof (struct in6_addr));
+
+	g_assert (!nm_utils_resolve_conf_parse (AF_INET, "", ns4, NULL));
+	g_assert_cmpint (ns4->len, ==, 0);
+
+	g_assert (!nm_utils_resolve_conf_parse (AF_INET6, "", ns6, NULL));
+	g_assert_cmpint (ns6->len, ==, 0);
+
+	g_array_free (ns4, TRUE);
+	g_array_free (ns6, TRUE);
+}
+
+#define assert_dns4_entry(a, i, s) \
+	g_assert_cmpint ((g_array_index ((a), guint32, (i))), ==, nmtst_inet4_from_string (s));
+
+#define assert_dns6_entry(a, i, s) \
+	g_assert (IN6_ARE_ADDR_EQUAL (&g_array_index ((a), struct in6_addr, (i)), nmtst_inet6_from_string (s)))
+
+#define assert_dns_option(a, i, s) \
+	g_assert_cmpstr ((a)->pdata[(i)], ==, (s));
+
+static void
+test_capture_basic4 (void)
+{
+	GArray *ns4 = g_array_new (FALSE, FALSE, sizeof (guint32));
+	const char *rc =
+"# neato resolv.conf\r\n"
+"domain foobar.com\r\n"
+"search foobar.com\r\n"
+"nameserver 4.2.2.1\r\n"
+"nameserver 4.2.2.2\r\n";
+
+	g_assert (nm_utils_resolve_conf_parse (AF_INET, rc, ns4, NULL));
+	g_assert_cmpint (ns4->len, ==, 2);
+	assert_dns4_entry (ns4, 0, "4.2.2.1");
+	assert_dns4_entry (ns4, 1, "4.2.2.2");
+
+	g_array_free (ns4, TRUE);
+}
+
+static void
+test_capture_dup4 (void)
+{
+	GArray *ns4 = g_array_new (FALSE, FALSE, sizeof (guint32));
+	const char *rc =
+"# neato resolv.conf\r\n"
+"domain foobar.com\r\n"
+"search foobar.com\r\n"
+"nameserver 4.2.2.1\r\n"
+"nameserver 4.2.2.1\r\n"
+"nameserver 4.2.2.2\r\n";
+
+	/* Check that duplicates are ignored */
+	g_assert (nm_utils_resolve_conf_parse (AF_INET, rc, ns4, NULL));
+	g_assert_cmpint (ns4->len, ==, 2);
+	assert_dns4_entry (ns4, 0, "4.2.2.1");
+	assert_dns4_entry (ns4, 1, "4.2.2.2");
+
+	g_array_free (ns4, TRUE);
+}
+
+static void
+test_capture_basic6 (void)
+{
+	GArray *ns6 = g_array_new (FALSE, FALSE, sizeof (struct in6_addr));
+	const char *rc =
+"# neato resolv.conf\r\n"
+"domain foobar.com\r\n"
+"search foobar.com\r\n"
+"nameserver 2001:4860:4860::8888\r\n"
+"nameserver 2001:4860:4860::8844\r\n";
+
+	g_assert (nm_utils_resolve_conf_parse (AF_INET6, rc, ns6, NULL));
+	g_assert_cmpint (ns6->len, ==, 2);
+	assert_dns6_entry (ns6, 0, "2001:4860:4860::8888");
+	assert_dns6_entry (ns6, 1, "2001:4860:4860::8844");
+
+	g_array_free (ns6, TRUE);
+}
+
+static void
+test_capture_dup6 (void)
+{
+	GArray *ns6 = g_array_new (FALSE, FALSE, sizeof (struct in6_addr));
+	const char *rc =
+"# neato resolv.conf\r\n"
+"domain foobar.com\r\n"
+"search foobar.com\r\n"
+"nameserver 2001:4860:4860::8888\r\n"
+"nameserver 2001:4860:4860::8888\r\n"
+"nameserver 2001:4860:4860::8844\r\n";
+
+	/* Check that duplicates are ignored */
+	g_assert (nm_utils_resolve_conf_parse (AF_INET6, rc, ns6, NULL));
+	g_assert_cmpint (ns6->len, ==, 2);
+	assert_dns6_entry (ns6, 0, "2001:4860:4860::8888");
+	assert_dns6_entry (ns6, 1, "2001:4860:4860::8844");
+
+	g_array_free (ns6, TRUE);
+}
+
+static void
+test_capture_addr4_with_6 (void)
+{
+	GArray *ns4 = g_array_new (FALSE, FALSE, sizeof (guint32));
+	const char *rc =
+"# neato resolv.conf\r\n"
+"domain foobar.com\r\n"
+"search foobar.com\r\n"
+"nameserver 4.2.2.1\r\n"
+"nameserver 4.2.2.2\r\n"
+"nameserver 2001:4860:4860::8888\r\n";
+
+	g_assert (nm_utils_resolve_conf_parse (AF_INET, rc, ns4, NULL));
+	g_assert_cmpint (ns4->len, ==, 2);
+	assert_dns4_entry (ns4, 0, "4.2.2.1");
+	assert_dns4_entry (ns4, 1, "4.2.2.2");
+
+	g_array_free (ns4, TRUE);
+}
+
+static void
+test_capture_addr6_with_4 (void)
+{
+	GArray *ns6 = g_array_new (FALSE, FALSE, sizeof (struct in6_addr));
+	const char *rc =
+"# neato resolv.conf\r\n"
+"domain foobar.com\r\n"
+"search foobar.com\r\n"
+"nameserver 4.2.2.1\r\n"
+"nameserver 2001:4860:4860::8888\r\n"
+"nameserver 2001:4860:4860::8844\r\n";
+
+	g_assert (nm_utils_resolve_conf_parse (AF_INET6, rc, ns6, NULL));
+	g_assert_cmpint (ns6->len, ==, 2);
+	assert_dns6_entry (ns6, 0, "2001:4860:4860::8888");
+	assert_dns6_entry (ns6, 1, "2001:4860:4860::8844");
+
+	g_array_free (ns6, TRUE);
+}
+
+static void
+test_capture_format (void)
+{
+	GArray *ns4 = g_array_new (FALSE, FALSE, sizeof (guint32));
+	const char *rc =
+" nameserver 4.2.2.1\r\n"     /* bad */
+"nameserver4.2.2.1\r\n"       /* bad */
+"nameserver     4.2.2.3\r"    /* good */
+"nameserver\t\t4.2.2.4\r\n"   /* good */
+"nameserver  4.2.2.5\t\t\r\n" /* good */
+"nameserver  4.2.2.6   \r\n"; /* good */
+
+	g_assert (nm_utils_resolve_conf_parse (AF_INET, rc, ns4, NULL));
+	g_assert_cmpint (ns4->len, ==, 4);
+	assert_dns4_entry (ns4, 0, "4.2.2.3");
+	assert_dns4_entry (ns4, 1, "4.2.2.4");
+	assert_dns4_entry (ns4, 2, "4.2.2.5");
+	assert_dns4_entry (ns4, 3, "4.2.2.6");
+
+	g_array_free (ns4, TRUE);
+}
+
+static void
+test_capture_dns_options (void)
+{
+	GArray *ns4 = g_array_new (FALSE, FALSE, sizeof (guint32));
+	GPtrArray *dns_options = g_ptr_array_new_with_free_func (g_free);
+	const char *rc =
+"nameserver 4.2.2.1\r\n"
+"options debug rotate  timeout:5 \r\n"
+"options edns0\r\n";
+
+	g_assert (nm_utils_resolve_conf_parse (AF_INET, rc, ns4, dns_options));
+	g_assert_cmpint (dns_options->len, ==, 4);
+	assert_dns_option (dns_options, 0, "debug");
+	assert_dns_option (dns_options, 1, "rotate");
+	assert_dns_option (dns_options, 2, "timeout:5");
+	assert_dns_option (dns_options, 3, "edns0");
+
+	g_array_free (ns4, TRUE);
+	g_ptr_array_free (dns_options, TRUE);
+}
+
+static void
+test_capture_dns_options_dup (void)
+{
+	GArray *ns4 = g_array_new (FALSE, FALSE, sizeof (guint32));
+	GPtrArray *dns_options = g_ptr_array_new_with_free_func (g_free);
+	const char *rc =
+"options debug rotate timeout:3\r\n"
+"options edns0 debug\r\n"
+"options timeout:5\r\n";
+
+	g_assert (nm_utils_resolve_conf_parse (AF_INET, rc, ns4, dns_options));
+	g_assert_cmpint (dns_options->len, ==, 4);
+	assert_dns_option (dns_options, 0, "debug");
+	assert_dns_option (dns_options, 1, "rotate");
+	assert_dns_option (dns_options, 2, "timeout:3");
+	assert_dns_option (dns_options, 3, "edns0");
+
+	g_array_free (ns4, TRUE);
+	g_ptr_array_free (dns_options, TRUE);
+}
+
+static void
+test_capture_dns_options_valid4 (void)
+{
+	GArray *ns4 = g_array_new (FALSE, FALSE, sizeof (guint32));
+	GPtrArray *dns_options = g_ptr_array_new_with_free_func (g_free);
+	const char *rc =
+"options debug: rotate:yes edns0 foobar : inet6\r\n";
+
+	g_assert (nm_utils_resolve_conf_parse (AF_INET, rc, ns4, dns_options));
+	g_assert_cmpint (dns_options->len, ==, 1);
+	assert_dns_option (dns_options, 0, "edns0");
+
+	g_array_free (ns4, TRUE);
+	g_ptr_array_free (dns_options, TRUE);
+}
+
+static void
+test_capture_dns_options_valid6 (void)
+{
+	GArray *ns6 = g_array_new (FALSE, FALSE, sizeof (struct in6_addr));
+	GPtrArray *dns_options = g_ptr_array_new_with_free_func (g_free);
+	const char *rc =
+"options inet6 debug foobar rotate:\r\n";
+
+	g_assert (nm_utils_resolve_conf_parse (AF_INET6, rc, ns6, dns_options));
+	g_assert_cmpint (dns_options->len, ==, 2);
+	assert_dns_option (dns_options, 0, "inet6");
+	assert_dns_option (dns_options, 1, "debug");
+
+	g_array_free (ns6, TRUE);
+	g_ptr_array_free (dns_options, TRUE);
+}
+/*****************************************************************************/
+
+NMTST_DEFINE ();
+
+int
+main (int argc, char **argv)
+{
+	nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT");
+
+	g_test_add_func ("/resolvconf-capture/empty", test_capture_empty);
+	g_test_add_func ("/resolvconf-capture/basic4", test_capture_basic4);
+	g_test_add_func ("/resolvconf-capture/dup4", test_capture_dup4);
+	g_test_add_func ("/resolvconf-capture/basic6", test_capture_basic6);
+	g_test_add_func ("/resolvconf-capture/dup6", test_capture_dup6);
+	g_test_add_func ("/resolvconf-capture/addr4-with-6", test_capture_addr4_with_6);
+	g_test_add_func ("/resolvconf-capture/addr6-with-4", test_capture_addr6_with_4);
+	g_test_add_func ("/resolvconf-capture/format", test_capture_format);
+	g_test_add_func ("/resolvconf-capture/dns-options", test_capture_dns_options);
+	g_test_add_func ("/resolvconf-capture/dns-options-dup", test_capture_dns_options_dup);
+	g_test_add_func ("/resolvconf-capture/dns-options-valid4", test_capture_dns_options_valid4);
+	g_test_add_func ("/resolvconf-capture/dns-options-valid6", test_capture_dns_options_valid6);
+
+	return g_test_run ();
+}
+