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/Makefile.am33
-rw-r--r--src/tests/Makefile.in83
-rw-r--r--src/tests/config/Makefile.am12
-rw-r--r--src/tests/config/Makefile.in30
-rw-r--r--src/tests/config/NetworkManager.conf16
-rw-r--r--src/tests/config/conf.d/20-config-enable-1.conf5
-rw-r--r--src/tests/config/global-dns-invalid.conf9
-rw-r--r--src/tests/config/nm-test-device.h2
-rw-r--r--src/tests/config/test-config.c498
-rw-r--r--src/tests/test-dcb.c12
-rw-r--r--src/tests/test-general-with-expect.c5
-rw-r--r--src/tests/test-general.c315
-rw-r--r--src/tests/test-ip4-config.c28
-rw-r--r--src/tests/test-ip6-config.c19
-rw-r--r--src/tests/test-resolvconf-capture.c114
-rw-r--r--src/tests/test-route-manager.c19
-rw-r--r--src/tests/test-utils.c63
-rw-r--r--src/tests/test-wired-defname.c14
18 files changed, 1145 insertions, 132 deletions
diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
index eebdb248..26c2ed7f 100644
--- a/src/tests/Makefile.am
+++ b/src/tests/Makefile.am
@@ -1,8 +1,8 @@
 SUBDIRS = config
 
 AM_CPPFLAGS = \
-	-I$(top_srcdir)/include \
-	-I$(top_builddir)/include \
+	-I$(top_srcdir)/shared \
+	-I$(top_builddir)/shared \
 	-I$(top_srcdir)/libnm-core \
 	-I$(top_builddir)/libnm-core \
 	-I$(top_srcdir)/src/platform \
@@ -11,10 +11,9 @@ AM_CPPFLAGS = \
 	-I$(top_srcdir)/src \
 	-I$(top_builddir)/src \
 	-DG_LOG_DOMAIN=\""NetworkManager"\" \
-	-DNETWORKMANAGER_COMPILATION \
+	-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \
 	-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
-	$(GLIB_CFLAGS) \
-	$(DBUS_CFLAGS)
+	$(GLIB_CFLAGS)
 
 noinst_PROGRAMS = \
 	test-general \
@@ -25,7 +24,8 @@ noinst_PROGRAMS = \
 	test-route-manager-fake \
 	test-dcb \
 	test-resolvconf-capture \
-	test-wired-defname
+	test-wired-defname \
+	test-utils
 
 ####### ip4 config test #######
 
@@ -111,6 +111,22 @@ test_wired_defname_SOURCES = \
 test_wired_defname_LDADD = \
 	$(top_builddir)/src/libNetworkManager.la
 
+####### utils test #######
+
+test_utils_SOURCES = \
+	test-utils.c
+
+test_utils_DEPENDENCIES = \
+	$(top_srcdir)/src/NetworkManagerUtils.c
+
+test_utils_CPPFLAGS = \
+	$(AM_CPPFLAGS) \
+	-DPREFIX=\"/nonexistent\" \
+	-DNMSTATEDIR=\"/nonsense\"
+
+test_utils_LDADD = \
+	$(top_builddir)/src/libNetworkManager.la
+
 ####### secret agent interface test #######
 
 EXTRA_DIST = test-secret-agent.py
@@ -127,13 +143,14 @@ TESTS = \
 	test-resolvconf-capture \
 	test-general \
 	test-general-with-expect \
-	test-wired-defname
+	test-wired-defname \
+	test-utils
 
 
 if ENABLE_TESTS
 
 check-local:
-	@for t in bond bridge ethernet gre infiniband macvlan tun veth vlan vxlan; do \
+	@for t in bond bridge ethernet infiniband ip_tunnel macvlan tun veth vlan vxlan; do \
 		# Ensure the device subclass factory registration constructors exist \
 		# which could inadvertently break if src/Makefile.am gets changed \
 		if ! LC_ALL=C nm $(top_builddir)/src/NetworkManager | LC_ALL=C grep -q "register_device_factory_internal_$$t" ; then \
diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in
index a4527284..e0967f7b 100644
--- a/src/tests/Makefile.in
+++ b/src/tests/Makefile.in
@@ -92,12 +92,14 @@ noinst_PROGRAMS = test-general$(EXEEXT) \
 	test-general-with-expect$(EXEEXT) test-ip4-config$(EXEEXT) \
 	test-ip6-config$(EXEEXT) test-route-manager-linux$(EXEEXT) \
 	test-route-manager-fake$(EXEEXT) test-dcb$(EXEEXT) \
-	test-resolvconf-capture$(EXEEXT) test-wired-defname$(EXEEXT)
+	test-resolvconf-capture$(EXEEXT) test-wired-defname$(EXEEXT) \
+	test-utils$(EXEEXT)
 TESTS = test-ip4-config$(EXEEXT) test-ip6-config$(EXEEXT) \
 	test-route-manager-fake$(EXEEXT) \
 	test-route-manager-linux$(EXEEXT) test-dcb$(EXEEXT) \
 	test-resolvconf-capture$(EXEEXT) test-general$(EXEEXT) \
-	test-general-with-expect$(EXEEXT) test-wired-defname$(EXEEXT)
+	test-general-with-expect$(EXEEXT) test-wired-defname$(EXEEXT) \
+	test-utils$(EXEEXT)
 subdir = src/tests
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \
@@ -165,6 +167,8 @@ test_route_manager_linux_OBJECTS =  \
 	$(am_test_route_manager_linux_OBJECTS)
 test_route_manager_linux_DEPENDENCIES =  \
 	$(top_builddir)/src/libNetworkManager.la
+am_test_utils_OBJECTS = test_utils-test-utils.$(OBJEXT)
+test_utils_OBJECTS = $(am_test_utils_OBJECTS)
 am_test_wired_defname_OBJECTS = test-wired-defname.$(OBJEXT)
 test_wired_defname_OBJECTS = $(am_test_wired_defname_OBJECTS)
 test_wired_defname_DEPENDENCIES =  \
@@ -207,13 +211,13 @@ SOURCES = $(test_dcb_SOURCES) $(test_general_SOURCES) \
 	$(test_general_with_expect_SOURCES) $(test_ip4_config_SOURCES) \
 	$(test_ip6_config_SOURCES) $(test_resolvconf_capture_SOURCES) \
 	$(test_route_manager_fake_SOURCES) \
-	$(test_route_manager_linux_SOURCES) \
+	$(test_route_manager_linux_SOURCES) $(test_utils_SOURCES) \
 	$(test_wired_defname_SOURCES)
 DIST_SOURCES = $(test_dcb_SOURCES) $(test_general_SOURCES) \
 	$(test_general_with_expect_SOURCES) $(test_ip4_config_SOURCES) \
 	$(test_ip6_config_SOURCES) $(test_resolvconf_capture_SOURCES) \
 	$(test_route_manager_fake_SOURCES) \
-	$(test_route_manager_linux_SOURCES) \
+	$(test_route_manager_linux_SOURCES) $(test_utils_SOURCES) \
 	$(test_wired_defname_SOURCES)
 RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
 	ctags-recursive dvi-recursive html-recursive info-recursive \
@@ -502,7 +506,6 @@ BLUEZ5_LIBS = @BLUEZ5_LIBS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
-CKDB_PATH = @CKDB_PATH@
 CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@
 CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@
 CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@
@@ -514,8 +517,6 @@ CXXDEPMODE = @CXXDEPMODE@
 CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DBUS_CFLAGS = @DBUS_CFLAGS@
-DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@
-DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@
 DBUS_LIBS = @DBUS_LIBS@
 DBUS_SYS_DIR = @DBUS_SYS_DIR@
 DEFS = @DEFS@
@@ -525,6 +526,7 @@ DHCPCD_PATH = @DHCPCD_PATH@
 DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@
 DLLTOOL = @DLLTOOL@
 DNSMASQ_PATH = @DNSMASQ_PATH@
+DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
@@ -579,16 +581,13 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
 INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
 INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
 IPTABLES_PATH = @IPTABLES_PATH@
-IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
-IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
 KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
 LCOV = @LCOV@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@
+LIBAUDIT_LIBS = @LIBAUDIT_LIBS@
 LIBDL = @LIBDL@
-LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
-LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
-LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
@@ -625,6 +624,8 @@ NEWT_LIBS = @NEWT_LIBS@
 NM = @NM@
 NMEDIT = @NMEDIT@
 NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@
+NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT = @NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT@
+NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT = @NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT@
 NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
 NM_MICRO_VERSION = @NM_MICRO_VERSION@
 NM_MINOR_VERSION = @NM_MINOR_VERSION@
@@ -653,7 +654,6 @@ POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PATH = @PPPD_PATH@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
-PPPOE_PATH = @PPPOE_PATH@
 QT_CFLAGS = @QT_CFLAGS@
 QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
@@ -668,6 +668,8 @@ SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@
 SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@
 SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@
 SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@
+SYSTEMD_JOURNAL_CFLAGS = @SYSTEMD_JOURNAL_CFLAGS@
+SYSTEMD_JOURNAL_LIBS = @SYSTEMD_JOURNAL_LIBS@
 SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@
 SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
@@ -728,6 +730,7 @@ mkdir_p = @mkdir_p@
 nmbinary = @nmbinary@
 nmconfdir = @nmconfdir@
 nmdatadir = @nmdatadir@
+nmlibdir = @nmlibdir@
 nmrundir = @nmrundir@
 nmstatedir = @nmstatedir@
 oldincludedir = @oldincludedir@
@@ -735,6 +738,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -752,8 +756,8 @@ with_resolvconf = @with_resolvconf@
 with_valgrind = @with_valgrind@
 SUBDIRS = config
 AM_CPPFLAGS = \
-	-I$(top_srcdir)/include \
-	-I$(top_builddir)/include \
+	-I$(top_srcdir)/shared \
+	-I$(top_builddir)/shared \
 	-I$(top_srcdir)/libnm-core \
 	-I$(top_builddir)/libnm-core \
 	-I$(top_srcdir)/src/platform \
@@ -762,10 +766,9 @@ AM_CPPFLAGS = \
 	-I$(top_srcdir)/src \
 	-I$(top_builddir)/src \
 	-DG_LOG_DOMAIN=\""NetworkManager"\" \
-	-DNETWORKMANAGER_COMPILATION \
+	-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \
 	-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
-	$(GLIB_CFLAGS) \
-	$(DBUS_CFLAGS)
+	$(GLIB_CFLAGS)
 
 
 ####### ip4 config test #######
@@ -852,6 +855,22 @@ test_wired_defname_LDADD = \
 	$(top_builddir)/src/libNetworkManager.la
 
 
+####### utils test #######
+test_utils_SOURCES = \
+	test-utils.c
+
+test_utils_DEPENDENCIES = \
+	$(top_srcdir)/src/NetworkManagerUtils.c
+
+test_utils_CPPFLAGS = \
+	$(AM_CPPFLAGS) \
+	-DPREFIX=\"/nonexistent\" \
+	-DNMSTATEDIR=\"/nonsense\"
+
+test_utils_LDADD = \
+	$(top_builddir)/src/libNetworkManager.la
+
+
 ####### secret agent interface test #######
 EXTRA_DIST = test-secret-agent.py
 all: all-recursive
@@ -929,6 +948,10 @@ test-route-manager-linux$(EXEEXT): $(test_route_manager_linux_OBJECTS) $(test_ro
 	@rm -f test-route-manager-linux$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(test_route_manager_linux_OBJECTS) $(test_route_manager_linux_LDADD) $(LIBS)
 
+test-utils$(EXEEXT): $(test_utils_OBJECTS) $(test_utils_DEPENDENCIES) $(EXTRA_test_utils_DEPENDENCIES) 
+	@rm -f test-utils$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_utils_OBJECTS) $(test_utils_LDADD) $(LIBS)
+
 test-wired-defname$(EXEEXT): $(test_wired_defname_OBJECTS) $(test_wired_defname_DEPENDENCIES) $(EXTRA_test_wired_defname_DEPENDENCIES) 
 	@rm -f test-wired-defname$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(test_wired_defname_OBJECTS) $(test_wired_defname_LDADD) $(LIBS)
@@ -950,6 +973,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_route_manager_fake-test-route-manager.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_route_manager_linux-test-common.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_route_manager_linux-test-route-manager.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_utils-test-utils.Po@am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -1028,6 +1052,20 @@ test_route_manager_linux-test-route-manager.obj: test-route-manager.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_route_manager_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_route_manager_linux-test-route-manager.obj `if test -f 'test-route-manager.c'; then $(CYGPATH_W) 'test-route-manager.c'; else $(CYGPATH_W) '$(srcdir)/test-route-manager.c'; fi`
 
+test_utils-test-utils.o: test-utils.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils-test-utils.o -MD -MP -MF $(DEPDIR)/test_utils-test-utils.Tpo -c -o test_utils-test-utils.o `test -f 'test-utils.c' || echo '$(srcdir)/'`test-utils.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_utils-test-utils.Tpo $(DEPDIR)/test_utils-test-utils.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-utils.c' object='test_utils-test-utils.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils-test-utils.o `test -f 'test-utils.c' || echo '$(srcdir)/'`test-utils.c
+
+test_utils-test-utils.obj: test-utils.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils-test-utils.obj -MD -MP -MF $(DEPDIR)/test_utils-test-utils.Tpo -c -o test_utils-test-utils.obj `if test -f 'test-utils.c'; then $(CYGPATH_W) 'test-utils.c'; else $(CYGPATH_W) '$(srcdir)/test-utils.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_utils-test-utils.Tpo $(DEPDIR)/test_utils-test-utils.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-utils.c' object='test_utils-test-utils.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils-test-utils.obj `if test -f 'test-utils.c'; then $(CYGPATH_W) 'test-utils.c'; else $(CYGPATH_W) '$(srcdir)/test-utils.c'; fi`
+
 mostlyclean-libtool:
 	-rm -f *.lo
 
@@ -1337,6 +1375,13 @@ test-wired-defname.log: test-wired-defname$(EXEEXT)
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test-utils.log: test-utils$(EXEEXT)
+	@p='test-utils$(EXEEXT)'; \
+	b='test-utils'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 .test.log:
 	@p='$<'; \
 	$(am__set_b); \
@@ -1543,7 +1588,7 @@ uninstall-am:
 @VALGRIND_RULES@
 
 @ENABLE_TESTS_TRUE@check-local:
-@ENABLE_TESTS_TRUE@	@for t in bond bridge ethernet gre infiniband macvlan tun veth vlan vxlan; do \
+@ENABLE_TESTS_TRUE@	@for t in bond bridge ethernet infiniband ip_tunnel macvlan tun veth vlan vxlan; do \
 @ENABLE_TESTS_TRUE@		# Ensure the device subclass factory registration constructors exist \
 @ENABLE_TESTS_TRUE@		# which could inadvertently break if src/Makefile.am gets changed \
 @ENABLE_TESTS_TRUE@		if ! LC_ALL=C nm $(top_builddir)/src/NetworkManager | LC_ALL=C grep -q "register_device_factory_internal_$$t" ; then \
diff --git a/src/tests/config/Makefile.am b/src/tests/config/Makefile.am
index a5e068e4..5d4aed5c 100644
--- a/src/tests/config/Makefile.am
+++ b/src/tests/config/Makefile.am
@@ -1,17 +1,17 @@
 AM_CPPFLAGS = \
-	-I$(top_srcdir)/include \
-	-I$(top_builddir)/include \
+	-I$(top_srcdir)/shared \
+	-I$(top_builddir)/shared \
 	-I$(top_srcdir)/libnm-core \
 	-I$(top_builddir)/libnm-core \
 	-I$(top_srcdir)/src/ \
 	-I$(top_srcdir)/src/devices \
 	-I${top_srcdir}/src/platform \
 	-DG_LOG_DOMAIN=\""NetworkManager"\" \
-	-DNETWORKMANAGER_COMPILATION \
+	-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \
 	-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
 	$(GLIB_CFLAGS) \
-	$(DBUS_CFLAGS) \
-	-DSRCDIR=\""$(srcdir)"\"
+	-DSRCDIR=\""$(srcdir)"\" \
+	-DBUILDDIR=\""$(builddir)"\"
 
 noinst_PROGRAMS = \
 	test-config
@@ -30,6 +30,8 @@ TESTS = test-config
 EXTRA_DIST = \
 	NetworkManager.conf \
 	bad.conf \
+	global-dns-invalid.conf \
 	conf.d/00-overrides.conf \
 	conf.d/10-more.conf \
+	conf.d/20-config-enable-1.conf \
 	conf.d/90-last.conf
diff --git a/src/tests/config/Makefile.in b/src/tests/config/Makefile.in
index 20bbe60a..994e7068 100644
--- a/src/tests/config/Makefile.in
+++ b/src/tests/config/Makefile.in
@@ -403,7 +403,6 @@ BLUEZ5_LIBS = @BLUEZ5_LIBS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
-CKDB_PATH = @CKDB_PATH@
 CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@
 CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@
 CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@
@@ -415,8 +414,6 @@ CXXDEPMODE = @CXXDEPMODE@
 CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DBUS_CFLAGS = @DBUS_CFLAGS@
-DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@
-DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@
 DBUS_LIBS = @DBUS_LIBS@
 DBUS_SYS_DIR = @DBUS_SYS_DIR@
 DEFS = @DEFS@
@@ -426,6 +423,7 @@ DHCPCD_PATH = @DHCPCD_PATH@
 DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@
 DLLTOOL = @DLLTOOL@
 DNSMASQ_PATH = @DNSMASQ_PATH@
+DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
@@ -480,16 +478,13 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
 INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
 INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
 IPTABLES_PATH = @IPTABLES_PATH@
-IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
-IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
 KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
 LCOV = @LCOV@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@
+LIBAUDIT_LIBS = @LIBAUDIT_LIBS@
 LIBDL = @LIBDL@
-LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
-LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
-LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
@@ -526,6 +521,8 @@ NEWT_LIBS = @NEWT_LIBS@
 NM = @NM@
 NMEDIT = @NMEDIT@
 NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@
+NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT = @NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT@
+NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT = @NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT@
 NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
 NM_MICRO_VERSION = @NM_MICRO_VERSION@
 NM_MINOR_VERSION = @NM_MINOR_VERSION@
@@ -554,7 +551,6 @@ POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PATH = @PPPD_PATH@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
-PPPOE_PATH = @PPPOE_PATH@
 QT_CFLAGS = @QT_CFLAGS@
 QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
@@ -569,6 +565,8 @@ SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@
 SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@
 SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@
 SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@
+SYSTEMD_JOURNAL_CFLAGS = @SYSTEMD_JOURNAL_CFLAGS@
+SYSTEMD_JOURNAL_LIBS = @SYSTEMD_JOURNAL_LIBS@
 SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@
 SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
@@ -629,6 +627,7 @@ mkdir_p = @mkdir_p@
 nmbinary = @nmbinary@
 nmconfdir = @nmconfdir@
 nmdatadir = @nmdatadir@
+nmlibdir = @nmlibdir@
 nmrundir = @nmrundir@
 nmstatedir = @nmstatedir@
 oldincludedir = @oldincludedir@
@@ -636,6 +635,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -652,19 +652,19 @@ with_netconfig = @with_netconfig@
 with_resolvconf = @with_resolvconf@
 with_valgrind = @with_valgrind@
 AM_CPPFLAGS = \
-	-I$(top_srcdir)/include \
-	-I$(top_builddir)/include \
+	-I$(top_srcdir)/shared \
+	-I$(top_builddir)/shared \
 	-I$(top_srcdir)/libnm-core \
 	-I$(top_builddir)/libnm-core \
 	-I$(top_srcdir)/src/ \
 	-I$(top_srcdir)/src/devices \
 	-I${top_srcdir}/src/platform \
 	-DG_LOG_DOMAIN=\""NetworkManager"\" \
-	-DNETWORKMANAGER_COMPILATION \
+	-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \
 	-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
 	$(GLIB_CFLAGS) \
-	$(DBUS_CFLAGS) \
-	-DSRCDIR=\""$(srcdir)"\"
+	-DSRCDIR=\""$(srcdir)"\" \
+	-DBUILDDIR=\""$(builddir)"\"
 
 test_config_SOURCES = \
 	nm-test-device.c \
@@ -677,8 +677,10 @@ test_config_LDADD = \
 EXTRA_DIST = \
 	NetworkManager.conf \
 	bad.conf \
+	global-dns-invalid.conf \
 	conf.d/00-overrides.conf \
 	conf.d/10-more.conf \
+	conf.d/20-config-enable-1.conf \
 	conf.d/90-last.conf
 
 all: all-am
diff --git a/src/tests/config/NetworkManager.conf b/src/tests/config/NetworkManager.conf
index a750c801..da7b1fd4 100644
--- a/src/tests/config/NetworkManager.conf
+++ b/src/tests/config/NetworkManager.conf
@@ -81,3 +81,19 @@ ord.key07=A-0.3.07
 ord.key08=A-0.3.08
 ord.key09=A-0.3.09
 ord.ovw01=A-0.3.ovw01
+
+[global-dns]
+enable=yes
+searches=foo.com,bar.org
+options=debug,edns0
+
+[global-dns-domain-*]
+servers=1.1.1.1,bad,1::128
+options=opt1,opt2
+
+[global-dns-domain-example.com]
+servers=2.2.2.2
+
+# Invalid section: 'servers' key is missing
+[global-dns-domain-test.com]
+options=opt3
diff --git a/src/tests/config/conf.d/20-config-enable-1.conf b/src/tests/config/conf.d/20-config-enable-1.conf
new file mode 100644
index 00000000..e6800f52
--- /dev/null
+++ b/src/tests/config/conf.d/20-config-enable-1.conf
@@ -0,0 +1,5 @@
+[.config]
+enable=nm-version:1.5.32,env:test-match-env-1
+
+[test-group-config-enable-1]
+key1=enabled
diff --git a/src/tests/config/global-dns-invalid.conf b/src/tests/config/global-dns-invalid.conf
new file mode 100644
index 00000000..e490f609
--- /dev/null
+++ b/src/tests/config/global-dns-invalid.conf
@@ -0,0 +1,9 @@
+# Invalid configuration, since there isn't a default domain section
+
+[global-dns]
+searches=foo.com
+options=timeout:5
+
+[global-dns-domain-test.com]
+servers=1.2.3.4
+options=myoption
diff --git a/src/tests/config/nm-test-device.h b/src/tests/config/nm-test-device.h
index 00b21c42..c3532c9c 100644
--- a/src/tests/config/nm-test-device.h
+++ b/src/tests/config/nm-test-device.h
@@ -21,7 +21,7 @@
 #ifndef __NETWORKMANAGER_TEST_DEVICE_H__
 #define __NETWORKMANAGER_TEST_DEVICE_H__
 
-#include <nm-device.h>
+#include "nm-device.h"
 
 G_BEGIN_DECLS
 
diff --git a/src/tests/config/test-config.c b/src/tests/config/test-config.c
index 6dad8216..e8de86c8 100644
--- a/src/tests/config/test-config.c
+++ b/src/tests/config/test-config.c
@@ -22,18 +22,36 @@
 
 #include <unistd.h>
 
-#include <glib.h>
 
-#include <nm-config.h>
+#include "nm-config.h"
+#include "nm-default.h"
 #include "nm-test-device.h"
 #include "nm-fake-platform.h"
-#include "nm-logging.h"
-#include "nm-dbus-manager.h"
+#include "nm-bus-manager.h"
 
 #include "nm-test-utils.h"
 
+/********************************************************************************/
+
+static void
+_assert_config_value (const NMConfigData *config_data, const char *group, const char *key, const char *expected_value, const char *file, int line)
+{
+	gs_free char *value = NULL;
+
+	value = nm_config_data_get_value (config_data, group, key, NM_CONFIG_GET_VALUE_NONE);
+	if (g_strcmp0 (value, expected_value)) {
+		g_error ("(%s:%d) invalid value in config-data %s.%s = %s%s%s (instead of %s%s%s)",
+		         file, line, group, key,
+		         NM_PRINT_FMT_QUOTED (value, "\"", value, "\"", "(null)"),
+		         NM_PRINT_FMT_QUOTED (expected_value, "\"", expected_value, "\"", "(null)"));
+	}
+}
+#define assert_config_value(config_data, group, key, expected_value) _assert_config_value (config_data, group, key, expected_value, __FILE__, __LINE__)
+
+/********************************************************************************/
+
 static NMConfig *
-setup_config (GError **error, const char *config_file, const char *config_dir, ...)
+setup_config (GError **error, const char *config_file, const char *intern_config, const char *const* atomic_section_prefixes, const char *config_dir, const char *system_config_dir, ...)
 {
 	va_list ap;
 	GPtrArray *args;
@@ -51,10 +69,18 @@ setup_config (GError **error, const char *config_file, const char *config_dir, .
 	g_ptr_array_add (args, "test-config");
 	g_ptr_array_add (args, "--config");
 	g_ptr_array_add (args, (char *)config_file);
+	if (intern_config) {
+		g_ptr_array_add (args, "--intern-config");
+		g_ptr_array_add (args, (char *)intern_config);
+	}
 	g_ptr_array_add (args, "--config-dir");
 	g_ptr_array_add (args, (char *)config_dir);
+	if (system_config_dir) {
+		g_ptr_array_add (args, "--system-config-dir");
+		g_ptr_array_add (args, (char *) system_config_dir);
+	}
 
-	va_start (ap, config_dir);
+	va_start (ap, system_config_dir);
 	while ((arg = va_arg (ap, char *)))
 		g_ptr_array_add (args, arg);
 	va_end (ap);
@@ -74,7 +100,7 @@ setup_config (GError **error, const char *config_file, const char *config_dir, .
 
 	g_ptr_array_free (args, TRUE);
 
-	config = nm_config_setup (cli, &local_error);
+	config = nm_config_setup (cli, (char **) atomic_section_prefixes, &local_error);
 	if (error) {
 		g_assert (!config);
 		g_assert (local_error);
@@ -97,7 +123,7 @@ test_config_simple (void)
 	gs_unref_object NMDevice *dev51 = nm_test_device_new ("00:00:00:00:00:51");
 	gs_unref_object NMDevice *dev52 = nm_test_device_new ("00:00:00:00:00:52");
 
-	config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "/no/such/dir", NULL);
+	config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, "/no/such/dir", "", NULL);
 
 	g_assert_cmpstr (nm_config_data_get_config_main_file (nm_config_get_data_orig (config)), ==, SRCDIR "/NetworkManager.conf");
 	g_assert_cmpstr (nm_config_get_dhcp_client (config), ==, "dhclient");
@@ -174,9 +200,9 @@ test_config_simple (void)
 static void
 test_config_non_existent (void)
 {
-	gs_free_error GError *error = NULL;
+	GError *error = NULL;
 
-	setup_config (&error, SRCDIR "/no-such-file", "/no/such/dir", NULL);
+	setup_config (&error, SRCDIR "/no-such-file", "", NULL, "/no/such/dir", "", NULL);
 	g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND);
 	g_clear_error (&error);
 }
@@ -184,9 +210,9 @@ test_config_non_existent (void)
 static void
 test_config_parse_error (void)
 {
-	gs_free_error GError *error = NULL;
+	GError *error = NULL;
 
-	setup_config (&error, SRCDIR "/bad.conf", "/no/such/dir", NULL);
+	setup_config (&error, SRCDIR "/bad.conf", "", NULL, "/no/such/dir", "", NULL);
 	g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE);
 	g_clear_error (&error);
 }
@@ -197,7 +223,7 @@ test_config_override (void)
 	NMConfig *config;
 	const char **plugins;
 
-	config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "/no/such/dir",
+	config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, "/no/such/dir", "",
 	                       "--plugins", "alpha,beta,gamma,delta",
 	                       "--connectivity-interval", "12",
 	                       NULL);
@@ -218,6 +244,76 @@ test_config_override (void)
 }
 
 static void
+test_config_global_dns (void)
+{
+	NMConfig *config;
+	const NMGlobalDnsConfig *dns;
+	NMGlobalDnsDomain *domain;
+	const char *const *strv;
+
+	config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL,
+	                       "/no/such/dir", "", NULL);
+
+	dns = nm_config_data_get_global_dns_config (nm_config_get_data_orig (config));
+	g_assert (dns);
+
+	strv = nm_global_dns_config_get_searches (dns);
+	g_assert (strv);
+	g_assert_cmpuint (g_strv_length ((char **) strv), ==, 2);
+	g_assert_cmpstr (strv[0], ==, "foo.com");
+	g_assert_cmpstr (strv[1], ==, "bar.org");
+
+	strv = nm_global_dns_config_get_options (dns);
+	g_assert (strv);
+	g_assert_cmpuint (g_strv_length ((char **) strv), ==, 2);
+	g_assert_cmpstr (strv[0], ==, "debug");
+	g_assert_cmpstr (strv[1], ==, "edns0");
+
+	g_assert_cmpuint (nm_global_dns_config_get_num_domains (dns), ==, 2);
+
+	/* Default domain */
+	domain = nm_global_dns_config_lookup_domain (dns, "*");
+	g_assert (domain);
+
+	strv = nm_global_dns_domain_get_servers (domain);
+	g_assert (strv);
+	g_assert_cmpuint (g_strv_length ((char **) strv), ==, 2);
+	g_assert_cmpstr (strv[0], ==, "1.1.1.1");
+	g_assert_cmpstr (strv[1], ==, "1::128");
+
+	strv = nm_global_dns_domain_get_options (domain);
+	g_assert (strv);
+	g_assert_cmpuint (g_strv_length ((char **) strv), ==, 2);
+	g_assert_cmpstr (strv[0], ==, "opt1");
+	g_assert_cmpstr (strv[1], ==, "opt2");
+
+	/* 'example.com' domain */
+	domain = nm_global_dns_config_lookup_domain (dns, "example.com");
+	g_assert (domain);
+
+	strv = nm_global_dns_domain_get_servers (domain);
+	g_assert (strv);
+	g_assert_cmpuint (g_strv_length ((char **) strv), ==, 1);
+	g_assert_cmpstr (strv[0], ==, "2.2.2.2");
+
+	strv = nm_global_dns_domain_get_options (domain);
+	g_assert (!strv || g_strv_length ((char **) strv) == 0);
+
+	/* Non-existent domain 'test.com' */
+	domain = nm_global_dns_config_lookup_domain (dns, "test.com");
+	g_assert (!domain);
+
+	g_object_unref (config);
+
+	/* Check that a file without a default domain section gives a NULL configuration */
+	config = setup_config (NULL, SRCDIR "/global-dns-invalid.conf", "", NULL,
+	                       "/no/such/dir", "", NULL);
+	dns = nm_config_data_get_global_dns_config (nm_config_get_data_orig (config));
+	g_assert (!dns);
+	g_object_unref (config);
+}
+
+static void
 test_config_no_auto_default (void)
 {
 	NMConfig *config;
@@ -235,7 +331,7 @@ test_config_no_auto_default (void)
 	g_assert_cmpint (nwrote, ==, 18);
 	close (fd);
 
-	config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "/no/such/dir",
+	config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, "/no/such/dir", "",
 	                       "--no-auto-default", state_file,
 	                       NULL);
 
@@ -257,7 +353,7 @@ test_config_no_auto_default (void)
 
 	g_object_unref (config);
 
-	config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "/no/such/dir",
+	config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, "/no/such/dir", "",
 	                       "--no-auto-default", state_file,
 	                       NULL);
 
@@ -285,7 +381,7 @@ test_config_confdir (void)
 	char *value;
 	GSList *specs;
 
-	config = setup_config (NULL, SRCDIR "/NetworkManager.conf", SRCDIR "/conf.d", NULL);
+	config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, SRCDIR "/conf.d", "", NULL);
 
 	g_assert_cmpstr (nm_config_data_get_config_main_file (nm_config_get_data_orig (config)), ==, SRCDIR "/NetworkManager.conf");
 	g_assert_cmpstr (nm_config_get_dhcp_client (config), ==, "dhcpcd");
@@ -391,13 +487,336 @@ test_config_confdir_parse_error (void)
 	GError *error = NULL;
 
 	/* Using SRCDIR as the conf dir will pick up bad.conf */
-	setup_config (&error, SRCDIR "/NetworkManager.conf", SRCDIR, NULL);
+	setup_config (&error, SRCDIR "/NetworkManager.conf", "", NULL, SRCDIR, "", NULL);
 	g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE);
 	g_clear_error (&error);
 }
 
 /*****************************************************************************/
 
+typedef void (*TestSetValuesUserSetFcn) (NMConfig *config, gboolean is_user, GKeyFile *keyfile_user, NMConfigChangeFlags *out_expected_changes);
+typedef void (*TestSetValuesCheckStateFcn) (NMConfig *config, NMConfigData *config_data, gboolean is_change_event, NMConfigChangeFlags changes, NMConfigData *old_data);
+
+typedef struct {
+	NMConfigChangeFlags changes;
+	TestSetValuesCheckStateFcn check_state_fcn;
+} TestSetValuesConfigChangedData;
+
+static void
+_set_values_config_changed_cb (NMConfig *config,
+                               NMConfigData *config_data,
+                               NMConfigChangeFlags changes,
+                               NMConfigData *old_data,
+                               TestSetValuesConfigChangedData *config_changed_data)
+{
+	g_assert (changes != NM_CONFIG_CHANGE_NONE);
+	g_assert (config_changed_data);
+	g_assert (config_changed_data->changes == NM_CONFIG_CHANGE_NONE);
+
+	if (changes == NM_CONFIG_CHANGE_SIGHUP)
+		return;
+	changes &= ~NM_CONFIG_CHANGE_SIGHUP;
+
+	config_changed_data->changes = changes;
+
+	if (config_changed_data->check_state_fcn)
+		config_changed_data->check_state_fcn (config, config_data, TRUE, changes, old_data);
+}
+
+static void
+_set_values_user (NMConfig *config,
+                  const char *CONFIG_USER,
+                  TestSetValuesUserSetFcn set_fcn,
+                  TestSetValuesCheckStateFcn check_state_fcn)
+{
+	GKeyFile *keyfile_user;
+	gboolean success;
+	gs_free_error GError *error = NULL;
+	TestSetValuesConfigChangedData config_changed_data = {
+		.changes = NM_CONFIG_CHANGE_NONE,
+		.check_state_fcn = check_state_fcn,
+	};
+	NMConfigChangeFlags expected_changes = NM_CONFIG_CHANGE_NONE;
+	gs_unref_object NMConfigData *config_data_before = NULL;
+
+	keyfile_user = nm_config_create_keyfile ();
+
+	success = g_key_file_load_from_file (keyfile_user, CONFIG_USER, G_KEY_FILE_NONE, &error);
+	nmtst_assert_success (success, error);
+
+	if (set_fcn)
+		set_fcn (config, TRUE, keyfile_user, &expected_changes);
+
+	success = g_key_file_save_to_file (keyfile_user, CONFIG_USER, &error);
+	nmtst_assert_success (success, error);
+
+	g_signal_connect (G_OBJECT (config),
+	                  NM_CONFIG_SIGNAL_CONFIG_CHANGED,
+	                  G_CALLBACK (_set_values_config_changed_cb),
+	                  &config_changed_data);
+
+	config_data_before = g_object_ref (nm_config_get_data (config));
+
+	if (expected_changes != NM_CONFIG_CHANGE_NONE)
+		g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*config: update *");
+	else
+		g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*config: signal SIGHUP (no changes from disk)*");
+
+	nm_config_reload (config, SIGHUP);
+
+	g_test_assert_expected_messages ();
+
+	g_assert (expected_changes == config_changed_data.changes);
+
+	if (check_state_fcn)
+		check_state_fcn (config, nm_config_get_data (config), FALSE, NM_CONFIG_CHANGE_NONE, config_data_before);
+
+	g_signal_handlers_disconnect_by_func (config, _set_values_config_changed_cb, &config_changed_data);
+
+	g_key_file_unref (keyfile_user);
+}
+
+static void
+_set_values_intern (NMConfig *config,
+                    TestSetValuesUserSetFcn set_fcn,
+                    TestSetValuesCheckStateFcn check_state_fcn)
+{
+	GKeyFile *keyfile_intern;
+	TestSetValuesConfigChangedData config_changed_data = {
+		.changes = NM_CONFIG_CHANGE_NONE,
+		.check_state_fcn = check_state_fcn,
+	};
+	NMConfigChangeFlags expected_changes = NM_CONFIG_CHANGE_NONE;
+	gs_unref_object NMConfigData *config_data_before = NULL;
+
+	config_data_before = g_object_ref (nm_config_get_data (config));
+
+	keyfile_intern = nm_config_data_clone_keyfile_intern (config_data_before);
+
+	if (set_fcn)
+		set_fcn (config, FALSE, keyfile_intern, &expected_changes);
+
+	g_signal_connect (G_OBJECT (config),
+	                  NM_CONFIG_SIGNAL_CONFIG_CHANGED,
+	                  G_CALLBACK (_set_values_config_changed_cb),
+	                  &config_changed_data);
+
+	if (expected_changes != NM_CONFIG_CHANGE_NONE)
+		g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*config: update *");
+
+	nm_config_set_values (config, keyfile_intern, TRUE, FALSE);
+
+	g_test_assert_expected_messages ();
+
+	g_assert (expected_changes == config_changed_data.changes);
+
+	if (check_state_fcn)
+		check_state_fcn (config, nm_config_get_data (config), FALSE, NM_CONFIG_CHANGE_NONE, config_data_before);
+
+	g_signal_handlers_disconnect_by_func (config, _set_values_config_changed_cb, &config_changed_data);
+
+	g_key_file_unref (keyfile_intern);
+}
+
+static void
+_set_values_user_intern_section_set (NMConfig *config, gboolean set_user, GKeyFile *keyfile, NMConfigChangeFlags *out_expected_changes)
+{
+	g_key_file_set_string (keyfile, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN"section1", "key", "this-should-be-ignored");
+}
+
+static void
+_set_values_user_intern_section_check (NMConfig *config, NMConfigData *config_data, gboolean is_change_event, NMConfigChangeFlags changes, NMConfigData *old_data)
+{
+	g_assert (changes == NM_CONFIG_CHANGE_NONE);
+	g_assert (!nm_config_data_has_group (config_data, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN"section1"));
+}
+
+static void
+_set_values_user_initial_values_set (NMConfig *config, gboolean set_user, GKeyFile *keyfile, NMConfigChangeFlags *out_expected_changes)
+{
+	g_key_file_remove_group (keyfile, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN"section1", NULL);
+	g_key_file_set_string (keyfile, "section1", "key1", "value1");
+	*out_expected_changes = NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_USER;
+}
+
+static void
+_set_values_user_initial_values_check (NMConfig *config, NMConfigData *config_data, gboolean is_change_event, NMConfigChangeFlags changes, NMConfigData *old_data)
+{
+	if (is_change_event)
+		g_assert (changes == (NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_USER));
+	assert_config_value (config_data, "section1", "key1", "value1");
+}
+
+static void
+_set_values_intern_internal_set (NMConfig *config, gboolean set_user, GKeyFile *keyfile, NMConfigChangeFlags *out_expected_changes)
+{
+	g_key_file_set_string (keyfile, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN"section1", "key", "internal-section");
+	*out_expected_changes = NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_INTERN;
+}
+
+static void
+_set_values_intern_internal_check (NMConfig *config, NMConfigData *config_data, gboolean is_change_event, NMConfigChangeFlags changes, NMConfigData *old_data)
+{
+	if (is_change_event)
+		g_assert (changes == (NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_INTERN));
+	assert_config_value (config_data, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN"section1", "key", "internal-section");
+}
+
+static void
+_set_values_user_atomic_section_1_set (NMConfig *config, gboolean set_user, GKeyFile *keyfile, NMConfigChangeFlags *out_expected_changes)
+{
+	g_key_file_set_string (keyfile, "atomic-prefix-1.section-a", "key1", "user-value1");
+	g_key_file_set_string (keyfile, "atomic-prefix-1.section-a", "key2", "user-value2");
+	g_key_file_set_string (keyfile, "atomic-prefix-1.section-b", "key1", "user-value1");
+	g_key_file_set_string (keyfile, "non-atomic-prefix-1.section-a", "nap1-key1", "user-value1");
+	g_key_file_set_string (keyfile, "non-atomic-prefix-1.section-a", "nap1-key2", "user-value2");
+	*out_expected_changes = NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_USER;
+}
+
+static void
+_set_values_user_atomic_section_1_check (NMConfig *config, NMConfigData *config_data, gboolean is_change_event, NMConfigChangeFlags changes, NMConfigData *old_data)
+{
+	if (is_change_event)
+		g_assert (changes == (NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_USER));
+	assert_config_value (config_data, "atomic-prefix-1.section-a", "key1", "user-value1");
+	assert_config_value (config_data, "atomic-prefix-1.section-a", "key2", "user-value2");
+	assert_config_value (config_data, "atomic-prefix-1.section-b", "key1", "user-value1");
+	assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key1", "user-value1");
+	assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key2", "user-value2");
+}
+
+static void
+_set_values_intern_atomic_section_1_set (NMConfig *config, gboolean set_user, GKeyFile *keyfile, NMConfigChangeFlags *out_expected_changes)
+{
+	g_key_file_set_string (keyfile, "atomic-prefix-1.section-a", "key1", "intern-value1");
+	g_key_file_set_string (keyfile, "atomic-prefix-1.section-a", "key3", "intern-value3");
+	g_key_file_set_string (keyfile, "non-atomic-prefix-1.section-a", "nap1-key1", "intern-value1");
+	g_key_file_set_string (keyfile, "non-atomic-prefix-1.section-a", "nap1-key3", "intern-value3");
+	*out_expected_changes = NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_INTERN;
+}
+
+static void
+_set_values_intern_atomic_section_1_check (NMConfig *config, NMConfigData *config_data, gboolean is_change_event, NMConfigChangeFlags changes, NMConfigData *old_data)
+{
+	if (is_change_event)
+		g_assert (changes == (NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_INTERN));
+	assert_config_value (config_data, "atomic-prefix-1.section-a", "key1", "intern-value1");
+	assert_config_value (config_data, "atomic-prefix-1.section-a", "key2", NULL);
+	assert_config_value (config_data, "atomic-prefix-1.section-a", "key3", "intern-value3");
+	assert_config_value (config_data, "atomic-prefix-1.section-b", "key1", "user-value1");
+	assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key1", "intern-value1");
+	assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key2", "user-value2");
+	assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key3", "intern-value3");
+	g_assert ( nm_config_data_is_intern_atomic_group (config_data, "atomic-prefix-1.section-a"));
+	g_assert (!nm_config_data_is_intern_atomic_group (config_data, "atomic-prefix-1.section-b"));
+	g_assert (!nm_config_data_is_intern_atomic_group (config_data, "non-atomic-prefix-1.section-a"));
+}
+
+static void
+_set_values_user_atomic_section_2_set (NMConfig *config, gboolean set_user, GKeyFile *keyfile, NMConfigChangeFlags *out_expected_changes)
+{
+	g_key_file_set_string (keyfile, "atomic-prefix-1.section-a", "key1", "user-value1-x");
+	g_key_file_set_string (keyfile, "atomic-prefix-1.section-a", "key2", "user-value2");
+	g_key_file_set_string (keyfile, "non-atomic-prefix-1.section-a", "nap1-key1", "user-value1-x");
+	g_key_file_set_string (keyfile, "non-atomic-prefix-1.section-a", "nap1-key2", "user-value2-x");
+	*out_expected_changes = NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_USER | NM_CONFIG_CHANGE_VALUES_INTERN;
+}
+
+static void
+_set_values_user_atomic_section_2_check (NMConfig *config, NMConfigData *config_data, gboolean is_change_event, NMConfigChangeFlags changes, NMConfigData *old_data)
+{
+	if (is_change_event)
+		g_assert (changes == (NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_USER | NM_CONFIG_CHANGE_VALUES_INTERN));
+	assert_config_value (config_data, "atomic-prefix-1.section-a", "key1", "user-value1-x");
+	assert_config_value (config_data, "atomic-prefix-1.section-a", "key2", "user-value2");
+	assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key1", "user-value1-x");
+	assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key2", "user-value2-x");
+	assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key3", "intern-value3");
+	g_assert (!nm_config_data_is_intern_atomic_group (config_data, "atomic-prefix-1.section-a"));
+	g_assert (!nm_config_data_is_intern_atomic_group (config_data, "atomic-prefix-1.section-b"));
+	g_assert (!nm_config_data_is_intern_atomic_group (config_data, "non-atomic-prefix-1.section-a"));
+}
+
+static void
+_set_values_intern_atomic_section_2_set (NMConfig *config, gboolean set_user, GKeyFile *keyfile, NMConfigChangeFlags *out_expected_changes)
+{
+	/* let's hide an atomic section and one key. */
+	g_key_file_set_string (keyfile, "atomic-prefix-1.section-a", NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS, "any-value");
+	g_key_file_set_string (keyfile, "non-atomic-prefix-1.section-a", NM_CONFIG_KEYFILE_KEYPREFIX_WAS"nap1-key1", "any-value");
+	g_key_file_set_string (keyfile, "non-atomic-prefix-1.section-a", "nap1-key3", "intern-value3");
+	g_key_file_set_string (keyfile, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN"with-whitespace", "key1", " b c\\,  d  ");
+	g_key_file_set_value  (keyfile, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN"with-whitespace", "key2", " b c\\,  d  ");
+	*out_expected_changes = NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_INTERN;
+}
+
+static void
+_set_values_intern_atomic_section_2_check (NMConfig *config, NMConfigData *config_data, gboolean is_change_event, NMConfigChangeFlags changes, NMConfigData *old_data)
+{
+	if (is_change_event)
+		g_assert (changes == (NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_INTERN));
+	g_assert (!nm_config_data_has_group (config_data, "atomic-prefix-1.section-a"));
+	assert_config_value (config_data, "atomic-prefix-1.section-b", "key1", "user-value1");
+	assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key1", NULL);
+	assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key2", "user-value2-x");
+	assert_config_value (config_data, "non-atomic-prefix-1.section-a", "nap1-key3", "intern-value3");
+	g_assert (!nm_config_data_is_intern_atomic_group (config_data, "atomic-prefix-1.section-a"));
+	g_assert (!nm_config_data_is_intern_atomic_group (config_data, "atomic-prefix-1.section-b"));
+	g_assert (!nm_config_data_is_intern_atomic_group (config_data, "non-atomic-prefix-1.section-a"));
+	assert_config_value (config_data, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN"with-whitespace", "key1", " b c\\,  d  ");
+	assert_config_value (config_data, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN"with-whitespace", "key2", " b c\\,  d  ");
+}
+
+static void
+test_config_set_values (void)
+{
+	gs_unref_object NMConfig *config = NULL;
+	const char *CONFIG_USER = BUILDDIR"/test-set-values-user.conf";
+	const char *CONFIG_INTERN = BUILDDIR"/test-set-values-intern.conf";
+	const char *atomic_section_prefixes[] = {
+		"atomic-prefix-1.",
+		"atomic-prefix-2.",
+		NULL,
+	};
+
+	g_assert (g_file_set_contents (CONFIG_USER, "", 0, NULL));
+	g_assert (g_file_set_contents (CONFIG_INTERN, "", 0, NULL));
+
+	config = setup_config (NULL, CONFIG_USER, CONFIG_INTERN, atomic_section_prefixes, "", "", NULL);
+
+	_set_values_user (config, CONFIG_USER,
+	                  _set_values_user_intern_section_set,
+	                  _set_values_user_intern_section_check);
+
+	_set_values_user (config, CONFIG_USER,
+	                  _set_values_user_initial_values_set,
+	                  _set_values_user_initial_values_check);
+
+	_set_values_intern (config,
+	                    _set_values_intern_internal_set,
+	                    _set_values_intern_internal_check);
+
+	_set_values_user (config, CONFIG_USER,
+	                  _set_values_user_atomic_section_1_set,
+	                  _set_values_user_atomic_section_1_check);
+
+	_set_values_intern (config,
+	                    _set_values_intern_atomic_section_1_set,
+	                    _set_values_intern_atomic_section_1_check);
+
+	_set_values_user (config, CONFIG_USER,
+	                  _set_values_user_atomic_section_2_set,
+	                  _set_values_user_atomic_section_2_check);
+
+	_set_values_intern (config,
+	                    _set_values_intern_atomic_section_2_set,
+	                    _set_values_intern_atomic_section_2_check);
+
+	g_assert (remove (CONFIG_USER) == 0);
+	g_assert (remove (CONFIG_INTERN) == 0);
+}
+
+/*****************************************************************************/
+
 static void
 _test_signal_config_changed_cb (NMConfig *config,
                                 NMConfigData *config_data,
@@ -436,7 +855,7 @@ test_config_signal (void)
 	NMConfigChangeFlags expected;
 	gs_unref_object NMConfigData *config_data_orig = NULL;
 
-	config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "/no/such/dir", NULL);
+	config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, SRCDIR "/conf.d", "", NULL);
 
 	config_data_orig = g_object_ref (nm_config_get_data_orig (config));
 
@@ -479,6 +898,40 @@ test_config_signal (void)
 
 /*****************************************************************************/
 
+static void
+test_config_enable (void)
+{
+	gs_unref_object NMConfig *config = NULL;
+	guint match_nm_version = _nm_config_match_nm_version;
+	char *match_env = g_strdup (_nm_config_match_env);
+
+	g_clear_pointer (&_nm_config_match_env, g_free);
+	_nm_config_match_env = g_strdup ("something-else");
+
+	_nm_config_match_nm_version = nm_encode_version (1, 3, 4);
+	config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, SRCDIR "/conf.d", "", NULL);
+	assert_config_value (nm_config_get_data_orig (config), "test-group-config-enable-1", "key1", NULL);
+	g_clear_object (&config);
+
+	_nm_config_match_nm_version = nm_encode_version (1, 5, 32);
+	config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, SRCDIR "/conf.d", "", NULL);
+	assert_config_value (nm_config_get_data_orig (config), "test-group-config-enable-1", "key1", "enabled");
+	g_clear_object (&config);
+
+	_nm_config_match_nm_version = nm_encode_version (1, 5, 3);
+	g_clear_pointer (&_nm_config_match_env, g_free);
+	_nm_config_match_env = g_strdup ("test-match-env-1");
+	config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, SRCDIR "/conf.d", "", NULL);
+	assert_config_value (nm_config_get_data_orig (config), "test-group-config-enable-1", "key1", "enabled");
+	g_clear_object (&config);
+
+	_nm_config_match_nm_version = match_nm_version;
+	g_clear_pointer (&_nm_config_match_env, g_free);
+	_nm_config_match_env = match_env;
+}
+
+/*****************************************************************************/
+
 NMTST_DEFINE ();
 
 int
@@ -488,10 +941,10 @@ main (int argc, char **argv)
 
 	/* 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_dbus_manager_init_bus() which would
+	 * This way, we skip calling nm_bus_manager_init_bus() which would
 	 * either fail and/or cause unexpected actions in the test.
 	 * */
-	nm_dbus_manager_setup (g_object_new (NM_TYPE_DBUS_MANAGER, NULL));
+	nm_bus_manager_setup (g_object_new (NM_TYPE_BUS_MANAGER, NULL));
 
 	nm_fake_platform_setup ();
 
@@ -502,8 +955,13 @@ main (int argc, char **argv)
 	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/set-values", test_config_set_values);
+	g_test_add_func ("/config/global-dns", test_config_global_dns);
+
 	g_test_add_func ("/config/signal", test_config_signal);
 
+	g_test_add_func ("/config/enable", test_config_enable);
+
 	/* This one has to come last, because it leaves its values in
 	 * nm-config.c's global variables, and there's no way to reset
 	 * those to NULL.
diff --git a/src/tests/test-dcb.c b/src/tests/test-dcb.c
index dacb1f52..35f1ed0f 100644
--- a/src/tests/test-dcb.c
+++ b/src/tests/test-dcb.c
@@ -20,11 +20,13 @@
 
 #include "config.h"
 
-#include <glib.h>
 #include <string.h>
 
+#include "nm-default.h"
 #include "nm-dcb.h"
 
+#include "nm-test-utils.h"
+
 typedef struct {
 	guint num;
 	const char *cmds[];
@@ -335,14 +337,12 @@ test_fcoe_cleanup (void)
 
 /*******************************************/
 
+NMTST_DEFINE ();
+
 int
 main (int argc, char **argv)
 {
-	g_test_init (&argc, &argv, NULL);
-
-#if !GLIB_CHECK_VERSION (2, 35, 0)
-	g_type_init ();
-#endif
+	nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT");
 
 	g_test_add_func ("/dcb/fcoe", test_dcb_fcoe);
 	g_test_add_func ("/dcb/iscsi", test_dcb_iscsi);
diff --git a/src/tests/test-general-with-expect.c b/src/tests/test-general-with-expect.c
index 21fb0681..c6abdccf 100644
--- a/src/tests/test-general-with-expect.c
+++ b/src/tests/test-general-with-expect.c
@@ -20,7 +20,6 @@
 
 #include "config.h"
 
-#include <glib.h>
 #include <string.h>
 #include <errno.h>
 #include <time.h>
@@ -28,8 +27,8 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 
+#include "nm-default.h"
 #include "NetworkManagerUtils.h"
-#include "nm-logging.h"
 #include "nm-multi-index.h"
 
 #include "nm-test-utils.h"
@@ -865,9 +864,9 @@ main (int argc, char **argv)
 
 	g_test_add_func ("/general/nm_utils_monotonic_timestamp_as_boottime", test_nm_utils_monotonic_timestamp_as_boottime);
 	g_test_add_func ("/general/nm_utils_kill_child", test_nm_utils_kill_child);
+	g_test_add_func ("/general/nm_utils_array_remove_at_indexes", test_nm_utils_array_remove_at_indexes);
 	g_test_add_func ("/general/nm_ethernet_address_is_valid", test_nm_ethernet_address_is_valid);
 	g_test_add_func ("/general/nm_multi_index", test_nm_multi_index);
-	g_test_add_func ("/general/nm_utils_array_remove_at_indexes", test_nm_utils_array_remove_at_indexes);
 
 	return g_test_run ();
 }
diff --git a/src/tests/test-general.c b/src/tests/test-general.c
index 094a4a65..da68c9a9 100644
--- a/src/tests/test-general.c
+++ b/src/tests/test-general.c
@@ -20,12 +20,11 @@
 
 #include "config.h"
 
-#include <glib.h>
 #include <string.h>
 #include <errno.h>
 
+#include "nm-default.h"
 #include "NetworkManagerUtils.h"
-#include "nm-logging.h"
 #include "nm-core-internal.h"
 
 #include "nm-test-utils.h"
@@ -574,6 +573,62 @@ test_connection_no_match_ip4_addr (void)
 	g_object_unref (copy);
 }
 
+static void
+test_connection_no_match_vlan (void)
+{
+	NMConnection *orig, *copy, *matched;
+	GSList *connections = NULL;
+	NMSettingConnection *s_con;
+	NMSettingVlan *s_vlan_orig, *s_vlan_copy;
+	char *uuid;
+
+	orig = nm_simple_connection_new ();
+	s_con = (NMSettingConnection *) nm_setting_connection_new ();
+	nm_connection_add_setting (orig, (NMSetting *) s_con);
+	uuid = nm_utils_uuid_generate ();
+	g_object_set (G_OBJECT (s_con),
+	              NM_SETTING_CONNECTION_ID, "vlan-test",
+	              NM_SETTING_CONNECTION_UUID, uuid,
+	              NM_SETTING_CONNECTION_TYPE, NM_SETTING_VLAN_SETTING_NAME,
+	              NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
+	              NULL);
+	g_free (uuid);
+	nm_connection_add_setting (orig, nm_setting_vlan_new ());
+
+	copy = nm_simple_connection_new_clone (orig);
+	connections = g_slist_append (connections, copy);
+
+	/* Check that the connections do not match if VLAN flags differ */
+	s_vlan_orig = nm_connection_get_setting_vlan (orig);
+	g_assert (s_vlan_orig);
+	g_object_set (G_OBJECT (s_vlan_orig),
+	              NM_SETTING_VLAN_FLAGS, NM_VLAN_FLAG_REORDER_HEADERS,
+	              NULL);
+
+	s_vlan_copy = nm_connection_get_setting_vlan (copy);
+	g_assert (s_vlan_copy);
+	g_object_set (G_OBJECT (s_vlan_copy),
+	              NM_SETTING_VLAN_FLAGS, 0,
+	              NULL);
+
+	matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL);
+	g_assert (matched != copy);
+
+	/* Check that the connections do not match if VLAN priorities differ */
+	g_object_set (G_OBJECT (s_vlan_orig), NM_SETTING_VLAN_FLAGS, 0, NULL);
+	nm_setting_vlan_add_priority_str (s_vlan_orig, NM_VLAN_INGRESS_MAP, "1:3");
+
+	g_object_set (G_OBJECT (s_vlan_copy), NM_SETTING_VLAN_FLAGS, 0, NULL);
+	nm_setting_vlan_add_priority_str (s_vlan_copy, NM_VLAN_INGRESS_MAP, "4:2");
+
+	matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL);
+	g_assert (matched != copy);
+
+	g_slist_free (connections);
+	g_object_unref (orig);
+	g_object_unref (copy);
+}
+
 static NMConnection *
 _create_connection_autoconnect (const char *id, gboolean autoconnect, int autoconnect_priority)
 {
@@ -806,6 +861,258 @@ test_nm_match_spec_interface_name (void)
 
 /*******************************************/
 
+static void
+_do_test_match_spec_match_config (const char *file, gint line, const char *spec_str, guint version, guint v_maj, guint v_min, guint v_mic, NMMatchSpecMatchType expected)
+{
+	GSList *specs;
+	NMMatchSpecMatchType match_result;
+	guint c_maj, c_min, c_mic;
+
+	g_assert_cmpint (version, ==, nm_encode_version (v_maj, v_min, v_mic));
+
+	nm_decode_version (version, &c_maj, &c_min, &c_mic);
+	g_assert_cmpint (c_maj, ==, c_maj);
+	g_assert_cmpint (c_min, ==, c_min);
+	g_assert_cmpint (c_mic, ==, c_mic);
+
+	specs = nm_match_spec_split (spec_str);
+
+	match_result = nm_match_spec_match_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);
+
+	if (g_slist_length (specs) == 1 && match_result != NM_MATCH_SPEC_NEG_MATCH) {
+		/* there is only one spec in the list... test that we match except: */
+		char *sss = g_strdup_printf ("except:%s", (char *) specs->data);
+		GSList *specs2 = g_slist_append (NULL, sss);
+		NMMatchSpecMatchType match_result2;
+
+
+		match_result2 = nm_match_spec_match_config (specs2, version, NULL);
+		if (match_result == NM_MATCH_SPEC_NO_MATCH)
+			g_assert_cmpint (match_result2, ==, NM_MATCH_SPEC_NO_MATCH);
+		else
+			g_assert_cmpint (match_result2, ==, NM_MATCH_SPEC_NEG_MATCH);
+
+		g_slist_free_full (specs2, g_free);
+	}
+
+	g_slist_free_full (specs, g_free);
+}
+#define do_test_match_spec_match_config(spec, v_maj, v_min, v_mic, expected) \
+	_do_test_match_spec_match_config (__FILE__, __LINE__, (""spec), NM_ENCODE_VERSION ((v_maj), (v_min), (v_mic)), (v_maj), (v_min), (v_mic), (expected))
+
+static void
+test_nm_match_spec_match_config (void)
+{
+	do_test_match_spec_match_config ("", 1, 2, 3, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version:1.2.3", 1, 2, 2, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version:1.2.3", 1, 2, 3, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version:1.2.3", 1, 2, 4, NM_MATCH_SPEC_NO_MATCH);
+
+	do_test_match_spec_match_config ("nm-version:1.2", 1, 1, 2, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version:1.2", 1, 2, 0, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version:1.2", 1, 2, 2, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version:1.2", 1, 2, 3, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version:1.2", 1, 2, 4, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version:1.2", 1, 3, 0, NM_MATCH_SPEC_NO_MATCH);
+
+	do_test_match_spec_match_config ("nm-version-min:1.2.3", 0, 2, 30, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.2.3", 1, 1, 1, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.2.3", 1, 2, 2, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.2.3", 1, 2, 3, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.2.3", 1, 2, 5, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.2.3", 1, 3, 0, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.2.3", 1, 3, 30, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.2.3", 1, 4, 30, NM_MATCH_SPEC_NO_MATCH);
+
+	do_test_match_spec_match_config ("nm-version-min:1.2", 0, 2, 30, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.2", 1, 1, 1, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.2", 1, 2, 0, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.2", 1, 2, 3, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.2", 1, 2, 5, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.2", 1, 3, 0, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.2", 1, 3, 30, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.2", 1, 4, 30, NM_MATCH_SPEC_MATCH);
+
+	do_test_match_spec_match_config ("nm-version-min:1", 0, 2, 30, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1", 1, 1, 1, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1", 1, 2, 0, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1", 1, 2, 3, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1", 1, 2, 5, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1", 1, 3, 0, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1", 1, 3, 30, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1", 1, 4, 30, NM_MATCH_SPEC_MATCH);
+
+
+	do_test_match_spec_match_config ("nm-version-max:1.2.3", 0, 2, 30, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 1, 1, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 2, 0, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 2, 1, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 2, 2, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 2, 3, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 2, 5, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 3, 0, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 3, 30, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 4, 30, NM_MATCH_SPEC_NO_MATCH);
+
+	do_test_match_spec_match_config ("nm-version-max:1.2", 0, 2, 30, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1.2", 1, 1, 1, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1.2", 1, 2, 0, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1.2", 1, 2, 3, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1.2", 1, 2, 5, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1.2", 1, 3, 0, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1.2", 1, 3, 30, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1.2", 1, 4, 30, NM_MATCH_SPEC_NO_MATCH);
+
+	do_test_match_spec_match_config ("nm-version-max:1", 0, 2, 30, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1", 1, 1, 1, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1", 1, 2, 0, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1", 1, 2, 3, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1", 1, 2, 5, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1", 1, 3, 0, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1", 1, 3, 30, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1", 1, 4, 30, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-max:1", 2, 4, 30, NM_MATCH_SPEC_NO_MATCH);
+
+	do_test_match_spec_match_config ("except:nm-version:1.4.8", 1, 6, 0, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.6,except:nm-version:1.4.8", 1, 6, 0, NM_MATCH_SPEC_MATCH);
+
+	do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 2, 0, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 2, 0, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 2, 15, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 2, 16, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 2, 17, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 2, 20, NM_MATCH_SPEC_MATCH);
+
+	do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 3, 0, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 4, 0, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 4, 5, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 4, 6, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 4, 7, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 4, 8, NM_MATCH_SPEC_NEG_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 4, 9, NM_MATCH_SPEC_MATCH);
+
+	do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 5, 0, NM_MATCH_SPEC_NO_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 6, 0, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 6, 5, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 7, 7, NM_MATCH_SPEC_MATCH);
+	do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 8, 8, NM_MATCH_SPEC_MATCH);
+}
+
+/*******************************************/
+
+static void
+test_nm_utils_strbuf_append (void)
+{
+#define BUF_ORIG "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+#define STR_ORIG "abcdefghijklmnopqrstuvwxyz"
+	int buf_len;
+	int rep;
+	char buf[STRLEN (BUF_ORIG) + 1];
+	char str[STRLEN (BUF_ORIG) + 1];
+
+	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);
+			char *t_buf;
+			gsize t_len;
+			int test_mode;
+
+			strcpy (str, STR_ORIG);
+			str[s_len] = '\0';
+
+			g_assert_cmpint (str[sizeof (str) - 1], ==, '\0');
+			g_assert_cmpint (strlen (str), ==, s_len);
+
+			strcpy (buf, BUF_ORIG);
+
+			t_buf = buf;
+			t_len = buf_len;
+
+			test_mode = nmtst_get_rand_int () % 4;
+
+			switch (test_mode) {
+			case 0:
+				if (s_len == 1) {
+					nm_utils_strbuf_append_c (&t_buf, &t_len, str[0]);
+					break;
+				}
+				/* fall-through */
+			case 1:
+				nm_utils_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]);
+					break;
+				}
+				/* fall-through */
+			case 3:
+				nm_utils_strbuf_append (&t_buf, &t_len, "%s", str);
+				break;
+			}
+
+			/* Assert that the source-buffer is unmodified. */
+			g_assert_cmpint (str[s_len], ==, '\0');
+			str[s_len] = STR_ORIG[s_len];
+			g_assert (!memcmp (str, STR_ORIG, sizeof (str)));
+			str[s_len] = '\0';
+
+			g_assert_cmpint (t_len, >=, 0);
+			g_assert_cmpint (t_len, <=, buf_len);
+			g_assert (t_buf >= buf);
+
+			/* Assert what was written to the destination buffer. */
+			switch (buf_len) {
+			case 0:
+				g_assert_cmpint (t_len, ==, 0);
+				g_assert (t_buf == buf);
+				g_assert (!memcmp (buf, BUF_ORIG, sizeof (buf)));
+				break;
+			case 1:
+				if (s_len == 0) {
+					g_assert_cmpint (t_len, ==, 1);
+					g_assert (t_buf == buf);
+					g_assert (buf[0] == '\0');
+					g_assert (!memcmp (&buf[1], &BUF_ORIG[1], sizeof (buf) - 1));
+				} else {
+					g_assert_cmpint (t_len, ==, 0);
+					g_assert (t_buf == &buf[1]);
+					g_assert (buf[0] == '\0');
+					g_assert (!memcmp (&buf[1], &BUF_ORIG[1], sizeof (buf) - 1));
+				}
+				break;
+			default:
+				if (s_len == 0) {
+					g_assert_cmpint (t_len, ==, buf_len);
+					g_assert (t_buf == buf);
+					g_assert (buf[0] == '\0');
+					g_assert (!memcmp (&buf[1], &BUF_ORIG[1], sizeof (buf) - 1));
+				} else if (buf_len <= s_len) {
+					g_assert_cmpint (t_len, ==, 0);
+					g_assert (t_buf == &buf[buf_len]);
+					g_assert (!memcmp (buf, STR_ORIG, buf_len - 1));
+					g_assert (buf[buf_len - 1] == '\0');
+					g_assert (!memcmp (&buf[buf_len], &BUF_ORIG[buf_len], sizeof (buf) - buf_len));
+				} else {
+					g_assert_cmpint (t_len, >, 0);
+					g_assert_cmpint (buf_len - t_len, ==, s_len);
+					g_assert_cmpint (strlen (buf), ==, s_len);
+					g_assert (t_buf == &buf[s_len]);
+					g_assert (!memcmp (buf, STR_ORIG, s_len));
+					g_assert (buf[s_len] == '\0');
+					g_assert (!memcmp (&buf[s_len + 1], &BUF_ORIG[s_len + 1], sizeof (buf) - s_len - 1));
+				}
+				break;
+			}
+		}
+	}
+}
+
+/*******************************************/
+
 NMTST_DEFINE ();
 
 int
@@ -813,6 +1120,8 @@ main (int argc, char **argv)
 {
 	nmtst_init_with_logging (&argc, &argv, NULL, "ALL");
 
+	g_test_add_func ("/general/nm_utils_strbuf_append", test_nm_utils_strbuf_append);
+
 	g_test_add_func ("/general/nm_utils_ip6_address_clear_host_address", test_nm_utils_ip6_address_clear_host_address);
 	g_test_add_func ("/general/nm_utils_log_connection_diff", test_nm_utils_log_connection_diff);
 
@@ -826,10 +1135,12 @@ main (int argc, char **argv)
 	g_test_add_func ("/general/connection-match/wired2", test_connection_match_wired2);
 	g_test_add_func ("/general/connection-match/cloned_mac", test_connection_match_cloned_mac);
 	g_test_add_func ("/general/connection-match/no-match-ip4-addr", test_connection_no_match_ip4_addr);
+	g_test_add_func ("/general/connection-match/no-match-vlan", test_connection_no_match_vlan);
 
 	g_test_add_func ("/general/connection-sort/autoconnect-priority", test_connection_sort_autoconnect_priority);
 
 	g_test_add_func ("/general/nm_match_spec_interface_name", test_nm_match_spec_interface_name);
+	g_test_add_func ("/general/nm_match_spec_match_config", test_nm_match_spec_match_config);
 
 	return g_test_run ();
 }
diff --git a/src/tests/test-ip4-config.c b/src/tests/test-ip4-config.c
index 404940d4..16cd3d1e 100644
--- a/src/tests/test-ip4-config.c
+++ b/src/tests/test-ip4-config.c
@@ -20,13 +20,15 @@
 
 #include "config.h"
 
-#include <glib.h>
 #include <string.h>
 #include <arpa/inet.h>
 
+#include "nm-default.h"
 #include "nm-ip4-config.h"
 #include "nm-platform.h"
 
+#include "nm-test-utils.h"
+
 static void
 addr_init (NMPlatformIP4Address *a, const char *addr, const char *peer, guint plen)
 {
@@ -34,6 +36,8 @@ addr_init (NMPlatformIP4Address *a, const char *addr, const char *peer, guint pl
 	g_assert (inet_pton (AF_INET, addr, (void *) &a->address) == 1);
 	if (peer)
 		g_assert (inet_pton (AF_INET, peer, (void *) &a->peer_address) == 1);
+	else
+		a->peer_address = a->address;
 	a->plen = plen;
 }
 
@@ -71,7 +75,7 @@ build_test_config (void)
 	NMPlatformIP4Route route;
 
 	/* Build up the config to subtract */
-	config = nm_ip4_config_new ();
+	config = nm_ip4_config_new (1);
 
 	addr_init (&addr, "192.168.1.10", "1.2.3.4", 24);
 	nm_ip4_config_add_address (config, &addr);
@@ -150,7 +154,7 @@ test_subtract (void)
 	test_addr = nm_ip4_config_get_address (dst, 0);
 	g_assert (test_addr != NULL);
 	g_assert_cmpuint (test_addr->address, ==, addr_to_num (expected_addr));
-	g_assert_cmpuint (test_addr->peer_address, ==, 0);
+	g_assert_cmpuint (test_addr->peer_address, ==, test_addr->address);
 	g_assert_cmpuint (test_addr->plen, ==, expected_addr_plen);
 
 	g_assert_cmpuint (nm_ip4_config_get_gateway (dst), ==, 0);
@@ -191,8 +195,8 @@ test_compare_with_source (void)
 	NMPlatformIP4Address addr;
 	NMPlatformIP4Route route;
 
-	a = nm_ip4_config_new ();
-	b = nm_ip4_config_new ();
+	a = nm_ip4_config_new (1);
+	b = nm_ip4_config_new (2);
 
 	/* Address */
 	addr_init (&addr, "1.2.3.4", NULL, 24);
@@ -224,7 +228,7 @@ test_add_address_with_source (void)
 	NMPlatformIP4Address addr;
 	const NMPlatformIP4Address *test_addr;
 
-	a = nm_ip4_config_new ();
+	a = nm_ip4_config_new (1);
 
 	/* Test that a higher priority source is not overwritten */
 	addr_init (&addr, "1.2.3.4", NULL, 24);
@@ -264,7 +268,7 @@ test_add_route_with_source (void)
 	NMPlatformIP4Route route;
 	const NMPlatformIP4Route *test_route;
 
-	a = nm_ip4_config_new ();
+	a = nm_ip4_config_new (1);
 
 	/* Test that a higher priority source is not overwritten */
 	route_new (&route, "1.2.3.4", 24, "1.2.3.1");
@@ -341,7 +345,7 @@ test_strip_search_trailing_dot (void)
 {
 	NMIP4Config *config;
 
-	config = nm_ip4_config_new ();
+	config = nm_ip4_config_new (1);
 
 	nm_ip4_config_add_search (config, ".");
 	nm_ip4_config_add_search (config, "foo");
@@ -359,14 +363,12 @@ test_strip_search_trailing_dot (void)
 
 /*******************************************/
 
+NMTST_DEFINE ();
+
 int
 main (int argc, char **argv)
 {
-	g_test_init (&argc, &argv, NULL);
-
-#if !GLIB_CHECK_VERSION (2, 35, 0)
-	g_type_init ();
-#endif
+	nmtst_init_with_logging (&argc, &argv, NULL, "DEFAULT");
 
 	g_test_add_func ("/ip4-config/subtract", test_subtract);
 	g_test_add_func ("/ip4-config/compare-with-source", test_compare_with_source);
diff --git a/src/tests/test-ip6-config.c b/src/tests/test-ip6-config.c
index a5397b8a..2639a1f0 100644
--- a/src/tests/test-ip6-config.c
+++ b/src/tests/test-ip6-config.c
@@ -20,13 +20,12 @@
 
 #include "config.h"
 
-#include <glib.h>
 #include <string.h>
 #include <arpa/inet.h>
 
+#include "nm-default.h"
 #include "nm-ip6-config.h"
 
-#include "nm-logging.h"
 #include "nm-platform.h"
 #include "nm-test-utils.h"
 
@@ -36,7 +35,7 @@ build_test_config (void)
 	NMIP6Config *config;
 
 	/* Build up the config to subtract */
-	config = nm_ip6_config_new ();
+	config = nm_ip6_config_new (1);
 
 	nm_ip6_config_add_address (config, nmtst_platform_ip6_address ("abcd:1234:4321::cdde", "1:2:3:4::5", 64));
 	nm_ip6_config_add_route (config, nmtst_platform_ip6_route ("abcd:1234:4321::", 24, "abcd:1234:4321:cdde::2"));
@@ -129,8 +128,8 @@ test_compare_with_source (void)
 	NMPlatformIP6Address addr;
 	NMPlatformIP6Route route;
 
-	a = nm_ip6_config_new ();
-	b = nm_ip6_config_new ();
+	a = nm_ip6_config_new (1);
+	b = nm_ip6_config_new (2);
 
 	/* Address */
 	addr = *nmtst_platform_ip6_address ("1122:3344:5566::7788", NULL, 64);
@@ -162,7 +161,7 @@ test_add_address_with_source (void)
 	NMPlatformIP6Address addr;
 	const NMPlatformIP6Address *test_addr;
 
-	a = nm_ip6_config_new ();
+	a = nm_ip6_config_new (1);
 
 	/* Test that a higher priority source is not overwritten */
 	addr = *nmtst_platform_ip6_address ("1122:3344:5566::7788", NULL, 64);
@@ -202,7 +201,7 @@ test_add_route_with_source (void)
 	NMPlatformIP6Route route;
 	const NMPlatformIP6Route *test_route;
 
-	a = nm_ip6_config_new ();
+	a = nm_ip6_config_new (1);
 
 	/* Test that a higher priority source is not overwritten */
 	route = *nmtst_platform_ip6_route ("abcd:1234:4321::", 24, "abcd:1234:4321:cdde::2");
@@ -265,8 +264,8 @@ test_nm_ip6_config_addresses_sort_check (NMIP6Config *config, NMSettingIP6Config
 		if (!nm_ip6_config_equal (copy, config)) {
 			g_message ("%s", "SORTING yields unexpected output:");
 			for (i = 0; i < addr_count; i++) {
-				g_message ("   >> [%d] = %s", i, nm_platform_ip6_address_to_string (nm_ip6_config_get_address (config, i)));
-				g_message ("   << [%d] = %s", i, nm_platform_ip6_address_to_string (nm_ip6_config_get_address (copy, i)));
+				g_message ("   >> [%d] = %s", i, nm_platform_ip6_address_to_string (nm_ip6_config_get_address (config, i), NULL, 0));
+				g_message ("   << [%d] = %s", i, nm_platform_ip6_address_to_string (nm_ip6_config_get_address (copy, i), NULL, 0));
 			}
 			g_assert_not_reached ();
 		}
@@ -326,7 +325,7 @@ test_strip_search_trailing_dot (void)
 {
 	NMIP6Config *config;
 
-	config = nm_ip6_config_new ();
+	config = nm_ip6_config_new (1);
 
 	nm_ip6_config_add_search (config, ".");
 	nm_ip6_config_add_search (config, "foo");
diff --git a/src/tests/test-resolvconf-capture.c b/src/tests/test-resolvconf-capture.c
index f5cb298b..db7006ba 100644
--- a/src/tests/test-resolvconf-capture.c
+++ b/src/tests/test-resolvconf-capture.c
@@ -20,25 +20,27 @@
 
 #include "config.h"
 
-#include <glib.h>
 #include <string.h>
 #include <arpa/inet.h>
 
+#include "nm-default.h"
 #include "NetworkManagerUtils.h"
 #include "nm-ip4-config.h"
 #include "nm-ip6-config.h"
 #include "nm-platform.h"
 
+#include "nm-test-utils.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_ip4_config_capture_resolv_conf (ns4, "") == FALSE);
+	g_assert (nm_ip4_config_capture_resolv_conf (ns4, NULL, "") == FALSE);
 	g_assert_cmpint (ns4->len, ==, 0);
 
-	g_assert (nm_ip6_config_capture_resolv_conf (ns6, "") == FALSE);
+	g_assert (nm_ip6_config_capture_resolv_conf (ns6, NULL, "") == FALSE);
 	g_assert_cmpint (ns6->len, ==, 0);
 
 	g_array_free (ns4, TRUE);
@@ -67,6 +69,12 @@ assert_dns6_entry (const GArray *a, guint i, const char *s)
 }
 
 static void
+assert_dns_option (GPtrArray *a, guint i, const char *s)
+{
+	g_assert_cmpstr (a->pdata[i], ==, s);
+}
+
+static void
 test_capture_basic4 (void)
 {
 	GArray *ns4 = g_array_new (FALSE, FALSE, sizeof (guint32));
@@ -77,7 +85,7 @@ test_capture_basic4 (void)
 "nameserver 4.2.2.1\r\n"
 "nameserver 4.2.2.2\r\n";
 
-	g_assert (nm_ip4_config_capture_resolv_conf (ns4, rc));
+	g_assert (nm_ip4_config_capture_resolv_conf (ns4, NULL, rc));
 	g_assert_cmpint (ns4->len, ==, 2);
 	assert_dns4_entry (ns4, 0, "4.2.2.1");
 	assert_dns4_entry (ns4, 1, "4.2.2.2");
@@ -98,7 +106,7 @@ test_capture_dup4 (void)
 "nameserver 4.2.2.2\r\n";
 
 	/* Check that duplicates are ignored */
-	g_assert (nm_ip4_config_capture_resolv_conf (ns4, rc));
+	g_assert (nm_ip4_config_capture_resolv_conf (ns4, NULL, rc));
 	g_assert_cmpint (ns4->len, ==, 2);
 	assert_dns4_entry (ns4, 0, "4.2.2.1");
 	assert_dns4_entry (ns4, 1, "4.2.2.2");
@@ -117,7 +125,7 @@ test_capture_basic6 (void)
 "nameserver 2001:4860:4860::8888\r\n"
 "nameserver 2001:4860:4860::8844\r\n";
 
-	g_assert (nm_ip6_config_capture_resolv_conf (ns6, rc));
+	g_assert (nm_ip6_config_capture_resolv_conf (ns6, NULL, rc));
 	g_assert_cmpint (ns6->len, ==, 2);
 	assert_dns6_entry (ns6, 0, "2001:4860:4860::8888");
 	assert_dns6_entry (ns6, 1, "2001:4860:4860::8844");
@@ -138,7 +146,7 @@ test_capture_dup6 (void)
 "nameserver 2001:4860:4860::8844\r\n";
 
 	/* Check that duplicates are ignored */
-	g_assert (nm_ip6_config_capture_resolv_conf (ns6, rc));
+	g_assert (nm_ip6_config_capture_resolv_conf (ns6, NULL, rc));
 	g_assert_cmpint (ns6->len, ==, 2);
 	assert_dns6_entry (ns6, 0, "2001:4860:4860::8888");
 	assert_dns6_entry (ns6, 1, "2001:4860:4860::8844");
@@ -158,7 +166,7 @@ test_capture_addr4_with_6 (void)
 "nameserver 4.2.2.2\r\n"
 "nameserver 2001:4860:4860::8888\r\n";
 
-	g_assert (nm_ip4_config_capture_resolv_conf (ns4, rc));
+	g_assert (nm_ip4_config_capture_resolv_conf (ns4, NULL, rc));
 	g_assert_cmpint (ns4->len, ==, 2);
 	assert_dns4_entry (ns4, 0, "4.2.2.1");
 	assert_dns4_entry (ns4, 1, "4.2.2.2");
@@ -178,7 +186,7 @@ test_capture_addr6_with_4 (void)
 "nameserver 2001:4860:4860::8888\r\n"
 "nameserver 2001:4860:4860::8844\r\n";
 
-	g_assert (nm_ip6_config_capture_resolv_conf (ns6, rc));
+	g_assert (nm_ip6_config_capture_resolv_conf (ns6, NULL, rc));
 	g_assert_cmpint (ns6->len, ==, 2);
 	assert_dns6_entry (ns6, 0, "2001:4860:4860::8888");
 	assert_dns6_entry (ns6, 1, "2001:4860:4860::8844");
@@ -197,7 +205,7 @@ test_capture_format (void)
 "nameserver\t\t4.2.2.4\r\n"   /* good */
 "nameserver  4.2.2.5\t\t\r\n"; /* good */
 
-	g_assert (nm_ip4_config_capture_resolv_conf (ns4, rc));
+	g_assert (nm_ip4_config_capture_resolv_conf (ns4, NULL, rc));
 	g_assert_cmpint (ns4->len, ==, 3);
 	assert_dns4_entry (ns4, 0, "4.2.2.3");
 	assert_dns4_entry (ns4, 1, "4.2.2.4");
@@ -206,16 +214,88 @@ test_capture_format (void)
 	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_ip4_config_capture_resolv_conf (ns4, dns_options, rc));
+	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_ip4_config_capture_resolv_conf (ns4, dns_options, rc));
+	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_ip4_config_capture_resolv_conf (ns4, dns_options, rc));
+	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 (guint32));
+	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_ip6_config_capture_resolv_conf (ns6, dns_options, rc));
+	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)
 {
-	g_test_init (&argc, &argv, NULL);
-
-#if !GLIB_CHECK_VERSION (2,35,0)
-	g_type_init ();
-#endif
+	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);
@@ -225,6 +305,10 @@ main (int argc, char **argv)
 	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 ();
 }
diff --git a/src/tests/test-route-manager.c b/src/tests/test-route-manager.c
index 9046bf88..347c122c 100644
--- a/src/tests/test-route-manager.c
+++ b/src/tests/test-route-manager.c
@@ -20,15 +20,14 @@
 
 #include "config.h"
 
-#include <glib.h>
 #include <arpa/inet.h>
 #include <linux/rtnetlink.h>
 
+#include "nm-default.h"
 #include "test-common.h"
 
 #include "nm-platform.h"
 #include "nm-route-manager.h"
-#include "nm-logging.h"
 
 #include "nm-test-utils.h"
 
@@ -378,8 +377,8 @@ setup_dev0_ip6 (int ifindex)
 	nm_platform_ip6_address_add (NM_PLATFORM_GET,
 	                             ifindex,
 	                             *nmtst_inet6_from_string ("2001:db8:8086::666"),
-	                             in6addr_any,
 	                             64,
+	                             in6addr_any,
 	                             3600,
 	                             3600,
 	                             0);
@@ -482,8 +481,8 @@ update_dev0_ip6 (int ifindex)
 	nm_platform_ip6_address_add (NM_PLATFORM_GET,
 	                             ifindex,
 	                             *nmtst_inet6_from_string ("2001:db8:8086::2"),
-	                             in6addr_any,
 	                             64,
+	                             in6addr_any,
 	                             3600,
 	                             3600,
 	                             0);
@@ -798,10 +797,12 @@ _assert_route_check (const NMPlatformVTableRoute *vtable, gboolean has, const NM
 	if (!has) {
 		g_assert (!r);
 	} else {
+		char buf[sizeof (_nm_utils_to_string_buffer)];
+
 		if (!r || vtable->route_cmp (route, r) != 0)
 			g_error ("Invalid route. Expect %s, has %s",
-			         nmtst_static_1024_01 (vtable->route_to_string (route)),
-			         nmtst_static_1024_02 (vtable->route_to_string (r)));
+			         vtable->route_to_string (route, NULL, 0),
+			         vtable->route_to_string (r, buf, sizeof (buf)));
 		g_assert (r);
 	}
 }
@@ -874,7 +875,8 @@ fixture_setup (test_fixture *fixture, gconstpointer user_data)
 	                                link_callback,
 	                                "nm-test-device0");
 	nm_platform_link_delete (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, "nm-test-device0"));
-	g_assert (nm_platform_dummy_add (NM_PLATFORM_GET, "nm-test-device0", NULL) == NM_PLATFORM_ERROR_SUCCESS);
+	g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "nm-test-device0"));
+	g_assert (nm_platform_link_dummy_add (NM_PLATFORM_GET, "nm-test-device0", NULL) == NM_PLATFORM_ERROR_SUCCESS);
 	accept_signal (link_added);
 	free_signal (link_added);
 	fixture->ifindex0 = nm_platform_link_get_ifindex (NM_PLATFORM_GET, "nm-test-device0");
@@ -885,7 +887,8 @@ fixture_setup (test_fixture *fixture, gconstpointer user_data)
 	                                link_callback,
 	                                "nm-test-device1");
 	nm_platform_link_delete (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, "nm-test-device1"));
-	g_assert (nm_platform_dummy_add (NM_PLATFORM_GET, "nm-test-device1", NULL) == NM_PLATFORM_ERROR_SUCCESS);
+	g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "nm-test-device1"));
+	g_assert (nm_platform_link_dummy_add (NM_PLATFORM_GET, "nm-test-device1", NULL) == NM_PLATFORM_ERROR_SUCCESS);
 	accept_signal (link_added);
 	free_signal (link_added);
 	fixture->ifindex1 = nm_platform_link_get_ifindex (NM_PLATFORM_GET, "nm-test-device1");
diff --git a/src/tests/test-utils.c b/src/tests/test-utils.c
new file mode 100644
index 00000000..79a7e680
--- /dev/null
+++ b/src/tests/test-utils.c
@@ -0,0 +1,63 @@
+/* -*- 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) 2015 Red Hat, Inc.
+ *
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <errno.h>
+#include <arpa/inet.h>
+
+#include "NetworkManagerUtils.c"
+
+#include "nm-test-utils.h"
+
+static void
+test_stable_privacy (void)
+{
+	struct in6_addr addr1;
+
+	inet_pton (AF_INET6, "1234::", &addr1);
+	_set_stable_privacy (&addr1, "eth666", "6b138152-9f3e-4b97-aaf7-e6e553f2a24e", 0, "key", 3, NULL);
+	nmtst_assert_ip6_address (&addr1, "1234::4ceb:14cd:3d54:793f");
+
+	/* We get an address without the UUID. */
+	inet_pton (AF_INET6, "1::", &addr1);
+	_set_stable_privacy (&addr1, "eth666", NULL, 384, "key", 3, NULL);
+	nmtst_assert_ip6_address (&addr1, "1::11aa:2530:9144:dafa");
+
+	/* We get a different address in a different network. */
+	inet_pton (AF_INET6, "2::", &addr1);
+	_set_stable_privacy (&addr1, "eth666", NULL, 384, "key", 3, NULL);
+	nmtst_assert_ip6_address (&addr1, "2::338e:8d:c11:8726");
+}
+
+/*******************************************/
+
+NMTST_DEFINE ();
+
+int
+main (int argc, char **argv)
+{
+	nmtst_init_with_logging (&argc, &argv, NULL, "ALL");
+
+	g_test_add_func ("/utils/stable_privacy", test_stable_privacy);
+
+	return g_test_run ();
+}
diff --git a/src/tests/test-wired-defname.c b/src/tests/test-wired-defname.c
index b2933de0..989345d8 100644
--- a/src/tests/test-wired-defname.c
+++ b/src/tests/test-wired-defname.c
@@ -20,13 +20,13 @@
 
 #include "config.h"
 
-#include <glib.h>
-#include <glib-object.h>
 
 #include <nm-simple-connection.h>
 #include <nm-setting-connection.h>
+#include "nm-default.h"
 #include "nm-device-ethernet-utils.h"
-#include "gsystem-local-alloc.h"
+
+#include "nm-test-utils.h"
 
 static NMConnection *
 _new_connection (const char *id)
@@ -112,14 +112,12 @@ test_defname_multiple_conflicts (void)
 
 /*******************************************/
 
+NMTST_DEFINE ();
+
 int
 main (int argc, char **argv)
 {
-#if !GLIB_CHECK_VERSION (2, 35, 0)
-	g_type_init ();
-#endif
-
-	g_test_init (&argc, &argv, NULL);
+	nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT");
 
 	g_test_add_func ("/defname/no_connections", test_defname_no_connections);
 	g_test_add_func ("/defname/no_conflict", test_defname_no_conflict);