diff options
Diffstat (limited to 'libnm-glib/tests')
| -rw-r--r-- | libnm-glib/tests/Makefile.am | 36 | ||||
| -rw-r--r-- | libnm-glib/tests/Makefile.in | 105 | ||||
| -rwxr-xr-x | libnm-glib/tests/test-fake-nm.py | 776 | ||||
| -rw-r--r-- | libnm-glib/tests/test-nm-client.c | 953 | ||||
| -rw-r--r-- | libnm-glib/tests/test-remote-settings-client.c | 24 | ||||
| -rwxr-xr-x | libnm-glib/tests/test-remote-settings-service.py | 37 |
6 files changed, 1861 insertions, 70 deletions
diff --git a/libnm-glib/tests/Makefile.am b/libnm-glib/tests/Makefile.am index 07994481..38f449ac 100644 --- a/libnm-glib/tests/Makefile.am +++ b/libnm-glib/tests/Makefile.am @@ -5,20 +5,29 @@ AM_CPPFLAGS = \ -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-util \ -I$(top_builddir)/libnm-util \ - -I$(top_srcdir)/libnm-glib + -I$(top_srcdir)/libnm-glib \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) + +noinst_PROGRAMS = test-nm-client test-remote-settings-client + +####### NMClient and non-settings tests ####### -noinst_PROGRAMS = test-remote-settings-client +test_nm_client_SOURCES = \ + test-nm-client.c + +test_nm_client_LDADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/libnm-glib/libnm-glib-test.la \ + $(GLIB_LIBS) \ + $(DBUS_LIBS) ####### remote settings client test ####### test_remote_settings_client_SOURCES = \ test-remote-settings-client.c -test_remote_settings_client_CPPFLAGS = \ - $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ - $(AM_CPPFLAGS) - test_remote_settings_client_LDADD = \ $(top_builddir)/libnm-util/libnm-util.la \ $(top_builddir)/libnm-glib/libnm-glib-test.la \ @@ -27,11 +36,18 @@ test_remote_settings_client_LDADD = \ ########################################### +TEST_NM_BIN = test-fake-nm.py TEST_RSS_BIN = test-remote-settings-service.py -EXTRA_DIST = $(TEST_RSS_BIN) +EXTRA_DIST = $(TEST_RSS_BIN) $(TEST_NM_BIN) -check-local: test-remote-settings-client - $(abs_builddir)/test-remote-settings-client $(abs_srcdir) $(TEST_RSS_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; endif diff --git a/libnm-glib/tests/Makefile.in b/libnm-glib/tests/Makefile.in index e9ea17b1..28acdea0 100644 --- a/libnm-glib/tests/Makefile.in +++ b/libnm-glib/tests/Makefile.in @@ -78,13 +78,14 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -@ENABLE_TESTS_TRUE@noinst_PROGRAMS = \ +@ENABLE_TESTS_TRUE@noinst_PROGRAMS = test-nm-client$(EXEEXT) \ @ENABLE_TESTS_TRUE@ test-remote-settings-client$(EXEEXT) subdir = libnm-glib/tests DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/build-aux/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_warnings.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -103,13 +104,12 @@ CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) -am__test_remote_settings_client_SOURCES_DIST = \ - test-remote-settings-client.c -@ENABLE_TESTS_TRUE@am_test_remote_settings_client_OBJECTS = test_remote_settings_client-test-remote-settings-client.$(OBJEXT) -test_remote_settings_client_OBJECTS = \ - $(am_test_remote_settings_client_OBJECTS) +am__test_nm_client_SOURCES_DIST = test-nm-client.c +@ENABLE_TESTS_TRUE@am_test_nm_client_OBJECTS = \ +@ENABLE_TESTS_TRUE@ test-nm-client.$(OBJEXT) +test_nm_client_OBJECTS = $(am_test_nm_client_OBJECTS) am__DEPENDENCIES_1 = -@ENABLE_TESTS_TRUE@test_remote_settings_client_DEPENDENCIES = \ +@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@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) @@ -117,6 +117,16 @@ 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 = \ + test-remote-settings-client.c +@ENABLE_TESTS_TRUE@am_test_remote_settings_client_OBJECTS = \ +@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@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -151,8 +161,10 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(test_remote_settings_client_SOURCES) -DIST_SOURCES = $(am__test_remote_settings_client_SOURCES_DIST) +SOURCES = $(test_nm_client_SOURCES) \ + $(test_remote_settings_client_SOURCES) +DIST_SOURCES = $(am__test_nm_client_SOURCES_DIST) \ + $(am__test_remote_settings_client_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -203,12 +215,15 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIRNAME = @DATADIRNAME@ DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ +DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ DBUS_LIBS = @DBUS_LIBS@ DBUS_SYS_DIR = @DBUS_SYS_DIR@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ +DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ DNSMASQ_PATH = @DNSMASQ_PATH@ DSYMUTIL = @DSYMUTIL@ @@ -233,7 +248,6 @@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GTKDOC_CHECK = @GTKDOC_CHECK@ -GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ @@ -278,12 +292,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ +LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ +LIBNDP_LIBS = @LIBNDP_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ +LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -300,6 +318,8 @@ MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ +NEWT_CFLAGS = @NEWT_CFLAGS@ +NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ @@ -327,11 +347,16 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POLKIT_CFLAGS = @POLKIT_CFLAGS@ POLKIT_LIBS = @POLKIT_LIBS@ POSUB = @POSUB@ +PPPD_PATH = @PPPD_PATH@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +PPPOE_PATH = @PPPOE_PATH@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -346,6 +371,7 @@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ +VALGRIND_RULES = @VALGRIND_RULES@ VAPIGEN = @VAPIGEN@ VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ @@ -408,6 +434,7 @@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ +subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ target_alias = @target_alias@ @@ -418,23 +445,33 @@ with_dhclient = @with_dhclient@ with_dhcpcd = @with_dhcpcd@ with_netconfig = @with_netconfig@ 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@ -I$(top_srcdir)/libnm-glib \ +@ENABLE_TESTS_TRUE@ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ +@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@ 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@ $(GLIB_LIBS) \ +@ENABLE_TESTS_TRUE@ $(DBUS_LIBS) ####### remote settings client test ####### @ENABLE_TESTS_TRUE@test_remote_settings_client_SOURCES = \ @ENABLE_TESTS_TRUE@ test-remote-settings-client.c -@ENABLE_TESTS_TRUE@test_remote_settings_client_CPPFLAGS = \ -@ENABLE_TESTS_TRUE@ $(GLIB_CFLAGS) \ -@ENABLE_TESTS_TRUE@ $(DBUS_CFLAGS) \ -@ENABLE_TESTS_TRUE@ $(AM_CPPFLAGS) - @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 \ @@ -443,8 +480,9 @@ with_resolvconf = @with_resolvconf@ ########################################### +@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) +@ENABLE_TESTS_TRUE@EXTRA_DIST = $(TEST_RSS_BIN) $(TEST_NM_BIN) all: all-am .SUFFIXES: @@ -489,6 +527,10 @@ clean-noinstPROGRAMS: echo " rm -f" $$list; \ rm -f $$list +test-nm-client$(EXEEXT): $(test_nm_client_OBJECTS) $(test_nm_client_DEPENDENCIES) $(EXTRA_test_nm_client_DEPENDENCIES) + @rm -f test-nm-client$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_nm_client_OBJECTS) $(test_nm_client_LDADD) $(LIBS) + test-remote-settings-client$(EXEEXT): $(test_remote_settings_client_OBJECTS) $(test_remote_settings_client_DEPENDENCIES) $(EXTRA_test_remote_settings_client_DEPENDENCIES) @rm -f test-remote-settings-client$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_remote_settings_client_OBJECTS) $(test_remote_settings_client_LDADD) $(LIBS) @@ -499,7 +541,8 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.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@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -522,20 +565,6 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< -test_remote_settings_client-test-remote-settings-client.o: test-remote-settings-client.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_remote_settings_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_remote_settings_client-test-remote-settings-client.o -MD -MP -MF $(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Tpo -c -o test_remote_settings_client-test-remote-settings-client.o `test -f 'test-remote-settings-client.c' || echo '$(srcdir)/'`test-remote-settings-client.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Tpo $(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-remote-settings-client.c' object='test_remote_settings_client-test-remote-settings-client.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_remote_settings_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_remote_settings_client-test-remote-settings-client.o `test -f 'test-remote-settings-client.c' || echo '$(srcdir)/'`test-remote-settings-client.c - -test_remote_settings_client-test-remote-settings-client.obj: test-remote-settings-client.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_remote_settings_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_remote_settings_client-test-remote-settings-client.obj -MD -MP -MF $(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Tpo -c -o test_remote_settings_client-test-remote-settings-client.obj `if test -f 'test-remote-settings-client.c'; then $(CYGPATH_W) 'test-remote-settings-client.c'; else $(CYGPATH_W) '$(srcdir)/test-remote-settings-client.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Tpo $(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-remote-settings-client.c' object='test_remote_settings_client-test-remote-settings-client.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_remote_settings_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_remote_settings_client-test-remote-settings-client.obj `if test -f 'test-remote-settings-client.c'; then $(CYGPATH_W) 'test-remote-settings-client.c'; else $(CYGPATH_W) '$(srcdir)/test-remote-settings-client.c'; fi` - mostlyclean-libtool: -rm -f *.lo @@ -748,8 +777,14 @@ uninstall-am: tags tags-am uninstall uninstall-am -@ENABLE_TESTS_TRUE@check-local: test-remote-settings-client -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-remote-settings-client $(abs_srcdir) $(TEST_RSS_BIN) +@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. diff --git a/libnm-glib/tests/test-fake-nm.py b/libnm-glib/tests/test-fake-nm.py new file mode 100755 index 00000000..46ca3ff0 --- /dev/null +++ b/libnm-glib/tests/test-fake-nm.py @@ -0,0 +1,776 @@ +#!/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 new file mode 100644 index 00000000..b181c8fa --- /dev/null +++ b/libnm-glib/tests/test-nm-client.c @@ -0,0 +1,953 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2010 - 2014 Red Hat, Inc. + * + */ + +#include <dbus/dbus.h> +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> +#include <glib.h> +#include <string.h> +#include <sys/types.h> +#include <signal.h> + +#include <NetworkManager.h> +#include "nm-client.h" +#include "nm-device-wifi.h" +#include "nm-device-ethernet.h" +#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; +static GMainLoop *loop = NULL; + +/*******************************************************************/ + +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) +{ + ServiceInfo *sinfo; + const char *args[2] = { fake_exec, NULL }; + GError *error = NULL; + int i = 100; + + g_assert (!sinfo_static); + + sinfo = g_malloc0 (sizeof (*sinfo)); + + sinfo_static = sinfo; + + sinfo->bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + test_assert (sinfo->bus); + + 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; +} + +#define _sinfo (service_get ()) + +/*******************************************************************/ + +static gboolean +loop_quit (gpointer user_data) +{ + g_main_loop_quit ((GMainLoop *) user_data); + return G_SOURCE_REMOVE; +} + +static gboolean +add_device (const char *method, const char *ifname, char **out_path) +{ + GError *error = NULL; + GVariant *ret; + + 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)"); + if (out_path) + g_variant_get (ret, "(o)", out_path); + g_variant_unref (ret); + return TRUE; +} + +/*******************************************************************/ + +typedef struct { + GMainLoop *loop; + gboolean signaled; + gboolean notified; + guint quit_count; + guint quit_id; +} DeviceAddedInfo; + +static void +device_add_check_quit (DeviceAddedInfo *info) +{ + info->quit_count--; + if (info->quit_count == 0) { + g_source_remove (info->quit_id); + info->quit_id = 0; + g_main_loop_quit (info->loop); + } +} + +static void +device_added_cb (NMClient *c, + NMDevice *device, + DeviceAddedInfo *info) +{ + test_assert (device); + test_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); + info->signaled = TRUE; + device_add_check_quit (info); +} + +static void +devices_notify_cb (NMClient *c, + GParamSpec *pspec, + DeviceAddedInfo *info) +{ + const GPtrArray *devices; + NMDevice *device; + + devices = nm_client_get_devices (c); + test_assert (devices); + test_assert_cmpint (devices->len, ==, 1); + + device = g_ptr_array_index (devices, 0); + test_assert (device); + test_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); + + info->notified = TRUE; + + device_add_check_quit (info); +} + +static void +test_device_added (void) +{ + 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); + + devices = nm_client_get_devices (_sinfo->client); + test_assert (devices == NULL); + + /* Tell the test service to add a new device */ + add_device ("AddWiredDevice", "eth0", NULL); + + g_signal_connect (_sinfo->client, + "device-added", + (GCallback) device_added_cb, + &info); + info.quit_count++; + + g_signal_connect (_sinfo->client, + "notify::devices", + (GCallback) devices_notify_cb, + &info); + info.quit_count++; + + /* Wait for libnm-glib to find the device */ + 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_signal_handlers_disconnect_by_func (_sinfo->client, device_added_cb, &info); + g_signal_handlers_disconnect_by_func (_sinfo->client, devices_notify_cb, &info); + + devices = nm_client_get_devices (_sinfo->client); + test_assert (devices); + test_assert_cmpint (devices->len, ==, 1); + + device = g_ptr_array_index (devices, 0); + test_assert (device); + test_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); + + service_cleanup (); +} + +/*******************************************************************/ + +static const char *expected_bssid = "66:55:44:33:22:11"; + +typedef struct { + GMainLoop *loop; + gboolean found; + char *ap_path; + gboolean signaled; + gboolean notified; + guint quit_id; + guint quit_count; +} WifiApInfo; + +static void +wifi_check_quit (WifiApInfo *info) +{ + info->quit_count--; + if (info->quit_count == 0) { + g_source_remove (info->quit_id); + info->quit_id = 0; + g_main_loop_quit (info->loop); + } +} + +static void +wifi_device_added_cb (NMClient *c, + NMDevice *device, + WifiApInfo *info) +{ + test_assert_cmpstr (nm_device_get_iface (device), ==, "wlan0"); + info->found = TRUE; + wifi_check_quit (info); +} + +static void +got_ap_path (WifiApInfo *info, const char *path) +{ + if (info->ap_path) + test_assert_cmpstr (info->ap_path, ==, path); + else + info->ap_path = g_strdup (path); +} + +static void +wifi_ap_added_cb (NMDeviceWifi *w, + NMAccessPoint *ap, + WifiApInfo *info) +{ + test_assert (ap); + test_assert_cmpstr (nm_access_point_get_bssid (ap), ==, expected_bssid); + got_ap_path (info, nm_object_get_path (NM_OBJECT (ap))); + + info->signaled = TRUE; + wifi_check_quit (info); +} + +static void +wifi_ap_add_notify_cb (NMDeviceWifi *w, + GParamSpec *pspec, + WifiApInfo *info) +{ + const GPtrArray *aps; + NMAccessPoint *ap; + + aps = nm_device_wifi_get_access_points (w); + test_assert (aps); + test_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"); + got_ap_path (info, nm_object_get_path (NM_OBJECT (ap))); + + info->notified = TRUE; + wifi_check_quit (info); +} + +static void +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))); + + info->signaled = TRUE; + wifi_check_quit (info); +} + +static void +wifi_ap_remove_notify_cb (NMDeviceWifi *w, + GParamSpec *pspec, + WifiApInfo *info) +{ + const GPtrArray *aps; + + aps = nm_device_wifi_get_access_points (w); + test_assert (aps == NULL); + + info->notified = TRUE; + wifi_check_quit (info); +} + +static void +test_wifi_ap_added_removed (void) +{ + 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); + + /*************************************/ + /* Add the wifi device */ + add_device ("AddWifiDevice", "wlan0", NULL); + + g_signal_connect (_sinfo->client, + "device-added", + (GCallback) wifi_device_added_cb, + &info); + info.quit_count = 1; + + /* Wait for libnm-glib to find the device */ + 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); + + wifi = (NMDeviceWifi *) nm_client_get_device_by_iface (_sinfo->client, "wlan0"); + test_assert (NM_IS_DEVICE_WIFI (wifi)); + + /*************************************/ + /* Add the wifi device */ + info.signaled = FALSE; + info.notified = FALSE; + info.quit_id = 0; + + 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_variant_get (ret, "(o)", &expected_path); + g_variant_unref (ret); + + g_signal_connect (wifi, + "access-point-added", + (GCallback) wifi_ap_added_cb, + &info); + info.quit_count = 1; + + g_signal_connect (wifi, + "notify::access-points", + (GCallback) wifi_ap_add_notify_cb, + &info); + info.quit_count++; + + /* Wait for libnm-glib to find the AP */ + 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_signal_handlers_disconnect_by_func (wifi, wifi_ap_added_cb, &info); + g_signal_handlers_disconnect_by_func (wifi, wifi_ap_add_notify_cb, &info); + + /*************************************/ + /* Remove the wifi device */ + info.signaled = FALSE; + info.notified = FALSE; + info.quit_id = 0; + + 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_clear_pointer (&ret, g_variant_unref); + + g_signal_connect (wifi, + "access-point-removed", + (GCallback) wifi_ap_removed_cb, + &info); + info.quit_count = 1; + + g_signal_connect (wifi, + "notify::access-points", + (GCallback) wifi_ap_remove_notify_cb, + &info); + info.quit_count++; + + /* Wait for libnm-glib to find the AP */ + 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_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 (); +} + +/*******************************************************************/ + +static const char *expected_nsp_name = "Clear"; + +typedef struct { + GMainLoop *loop; + gboolean found; + char *nsp_path; + gboolean signaled; + gboolean notified; + guint quit_id; + guint quit_count; +} WimaxNspInfo; + +static void +wimax_check_quit (WimaxNspInfo *info) +{ + info->quit_count--; + if (info->quit_count == 0) { + g_source_remove (info->quit_id); + info->quit_id = 0; + g_main_loop_quit (info->loop); + } +} + +static void +wimax_device_added_cb (NMClient *c, + NMDevice *device, + WimaxNspInfo *info) +{ + test_assert_cmpstr (nm_device_get_iface (device), ==, "wmx0"); + info->found = TRUE; + wimax_check_quit (info); +} + +static void +got_nsp_path (WimaxNspInfo *info, const char *path) +{ + if (info->nsp_path) + test_assert_cmpstr (info->nsp_path, ==, path); + else + info->nsp_path = g_strdup (path); +} + +static void +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); + got_nsp_path (info, nm_object_get_path (NM_OBJECT (nsp))); + + info->signaled = TRUE; + wimax_check_quit (info); +} + +static void +wimax_nsp_add_notify_cb (NMDeviceWimax *w, + GParamSpec *pspec, + WimaxNspInfo *info) +{ + const GPtrArray *nsps; + NMWimaxNsp *nsp; + + nsps = nm_device_wimax_get_nsps (w); + test_assert (nsps); + test_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); + got_nsp_path (info, nm_object_get_path (NM_OBJECT (nsp))); + + info->notified = TRUE; + wimax_check_quit (info); +} + +static void +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))); + + info->signaled = TRUE; + wimax_check_quit (info); +} + +static void +wimax_nsp_remove_notify_cb (NMDeviceWimax *w, + GParamSpec *pspec, + WimaxNspInfo *info) +{ + const GPtrArray *nsps; + + nsps = nm_device_wimax_get_nsps (w); + test_assert (nsps == NULL); + + info->notified = TRUE; + wimax_check_quit (info); +} + +static void +test_wimax_nsp_added_removed (void) +{ + 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); + + /*************************************/ + /* Add the wimax device */ + add_device ("AddWimaxDevice", "wmx0", NULL); + + g_signal_connect (_sinfo->client, + "device-added", + (GCallback) wimax_device_added_cb, + &info); + info.quit_count = 1; + + /* Wait for libnm-glib to find the device */ + 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); + + wimax = (NMDeviceWimax *) nm_client_get_device_by_iface (_sinfo->client, "wmx0"); + test_assert (NM_IS_DEVICE_WIMAX (wimax)); + + /*************************************/ + /* Add the wimax NSP */ + info.signaled = FALSE; + info.notified = FALSE; + info.quit_id = 0; + + 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_variant_get (ret, "(o)", &expected_path); + g_variant_unref (ret); + + g_signal_connect (wimax, + "nsp-added", + (GCallback) wimax_nsp_added_cb, + &info); + info.quit_count = 1; + + g_signal_connect (wimax, + "notify::nsps", + (GCallback) wimax_nsp_add_notify_cb, + &info); + info.quit_count++; + + /* Wait for libnm-glib to find the AP */ + 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_signal_handlers_disconnect_by_func (wimax, wimax_nsp_added_cb, &info); + g_signal_handlers_disconnect_by_func (wimax, wimax_nsp_add_notify_cb, &info); + + /*************************************/ + /* Remove the wimax NSP */ + info.signaled = FALSE; + info.notified = FALSE; + info.quit_id = 0; + + 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_clear_pointer (&ret, g_variant_unref); + + g_signal_connect (wimax, + "nsp-removed", + (GCallback) wimax_nsp_removed_cb, + &info); + info.quit_count = 1; + + g_signal_connect (wimax, + "notify::nsps", + (GCallback) wimax_nsp_remove_notify_cb, + &info); + info.quit_count++; + + /* Wait for libnm-glib to find the AP */ + 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_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 (); +} + +/*******************************************************************/ + +typedef struct { + GMainLoop *loop; + gboolean signaled; + gboolean notified; + guint quit_count; + guint quit_id; +} DaInfo; + +static void +da_check_quit (DaInfo *info) +{ + info->quit_count--; + if (info->quit_count == 0) { + g_source_remove (info->quit_id); + info->quit_id = 0; + g_main_loop_quit (info->loop); + } +} + +static void +da_device_added_cb (NMClient *c, + NMDevice *device, + DaInfo *info) +{ + da_check_quit (info); +} + +static void +da_device_removed_cb (NMClient *c, + NMDevice *device, + DaInfo *info) +{ + test_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); + info->signaled = TRUE; + da_check_quit (info); +} + +static void +da_devices_notify_cb (NMClient *c, + GParamSpec *pspec, + DaInfo *info) +{ + const GPtrArray *devices; + NMDevice *device; + guint i; + const char *iface; + + devices = nm_client_get_devices (c); + test_assert (devices); + test_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")); + } + + info->notified = TRUE; + da_check_quit (info); +} + +static void +test_devices_array (void) +{ + DaInfo info = { loop }; + char *paths[3] = { NULL, NULL, NULL }; + NMDevice *device; + const GPtrArray *devices; + 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); + + /*************************************/ + /* Add some devices */ + add_device ("AddWifiDevice", "wlan0", &paths[0]); + add_device ("AddWiredDevice", "eth0", &paths[1]); + add_device ("AddWiredDevice", "eth1", &paths[2]); + info.quit_count = 3; + + g_signal_connect (_sinfo->client, + "device-added", + (GCallback) da_device_added_cb, + &info); + + /* Wait for libnm-glib to find the device */ + 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); + + /* Ensure the devices now exist */ + devices = nm_client_get_devices (_sinfo->client); + test_assert (devices); + test_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 (_sinfo->client, "eth0"); + test_assert (NM_IS_DEVICE_ETHERNET (device)); + + device = nm_client_get_device_by_iface (_sinfo->client, "eth1"); + test_assert (NM_IS_DEVICE_ETHERNET (device)); + + /********************************/ + /* Now remove the device in the middle */ + 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_variant_unref (ret); + + g_signal_connect (_sinfo->client, + "device-removed", + (GCallback) da_device_removed_cb, + &info); + + g_signal_connect (_sinfo->client, + "notify::devices", + (GCallback) da_devices_notify_cb, + &info); + info.quit_count = 2; + + /* Wait for libnm-glib to find the device */ + 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); + + /* Ensure only two are left */ + devices = nm_client_get_devices (_sinfo->client); + test_assert (devices); + test_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 (_sinfo->client, "eth1"); + test_assert (NM_IS_DEVICE_ETHERNET (device)); + + g_free (paths[0]); + g_free (paths[1]); + g_free (paths[2]); + service_cleanup (); +} + +/*******************************************************************/ + +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); + + 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 ad62075d..e3ef7f22 100644 --- a/libnm-glib/tests/test-remote-settings-client.c +++ b/libnm-glib/tests/test-remote-settings-client.c @@ -342,17 +342,9 @@ test_remove_connection (void) /*******************************************************************/ -#if GLIB_CHECK_VERSION(2,25,12) -typedef GTestFixtureFunc TCFunc; -#else -typedef void (*TCFunc)(void); -#endif - -#define TESTCASE(t, d) g_test_create_case (#t, 0, d, NULL, (TCFunc) t, NULL) - -int main (int argc, char **argv) +int +main (int argc, char **argv) { - GTestSuite *suite; char *service_argv[3] = { NULL, NULL, NULL }; int ret; GError *error = NULL; @@ -360,7 +352,9 @@ 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); @@ -390,12 +384,10 @@ int main (int argc, char **argv) settings = nm_remote_settings_new (bus); test_assert (settings != NULL); - suite = g_test_get_root (); - - g_test_suite_add (suite, TESTCASE (test_add_connection, NULL)); - g_test_suite_add (suite, TESTCASE (test_make_invisible, NULL)); - g_test_suite_add (suite, TESTCASE (test_make_visible, NULL)); - g_test_suite_add (suite, TESTCASE (test_remove_connection, NULL)); + 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); ret = g_test_run (); diff --git a/libnm-glib/tests/test-remote-settings-service.py b/libnm-glib/tests/test-remote-settings-service.py index 86542005..439073ad 100755 --- a/libnm-glib/tests/test-remote-settings-service.py +++ b/libnm-glib/tests/test-remote-settings-service.py @@ -1,8 +1,9 @@ #!/usr/bin/env python # -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -import glib -import gobject +from __future__ import print_function + +from gi.repository import GLib, GObject import sys import dbus import dbus.service @@ -21,7 +22,7 @@ class UnknownPropertyException(dbus.DBusException): class PermissionDeniedException(dbus.DBusException): _dbus_error_name = IFACE_SETTINGS + '.PermissionDenied' -mainloop = gobject.MainLoop() +mainloop = GObject.MainLoop() class Connection(dbus.service.Object): def __init__(self, bus, object_path, settings, remove_func): @@ -30,7 +31,25 @@ class Connection(dbus.service.Object): 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: @@ -72,10 +91,10 @@ class Settings(dbus.service.Object): @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/%d" % self.counter + 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 %s" % path + print("Added connection {0}".format(path)) return path def delete_connection(self, connection): @@ -114,16 +133,16 @@ def main(): if not bus.request_name("org.freedesktop.NetworkManager"): sys.exit(1) - print "Service started" + print("Service started") - gobject.timeout_add_seconds(20, quit_cb, None) + GLib.timeout_add_seconds(20, quit_cb, None) try: mainloop.run() - except Exception, e: + except Exception as e: pass - print "Service stopped" + print("Service stopped") sys.exit(0) if __name__ == '__main__': |