summary refs log tree commit diff
path: root/libnm-glib/tests
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2015-01-22 00:29:39 +0100
committerMichael Biebl <biebl@debian.org>2015-01-22 00:29:39 +0100
commit2c032d8f1c6292c1338a615e6ec40252889ba85c (patch)
tree1f77182220b2b0264288ba4a476ab47e5bc48716 /libnm-glib/tests
parent33491bc4279481db8ae47213e34a6d695a0e8830 (diff)
Imported Upstream version 1.0.0 upstream/1.0.0
Diffstat (limited to 'libnm-glib/tests')
-rw-r--r--libnm-glib/tests/Makefile.am30
-rw-r--r--libnm-glib/tests/Makefile.in167
-rw-r--r--libnm-glib/tests/common.c121
-rw-r--r--libnm-glib/tests/common.h31
-rwxr-xr-xlibnm-glib/tests/libnm-glib-test-launch.sh9
-rwxr-xr-xlibnm-glib/tests/test-fake-nm.py776
-rw-r--r--libnm-glib/tests/test-nm-client.c499
-rw-r--r--libnm-glib/tests/test-remote-settings-client.c212
-rwxr-xr-xlibnm-glib/tests/test-remote-settings-service.py150
9 files changed, 676 insertions, 1319 deletions
diff --git a/libnm-glib/tests/Makefile.am b/libnm-glib/tests/Makefile.am
index 38f449ac..7b8f3627 100644
--- a/libnm-glib/tests/Makefile.am
+++ b/libnm-glib/tests/Makefile.am
@@ -2,52 +2,48 @@ if ENABLE_TESTS
 
 AM_CPPFLAGS = \
 	-I$(top_srcdir)/include \
-	-I$(top_builddir)/include \
 	-I$(top_srcdir)/libnm-util \
 	-I$(top_builddir)/libnm-util \
 	-I$(top_srcdir)/libnm-glib \
 	-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
+	-DTEST_NM_SERVICE=\"$(abs_top_srcdir)/tools/test-networkmanager-service.py\" \
 	$(GLIB_CFLAGS) \
 	$(DBUS_CFLAGS)
 
-noinst_PROGRAMS = test-nm-client test-remote-settings-client
+noinst_PROGRAMS = $(TESTS)
+
+TESTS = test-nm-client test-remote-settings-client
 
 ####### NMClient and non-settings tests #######
 
 test_nm_client_SOURCES = \
+	common.c \
+	common.h \
 	test-nm-client.c
 
 test_nm_client_LDADD = \
 	$(top_builddir)/libnm-util/libnm-util.la \
-	$(top_builddir)/libnm-glib/libnm-glib-test.la \
+	$(top_builddir)/libnm-glib/libnm-glib.la \
 	$(GLIB_LIBS) \
 	$(DBUS_LIBS)
 
 ####### remote settings client test #######
 
 test_remote_settings_client_SOURCES = \
+	common.c \
+	common.h \
 	test-remote-settings-client.c
 
 test_remote_settings_client_LDADD = \
 	$(top_builddir)/libnm-util/libnm-util.la \
-	$(top_builddir)/libnm-glib/libnm-glib-test.la \
+	$(top_builddir)/libnm-glib/libnm-glib.la \
 	$(GLIB_LIBS) \
 	$(DBUS_LIBS)
 
 ###########################################
 
-TEST_NM_BIN = test-fake-nm.py
-TEST_RSS_BIN = test-remote-settings-service.py
-
-EXTRA_DIST = $(TEST_RSS_BIN) $(TEST_NM_BIN)
-
-check-local: test-nm-client test-remote-settings-client
-	if test -z "$$DBUS_SESSION_BUS_ADDRESS" ; then \
-	    dbus-launch --exit-with-session $(abs_builddir)/test-nm-client $(abs_srcdir) $(TEST_NM_BIN); \
-	    dbus-launch --exit-with-session $(abs_builddir)/test-remote-settings-client $(abs_srcdir) $(TEST_RSS_BIN); \
-	else \
-	    $(abs_builddir)/test-nm-client $(abs_srcdir) $(TEST_NM_BIN); \
-	    $(abs_builddir)/test-remote-settings-client $(abs_srcdir) $(TEST_RSS_BIN); \
-	fi;
+TESTS_ENVIRONMENT = $(srcdir)/libnm-glib-test-launch.sh
 
 endif
+
+EXTRA_DIST = libnm-glib-test-launch.sh
diff --git a/libnm-glib/tests/Makefile.in b/libnm-glib/tests/Makefile.in
index 28acdea0..7dd74031 100644
--- a/libnm-glib/tests/Makefile.in
+++ b/libnm-glib/tests/Makefile.in
@@ -78,7 +78,8 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-@ENABLE_TESTS_TRUE@noinst_PROGRAMS = test-nm-client$(EXEEXT) \
+@ENABLE_TESTS_TRUE@noinst_PROGRAMS = $(am__EXEEXT_1)
+@ENABLE_TESTS_TRUE@TESTS = test-nm-client$(EXEEXT) \
 @ENABLE_TESTS_TRUE@	test-remote-settings-client$(EXEEXT)
 subdir = libnm-glib/tests
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
@@ -103,29 +104,32 @@ mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
+@ENABLE_TESTS_TRUE@am__EXEEXT_1 = test-nm-client$(EXEEXT) \
+@ENABLE_TESTS_TRUE@	test-remote-settings-client$(EXEEXT)
 PROGRAMS = $(noinst_PROGRAMS)
-am__test_nm_client_SOURCES_DIST = test-nm-client.c
-@ENABLE_TESTS_TRUE@am_test_nm_client_OBJECTS =  \
+am__test_nm_client_SOURCES_DIST = common.c common.h test-nm-client.c
+@ENABLE_TESTS_TRUE@am_test_nm_client_OBJECTS = common.$(OBJEXT) \
 @ENABLE_TESTS_TRUE@	test-nm-client.$(OBJEXT)
 test_nm_client_OBJECTS = $(am_test_nm_client_OBJECTS)
 am__DEPENDENCIES_1 =
 @ENABLE_TESTS_TRUE@test_nm_client_DEPENDENCIES =  \
 @ENABLE_TESTS_TRUE@	$(top_builddir)/libnm-util/libnm-util.la \
-@ENABLE_TESTS_TRUE@	$(top_builddir)/libnm-glib/libnm-glib-test.la \
+@ENABLE_TESTS_TRUE@	$(top_builddir)/libnm-glib/libnm-glib.la \
 @ENABLE_TESTS_TRUE@	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
 am__v_lt_0 = --silent
 am__v_lt_1 = 
-am__test_remote_settings_client_SOURCES_DIST =  \
+am__test_remote_settings_client_SOURCES_DIST = common.c common.h \
 	test-remote-settings-client.c
 @ENABLE_TESTS_TRUE@am_test_remote_settings_client_OBJECTS =  \
+@ENABLE_TESTS_TRUE@	common.$(OBJEXT) \
 @ENABLE_TESTS_TRUE@	test-remote-settings-client.$(OBJEXT)
 test_remote_settings_client_OBJECTS =  \
 	$(am_test_remote_settings_client_OBJECTS)
 @ENABLE_TESTS_TRUE@test_remote_settings_client_DEPENDENCIES =  \
 @ENABLE_TESTS_TRUE@	$(top_builddir)/libnm-util/libnm-util.la \
-@ENABLE_TESTS_TRUE@	$(top_builddir)/libnm-glib/libnm-glib-test.la \
+@ENABLE_TESTS_TRUE@	$(top_builddir)/libnm-glib/libnm-glib.la \
 @ENABLE_TESTS_TRUE@	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
 AM_V_P = $(am__v_P_@AM_V@)
 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -189,6 +193,28 @@ am__define_uniq_tagged_files = \
   done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
@@ -199,6 +225,8 @@ AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
+BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@
+BLUEZ5_LIBS = @BLUEZ5_LIBS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
@@ -322,6 +350,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@
 NEWT_LIBS = @NEWT_LIBS@
 NM = @NM@
 NMEDIT = @NMEDIT@
+NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@
 NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
 NM_MICRO_VERSION = @NM_MICRO_VERSION@
 NM_MINOR_VERSION = @NM_MINOR_VERSION@
@@ -341,6 +370,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
 PACKAGE_URL = @PACKAGE_URL@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
 PKG_CONFIG = @PKG_CONFIG@
 PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
@@ -367,7 +397,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@
 SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@
 SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
-UDEV_BASE_DIR = @UDEV_BASE_DIR@
+UDEV_DIR = @UDEV_DIR@
 USE_NLS = @USE_NLS@
 UUID_CFLAGS = @UUID_CFLAGS@
 UUID_LIBS = @UUID_LIBS@
@@ -448,41 +478,44 @@ with_resolvconf = @with_resolvconf@
 with_valgrind = @with_valgrind@
 @ENABLE_TESTS_TRUE@AM_CPPFLAGS = \
 @ENABLE_TESTS_TRUE@	-I$(top_srcdir)/include \
-@ENABLE_TESTS_TRUE@	-I$(top_builddir)/include \
 @ENABLE_TESTS_TRUE@	-I$(top_srcdir)/libnm-util \
 @ENABLE_TESTS_TRUE@	-I$(top_builddir)/libnm-util \
 @ENABLE_TESTS_TRUE@	-I$(top_srcdir)/libnm-glib \
 @ENABLE_TESTS_TRUE@	-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
+@ENABLE_TESTS_TRUE@	-DTEST_NM_SERVICE=\"$(abs_top_srcdir)/tools/test-networkmanager-service.py\" \
 @ENABLE_TESTS_TRUE@	$(GLIB_CFLAGS) \
 @ENABLE_TESTS_TRUE@	$(DBUS_CFLAGS)
 
 
 ####### NMClient and non-settings tests #######
 @ENABLE_TESTS_TRUE@test_nm_client_SOURCES = \
+@ENABLE_TESTS_TRUE@	common.c \
+@ENABLE_TESTS_TRUE@	common.h \
 @ENABLE_TESTS_TRUE@	test-nm-client.c
 
 @ENABLE_TESTS_TRUE@test_nm_client_LDADD = \
 @ENABLE_TESTS_TRUE@	$(top_builddir)/libnm-util/libnm-util.la \
-@ENABLE_TESTS_TRUE@	$(top_builddir)/libnm-glib/libnm-glib-test.la \
+@ENABLE_TESTS_TRUE@	$(top_builddir)/libnm-glib/libnm-glib.la \
 @ENABLE_TESTS_TRUE@	$(GLIB_LIBS) \
 @ENABLE_TESTS_TRUE@	$(DBUS_LIBS)
 
 
 ####### remote settings client test #######
 @ENABLE_TESTS_TRUE@test_remote_settings_client_SOURCES = \
+@ENABLE_TESTS_TRUE@	common.c \
+@ENABLE_TESTS_TRUE@	common.h \
 @ENABLE_TESTS_TRUE@	test-remote-settings-client.c
 
 @ENABLE_TESTS_TRUE@test_remote_settings_client_LDADD = \
 @ENABLE_TESTS_TRUE@	$(top_builddir)/libnm-util/libnm-util.la \
-@ENABLE_TESTS_TRUE@	$(top_builddir)/libnm-glib/libnm-glib-test.la \
+@ENABLE_TESTS_TRUE@	$(top_builddir)/libnm-glib/libnm-glib.la \
 @ENABLE_TESTS_TRUE@	$(GLIB_LIBS) \
 @ENABLE_TESTS_TRUE@	$(DBUS_LIBS)
 
 
 ###########################################
-@ENABLE_TESTS_TRUE@TEST_NM_BIN = test-fake-nm.py
-@ENABLE_TESTS_TRUE@TEST_RSS_BIN = test-remote-settings-service.py
-@ENABLE_TESTS_TRUE@EXTRA_DIST = $(TEST_RSS_BIN) $(TEST_NM_BIN)
+@ENABLE_TESTS_TRUE@TESTS_ENVIRONMENT = $(srcdir)/libnm-glib-test-launch.sh
+EXTRA_DIST = libnm-glib-test-launch.sh
 all: all-am
 
 .SUFFIXES:
@@ -541,6 +574,7 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-nm-client.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-remote-settings-client.Po@am__quote@
 
@@ -623,6 +657,99 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
 	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
+check-TESTS: $(TESTS)
+	@failed=0; all=0; xfail=0; xpass=0; skip=0; \
+	srcdir=$(srcdir); export srcdir; \
+	list=' $(TESTS) '; \
+	$(am__tty_colors); \
+	if test -n "$$list"; then \
+	  for tst in $$list; do \
+	    if test -f ./$$tst; then dir=./; \
+	    elif test -f $$tst; then dir=; \
+	    else dir="$(srcdir)/"; fi; \
+	    if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *[\ \	]$$tst[\ \	]*) \
+		xpass=`expr $$xpass + 1`; \
+		failed=`expr $$failed + 1`; \
+		col=$$red; res=XPASS; \
+	      ;; \
+	      *) \
+		col=$$grn; res=PASS; \
+	      ;; \
+	      esac; \
+	    elif test $$? -ne 77; then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *[\ \	]$$tst[\ \	]*) \
+		xfail=`expr $$xfail + 1`; \
+		col=$$lgn; res=XFAIL; \
+	      ;; \
+	      *) \
+		failed=`expr $$failed + 1`; \
+		col=$$red; res=FAIL; \
+	      ;; \
+	      esac; \
+	    else \
+	      skip=`expr $$skip + 1`; \
+	      col=$$blu; res=SKIP; \
+	    fi; \
+	    echo "$${col}$$res$${std}: $$tst"; \
+	  done; \
+	  if test "$$all" -eq 1; then \
+	    tests="test"; \
+	    All=""; \
+	  else \
+	    tests="tests"; \
+	    All="All "; \
+	  fi; \
+	  if test "$$failed" -eq 0; then \
+	    if test "$$xfail" -eq 0; then \
+	      banner="$$All$$all $$tests passed"; \
+	    else \
+	      if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+	      banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+	    fi; \
+	  else \
+	    if test "$$xpass" -eq 0; then \
+	      banner="$$failed of $$all $$tests failed"; \
+	    else \
+	      if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+	      banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+	    fi; \
+	  fi; \
+	  dashes="$$banner"; \
+	  skipped=""; \
+	  if test "$$skip" -ne 0; then \
+	    if test "$$skip" -eq 1; then \
+	      skipped="($$skip test was not run)"; \
+	    else \
+	      skipped="($$skip tests were not run)"; \
+	    fi; \
+	    test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$skipped"; \
+	  fi; \
+	  report=""; \
+	  if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+	    report="Please report to $(PACKAGE_BUGREPORT)"; \
+	    test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$report"; \
+	  fi; \
+	  dashes=`echo "$$dashes" | sed s/./=/g`; \
+	  if test "$$failed" -eq 0; then \
+	    col="$$grn"; \
+	  else \
+	    col="$$red"; \
+	  fi; \
+	  echo "$${col}$$dashes$${std}"; \
+	  echo "$${col}$$banner$${std}"; \
+	  test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+	  test -z "$$report" || echo "$${col}$$report$${std}"; \
+	  echo "$${col}$$dashes$${std}"; \
+	  test "$$failed" -eq 0; \
+	else :; fi
+
 distdir: $(DISTFILES)
 	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
 	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
@@ -653,9 +780,8 @@ distdir: $(DISTFILES)
 	    || exit 1; \
 	  fi; \
 	done
-@ENABLE_TESTS_FALSE@check-local:
 check-am: all-am
-	$(MAKE) $(AM_MAKEFLAGS) check-local
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
 check: check-am
 all-am: Makefile $(PROGRAMS)
 installdirs:
@@ -762,7 +888,7 @@ uninstall-am:
 
 .MAKE: check-am install-am install-strip
 
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am check-local clean \
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
 	clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \
 	ctags ctags-am distclean distclean-compile distclean-generic \
 	distclean-libtool distclean-tags distdir dvi dvi-am html \
@@ -777,15 +903,6 @@ uninstall-am:
 	tags tags-am uninstall uninstall-am
 
 
-@ENABLE_TESTS_TRUE@check-local: test-nm-client test-remote-settings-client
-@ENABLE_TESTS_TRUE@	if test -z "$$DBUS_SESSION_BUS_ADDRESS" ; then \
-@ENABLE_TESTS_TRUE@	    dbus-launch --exit-with-session $(abs_builddir)/test-nm-client $(abs_srcdir) $(TEST_NM_BIN); \
-@ENABLE_TESTS_TRUE@	    dbus-launch --exit-with-session $(abs_builddir)/test-remote-settings-client $(abs_srcdir) $(TEST_RSS_BIN); \
-@ENABLE_TESTS_TRUE@	else \
-@ENABLE_TESTS_TRUE@	    $(abs_builddir)/test-nm-client $(abs_srcdir) $(TEST_NM_BIN); \
-@ENABLE_TESTS_TRUE@	    $(abs_builddir)/test-remote-settings-client $(abs_srcdir) $(TEST_RSS_BIN); \
-@ENABLE_TESTS_TRUE@	fi;
-
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
diff --git a/libnm-glib/tests/common.c b/libnm-glib/tests/common.c
new file mode 100644
index 00000000..540d43af
--- /dev/null
+++ b/libnm-glib/tests/common.c
@@ -0,0 +1,121 @@
+/* -*- 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 2010 - 2014 Red Hat, Inc.
+ *
+ */
+
+#include "config.h"
+
+#include <dbus/dbus.h>
+#include <glib.h>
+#include <string.h>
+
+#include "NetworkManager.h"
+
+#include "common.h"
+
+static gboolean
+name_exists (GDBusConnection *c, const char *name)
+{
+	GVariant *reply;
+	gboolean exists = FALSE;
+
+	reply = g_dbus_connection_call_sync (c,
+	                                     DBUS_SERVICE_DBUS,
+	                                     DBUS_PATH_DBUS,
+	                                     DBUS_INTERFACE_DBUS,
+	                                     "GetNameOwner",
+	                                     g_variant_new ("(s)", name),
+	                                     NULL,
+	                                     G_DBUS_CALL_FLAGS_NO_AUTO_START,
+	                                     -1,
+	                                     NULL,
+	                                     NULL);
+	if (reply != NULL) {
+		exists = TRUE;
+		g_variant_unref (reply);
+	}
+
+	return exists;
+}
+
+NMTestServiceInfo *
+nm_test_service_init (void)
+{
+	NMTestServiceInfo *info;
+	const char *args[2] = { TEST_NM_SERVICE, NULL };
+	GError *error = NULL;
+	int i;
+
+	info = g_malloc0 (sizeof (*info));
+
+	info->bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL,  &error);
+	g_assert_no_error (error);
+
+	/* Spawn the test service. info->keepalive_fd will be a pipe to the service's
+	 * stdin; if it closes, the service will exit immediately. We use this to
+	 * make sure the service exits if the test program crashes.
+	 */
+	g_spawn_async_with_pipes (NULL, (char **) args, NULL, 0, NULL, NULL,
+	                          &info->pid, &info->keepalive_fd, NULL, NULL, &error);
+	g_assert_no_error (error);
+
+	/* Wait until the service is registered on the bus */
+	for (i = 100; i > 0; i--) {
+		if (name_exists (info->bus, "org.freedesktop.NetworkManager"))
+			break;
+		g_usleep (G_USEC_PER_SEC / 50);
+	}
+	g_assert (i > 0);
+
+	/* Grab a proxy to our fake NM service to trigger tests */
+	info->proxy = g_dbus_proxy_new_sync (info->bus,
+	                                     G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
+	                                     G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
+	                                     G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+	                                     NULL,
+	                                     NM_DBUS_SERVICE,
+	                                     NM_DBUS_PATH,
+	                                     "org.freedesktop.NetworkManager.LibnmGlibTest",
+	                                     NULL, &error);
+	g_assert_no_error (error);
+
+	return info;
+}
+
+void
+nm_test_service_cleanup (NMTestServiceInfo *info)
+{
+	int i;
+
+	g_object_unref (info->proxy);
+	kill (info->pid, SIGTERM);
+
+	/* Wait until the bus notices the service is gone */
+	for (i = 100; i > 0; i--) {
+		if (!name_exists (info->bus, "org.freedesktop.NetworkManager"))
+			break;
+		g_usleep (G_USEC_PER_SEC / 50);
+	}
+	g_assert (i > 0);
+
+	g_object_unref (info->bus);
+	close (info->keepalive_fd);
+
+	memset (info, 0, sizeof (*info));
+	g_free (info);
+}
diff --git a/libnm-glib/tests/common.h b/libnm-glib/tests/common.h
new file mode 100644
index 00000000..7c49d253
--- /dev/null
+++ b/libnm-glib/tests/common.h
@@ -0,0 +1,31 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright 2014 Red Hat, Inc.
+ */
+
+#include <gio/gio.h>
+
+typedef struct {
+	GDBusConnection *bus;
+	GDBusProxy *proxy;
+	GPid pid;
+	int keepalive_fd;
+} NMTestServiceInfo;
+
+NMTestServiceInfo *nm_test_service_init (void);
+void nm_test_service_cleanup (NMTestServiceInfo *info);
diff --git a/libnm-glib/tests/libnm-glib-test-launch.sh b/libnm-glib/tests/libnm-glib-test-launch.sh
new file mode 100755
index 00000000..42d9fbe2
--- /dev/null
+++ b/libnm-glib/tests/libnm-glib-test-launch.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+# Spawn DBus if there's none
+if [ -z "$DBUS_SESSION_BUS_ADDRESS" ]; then
+    eval `dbus-launch --sh-syntax`
+    trap "kill $DBUS_SESSION_BUS_PID" EXIT
+fi
+
+"$@"
diff --git a/libnm-glib/tests/test-fake-nm.py b/libnm-glib/tests/test-fake-nm.py
deleted file mode 100755
index 46ca3ff0..00000000
--- a/libnm-glib/tests/test-fake-nm.py
+++ /dev/null
@@ -1,776 +0,0 @@
-#!/usr/bin/env python
-# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-
-from __future__ import print_function
-
-from gi.repository import GLib, GObject
-import sys
-import dbus
-import dbus.service
-import dbus.mainloop.glib
-import random
-
-mainloop = GObject.MainLoop()
-quit_id = 0
-
-# NM State
-NM_STATE_UNKNOWN          = 0
-NM_STATE_ASLEEP           = 10
-NM_STATE_DISCONNECTED     = 20
-NM_STATE_DISCONNECTING    = 30
-NM_STATE_CONNECTING       = 40
-NM_STATE_CONNECTED_LOCAL  = 50
-NM_STATE_CONNECTED_SITE   = 60
-NM_STATE_CONNECTED_GLOBAL = 70
-
-# Device state
-NM_DEVICE_STATE_UNKNOWN      = 0
-NM_DEVICE_STATE_UNMANAGED    = 10
-NM_DEVICE_STATE_UNAVAILABLE  = 20
-NM_DEVICE_STATE_DISCONNECTED = 30
-NM_DEVICE_STATE_PREPARE      = 40
-NM_DEVICE_STATE_CONFIG       = 50
-NM_DEVICE_STATE_NEED_AUTH    = 60
-NM_DEVICE_STATE_IP_CONFIG    = 70
-NM_DEVICE_STATE_IP_CHECK     = 80
-NM_DEVICE_STATE_SECONDARIES  = 90
-NM_DEVICE_STATE_ACTIVATED    = 100
-NM_DEVICE_STATE_DEACTIVATING = 110
-NM_DEVICE_STATE_FAILED       = 120
-
-NM_DEVICE_TYPE_UNKNOWN    = 0
-NM_DEVICE_TYPE_ETHERNET   = 1
-NM_DEVICE_TYPE_WIFI       = 2
-NM_DEVICE_TYPE_UNUSED1    = 3
-NM_DEVICE_TYPE_UNUSED2    = 4
-NM_DEVICE_TYPE_BT         = 5
-NM_DEVICE_TYPE_OLPC_MESH  = 6
-NM_DEVICE_TYPE_WIMAX      = 7
-NM_DEVICE_TYPE_MODEM      = 8
-NM_DEVICE_TYPE_INFINIBAND = 9
-NM_DEVICE_TYPE_BOND       = 10
-NM_DEVICE_TYPE_VLAN       = 11
-NM_DEVICE_TYPE_ADSL       = 12
-NM_DEVICE_TYPE_BRIDGE     = 13
-NM_DEVICE_TYPE_GENERIC    = 14
-NM_DEVICE_TYPE_TEAM       = 15
-
-#########################################################
-IFACE_DBUS = 'org.freedesktop.DBus'
-
-class UnknownInterfaceException(dbus.DBusException):
-    _dbus_error_name = IFACE_DBUS + '.UnknownInterface'
-
-class UnknownPropertyException(dbus.DBusException):
-    _dbus_error_name = IFACE_DBUS + '.UnknownProperty'
-
-def to_path_array(src):
-    array = dbus.Array([], signature=dbus.Signature('o'))
-    for o in src:
-        array.append(o.path)
-    return array
-
-def to_path(src):
-    if src:
-        return dbus.ObjectPath(src.path)
-    return dbus.ObjectPath("/")
-
-class ExportedObj(dbus.service.Object):
-    def __init__(self, bus, object_path):
-        dbus.service.Object.__init__(self, bus, object_path)
-        self._bus = bus
-        self.path = object_path
-        self.__dbus_ifaces = {}
-
-    def add_dbus_interface(self, dbus_iface, get_props_func):
-        self.__dbus_ifaces[dbus_iface] = get_props_func
-
-    def _get_dbus_properties(self, iface):
-        return self.__dbus_ifaces[iface]()
-
-    @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}')
-    def GetAll(self, iface):
-        if iface not in self.__dbus_ifaces.keys():
-            raise UnknownInterfaceException()
-        return self._get_dbus_properties(iface)
-
-    @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v')
-    def Get(self, iface, name):
-        if iface not in self.__dbus_ifaces.keys():
-            raise UnknownInterfaceException()
-        props = self._get_dbus_properties(iface)
-        if not name in props.keys():
-            raise UnknownPropertyException()
-        return props[name]
-
-###################################################################
-IFACE_DEVICE = 'org.freedesktop.NetworkManager.Device'
-
-PD_UDI = "Udi"
-PD_IFACE = "Interface"
-PD_DRIVER = "Driver"
-PD_STATE = "State"
-PD_ACTIVE_CONNECTION = "ActiveConnection"
-PD_IP4_CONFIG = "Ip4Config"
-PD_IP6_CONFIG = "Ip6Config"
-PD_DHCP4_CONFIG = "Dhcp4Config"
-PD_DHCP6_CONFIG = "Dhcp6Config"
-PD_MANAGED = "Managed"
-PD_AUTOCONNECT = "Autoconnect"
-PD_DEVICE_TYPE = "DeviceType"
-PD_AVAILABLE_CONNECTIONS = "AvailableConnections"
-
-class Device(ExportedObj):
-    counter = 1
-
-    def __init__(self, bus, iface, devtype):
-        object_path = "/org/freedesktop/NetworkManager/Devices/%d" % Device.counter
-        Device.counter = Device.counter + 1
-        ExportedObj.__init__(self, bus, object_path)
-        self.add_dbus_interface(IFACE_DEVICE, self.__get_props)
-
-        self.iface = iface
-        self.udi = "/sys/devices/virtual/%s" % iface
-        self.devtype = devtype
-        self.active_connection = None
-        self.state = NM_DEVICE_STATE_UNAVAILABLE
-        self.ip4_config = None
-        self.ip6_config = None
-        self.dhcp4_config = None
-        self.dhcp6_config = None
-        self.available_connections = []
-
-    # Properties interface
-    def __get_props(self):
-        props = {}
-        props[PD_UDI] = self.udi
-        props[PD_IFACE] = self.iface
-        props[PD_DRIVER] = "virtual"
-        props[PD_STATE] = dbus.UInt32(self.state)
-        props[PD_ACTIVE_CONNECTION] = to_path(self.active_connection)
-        props[PD_IP4_CONFIG] = to_path(self.ip4_config)
-        props[PD_IP6_CONFIG] = to_path(self.ip6_config)
-        props[PD_DHCP4_CONFIG] = to_path(self.dhcp4_config)
-        props[PD_DHCP6_CONFIG] = to_path(self.dhcp6_config)
-        props[PD_MANAGED] = True
-        props[PD_AUTOCONNECT] = True
-        props[PD_DEVICE_TYPE] = dbus.UInt32(self.devtype)
-        props[PD_AVAILABLE_CONNECTIONS] = to_path_array(self.available_connections)
-        return props
-
-    # methods
-    @dbus.service.method(dbus_interface=IFACE_DEVICE, in_signature='', out_signature='')
-    def Disconnect(self):
-        pass
-
-    def __notify(self, propname):
-        props = self._get_dbus_properties(IFACE_DEVICE)
-        changed = { propname: props[propname] }
-        Device.PropertiesChanged(self, changed)
-
-    @dbus.service.signal(IFACE_DEVICE, signature='a{sv}')
-    def PropertiesChanged(self, changed):
-        pass
-
-
-###################################################################
-
-def random_mac():
-    return '%02X:%02X:%02X:%02X:%02X:%02X' % (
-        random.randint(0, 255), random.randint(0, 255), random.randint(0, 255),
-        random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
-      )
-
-###################################################################
-IFACE_WIRED = 'org.freedesktop.NetworkManager.Device.Wired'
-
-PE_HW_ADDRESS = "HwAddress"
-PE_PERM_HW_ADDRESS = "PermHwAddress"
-PE_SPEED = "Speed"
-PE_CARRIER = "Carrier"
-
-class WiredDevice(Device):
-    def __init__(self, bus, iface):
-        Device.__init__(self, bus, iface, NM_DEVICE_TYPE_ETHERNET)
-        self.add_dbus_interface(IFACE_WIRED, self.__get_props)
-
-        self.mac = random_mac()
-        self.carrier = False
-
-    # Properties interface
-    def __get_props(self):
-        props = {}
-        props[PE_HW_ADDRESS] = self.mac
-        props[PE_PERM_HW_ADDRESS] = self.mac
-        props[PE_SPEED] = dbus.UInt32(100)
-        props[PE_CARRIER] = self.carrier
-        return props
-
-    def __notify(self, propname):
-        props = self._get_dbus_properties(IFACE_WIRED)
-        changed = { propname: props[propname] }
-        WiredDevice.PropertiesChanged(self, changed)
-
-    @dbus.service.signal(IFACE_WIRED, signature='a{sv}')
-    def PropertiesChanged(self, changed):
-        pass
-
-###################################################################
-IFACE_WIFI_AP = 'org.freedesktop.NetworkManager.AccessPoint'
-
-PP_FLAGS = "Flags"
-PP_WPA_FLAGS = "WpaFlags"
-PP_RSN_FLAGS = "RsnFlags"
-PP_SSID = "Ssid"
-PP_FREQUENCY = "Frequency"
-PP_HW_ADDRESS = "HwAddress"
-PP_MODE = "Mode"
-PP_MAX_BITRATE = "MaxBitrate"
-PP_STRENGTH = "Strength"
-
-class WifiAp(ExportedObj):
-    counter = 0
-
-    def __init__(self, bus, ssid, mac, flags, wpaf, rsnf, freq):
-        path = "/org/freedesktop/NetworkManager/AccessPoint/%d" % WifiAp.counter
-        WifiAp.counter = WifiAp.counter + 1
-        ExportedObj.__init__(self, bus, path)
-        self.add_dbus_interface(IFACE_WIFI_AP, self.__get_props)
-
-        self.ssid = ssid
-        if mac:
-            self.bssid = mac
-        else:
-            self.bssid = random_mac()
-        self.flags = flags
-        self.wpaf = wpaf
-        self.rsnf = rsnf
-        self.freq = freq
-        self.strength = random.randint(0, 100)
-        self.strength_id = GLib.timeout_add_seconds(10, self.strength_cb, None)
-
-    def __del__(self):
-        if self.strength_id > 0:
-            GLib.source_remove(self.strength_id)
-        self.strength_id = 0
-
-    def strength_cb(self, ignored):
-        self.strength = random.randint(0, 100)
-        self.__notify(PP_STRENGTH)
-        return True
-
-    # Properties interface
-    def __get_props(self):
-        props = {}
-        props[PP_FLAGS] = dbus.UInt32(self.flags)
-        props[PP_WPA_FLAGS] = dbus.UInt32(self.wpaf)
-        props[PP_RSN_FLAGS] = dbus.UInt32(self.rsnf)
-        props[PP_SSID] = dbus.ByteArray(self.ssid)
-        props[PP_FREQUENCY] = dbus.UInt32(self.freq)
-        props[PP_HW_ADDRESS] = self.bssid
-        props[PP_MODE] = dbus.UInt32(2)  # NM_802_11_MODE_INFRA
-        props[PP_MAX_BITRATE] = dbus.UInt32(54000)
-        props[PP_STRENGTH] = dbus.Byte(self.strength)
-        return props
-
-    def __notify(self, propname):
-        props = self._get_dbus_properties(IFACE_WIFI_AP)
-        changed = { propname: props[propname] }
-        WifiAp.PropertiesChanged(self, changed)
-
-    @dbus.service.signal(IFACE_WIFI_AP, signature='a{sv}')
-    def PropertiesChanged(self, changed):
-        pass
-
-###################################################################
-IFACE_WIFI = 'org.freedesktop.NetworkManager.Device.Wireless'
-
-class ApNotFoundException(dbus.DBusException):
-    _dbus_error_name = IFACE_WIFI + '.AccessPointNotFound'
-
-PW_HW_ADDRESS = "HwAddress"
-PW_PERM_HW_ADDRESS = "PermHwAddress"
-PW_MODE = "Mode"
-PW_BITRATE = "Bitrate"
-PW_ACCESS_POINTS = "AccessPoints"
-PW_ACTIVE_ACCESS_POINT = "ActiveAccessPoint"
-PW_WIRELESS_CAPABILITIES = "WirelessCapabilities"
-
-class WifiDevice(Device):
-    def __init__(self, bus, iface):
-        Device.__init__(self, bus, iface, NM_DEVICE_TYPE_WIFI)
-        self.add_dbus_interface(IFACE_WIFI, self.__get_props)
-
-        self.mac = random_mac()
-        self.aps = []
-        self.active_ap = None
-
-    # methods
-    @dbus.service.method(dbus_interface=IFACE_WIFI, in_signature='', out_signature='ao')
-    def GetAccessPoints(self):
-        # only include non-hidden APs
-        array = []
-        for a in self.aps:
-            if a.ssid():
-                array.append(a)
-        return to_path_array(array)
-
-    @dbus.service.method(dbus_interface=IFACE_WIFI, in_signature='', out_signature='ao')
-    def GetAllAccessPoints(self):
-        # include all APs including hidden ones
-        return to_path_array(self.aps)
-
-    @dbus.service.method(dbus_interface=IFACE_WIFI, in_signature='a{sv}', out_signature='')
-    def RequestScan(self, props):
-        pass
-
-    @dbus.service.signal(IFACE_WIFI, signature='o')
-    def AccessPointAdded(self, ap_path):
-        pass
-
-    def add_ap(self, ap):
-        self.aps.append(ap)
-        self.__notify(PW_ACCESS_POINTS)
-        self.AccessPointAdded(to_path(ap))
-
-    @dbus.service.signal(IFACE_WIFI, signature='o')
-    def AccessPointRemoved(self, ap_path):
-        pass
-
-    def remove_ap(self, ap):
-        self.aps.remove(ap)
-        self.__notify(PW_ACCESS_POINTS)
-        self.AccessPointRemoved(to_path(ap))
-
-    # Properties interface
-    def __get_props(self):
-        props = {}
-        props[PW_HW_ADDRESS] = self.mac
-        props[PW_PERM_HW_ADDRESS] = self.mac
-        props[PW_MODE] = dbus.UInt32(3)  # NM_802_11_MODE_INFRA
-        props[PW_BITRATE] = dbus.UInt32(21000)
-        props[PW_WIRELESS_CAPABILITIES] = dbus.UInt32(0xFF)
-        props[PW_ACCESS_POINTS] = to_path_array(self.aps)
-        props[PW_ACTIVE_ACCESS_POINT] = to_path(self.active_ap)
-        return props
-
-    def __notify(self, propname):
-        props = self._get_dbus_properties(IFACE_WIFI)
-        changed = { propname: props[propname] }
-        WifiDevice.PropertiesChanged(self, changed)
-
-    @dbus.service.signal(IFACE_WIFI, signature='a{sv}')
-    def PropertiesChanged(self, changed):
-        pass
-
-    # test functions
-    def add_test_ap(self, ssid, mac):
-        ap = WifiAp(self._bus, ssid, mac, 0x1, 0x1cc, 0x1cc, 2412)
-        self.add_ap(ap)
-        return ap.path
-
-    def remove_ap_by_path(self, path):
-        for ap in self.aps:
-            if ap.path == path:
-                self.remove_ap(ap)
-                return
-        raise ApNotFoundException("AP %s not found" % path)
-
-
-###################################################################
-IFACE_WIMAX_NSP = 'org.freedesktop.NetworkManager.WiMax.Nsp'
-
-PN_NAME = "Name"
-PN_SIGNAL_QUALITY = "SignalQuality"
-PN_NETWORK_TYPE = "NetworkType"
-
-class WimaxNsp(ExportedObj):
-    counter = 0
-
-    def __init__(self, bus, name):
-        path = "/org/freedesktop/NetworkManager/Nsp/%d" % WimaxNsp.counter
-        WimaxNsp.counter = WimaxNsp.counter + 1
-        ExportedObj.__init__(self, bus, path)
-        self.add_dbus_interface(IFACE_WIMAX_NSP, self.__get_props)
-
-        self.name = name
-        self.strength = random.randint(0, 100)
-        self.strength_id = GLib.timeout_add_seconds(10, self.strength_cb, None)
-
-    def __del__(self):
-        if self.strength_id > 0:
-            GLib.source_remove(self.strength_id)
-        self.strength_id = 0
-
-    def strength_cb(self, ignored):
-        self.strength = random.randint(0, 100)
-        self.__notify(PN_SIGNAL_QUALITY)
-        return True
-
-    # Properties interface
-    def __get_props(self):
-        props = {}
-        props[PN_NAME] = self.name
-        props[PN_SIGNAL_QUALITY] = dbus.UInt32(self.strength)
-        props[PN_NETWORK_TYPE] = dbus.UInt32(0x1)  # NM_WIMAX_NSP_NETWORK_TYPE_HOME
-        return props
-
-    def __notify(self, propname):
-        props = self._get_dbus_properties(IFACE_WIMAX_NSP)
-        changed = { propname: props[propname] }
-        WimaxNsp.PropertiesChanged(self, changed)
-
-    @dbus.service.signal(IFACE_WIMAX_NSP, signature='a{sv}')
-    def PropertiesChanged(self, changed):
-        pass
-
-###################################################################
-IFACE_WIMAX = 'org.freedesktop.NetworkManager.Device.WiMax'
-
-class NspNotFoundException(dbus.DBusException):
-    _dbus_error_name = IFACE_WIMAX + '.NspNotFound'
-
-PX_NSPS = "Nsps"
-PX_HW_ADDRESS = "HwAddress"
-PX_CENTER_FREQUENCY = "CenterFrequency"
-PX_RSSI = "Rssi"
-PX_CINR = "Cinr"
-PX_TX_POWER = "TxPower"
-PX_BSID = "Bsid"
-PX_ACTIVE_NSP = "ActiveNsp"
-
-class WimaxDevice(Device):
-    def __init__(self, bus, iface):
-        Device.__init__(self, bus, iface, NM_DEVICE_TYPE_WIMAX)
-        self.add_dbus_interface(IFACE_WIMAX, self.__get_props)
-
-        self.mac = random_mac()
-        self.bsid = random_mac()
-        self.nsps = []
-        self.active_nsp = None
-
-    # methods
-    @dbus.service.method(dbus_interface=IFACE_WIMAX, in_signature='', out_signature='ao')
-    def GetNspList(self):
-        # include all APs including hidden ones
-        return to_path_array(self.nsps)
-
-    @dbus.service.signal(IFACE_WIMAX, signature='o')
-    def NspAdded(self, nsp_path):
-        pass
-
-    def add_nsp(self, nsp):
-        self.nsps.append(nsp)
-        self.__notify(PX_NSPS)
-        self.NspAdded(to_path(nsp))
-
-    @dbus.service.signal(IFACE_WIMAX, signature='o')
-    def NspRemoved(self, nsp_path):
-        pass
-
-    def remove_nsp(self, nsp):
-        self.nsps.remove(nsp)
-        self.__notify(PX_NSPS)
-        self.NspRemoved(to_path(nsp))
-
-    # Properties interface
-    def __get_props(self):
-        props = {}
-        props[PX_HW_ADDRESS] = self.mac
-        props[PX_CENTER_FREQUENCY] = dbus.UInt32(2525)
-        props[PX_RSSI] = dbus.Int32(-48)
-        props[PX_CINR] = dbus.Int32(24)
-        props[PX_TX_POWER] = dbus.Int32(9)
-        props[PX_BSID] = self.bsid
-        props[PX_NSPS] = to_path_array(self.nsps)
-        props[PX_ACTIVE_NSP] = to_path(self.active_nsp)
-        return props
-
-    def __notify(self, propname):
-        props = self._get_dbus_properties(IFACE_WIMAX)
-        changed = { propname: props[propname] }
-        WimaxDevice.PropertiesChanged(self, changed)
-
-    @dbus.service.signal(IFACE_WIMAX, signature='a{sv}')
-    def PropertiesChanged(self, changed):
-        pass
-
-    # test functions
-    def add_test_nsp(self, name):
-        nsp = WimaxNsp(self._bus, name)
-        self.add_nsp(nsp)
-        return nsp.path
-
-    def remove_nsp_by_path(self, path):
-        for nsp in self.nsps:
-            if nsp.path == path:
-                self.remove_nsp(nsp)
-                return
-        raise NspNotFoundException("NSP %s not found" % path)
-
-###################################################################
-IFACE_TEST = 'org.freedesktop.NetworkManager.LibnmGlibTest'
-IFACE_NM = 'org.freedesktop.NetworkManager'
-
-class PermissionDeniedException(dbus.DBusException):
-    _dbus_error_name = IFACE_NM + '.PermissionDenied'
-
-class UnknownDeviceException(dbus.DBusException):
-    _dbus_error_name = IFACE_NM + '.UnknownDevice'
-
-PM_DEVICES = 'Devices'
-PM_NETWORKING_ENABLED = 'NetworkingEnabled'
-PM_WWAN_ENABLED = 'WwanEnabled'
-PM_WWAN_HARDWARE_ENABLED = 'WwanHardwareEnabled'
-PM_WIRELESS_ENABLED = 'WirelessEnabled'
-PM_WIRELESS_HARDWARE_ENABLED = 'WirelessHardwareEnabled'
-PM_WIMAX_ENABLED = 'WimaxEnabled'
-PM_WIMAX_HARDWARE_ENABLED = 'WimaxHardwareEnabled'
-PM_ACTIVE_CONNECTIONS = 'ActiveConnections'
-PM_PRIMARY_CONNECTION = 'PrimaryConnection'
-PM_ACTIVATING_CONNECTION = 'ActivatingConnection'
-PM_STARTUP = 'Startup'
-PM_STATE = 'State'
-PM_VERSION = 'Version'
-PM_CONNECTIVITY = 'Connectivity'
-
-class NetworkManager(ExportedObj):
-    def __init__(self, bus, object_path):
-        ExportedObj.__init__(self, bus, object_path)
-        self.add_dbus_interface(IFACE_NM, self.__get_props)
-
-        self.devices = []
-        self.active_connections = []
-        self.primary_connection = None
-        self.activating_connection = None
-        self.state = NM_STATE_DISCONNECTED
-        self.connectivity = 1
-
-    @dbus.service.signal(IFACE_NM, signature='u')
-    def StateChanged(self, new_state):
-        pass
-
-    def set_state(self, new_state):
-        self.state = new_state
-        self.__notify(PM_STATE)
-        self.StateChanged(dbus.UInt32(self.state))
-
-    @dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='ao')
-    def GetDevices(self):
-        return self._get_dbus_properties(IFACE_NM)[PM_DEVICES]
-
-    @dbus.service.method(dbus_interface=IFACE_NM, in_signature='s', out_signature='o')
-    def GetDeviceByIpIface(self, ip_iface):
-        for d in self.devices:
-            # ignore iface/ip_iface distinction for now
-            if d.iface == ip_iface:
-                return d.path
-        raise UnknownDeviceException("No device found for the requested iface.")
-
-    @dbus.service.method(dbus_interface=IFACE_NM, in_signature='ooo', out_signature='o')
-    def ActivateConnection(self, conpath, devpath, specific_object):
-        device = None
-        for d in self.devices:
-            if d.path == devpath:
-                device = d
-                break
-        if not device:
-            raise UnknownDeviceException("No device found for the requested iface.")
-        raise PermissionDeniedException("Not yet implemented")
-
-    @dbus.service.method(dbus_interface=IFACE_NM, in_signature='a{sa{sv}}oo', out_signature='oo')
-    def AddAndActivateConnection(self, connection, devpath, specific_object):
-        device = None
-        for d in self.devices:
-            if d.path == devpath:
-                device = d
-                break
-        if not device:
-            raise UnknownDeviceException("No device found for the requested iface.")
-        raise PermissionDeniedException("Not yet implemented")
-
-    @dbus.service.method(dbus_interface=IFACE_NM, in_signature='o', out_signature='')
-    def DeactivateConnection(self, active_connection):
-        pass
-
-    @dbus.service.method(dbus_interface=IFACE_NM, in_signature='b', out_signature='')
-    def Sleep(self, do_sleep):
-        if do_sleep:
-            self.state = NM_STATE_ASLEEP
-        else:
-            self.state = NM_STATE_DISCONNECTED
-        self.__notify(PM_STATE)
-
-    @dbus.service.method(dbus_interface=IFACE_NM, in_signature='b', out_signature='')
-    def Enable(self, do_enable):
-        pass
-
-    @dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='a{ss}')
-    def GetPermissions(self):
-        return { "org.freedesktop.NetworkManager.enable-disable-network":   "yes",
-                 "org.freedesktop.NetworkManager.sleep-wake":               "no",
-                 "org.freedesktop.NetworkManager.enable-disable-wifi":      "yes",
-                 "org.freedesktop.NetworkManager.enable-disable-wwan":      "yes",
-                 "org.freedesktop.NetworkManager.enable-disable-wimax":     "yes",
-                 "org.freedesktop.NetworkManager.network-control":          "yes",
-                 "org.freedesktop.NetworkManager.wifi.share.protected":     "yes",
-                 "org.freedesktop.NetworkManager.wifi.share.open":          "yes",
-                 "org.freedesktop.NetworkManager.settings.modify.own":      "yes",
-                 "org.freedesktop.NetworkManager.settings.modify.system":   "yes",
-                 "org.freedesktop.NetworkManager.settings.modify.hostname": "yes" }
-
-    @dbus.service.method(dbus_interface=IFACE_NM, in_signature='ss', out_signature='')
-    def SetLogging(self, level, domains):
-        pass
-
-    @dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='ss')
-    def GetLogging(self):
-        return ("info", "HW,RFKILL,CORE,DEVICE,WIFI,ETHER")
-
-    @dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='u')
-    def CheckConnectivity(self):
-        raise PermissionDeniedException("You fail")
-
-    @dbus.service.signal(IFACE_NM, signature='o')
-    def DeviceAdded(self, devpath):
-        pass
-
-    def add_device(self, device):
-        self.devices.append(device)
-        self.__notify(PM_DEVICES)
-        self.DeviceAdded(to_path(device))
-
-    @dbus.service.signal(IFACE_NM, signature='o')
-    def DeviceRemoved(self, devpath):
-        pass
-
-    def remove_device(self, device):
-        self.devices.remove(device)
-        self.__notify(PM_DEVICES)
-        self.DeviceRemoved(to_path(device))
-
-    ################# D-Bus Properties interface
-    def __get_props(self):
-        props = {}
-        props[PM_DEVICES] = to_path_array(self.devices)
-        props[PM_NETWORKING_ENABLED] = True
-        props[PM_WWAN_ENABLED] = True
-        props[PM_WWAN_HARDWARE_ENABLED] = True
-        props[PM_WIRELESS_ENABLED] = True
-        props[PM_WIRELESS_HARDWARE_ENABLED] = True
-        props[PM_WIMAX_ENABLED] = True
-        props[PM_WIMAX_HARDWARE_ENABLED] = True
-        props[PM_ACTIVE_CONNECTIONS] = to_path_array(self.active_connections)
-        props[PM_PRIMARY_CONNECTION] = to_path(self.primary_connection)
-        props[PM_ACTIVATING_CONNECTION] = to_path(self.activating_connection)
-        props[PM_STARTUP] = False
-        props[PM_STATE] = dbus.UInt32(self.state)
-        props[PM_VERSION] = "0.9.9.0"
-        props[PM_CONNECTIVITY] = dbus.UInt32(self.connectivity)
-        return props
-
-    def __notify(self, propname):
-        props = self._get_dbus_properties(IFACE_NM)
-        changed = { propname: props[propname] }
-        NetworkManager.PropertiesChanged(self, changed)
-
-    @dbus.service.signal(IFACE_NM, signature='a{sv}')
-    def PropertiesChanged(self, changed):
-        pass
-
-    ################# Testing methods
-    @dbus.service.method(IFACE_TEST, in_signature='', out_signature='')
-    def Quit(self):
-        mainloop.quit()
-
-    @dbus.service.method(IFACE_TEST, in_signature='s', out_signature='o')
-    def AddWiredDevice(self, ifname):
-        for d in self.devices:
-            if d.iface == ifname:
-                raise PermissionDeniedError("Device already added")
-        dev = WiredDevice(self._bus, ifname)
-        self.add_device(dev)
-        return dbus.ObjectPath(dev.path)
-
-    @dbus.service.method(IFACE_TEST, in_signature='s', out_signature='o')
-    def AddWifiDevice(self, ifname):
-        for d in self.devices:
-            if d.iface == ifname:
-                raise PermissionDeniedError("Device already added")
-        dev = WifiDevice(self._bus, ifname)
-        self.add_device(dev)
-        return dbus.ObjectPath(dev.path)
-
-    @dbus.service.method(IFACE_TEST, in_signature='s', out_signature='o')
-    def AddWimaxDevice(self, ifname):
-        for d in self.devices:
-            if d.iface == ifname:
-                raise PermissionDeniedError("Device already added")
-        dev = WimaxDevice(self._bus, ifname)
-        self.add_device(dev)
-        return dbus.ObjectPath(dev.path)
-
-    @dbus.service.method(IFACE_TEST, in_signature='o', out_signature='')
-    def RemoveDevice(self, path):
-        for d in self.devices:
-            if d.path == path:
-                self.remove_device(d)
-                return
-        raise UnknownDeviceException("Device not found")
-
-    @dbus.service.method(IFACE_TEST, in_signature='sss', out_signature='o')
-    def AddWifiAp(self, ifname, ssid, mac):
-        for d in self.devices:
-            if d.iface == ifname:
-                return dbus.ObjectPath(d.add_test_ap(ssid, mac))
-        raise UnknownDeviceException("Device not found")
-
-    @dbus.service.method(IFACE_TEST, in_signature='so', out_signature='')
-    def RemoveWifiAp(self, ifname, ap_path):
-        for d in self.devices:
-            if d.iface == ifname:
-                d.remove_ap_by_path(ap_path)
-                return
-        raise UnknownDeviceException("Device not found")
-
-    @dbus.service.method(IFACE_TEST, in_signature='ss', out_signature='o')
-    def AddWimaxNsp(self, ifname, name):
-        for d in self.devices:
-            if d.iface == ifname:
-                return dbus.ObjectPath(d.add_test_nsp(name))
-        raise UnknownDeviceException("Device not found")
-
-    @dbus.service.method(IFACE_TEST, in_signature='so', out_signature='')
-    def RemoveWimaxNsp(self, ifname, nsp_path):
-        for d in self.devices:
-            if d.iface == ifname:
-                d.remove_nsp_by_path(nsp_path)
-                return
-        raise UnknownDeviceException("Device not found")
-
-def quit_cb(user_data):
-    mainloop.quit()
-
-def main():
-    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
-
-    random.seed()
-
-    bus = dbus.SessionBus()
-    nm = NetworkManager(bus, "/org/freedesktop/NetworkManager")
-    if not bus.request_name("org.freedesktop.NetworkManager"):
-        sys.exit(1)
-
-    # quit after inactivity to ensure we don't stick around if tests fail
-    quit_id = GLib.timeout_add_seconds(20, quit_cb, None)
-
-    try:
-        mainloop.run()
-    except Exception as e:
-        pass
-
-    sys.exit(0)
-
-if __name__ == '__main__':
-    main()
-
diff --git a/libnm-glib/tests/test-nm-client.c b/libnm-glib/tests/test-nm-client.c
index b181c8fa..af3722eb 100644
--- a/libnm-glib/tests/test-nm-client.c
+++ b/libnm-glib/tests/test-nm-client.c
@@ -14,10 +14,12 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * Copyright (C) 2010 - 2014 Red Hat, Inc.
+ * Copyright 2010 - 2014 Red Hat, Inc.
  *
  */
 
+#include "config.h"
+
 #include <dbus/dbus.h>
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-lowlevel.h>
@@ -33,153 +35,39 @@
 #include "nm-device-wimax.h"
 #include "nm-glib-compat.h"
 
-static const char *fake_path;
-static const char *fake_bin;
-static const char *fake_exec;
+#include "common.h"
+
 static GMainLoop *loop = NULL;
+static NMTestServiceInfo *sinfo;
 
 /*******************************************************************/
 
-typedef struct {
-	GDBusConnection *bus;
-	GDBusProxy *proxy;
-	GPid pid;
-	NMClient *client;
-} ServiceInfo;
-
-#define test_assert(condition) \
-do { \
-	if (!G_LIKELY (condition)) \
-		service_cleanup (); \
-	g_assert (condition); \
-} while (0)
-
-#define test_assert_cmpint(a, b, c) \
-do { \
-	if (!G_LIKELY (a b c)) \
-		service_cleanup (); \
-	g_assert_cmpint (a, b, c); \
-} while (0)
-
-#define test_assert_cmpstr(a, b, c) \
-do { \
-	if (!G_LIKELY (g_str_hash (a) b g_str_hash (c))) \
-		service_cleanup (); \
-	g_assert_cmpstr (a, b, c); \
-} while (0)
-
-#define test_assert_no_error(e) \
-do { \
-	if (G_UNLIKELY (e)) \
-		service_cleanup (); \
-	g_assert_no_error (e); \
-} while (0)
-
-static ServiceInfo * sinfo_static = NULL;
-
-static void
-service_cleanup (void)
-{
-	ServiceInfo *info = sinfo_static;
-
-	sinfo_static = NULL;
-
-	if (info) {
-		if (info->proxy)
-			g_object_unref (info->proxy);
-		if (info->bus)
-			g_object_unref (info->bus);
-		if (info->client)
-			g_object_unref (info->client);
-		if (info->pid)
-			kill (info->pid, SIGTERM);
-		memset (info, 0, sizeof (*info));
-		g_free (info);
-	} else
-		g_assert_not_reached ();
-}
-
-static gboolean
-name_exists (GDBusConnection *c, const char *name)
-{
-	GVariant *reply;
-	gboolean exists = FALSE;
-
-	reply = g_dbus_connection_call_sync (c,
-	                                     DBUS_SERVICE_DBUS,
-	                                     DBUS_PATH_DBUS,
-	                                     DBUS_INTERFACE_DBUS,
-	                                     "GetNameOwner",
-	                                     g_variant_new ("(s)", name),
-	                                     NULL,
-	                                     G_DBUS_CALL_FLAGS_NO_AUTO_START,
-	                                     -1,
-	                                     NULL,
-	                                     NULL);
-	if (reply != NULL) {
-		exists = TRUE;
-		g_variant_unref (reply);
-	}
-
-	return exists;
-}
-
-static ServiceInfo *
-service_init (void)
+static NMClient *
+test_client_new (void)
 {
-	ServiceInfo *sinfo;
-	const char *args[2] = { fake_exec, NULL };
+	NMClient *client;
+	DBusGConnection *bus;
 	GError *error = NULL;
-	int i = 100;
+	gboolean success;
 
-	g_assert (!sinfo_static);
+	bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+	g_assert_no_error (error);
 
-	sinfo = g_malloc0 (sizeof (*sinfo));
+	client = g_object_new (NM_TYPE_CLIENT,
+	                       NM_OBJECT_DBUS_CONNECTION, bus,
+	                       NM_OBJECT_DBUS_PATH, NM_DBUS_PATH,
+	                       NULL);
+	g_assert (client != NULL);
 
-	sinfo_static = sinfo;
+	dbus_g_connection_unref (bus);
 
-	sinfo->bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL,  NULL);
-	test_assert (sinfo->bus);
+	success = g_initable_init (G_INITABLE (client), NULL, &error);
+	g_assert_no_error (error);
+	g_assert (success == TRUE);
 
-	if (!g_spawn_async (fake_path, (char **) args, NULL, 0, NULL, NULL, &sinfo->pid, &error))
-		test_assert_no_error (error);
-
-	/* Wait until the service is registered on the bus */
-	while (i > 0) {
-		g_usleep (G_USEC_PER_SEC / 50);
-		if (name_exists (sinfo->bus, "org.freedesktop.NetworkManager"))
-			break;
-		i--;
-	}
-	test_assert (i > 0);
-
-	/* Grab a proxy to our fake NM service to trigger tests */
-	sinfo->proxy = g_dbus_proxy_new_sync (sinfo->bus,
-	                                      G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
-	                                        G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
-	                                        G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
-	                                      NULL,
-	                                      NM_DBUS_SERVICE,
-	                                      NM_DBUS_PATH,
-	                                      "org.freedesktop.NetworkManager.LibnmGlibTest",
-	                                      NULL, NULL);
-	test_assert (sinfo->proxy);
-
-	sinfo->client = nm_client_new ();
-	test_assert (sinfo->client != NULL);
-
-	return sinfo;
-}
-
-static ServiceInfo *
-service_get (void)
-{
-	g_assert (sinfo_static);
-	return sinfo_static;
+	return client;
 }
 
-#define _sinfo (service_get ())
-
 /*******************************************************************/
 
 static gboolean
@@ -195,16 +83,16 @@ add_device (const char *method, const char *ifname, char **out_path)
 	GError *error = NULL;
 	GVariant *ret;
 
-	ret = g_dbus_proxy_call_sync (_sinfo->proxy,
+	ret = g_dbus_proxy_call_sync (sinfo->proxy,
 	                              method,
 	                              g_variant_new ("(s)", ifname),
 	                              G_DBUS_CALL_FLAGS_NO_AUTO_START,
 	                              3000,
 	                              NULL,
 	                              &error);
-	test_assert_no_error (error);
-	test_assert (ret);
-	test_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)");
+	g_assert_no_error (error);
+	g_assert (ret);
+	g_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)");
 	if (out_path)
 		g_variant_get (ret, "(o)", out_path);
 	g_variant_unref (ret);
@@ -237,8 +125,8 @@ device_added_cb (NMClient *c,
                  NMDevice *device,
                  DeviceAddedInfo *info)
 {
-	test_assert (device);
-	test_assert_cmpstr (nm_device_get_iface (device), ==, "eth0");
+	g_assert (device);
+	g_assert_cmpstr (nm_device_get_iface (device), ==, "eth0");
 	info->signaled = TRUE;
 	device_add_check_quit (info);
 }
@@ -252,12 +140,12 @@ devices_notify_cb (NMClient *c,
 	NMDevice *device;
 
 	devices = nm_client_get_devices (c);
-	test_assert (devices);
-	test_assert_cmpint (devices->len, ==, 1);
+	g_assert (devices);
+	g_assert_cmpint (devices->len, ==, 1);
 
 	device = g_ptr_array_index (devices, 0);
-	test_assert (device);
-	test_assert_cmpstr (nm_device_get_iface (device), ==, "eth0");
+	g_assert (device);
+	g_assert_cmpstr (nm_device_get_iface (device), ==, "eth0");
 
 	info->notified = TRUE;
 
@@ -267,29 +155,27 @@ devices_notify_cb (NMClient *c,
 static void
 test_device_added (void)
 {
+	NMClient *client;
 	const GPtrArray *devices;
 	NMDevice *device;
 	DeviceAddedInfo info = { loop, FALSE, FALSE, 0, 0 };
 
-	service_init ();
-
-	/* Give NMClient a chance to initialize */
-	g_timeout_add_seconds (5, loop_quit, loop);
-	g_main_loop_run (loop);
+	sinfo = nm_test_service_init ();
+	client = test_client_new ();
 
-	devices = nm_client_get_devices (_sinfo->client);
-	test_assert (devices == NULL);
+	devices = nm_client_get_devices (client);
+	g_assert (devices == NULL);
 
 	/* Tell the test service to add a new device */
 	add_device ("AddWiredDevice", "eth0", NULL);
 
-	g_signal_connect (_sinfo->client,
+	g_signal_connect (client,
 	                  "device-added",
 	                  (GCallback) device_added_cb,
 	                  &info);
 	info.quit_count++;
 
-	g_signal_connect (_sinfo->client,
+	g_signal_connect (client,
 	                  "notify::devices",
 	                  (GCallback) devices_notify_cb,
 	                  &info);
@@ -299,21 +185,22 @@ test_device_added (void)
 	info.quit_id = g_timeout_add_seconds (5, loop_quit, loop);
 	g_main_loop_run (loop);
 
-	test_assert (info.signaled);
-	test_assert (info.notified);
+	g_assert (info.signaled);
+	g_assert (info.notified);
 
-	g_signal_handlers_disconnect_by_func (_sinfo->client, device_added_cb, &info);
-	g_signal_handlers_disconnect_by_func (_sinfo->client, devices_notify_cb, &info);
+	g_signal_handlers_disconnect_by_func (client, device_added_cb, &info);
+	g_signal_handlers_disconnect_by_func (client, devices_notify_cb, &info);
 
-	devices = nm_client_get_devices (_sinfo->client);
-	test_assert (devices);
-	test_assert_cmpint (devices->len, ==, 1);
+	devices = nm_client_get_devices (client);
+	g_assert (devices);
+	g_assert_cmpint (devices->len, ==, 1);
 
 	device = g_ptr_array_index (devices, 0);
-	test_assert (device);
-	test_assert_cmpstr (nm_device_get_iface (device), ==, "eth0");
+	g_assert (device);
+	g_assert_cmpstr (nm_device_get_iface (device), ==, "eth0");
 
-	service_cleanup ();
+	g_object_unref (client);
+	g_clear_pointer (&sinfo, nm_test_service_cleanup);
 }
 
 /*******************************************************************/
@@ -346,7 +233,7 @@ wifi_device_added_cb (NMClient *c,
                       NMDevice *device,
                       WifiApInfo *info)
 {
-	test_assert_cmpstr (nm_device_get_iface (device), ==, "wlan0");
+	g_assert_cmpstr (nm_device_get_iface (device), ==, "wlan0");
 	info->found = TRUE;
 	wifi_check_quit (info);
 }
@@ -355,7 +242,7 @@ static void
 got_ap_path (WifiApInfo *info, const char *path)
 {
 	if (info->ap_path)
-		test_assert_cmpstr (info->ap_path, ==, path);
+		g_assert_cmpstr (info->ap_path, ==, path);
 	else
 		info->ap_path = g_strdup (path);
 }
@@ -365,8 +252,8 @@ wifi_ap_added_cb (NMDeviceWifi *w,
                   NMAccessPoint *ap,
                   WifiApInfo *info)
 {
-	test_assert (ap);
-	test_assert_cmpstr (nm_access_point_get_bssid (ap), ==, expected_bssid);
+	g_assert (ap);
+	g_assert_cmpstr (nm_access_point_get_bssid (ap), ==, expected_bssid);
 	got_ap_path (info, nm_object_get_path (NM_OBJECT (ap)));
 
 	info->signaled = TRUE;
@@ -382,12 +269,12 @@ wifi_ap_add_notify_cb (NMDeviceWifi *w,
 	NMAccessPoint *ap;
 
 	aps = nm_device_wifi_get_access_points (w);
-	test_assert (aps);
-	test_assert_cmpint (aps->len, ==, 1);
+	g_assert (aps);
+	g_assert_cmpint (aps->len, ==, 1);
 
 	ap = g_ptr_array_index (aps, 0);
-	test_assert (ap);
-	test_assert_cmpstr (nm_access_point_get_bssid (ap), ==, "66:55:44:33:22:11");
+	g_assert (ap);
+	g_assert_cmpstr (nm_access_point_get_bssid (ap), ==, "66:55:44:33:22:11");
 	got_ap_path (info, nm_object_get_path (NM_OBJECT (ap)));
 
 	info->notified = TRUE;
@@ -399,8 +286,8 @@ wifi_ap_removed_cb (NMDeviceWifi *w,
                     NMAccessPoint *ap,
                     WifiApInfo *info)
 {
-	test_assert (ap);
-	test_assert_cmpstr (info->ap_path, ==, nm_object_get_path (NM_OBJECT (ap)));
+	g_assert (ap);
+	g_assert_cmpstr (info->ap_path, ==, nm_object_get_path (NM_OBJECT (ap)));
 
 	info->signaled = TRUE;
 	wifi_check_quit (info);
@@ -414,7 +301,7 @@ wifi_ap_remove_notify_cb (NMDeviceWifi *w,
 	const GPtrArray *aps;
 
 	aps = nm_device_wifi_get_access_points (w);
-	test_assert (aps == NULL);
+	g_assert (aps == NULL);
 
 	info->notified = TRUE;
 	wifi_check_quit (info);
@@ -423,23 +310,21 @@ wifi_ap_remove_notify_cb (NMDeviceWifi *w,
 static void
 test_wifi_ap_added_removed (void)
 {
+	NMClient *client;
 	NMDeviceWifi *wifi;
 	WifiApInfo info = { loop, FALSE, FALSE, 0, 0 };
 	GVariant *ret;
 	GError *error = NULL;
 	char *expected_path = NULL;
 
-	service_init ();
-
-	/* Give NMClient a chance to initialize */
-	g_timeout_add_seconds (5, loop_quit, loop);
-	g_main_loop_run (loop);
+	sinfo = nm_test_service_init ();
+	client = test_client_new ();
 
 	/*************************************/
 	/* Add the wifi device */
 	add_device ("AddWifiDevice", "wlan0", NULL);
 
-	g_signal_connect (_sinfo->client,
+	g_signal_connect (client,
 	                  "device-added",
 	                  (GCallback) wifi_device_added_cb,
 	                  &info);
@@ -449,11 +334,11 @@ test_wifi_ap_added_removed (void)
 	info.quit_id = g_timeout_add_seconds (5, loop_quit, loop);
 	g_main_loop_run (loop);
 
-	test_assert (info.found);
-	g_signal_handlers_disconnect_by_func (_sinfo->client, wifi_device_added_cb, &info);
+	g_assert (info.found);
+	g_signal_handlers_disconnect_by_func (client, wifi_device_added_cb, &info);
 
-	wifi = (NMDeviceWifi *) nm_client_get_device_by_iface (_sinfo->client, "wlan0");
-	test_assert (NM_IS_DEVICE_WIFI (wifi));
+	wifi = (NMDeviceWifi *) nm_client_get_device_by_iface (client, "wlan0");
+	g_assert (NM_IS_DEVICE_WIFI (wifi));
 
 	/*************************************/
 	/* Add the wifi device */
@@ -461,16 +346,16 @@ test_wifi_ap_added_removed (void)
 	info.notified = FALSE;
 	info.quit_id = 0;
 
-	ret = g_dbus_proxy_call_sync (_sinfo->proxy,
+	ret = g_dbus_proxy_call_sync (sinfo->proxy,
 	                              "AddWifiAp",
 	                              g_variant_new ("(sss)", "wlan0", "test-ap", expected_bssid),
 	                              G_DBUS_CALL_FLAGS_NO_AUTO_START,
 	                              3000,
 	                              NULL,
 	                              &error);
-	test_assert_no_error (error);
-	test_assert (ret);
-	test_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)");
+	g_assert_no_error (error);
+	g_assert (ret);
+	g_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)");
 	g_variant_get (ret, "(o)", &expected_path);
 	g_variant_unref (ret);
 
@@ -490,10 +375,10 @@ test_wifi_ap_added_removed (void)
 	info.quit_id = g_timeout_add_seconds (5, loop_quit, loop);
 	g_main_loop_run (loop);
 
-	test_assert (info.signaled);
-	test_assert (info.notified);
-	test_assert (info.ap_path);
-	test_assert_cmpstr (info.ap_path, ==, expected_path);
+	g_assert (info.signaled);
+	g_assert (info.notified);
+	g_assert (info.ap_path);
+	g_assert_cmpstr (info.ap_path, ==, expected_path);
 	g_signal_handlers_disconnect_by_func (wifi, wifi_ap_added_cb, &info);
 	g_signal_handlers_disconnect_by_func (wifi, wifi_ap_add_notify_cb, &info);
 
@@ -503,14 +388,14 @@ test_wifi_ap_added_removed (void)
 	info.notified = FALSE;
 	info.quit_id = 0;
 
-	ret = g_dbus_proxy_call_sync (_sinfo->proxy,
+	ret = g_dbus_proxy_call_sync (sinfo->proxy,
 	                              "RemoveWifiAp",
 	                              g_variant_new ("(so)", "wlan0", expected_path),
 	                              G_DBUS_CALL_FLAGS_NO_AUTO_START,
 	                              3000,
 	                              NULL,
 	                              &error);
-	test_assert_no_error (error);
+	g_assert_no_error (error);
 	g_clear_pointer (&ret, g_variant_unref);
 
 	g_signal_connect (wifi,
@@ -529,14 +414,16 @@ test_wifi_ap_added_removed (void)
 	info.quit_id = g_timeout_add_seconds (5, loop_quit, loop);
 	g_main_loop_run (loop);
 
-	test_assert (info.signaled);
-	test_assert (info.notified);
+	g_assert (info.signaled);
+	g_assert (info.notified);
 	g_signal_handlers_disconnect_by_func (wifi, wifi_ap_removed_cb, &info);
 	g_signal_handlers_disconnect_by_func (wifi, wifi_ap_remove_notify_cb, &info);
 
 	g_free (info.ap_path);
 	g_free (expected_path);
-	service_cleanup ();
+
+	g_object_unref (client);
+	g_clear_pointer (&sinfo, nm_test_service_cleanup);
 }
 
 /*******************************************************************/
@@ -569,7 +456,7 @@ wimax_device_added_cb (NMClient *c,
                        NMDevice *device,
                        WimaxNspInfo *info)
 {
-	test_assert_cmpstr (nm_device_get_iface (device), ==, "wmx0");
+	g_assert_cmpstr (nm_device_get_iface (device), ==, "wmx0");
 	info->found = TRUE;
 	wimax_check_quit (info);
 }
@@ -578,7 +465,7 @@ static void
 got_nsp_path (WimaxNspInfo *info, const char *path)
 {
 	if (info->nsp_path)
-		test_assert_cmpstr (info->nsp_path, ==, path);
+		g_assert_cmpstr (info->nsp_path, ==, path);
 	else
 		info->nsp_path = g_strdup (path);
 }
@@ -588,8 +475,8 @@ wimax_nsp_added_cb (NMDeviceWimax *w,
                     NMWimaxNsp *nsp,
                     WimaxNspInfo *info)
 {
-	test_assert (nsp);
-	test_assert_cmpstr (nm_wimax_nsp_get_name (nsp), ==, expected_nsp_name);
+	g_assert (nsp);
+	g_assert_cmpstr (nm_wimax_nsp_get_name (nsp), ==, expected_nsp_name);
 	got_nsp_path (info, nm_object_get_path (NM_OBJECT (nsp)));
 
 	info->signaled = TRUE;
@@ -605,12 +492,12 @@ wimax_nsp_add_notify_cb (NMDeviceWimax *w,
 	NMWimaxNsp *nsp;
 
 	nsps = nm_device_wimax_get_nsps (w);
-	test_assert (nsps);
-	test_assert_cmpint (nsps->len, ==, 1);
+	g_assert (nsps);
+	g_assert_cmpint (nsps->len, ==, 1);
 
 	nsp = g_ptr_array_index (nsps, 0);
-	test_assert (nsp);
-	test_assert_cmpstr (nm_wimax_nsp_get_name (nsp), ==, expected_nsp_name);
+	g_assert (nsp);
+	g_assert_cmpstr (nm_wimax_nsp_get_name (nsp), ==, expected_nsp_name);
 	got_nsp_path (info, nm_object_get_path (NM_OBJECT (nsp)));
 
 	info->notified = TRUE;
@@ -622,8 +509,8 @@ wimax_nsp_removed_cb (NMDeviceWimax *w,
                       NMWimaxNsp *nsp,
                       WimaxNspInfo *info)
 {
-	test_assert (nsp);
-	test_assert_cmpstr (info->nsp_path, ==, nm_object_get_path (NM_OBJECT (nsp)));
+	g_assert (nsp);
+	g_assert_cmpstr (info->nsp_path, ==, nm_object_get_path (NM_OBJECT (nsp)));
 
 	info->signaled = TRUE;
 	wimax_check_quit (info);
@@ -637,7 +524,7 @@ wimax_nsp_remove_notify_cb (NMDeviceWimax *w,
 	const GPtrArray *nsps;
 
 	nsps = nm_device_wimax_get_nsps (w);
-	test_assert (nsps == NULL);
+	g_assert (nsps == NULL);
 
 	info->notified = TRUE;
 	wimax_check_quit (info);
@@ -646,23 +533,21 @@ wimax_nsp_remove_notify_cb (NMDeviceWimax *w,
 static void
 test_wimax_nsp_added_removed (void)
 {
+	NMClient *client;
 	NMDeviceWimax *wimax;
 	WimaxNspInfo info = { loop, FALSE, FALSE, 0, 0 };
 	GVariant *ret;
 	GError *error = NULL;
 	char *expected_path = NULL;
 
-	service_init ();
-
-	/* Give NMClient a chance to initialize */
-	g_timeout_add_seconds (5, loop_quit, loop);
-	g_main_loop_run (loop);
+	sinfo = nm_test_service_init ();
+	client = test_client_new ();
 
 	/*************************************/
 	/* Add the wimax device */
 	add_device ("AddWimaxDevice", "wmx0", NULL);
 
-	g_signal_connect (_sinfo->client,
+	g_signal_connect (client,
 	                  "device-added",
 	                  (GCallback) wimax_device_added_cb,
 	                  &info);
@@ -672,11 +557,11 @@ test_wimax_nsp_added_removed (void)
 	info.quit_id = g_timeout_add_seconds (5, loop_quit, loop);
 	g_main_loop_run (loop);
 
-	test_assert (info.found);
-	g_signal_handlers_disconnect_by_func (_sinfo->client, wimax_device_added_cb, &info);
+	g_assert (info.found);
+	g_signal_handlers_disconnect_by_func (client, wimax_device_added_cb, &info);
 
-	wimax = (NMDeviceWimax *) nm_client_get_device_by_iface (_sinfo->client, "wmx0");
-	test_assert (NM_IS_DEVICE_WIMAX (wimax));
+	wimax = (NMDeviceWimax *) nm_client_get_device_by_iface (client, "wmx0");
+	g_assert (NM_IS_DEVICE_WIMAX (wimax));
 
 	/*************************************/
 	/* Add the wimax NSP */
@@ -684,16 +569,16 @@ test_wimax_nsp_added_removed (void)
 	info.notified = FALSE;
 	info.quit_id = 0;
 
-	ret = g_dbus_proxy_call_sync (_sinfo->proxy,
+	ret = g_dbus_proxy_call_sync (sinfo->proxy,
 	                              "AddWimaxNsp",
 	                              g_variant_new ("(ss)", "wmx0", expected_nsp_name),
 	                              G_DBUS_CALL_FLAGS_NO_AUTO_START,
 	                              3000,
 	                              NULL,
 	                              &error);
-	test_assert_no_error (error);
-	test_assert (ret);
-	test_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)");
+	g_assert_no_error (error);
+	g_assert (ret);
+	g_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)");
 	g_variant_get (ret, "(o)", &expected_path);
 	g_variant_unref (ret);
 
@@ -713,10 +598,10 @@ test_wimax_nsp_added_removed (void)
 	info.quit_id = g_timeout_add_seconds (5, loop_quit, loop);
 	g_main_loop_run (loop);
 
-	test_assert (info.signaled);
-	test_assert (info.notified);
-	test_assert (info.nsp_path);
-	test_assert_cmpstr (info.nsp_path, ==, expected_path);
+	g_assert (info.signaled);
+	g_assert (info.notified);
+	g_assert (info.nsp_path);
+	g_assert_cmpstr (info.nsp_path, ==, expected_path);
 	g_signal_handlers_disconnect_by_func (wimax, wimax_nsp_added_cb, &info);
 	g_signal_handlers_disconnect_by_func (wimax, wimax_nsp_add_notify_cb, &info);
 
@@ -726,14 +611,14 @@ test_wimax_nsp_added_removed (void)
 	info.notified = FALSE;
 	info.quit_id = 0;
 
-	ret = g_dbus_proxy_call_sync (_sinfo->proxy,
+	ret = g_dbus_proxy_call_sync (sinfo->proxy,
 	                              "RemoveWimaxNsp",
 	                              g_variant_new ("(so)", "wmx0", expected_path),
 	                              G_DBUS_CALL_FLAGS_NO_AUTO_START,
 	                              3000,
 	                              NULL,
 	                              &error);
-	test_assert_no_error (error);
+	g_assert_no_error (error);
 	g_clear_pointer (&ret, g_variant_unref);
 
 	g_signal_connect (wimax,
@@ -752,14 +637,16 @@ test_wimax_nsp_added_removed (void)
 	info.quit_id = g_timeout_add_seconds (5, loop_quit, loop);
 	g_main_loop_run (loop);
 
-	test_assert (info.signaled);
-	test_assert (info.notified);
+	g_assert (info.signaled);
+	g_assert (info.notified);
 	g_signal_handlers_disconnect_by_func (wimax, wimax_nsp_removed_cb, &info);
 	g_signal_handlers_disconnect_by_func (wimax, wimax_nsp_remove_notify_cb, &info);
 
 	g_free (info.nsp_path);
 	g_free (expected_path);
-	service_cleanup ();
+
+	g_object_unref (client);
+	g_clear_pointer (&sinfo, nm_test_service_cleanup);
 }
 
 /*******************************************************************/
@@ -796,7 +683,7 @@ da_device_removed_cb (NMClient *c,
                       NMDevice *device,
                       DaInfo *info)
 {
-	test_assert_cmpstr (nm_device_get_iface (device), ==, "eth0");
+	g_assert_cmpstr (nm_device_get_iface (device), ==, "eth0");
 	info->signaled = TRUE;
 	da_check_quit (info);
 }
@@ -812,14 +699,14 @@ da_devices_notify_cb (NMClient *c,
 	const char *iface;
 
 	devices = nm_client_get_devices (c);
-	test_assert (devices);
-	test_assert_cmpint (devices->len, ==, 2);
+	g_assert (devices);
+	g_assert_cmpint (devices->len, ==, 2);
 
 	for (i = 0; i < devices->len; i++) {
 		device = g_ptr_array_index (devices, i);
 		iface = nm_device_get_iface (device);
 
-		test_assert (!strcmp (iface, "wlan0") || !strcmp (iface, "eth1"));
+		g_assert (!strcmp (iface, "wlan0") || !strcmp (iface, "eth1"));
 	}
 
 	info->notified = TRUE;
@@ -829,6 +716,7 @@ da_devices_notify_cb (NMClient *c,
 static void
 test_devices_array (void)
 {
+	NMClient *client;
 	DaInfo info = { loop };
 	char *paths[3] = { NULL, NULL, NULL };
 	NMDevice *device;
@@ -836,11 +724,8 @@ test_devices_array (void)
 	GError *error = NULL;
 	GVariant *ret;
 
-	service_init ();
-
-	/* Give NMClient a chance to initialize */
-	g_timeout_add_seconds (5, loop_quit, loop);
-	g_main_loop_run (loop);
+	sinfo = nm_test_service_init ();
+	client = test_client_new ();
 
 	/*************************************/
 	/* Add some devices */
@@ -849,7 +734,7 @@ test_devices_array (void)
 	add_device ("AddWiredDevice", "eth1", &paths[2]);
 	info.quit_count = 3;
 
-	g_signal_connect (_sinfo->client,
+	g_signal_connect (client,
 	                  "device-added",
 	                  (GCallback) da_device_added_cb,
 	                  &info);
@@ -858,42 +743,42 @@ test_devices_array (void)
 	info.quit_id = g_timeout_add_seconds (5, loop_quit, loop);
 	g_main_loop_run (loop);
 
-	test_assert_cmpint (info.quit_count, ==, 0);
-	g_signal_handlers_disconnect_by_func (_sinfo->client, da_device_added_cb, &info);
+	g_assert_cmpint (info.quit_count, ==, 0);
+	g_signal_handlers_disconnect_by_func (client, da_device_added_cb, &info);
 
 	/* Ensure the devices now exist */
-	devices = nm_client_get_devices (_sinfo->client);
-	test_assert (devices);
-	test_assert_cmpint (devices->len, ==, 3);
+	devices = nm_client_get_devices (client);
+	g_assert (devices);
+	g_assert_cmpint (devices->len, ==, 3);
 
-	device = nm_client_get_device_by_iface (_sinfo->client, "wlan0");
-	test_assert (NM_IS_DEVICE_WIFI (device));
+	device = nm_client_get_device_by_iface (client, "wlan0");
+	g_assert (NM_IS_DEVICE_WIFI (device));
 
-	device = nm_client_get_device_by_iface (_sinfo->client, "eth0");
-	test_assert (NM_IS_DEVICE_ETHERNET (device));
+	device = nm_client_get_device_by_iface (client, "eth0");
+	g_assert (NM_IS_DEVICE_ETHERNET (device));
 
-	device = nm_client_get_device_by_iface (_sinfo->client, "eth1");
-	test_assert (NM_IS_DEVICE_ETHERNET (device));
+	device = nm_client_get_device_by_iface (client, "eth1");
+	g_assert (NM_IS_DEVICE_ETHERNET (device));
 
 	/********************************/
 	/* Now remove the device in the middle */
-	ret = g_dbus_proxy_call_sync (_sinfo->proxy,
+	ret = g_dbus_proxy_call_sync (sinfo->proxy,
 	                              "RemoveDevice",
 	                              g_variant_new ("(o)", paths[1]),
 	                              G_DBUS_CALL_FLAGS_NO_AUTO_START,
 	                              3000,
 	                              NULL,
 	                              &error);
-	test_assert_no_error (error);
-	test_assert (ret);
+	g_assert_no_error (error);
+	g_assert (ret);
 	g_variant_unref (ret);
 
-	g_signal_connect (_sinfo->client,
+	g_signal_connect (client,
 	                  "device-removed",
 	                  (GCallback) da_device_removed_cb,
 	                  &info);
 
-	g_signal_connect (_sinfo->client,
+	g_signal_connect (client,
 	                  "notify::devices",
 	                  (GCallback) da_devices_notify_cb,
 	                  &info);
@@ -903,25 +788,94 @@ test_devices_array (void)
 	info.quit_id = g_timeout_add_seconds (5, loop_quit, loop);
 	g_main_loop_run (loop);
 
-	test_assert_cmpint (info.quit_count, ==, 0);
-	g_signal_handlers_disconnect_by_func (_sinfo->client, da_device_removed_cb, &info);
-	g_signal_handlers_disconnect_by_func (_sinfo->client, da_devices_notify_cb, &info);
+	g_assert_cmpint (info.quit_count, ==, 0);
+	g_signal_handlers_disconnect_by_func (client, da_device_removed_cb, &info);
+	g_signal_handlers_disconnect_by_func (client, da_devices_notify_cb, &info);
 
 	/* Ensure only two are left */
-	devices = nm_client_get_devices (_sinfo->client);
-	test_assert (devices);
-	test_assert_cmpint (devices->len, ==, 2);
+	devices = nm_client_get_devices (client);
+	g_assert (devices);
+	g_assert_cmpint (devices->len, ==, 2);
 
-	device = nm_client_get_device_by_iface (_sinfo->client, "wlan0");
-	test_assert (NM_IS_DEVICE_WIFI (device));
+	device = nm_client_get_device_by_iface (client, "wlan0");
+	g_assert (NM_IS_DEVICE_WIFI (device));
 
-	device = nm_client_get_device_by_iface (_sinfo->client, "eth1");
-	test_assert (NM_IS_DEVICE_ETHERNET (device));
+	device = nm_client_get_device_by_iface (client, "eth1");
+	g_assert (NM_IS_DEVICE_ETHERNET (device));
 
 	g_free (paths[0]);
 	g_free (paths[1]);
 	g_free (paths[2]);
-	service_cleanup ();
+
+	g_object_unref (client);
+	g_clear_pointer (&sinfo, nm_test_service_cleanup);
+}
+
+static void
+manager_running_changed (GObject *client,
+                         GParamSpec *pspec,
+                         gpointer user_data)
+{
+	int *running_changed = user_data;
+
+	(*running_changed)++;
+	g_main_loop_quit (loop);
+}
+
+static void
+test_client_manager_running (void)
+{
+	NMClient *client1, *client2;
+	guint quit_id;
+	int running_changed = 0;
+	GError *error = NULL;
+
+	client1 = test_client_new ();
+
+	g_assert (!nm_client_get_manager_running (client1));
+	g_assert_cmpstr (nm_client_get_version (client1), ==, NULL);
+
+	g_assert (!nm_client_networking_get_enabled (client1));
+	/* This will have no effect, but it shouldn't cause any warnings either. */
+	nm_client_networking_set_enabled (client1, TRUE);
+	g_assert (!nm_client_networking_get_enabled (client1));
+
+	/* OTOH, this should result in an error */
+	nm_client_set_logging (client1, "DEFAULT", "INFO", &error);
+	g_assert_error (error, NM_CLIENT_ERROR, NM_CLIENT_ERROR_MANAGER_NOT_RUNNING);
+	g_clear_error (&error);
+
+	/* Now start the test service. */
+	sinfo = nm_test_service_init ();
+	client2 = test_client_new ();
+
+	/* client2 should know that NM is running, but the previously-created
+	 * client1 hasn't gotten the news yet.
+	 */
+	g_assert (!nm_client_get_manager_running (client1));
+	g_assert (nm_client_get_manager_running (client2));
+
+	g_signal_connect (client1, "notify::" NM_CLIENT_MANAGER_RUNNING,
+	                  G_CALLBACK (manager_running_changed), &running_changed);
+	quit_id = g_timeout_add_seconds (5, loop_quit, loop);
+	g_main_loop_run (loop);
+	g_assert_cmpint (running_changed, ==, 1);
+	g_assert (nm_client_get_manager_running (client1));
+	g_source_remove (quit_id);
+
+	/* And kill it */
+	g_clear_pointer (&sinfo, nm_test_service_cleanup);
+
+	g_assert (nm_client_get_manager_running (client1));
+
+	quit_id = g_timeout_add_seconds (5, loop_quit, loop);
+	g_main_loop_run (loop);
+	g_assert_cmpint (running_changed, ==, 2);
+	g_assert (!nm_client_get_manager_running (client1));
+	g_source_remove (quit_id);
+
+	g_object_unref (client1);
+	g_object_unref (client2);
 }
 
 /*******************************************************************/
@@ -929,24 +883,19 @@ test_devices_array (void)
 int
 main (int argc, char **argv)
 {
-	g_assert (argc == 3);
-
 #if !GLIB_CHECK_VERSION (2, 35, 0)
 	g_type_init ();
 #endif
 
 	g_test_init (&argc, &argv, NULL);
 
-	fake_path = argv[1];
-	fake_bin = argv[2];
-	fake_exec = g_strdup_printf ("%s/%s", argv[1], argv[2]);
-
 	loop = g_main_loop_new (NULL, FALSE);
 
 	g_test_add_func ("/libnm-glib/device-added", test_device_added);
 	g_test_add_func ("/libnm-glib/wifi-ap-added-removed", test_wifi_ap_added_removed);
 	g_test_add_func ("/libnm-glib/wimax-nsp-added-removed", test_wimax_nsp_added_removed);
 	g_test_add_func ("/libnm-glib/devices-array", test_devices_array);
+	g_test_add_func ("/libnm-glib/client-manager-running", test_client_manager_running);
 
 	return g_test_run ();
 }
diff --git a/libnm-glib/tests/test-remote-settings-client.c b/libnm-glib/tests/test-remote-settings-client.c
index e3ef7f22..237e287f 100644
--- a/libnm-glib/tests/test-remote-settings-client.c
+++ b/libnm-glib/tests/test-remote-settings-client.c
@@ -14,10 +14,12 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * Copyright (C) 2010 - 2011 Red Hat, Inc.
+ * Copyright 2010 - 2011 Red Hat, Inc.
  *
  */
 
+#include "config.h"
+
 #include <dbus/dbus.h>
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-lowlevel.h>
@@ -33,8 +35,9 @@
 #include <nm-utils.h>
 
 #include "nm-remote-settings.h"
+#include "common.h"
 
-static GPid spid = 0;
+static NMTestServiceInfo *sinfo;
 static NMRemoteSettings *settings = NULL;
 DBusGConnection *bus = NULL;
 NMRemoteConnection *remote = NULL;
@@ -42,23 +45,6 @@ NMRemoteConnection *remote = NULL;
 /*******************************************************************/
 
 static void
-cleanup (void)
-{
-	if (settings)
-		g_object_unref (settings);
-	kill (spid, SIGTERM);
-}
-
-#define test_assert(condition) \
-do { \
-	if (!G_LIKELY (condition)) \
-		cleanup (); \
-	g_assert (condition); \
-} while (0)
-
-/*******************************************************************/
-
-static void
 add_cb (NMRemoteSettings *s,
         NMRemoteConnection *connection,
         GError *error,
@@ -69,6 +55,7 @@ add_cb (NMRemoteSettings *s,
 
 	*((gboolean *) user_data) = TRUE;
 	remote = connection;
+	g_object_add_weak_pointer (G_OBJECT (connection), (void **) &remote);
 }
 
 #define TEST_CON_ID "blahblahblah"
@@ -103,20 +90,20 @@ test_add_connection (void)
 	                                             connection,
 	                                             add_cb,
 	                                             &done);
-	test_assert (success == TRUE);
+	g_assert (success == TRUE);
 
 	start = time (NULL);
 	do {
 		now = time (NULL);
 		g_main_context_iteration (NULL, FALSE);
 	} while ((done == FALSE) && (now - start < 5));
-	test_assert (done == TRUE);
-	test_assert (remote != NULL);
+	g_assert (done == TRUE);
+	g_assert (remote != NULL);
 
 	/* Make sure the connection is the same as what we added */
-	test_assert (nm_connection_compare (connection,
-	                                    NM_CONNECTION (remote),
-	                                    NM_SETTING_COMPARE_FLAG_EXACT) == TRUE);
+	g_assert (nm_connection_compare (connection,
+	                                 NM_CONNECTION (remote),
+	                                 NM_SETTING_COMPARE_FLAG_EXACT) == TRUE);
 }
 
 /*******************************************************************/
@@ -130,10 +117,8 @@ set_visible_cb (DBusGProxy *proxy,
 	gboolean success;
 
 	success = dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID);
-	if (!success)
-		g_warning ("Failed to change connection visibility: %s", error->message);
-	test_assert (success == TRUE);
-	test_assert (error == NULL);
+	g_assert_no_error (error);
+	g_assert (success == TRUE);
 }
 
 static void
@@ -161,7 +146,7 @@ test_make_invisible (void)
 	gboolean done = FALSE, has_settings = FALSE;
 	char *path;
 
-	test_assert (remote != NULL);
+	g_assert (remote != NULL);
 
 	/* Listen for the remove event when the connection becomes invisible */
 	g_signal_connect (remote, "removed", G_CALLBACK (invis_removed_cb), &done);
@@ -171,7 +156,7 @@ test_make_invisible (void)
 	                                   NM_DBUS_SERVICE,
 	                                   path,
 	                                   NM_DBUS_IFACE_SETTINGS_CONNECTION);
-	test_assert (proxy != NULL);
+	g_assert (proxy != NULL);
 
 	/* Bypass the NMRemoteSettings object so we can test it independently */
 	dbus_g_proxy_begin_call (proxy, "SetVisible", set_visible_cb, NULL, NULL,
@@ -183,22 +168,26 @@ test_make_invisible (void)
 		now = time (NULL);
 		g_main_context_iteration (NULL, FALSE);
 	} while ((done == FALSE) && (now - start < 5));
-	test_assert (done == TRUE);
+	g_assert (done == TRUE);
+
+	g_assert (remote);
+	g_signal_handlers_disconnect_by_func (remote, G_CALLBACK (invis_removed_cb), &done);
 
 	/* Ensure NMRemoteSettings no longer has the connection */
 	list = nm_remote_settings_list_connections (settings);
 	for (iter = list; iter; iter = g_slist_next (iter)) {
 		NMConnection *candidate = NM_CONNECTION (iter->data);
 
-		test_assert ((gpointer) remote != (gpointer) candidate);
-		test_assert (strcmp (path, nm_connection_get_path (candidate)) != 0);
+		g_assert ((gpointer) remote != (gpointer) candidate);
+		g_assert (strcmp (path, nm_connection_get_path (candidate)) != 0);
 	}
 
 	/* And ensure the invisible connection no longer has any settings */
+	g_assert (remote);
 	nm_connection_for_each_setting_value (NM_CONNECTION (remote),
 	                                      invis_has_settings_cb,
 	                                      &has_settings);
-	test_assert (has_settings == FALSE);
+	g_assert (has_settings == FALSE);
 
 	g_free (path);
 	g_object_unref (proxy);
@@ -224,7 +213,7 @@ test_make_visible (void)
 	char *path;
 	NMRemoteConnection *new = NULL;
 
-	test_assert (remote != NULL);
+	g_assert (remote != NULL);
 
 	/* Wait for the new-connection signal when the connection is visible again */
 	g_signal_connect (settings, NM_REMOTE_SETTINGS_NEW_CONNECTION,
@@ -235,7 +224,7 @@ test_make_visible (void)
 	                                   NM_DBUS_SERVICE,
 	                                   path,
 	                                   NM_DBUS_IFACE_SETTINGS_CONNECTION);
-	test_assert (proxy != NULL);
+	g_assert (proxy != NULL);
 
 	/* Bypass the NMRemoteSettings object so we can test it independently */
 	dbus_g_proxy_begin_call (proxy, "SetVisible", set_visible_cb, NULL, NULL,
@@ -250,7 +239,10 @@ test_make_visible (void)
 	} while ((new == NULL) && (now - start < 5));
 
 	/* Ensure the new connection is the same as the one we made visible again */
-	test_assert (new == remote);
+	g_assert (new);
+	g_assert (new == remote);
+
+	g_signal_handlers_disconnect_by_func (settings, G_CALLBACK (vis_new_connection_cb), &new);
 
 	/* Ensure NMRemoteSettings has the connection */
 	list = nm_remote_settings_list_connections (settings);
@@ -258,13 +250,13 @@ test_make_visible (void)
 		NMConnection *candidate = NM_CONNECTION (iter->data);
 
 		if ((gpointer) remote == (gpointer) candidate) {
-			test_assert (strcmp (path, nm_connection_get_path (candidate)) == 0);
-			test_assert (strcmp (TEST_CON_ID, nm_connection_get_id (candidate)) == 0);
+			g_assert_cmpstr (path, ==, nm_connection_get_path (candidate));
+			g_assert_cmpstr (TEST_CON_ID, ==, nm_connection_get_id (candidate));
 			found = TRUE;
 			break;
 		}
 	}
-	test_assert (found == TRUE);
+	g_assert (found == TRUE);
 
 	g_free (path);
 	g_object_unref (proxy);
@@ -281,10 +273,8 @@ deleted_cb (DBusGProxy *proxy,
 	gboolean success;
 
 	success = dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID);
-	if (!success)
-		g_warning ("Failed to delete connection: %s", error->message);
-	test_assert (success == TRUE);
-	test_assert (error == NULL);
+	g_assert_no_error (error);
+	g_assert (success == TRUE);
 }
 
 static void
@@ -305,9 +295,11 @@ test_remove_connection (void)
 
 	/* Find a connection to delete */
 	list = nm_remote_settings_list_connections (settings);
-	test_assert (g_slist_length (list) > 0);
+	g_assert_cmpint (g_slist_length (list), >, 0);
 
 	connection = NM_REMOTE_CONNECTION (list->data);
+	g_assert (connection);
+	g_assert (remote == connection);
 	path = g_strdup (nm_connection_get_path (NM_CONNECTION (connection)));
 	g_signal_connect (connection, "removed", G_CALLBACK (removed_cb), &done);
 
@@ -315,7 +307,7 @@ test_remove_connection (void)
 	                                   NM_DBUS_SERVICE,
 	                                   path,
 	                                   NM_DBUS_IFACE_SETTINGS_CONNECTION);
-	test_assert (proxy != NULL);
+	g_assert (proxy != NULL);
 
 	/* Bypass the NMRemoteSettings object so we can test it independently */
 	dbus_g_proxy_begin_call (proxy, "Delete", deleted_cb, NULL, NULL, G_TYPE_INVALID);
@@ -325,15 +317,17 @@ test_remove_connection (void)
 		now = time (NULL);
 		g_main_context_iteration (NULL, FALSE);
 	} while ((done == FALSE) && (now - start < 5));
-	test_assert (done == TRUE);
+	g_assert (done == TRUE);
+
+	g_assert (!remote);
 
 	/* Ensure NMRemoteSettings no longer has the connection */
 	list = nm_remote_settings_list_connections (settings);
 	for (iter = list; iter; iter = g_slist_next (iter)) {
 		NMConnection *candidate = NM_CONNECTION (iter->data);
 
-		test_assert ((gpointer) connection != (gpointer) candidate);
-		test_assert (strcmp (path, nm_connection_get_path (candidate)) != 0);
+		g_assert ((gpointer) connection != (gpointer) candidate);
+		g_assert_cmpstr (path, ==, nm_connection_get_path (candidate));
 	}
 
 	g_free (path);
@@ -342,15 +336,93 @@ test_remove_connection (void)
 
 /*******************************************************************/
 
+static GMainLoop *loop;
+
+static gboolean
+loop_quit (gpointer user_data)
+{
+	g_main_loop_quit (loop);
+	return G_SOURCE_REMOVE;
+}
+
+static void
+settings_service_running_changed (GObject *client,
+                                  GParamSpec *pspec,
+                                  gpointer user_data)
+{
+	int *running_changed = user_data;
+
+	(*running_changed)++;
+	g_main_loop_quit (loop);
+}
+
+static void
+test_service_running (void)
+{
+	NMRemoteSettings *settings2;
+	guint quit_id;
+	int running_changed = 0;
+	gboolean running;
+
+	loop = g_main_loop_new (NULL, FALSE);
+
+	g_object_get (G_OBJECT (settings),
+	              NM_REMOTE_SETTINGS_SERVICE_RUNNING, &running,
+	              NULL);
+	g_assert (running == TRUE);
+
+	/* Now kill the test service. */
+	nm_test_service_cleanup (sinfo);
+
+	settings2 = nm_remote_settings_new (bus);
+
+	/* settings2 should know that NM is running, but the previously-created
+	 * settings hasn't gotten the news yet.
+	 */
+	g_object_get (G_OBJECT (settings2),
+	              NM_REMOTE_SETTINGS_SERVICE_RUNNING, &running,
+	              NULL);
+	g_assert (running == FALSE);
+	g_object_get (G_OBJECT (settings),
+	              NM_REMOTE_SETTINGS_SERVICE_RUNNING, &running,
+	              NULL);
+	g_assert (running == TRUE);
+
+	g_signal_connect (settings, "notify::" NM_REMOTE_SETTINGS_SERVICE_RUNNING,
+	                  G_CALLBACK (settings_service_running_changed), &running_changed);
+	quit_id = g_timeout_add_seconds (5, loop_quit, loop);
+	g_main_loop_run (loop);
+	g_assert_cmpint (running_changed, ==, 1);
+	g_source_remove (quit_id);
+
+	g_object_get (G_OBJECT (settings2),
+	              NM_REMOTE_SETTINGS_SERVICE_RUNNING, &running,
+	              NULL);
+	g_assert (running == FALSE);
+
+	/* Now restart it */
+	sinfo =  nm_test_service_init ();
+
+	quit_id = g_timeout_add_seconds (5, loop_quit, loop);
+	g_main_loop_run (loop);
+	g_assert_cmpint (running_changed, ==, 2);
+	g_source_remove (quit_id);
+
+	g_object_get (G_OBJECT (settings2),
+	              NM_REMOTE_SETTINGS_SERVICE_RUNNING, &running,
+	              NULL);
+	g_assert (running == TRUE);
+
+	g_object_unref (settings2);
+}
+
+/*******************************************************************/
+
 int
 main (int argc, char **argv)
 {
-    char *service_argv[3] = { NULL, NULL, NULL };
 	int ret;
 	GError *error = NULL;
-	int i = 100;
-
-	g_assert (argc == 3);
 
 #if !GLIB_CHECK_VERSION (2, 35, 0)
 	g_type_init ();
@@ -359,39 +431,27 @@ main (int argc, char **argv)
 	g_test_init (&argc, &argv, NULL);
 
 	bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
-	if (!bus) {
-		g_warning ("Error connecting to D-Bus: %s", error->message);
-		g_assert (error == NULL);
-	}
-
-	service_argv[0] = g_strdup_printf ("%s/%s", argv[1], argv[2]);
-	if (!g_spawn_async (argv[1], service_argv, NULL, 0, NULL, NULL, &spid, &error)) {
-		g_warning ("Error spawning %s: %s", argv[2], error->message);
-		g_assert (error == NULL);
-	}
+	g_assert_no_error (error);
 
-	/* Wait until the service is registered on the bus */
-	while (i > 0) {
-		g_usleep (G_USEC_PER_SEC / 50);
-		if (dbus_bus_name_has_owner (dbus_g_connection_get_connection (bus),
-		                             "org.freedesktop.NetworkManager",
-		                             NULL))
-			break;
-		i--;
-	}
-	test_assert (i > 0);
+	sinfo = nm_test_service_init ();
 
 	settings = nm_remote_settings_new (bus);
-	test_assert (settings != NULL);
+	g_assert (settings != NULL);
 
+	/* FIXME: these tests assume that they get run in order, but g_test_run()
+	 * does not actually guarantee that!
+	 */
 	g_test_add_func ("/remote_settings/add_connection", test_add_connection);
 	g_test_add_func ("/remote_settings/make_invisible", test_make_invisible);
 	g_test_add_func ("/remote_settings/make_visible", test_make_visible);
 	g_test_add_func ("/remote_settings/remove_connection", test_remove_connection);
+	g_test_add_func ("/remote_settings/service_running", test_service_running);
 
 	ret = g_test_run ();
 
-	cleanup ();
+	nm_test_service_cleanup (sinfo);
+	g_object_unref (settings);
+	dbus_g_connection_unref (bus);
 
 	return ret;
 }
diff --git a/libnm-glib/tests/test-remote-settings-service.py b/libnm-glib/tests/test-remote-settings-service.py
deleted file mode 100755
index 439073ad..00000000
--- a/libnm-glib/tests/test-remote-settings-service.py
+++ /dev/null
@@ -1,150 +0,0 @@
-#!/usr/bin/env python
-# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-
-from __future__ import print_function
-
-from gi.repository import GLib, GObject
-import sys
-import dbus
-import dbus.service
-import dbus.mainloop.glib
-
-IFACE_SETTINGS = 'org.freedesktop.NetworkManager.Settings'
-IFACE_CONNECTION = 'org.freedesktop.NetworkManager.Settings.Connection'
-IFACE_DBUS = 'org.freedesktop.DBus'
-
-class UnknownInterfaceException(dbus.DBusException):
-    _dbus_error_name = IFACE_DBUS + '.UnknownInterface'
-
-class UnknownPropertyException(dbus.DBusException):
-    _dbus_error_name = IFACE_DBUS + '.UnknownProperty'
-
-class PermissionDeniedException(dbus.DBusException):
-    _dbus_error_name = IFACE_SETTINGS + '.PermissionDenied'
-
-mainloop = GObject.MainLoop()
-
-class Connection(dbus.service.Object):
-    def __init__(self, bus, object_path, settings, remove_func):
-        dbus.service.Object.__init__(self, bus, object_path)
-        self.path = object_path
-        self.settings = settings
-        self.remove_func = remove_func
-        self.visible = True
-        self.props = {}
-        self.props['Unsaved'] = False
-
-    # Properties interface
-    @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}')
-    def GetAll(self, iface):
-        if iface != IFACE_CONNECTION:
-            raise UnknownInterfaceException()
-        return self.props
-
-    @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v')
-    def Get(self, iface, name):
-        if iface != IFACE_CONNECTION:
-            raise UnknownInterfaceException()
-        if not name in self.props.keys():
-            raise UnknownPropertyException()
-        return self.props[name]
-
-    # Connection methods
-    @dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='', out_signature='a{sa{sv}}')
-    def GetSettings(self):
-        if not self.visible:
-            raise PermissionDeniedException()
-        return self.settings
-
-    @dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='b', out_signature='')
-    def SetVisible(self, vis):
-        self.visible = vis
-        self.Updated()
-
-    @dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='', out_signature='')
-    def Delete(self):
-        self.remove_func(self)
-        self.Removed()
-
-    @dbus.service.signal(IFACE_CONNECTION, signature='')
-    def Removed(self):
-        pass
-
-    @dbus.service.signal(IFACE_CONNECTION, signature='')
-    def Updated(self):
-        pass
-
-class Settings(dbus.service.Object):
-    def __init__(self, bus, object_path):
-        dbus.service.Object.__init__(self, bus, object_path)
-        self.connections = {}
-        self.bus = bus
-        self.counter = 1
-        self.props = {}
-        self.props['Hostname'] = "foobar.baz"
-        self.props['CanModify'] = True
-
-    @dbus.service.method(dbus_interface=IFACE_SETTINGS, in_signature='', out_signature='ao')
-    def ListConnections(self):
-        connections = []
-        return self.connections.keys()
-
-    @dbus.service.method(dbus_interface=IFACE_SETTINGS, in_signature='a{sa{sv}}', out_signature='o')
-    def AddConnection(self, settings):
-        path = "/org/freedesktop/NetworkManager/Settings/Connection/{0}".format(self.counter)
-        self.counter = self.counter + 1
-        self.connections[path] = Connection(self.bus, path, settings, self.delete_connection)
-        print("Added connection {0}".format(path))
-        return path
-
-    def delete_connection(self, connection):
-        del self.connections[connection.path]
-
-    @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}')
-    def GetAll(self, iface):
-        if iface != IFACE_SETTINGS:
-            raise UnknownInterfaceException()
-        return self.props
-
-    @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v')
-    def Get(self, iface, name):
-        if iface != IFACE_SETTINGS:
-            raise UnknownInterfaceException()
-        if not name in self.props.keys():
-            raise UnknownPropertyException()
-        return self.props[name]
-
-    @dbus.service.signal(IFACE_SETTINGS, signature='o')
-    def NewConnection(self, path):
-        pass
-
-    @dbus.service.method(IFACE_SETTINGS, in_signature='', out_signature='')
-    def Quit(self):
-        mainloop.quit()
-
-def quit_cb(user_data):
-    mainloop.quit()
-
-def main():
-    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
-
-    bus = dbus.SessionBus()
-    obj = Settings(bus, "/org/freedesktop/NetworkManager/Settings")
-    if not bus.request_name("org.freedesktop.NetworkManager"):
-        sys.exit(1)
-
-    print("Service started")
-
-    GLib.timeout_add_seconds(20, quit_cb, None)
-
-    try:
-        mainloop.run()
-    except Exception as e:
-        pass
-
-    print("Service stopped")
-    sys.exit(0)
-
-if __name__ == '__main__':
-    main()
-