diff options
author | Thomas Haller <thaller@redhat.com> | 2016-10-12 11:56:33 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2016-10-13 21:33:33 +0200 |
commit | f42466215aa6de79f14a00f256286e49e235914b (patch) | |
tree | f196ca5a3d876776d9ecc606095929f950c58dc1 /dispatcher/tests | |
parent | 8b660f245667c33e89d883ec71cc3df54b6c655f (diff) | |
download | NetworkManager-f42466215aa6de79f14a00f256286e49e235914b.tar.gz |
callouts/dispatcher: rename directory callouts
Originally, the "callouts" directory contained various programs
that NetworkManager would call, for example the dhcp helper.
For a while, it only contains nm-dispatcher. Thus rename the directory
to indicate that it's for dispatcher.
Diffstat (limited to 'dispatcher/tests')
-rw-r--r-- | dispatcher/tests/Makefile.am | 41 | ||||
-rw-r--r-- | dispatcher/tests/dispatcher-connectivity-full | 23 | ||||
-rw-r--r-- | dispatcher/tests/dispatcher-connectivity-unknown | 22 | ||||
-rw-r--r-- | dispatcher/tests/dispatcher-down | 22 | ||||
-rw-r--r-- | dispatcher/tests/dispatcher-external | 39 | ||||
-rw-r--r-- | dispatcher/tests/dispatcher-up | 65 | ||||
-rw-r--r-- | dispatcher/tests/dispatcher-vpn-down | 64 | ||||
-rw-r--r-- | dispatcher/tests/dispatcher-vpn-up | 64 | ||||
-rw-r--r-- | dispatcher/tests/test-dispatcher-envp.c | 671 |
9 files changed, 1011 insertions, 0 deletions
diff --git a/dispatcher/tests/Makefile.am b/dispatcher/tests/Makefile.am new file mode 100644 index 0000000000..e7e50adc03 --- /dev/null +++ b/dispatcher/tests/Makefile.am @@ -0,0 +1,41 @@ +if ENABLE_TESTS + +AM_CPPFLAGS = \ + -I$(top_srcdir)/shared \ + -I$(top_builddir)/shared \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ + -I$(top_srcdir)/dispatcher \ + -I$(top_builddir)/dispatcher \ + -DNETWORKMANAGER_COMPILATION \ + -DSRCDIR=\"$(abs_srcdir)\" \ + $(GLIB_CFLAGS) + +noinst_PROGRAMS = \ + test-dispatcher-envp + +############################################################################### + +test_dispatcher_envp_SOURCES = \ + test-dispatcher-envp.c + +test_dispatcher_envp_LDADD = \ + $(top_builddir)/libnm/libnm.la \ + $(top_builddir)/dispatcher/libnm-dispatcher-core.la \ + $(GLIB_LIBS) + +############################################################################### + +@VALGRIND_RULES@ +TESTS = test-dispatcher-envp + +endif + +EXTRA_DIST= \ + dispatcher-connectivity-full \ + dispatcher-connectivity-unknown \ + dispatcher-down \ + dispatcher-external \ + dispatcher-up \ + dispatcher-vpn-down \ + dispatcher-vpn-up diff --git a/dispatcher/tests/dispatcher-connectivity-full b/dispatcher/tests/dispatcher-connectivity-full new file mode 100644 index 0000000000..0b2796d12d --- /dev/null +++ b/dispatcher/tests/dispatcher-connectivity-full @@ -0,0 +1,23 @@ +[main] +action=connectiviy-change +expected-iface=wlan0 +uuid=3fd2a33a-d81b-423f-ae99-e6baba742311 +id=Random Connection +connectivity-state=FULL + +[device] +state=30 +ip-interface=wlan0 +type=2 +interface=wlan0 +path=/org/freedesktop/NetworkManager/Devices/0 + +[env] +PATH= +CONNECTION_UUID=3fd2a33a-d81b-423f-ae99-e6baba742311 +CONNECTION_DBUS_PATH=/org/freedesktop/NetworkManager/Connections/5 +CONNECTION_ID=Random Connection +CONNECTION_FILENAME=/dispatcher/tests/dispatcher-connectivity-full +DEVICE_IFACE=wlan0 +DEVICE_IP_IFACE=wlan0 +CONNECTIVITY_STATE=FULL diff --git a/dispatcher/tests/dispatcher-connectivity-unknown b/dispatcher/tests/dispatcher-connectivity-unknown new file mode 100644 index 0000000000..4d797712a4 --- /dev/null +++ b/dispatcher/tests/dispatcher-connectivity-unknown @@ -0,0 +1,22 @@ +[main] +action=connectiviy-change +expected-iface=wlan0 +uuid=3fd2a33a-d81b-423f-ae99-e6baba742311 +id=Random Connection +connectivity-state=UNKNOWN + +[device] +state=30 +ip-interface=wlan0 +type=2 +interface=wlan0 +path=/org/freedesktop/NetworkManager/Devices/0 + +[env] +PATH= +CONNECTION_UUID=3fd2a33a-d81b-423f-ae99-e6baba742311 +CONNECTION_DBUS_PATH=/org/freedesktop/NetworkManager/Connections/5 +CONNECTION_ID=Random Connection +CONNECTION_FILENAME=/dispatcher/tests/dispatcher-connectivity-unknown +DEVICE_IFACE=wlan0 +DEVICE_IP_IFACE=wlan0 diff --git a/dispatcher/tests/dispatcher-down b/dispatcher/tests/dispatcher-down new file mode 100644 index 0000000000..e0e44a7234 --- /dev/null +++ b/dispatcher/tests/dispatcher-down @@ -0,0 +1,22 @@ +[main] +action=down +expected-iface=wlan0 +uuid=3fd2a33a-d81b-423f-ae99-e6baba742311 +id=Random Connection + +[device] +state=30 +ip-interface=wlan0 +type=2 +interface=wlan0 +path=/org/freedesktop/NetworkManager/Devices/0 + +[env] +PATH= +CONNECTION_UUID=3fd2a33a-d81b-423f-ae99-e6baba742311 +CONNECTION_DBUS_PATH=/org/freedesktop/NetworkManager/Connections/5 +CONNECTION_ID=Random Connection +CONNECTION_FILENAME=/dispatcher/tests/dispatcher-down +DEVICE_IFACE=wlan0 +DEVICE_IP_IFACE=wlan0 + diff --git a/dispatcher/tests/dispatcher-external b/dispatcher/tests/dispatcher-external new file mode 100644 index 0000000000..41f01d4636 --- /dev/null +++ b/dispatcher/tests/dispatcher-external @@ -0,0 +1,39 @@ +[main] +action=up +expected-iface=virbr0 +uuid=92bbc2fb-7304-46be-8ebb-6093dbe19a6a +id=virbr0 +external=1 + +[device] +state=100 +ip-interface=virbr0 +type=13 +interface=virbr0 +path=/org/freedesktop/NetworkManager/Devices/0 + +[proxy] +pac-url=http://networkmanager.com/proxy.pac +pac-script="function FindProxyForURL (url, host) {}" + +[ip4] +addresses=192.168.122.1/24 0.0.0.0 +domains= +gateway=0.0.0.0 + +[env] +PATH= +CONNECTION_UUID=92bbc2fb-7304-46be-8ebb-6093dbe19a6a +CONNECTION_DBUS_PATH=/org/freedesktop/NetworkManager/Connections/5 +CONNECTION_FILENAME=/dispatcher/tests/dispatcher-external +CONNECTION_ID=virbr0 +CONNECTION_EXTERNAL=1 +DEVICE_IFACE=virbr0 +DEVICE_IP_IFACE=virbr0 +PROXY_PAC_URL=http://networkmanager.com/proxy.pac +PROXY_PAC_SCRIPT="function FindProxyForURL (url, host) {}" +IP4_NUM_ADDRESSES=1 +IP4_ADDRESS_0=192.168.122.1/24 0.0.0.0 +IP4_GATEWAY=0.0.0.0 +IP4_NUM_ROUTES=0 + diff --git a/dispatcher/tests/dispatcher-up b/dispatcher/tests/dispatcher-up new file mode 100644 index 0000000000..ad7e87d3b1 --- /dev/null +++ b/dispatcher/tests/dispatcher-up @@ -0,0 +1,65 @@ +[main] +action=up +expected-iface=wlan0 +uuid=3fd2a33a-d81b-423f-ae99-e6baba742311 +id=Random Connection + +[device] +state=100 +ip-interface=wlan0 +type=2 +interface=wlan0 +path=/org/freedesktop/NetworkManager/Devices/0 + +[dhcp4] +netbios_name_servers=0.0.0.0 +domain_name_servers=68.87.77.134 68.87.72.134 192.168.1.1 +dhcp_lease_time=86400 +network_number=192.168.1.0 +domain_name=hsd1.mn.comcast.net. +ip_address=192.168.1.119 +dhcp_message_type=5 +dhcp_server_identifier=192.168.1.1 +routers=192.168.1.1 +broadcast_address=192.168.1.255 +subnet_mask=255.255.255.0 +expiry=1304300446 + +[proxy] +pac-url=http://networkmanager.com/proxy.pac +pac-script="function FindProxyForURL (url, host) {}" + +[ip4] +addresses=192.168.1.119/24 192.168.1.1 +nameservers=68.87.77.134 68.87.72.134 192.168.1.1 +domains=hsd1.mn.comcast.net. + +[env] +PATH= +CONNECTION_UUID=3fd2a33a-d81b-423f-ae99-e6baba742311 +CONNECTION_DBUS_PATH=/org/freedesktop/NetworkManager/Connections/5 +CONNECTION_ID=Random Connection +CONNECTION_FILENAME=/dispatcher/tests/dispatcher-up +DEVICE_IFACE=wlan0 +DEVICE_IP_IFACE=wlan0 +PROXY_PAC_URL=http://networkmanager.com/proxy.pac +PROXY_PAC_SCRIPT="function FindProxyForURL (url, host) {}" +IP4_ADDRESS_0=192.168.1.119/24 192.168.1.1 +IP4_NUM_ADDRESSES=1 +IP4_NAMESERVERS=68.87.77.134 68.87.72.134 192.168.1.1 +IP4_GATEWAY=192.168.1.1 +IP4_DOMAINS=hsd1.mn.comcast.net. +IP4_NUM_ROUTES=0 +DHCP4_NETBIOS_NAME_SERVERS=0.0.0.0 +DHCP4_DOMAIN_NAME_SERVERS=68.87.77.134 68.87.72.134 192.168.1.1 +DHCP4_DHCP_LEASE_TIME=86400 +DHCP4_NETWORK_NUMBER=192.168.1.0 +DHCP4_DOMAIN_NAME=hsd1.mn.comcast.net. +DHCP4_IP_ADDRESS=192.168.1.119 +DHCP4_DHCP_MESSAGE_TYPE=5 +DHCP4_DHCP_SERVER_IDENTIFIER=192.168.1.1 +DHCP4_ROUTERS=192.168.1.1 +DHCP4_BROADCAST_ADDRESS=192.168.1.255 +DHCP4_SUBNET_MASK=255.255.255.0 +DHCP4_EXPIRY=1304300446 + diff --git a/dispatcher/tests/dispatcher-vpn-down b/dispatcher/tests/dispatcher-vpn-down new file mode 100644 index 0000000000..c921f105d5 --- /dev/null +++ b/dispatcher/tests/dispatcher-vpn-down @@ -0,0 +1,64 @@ +[main] +action=vpn-down +expected-iface=tun0 +uuid=355653c0-34d3-4777-ad25-f9a498b7ef8e +id=Random Connection + +[device] +state=100 +ip-interface=tun0 +type=2 +interface=wlan0 +path=/org/freedesktop/NetworkManager/Devices/0 + +[dhcp4] +netbios_name_servers=0.0.0.0 +domain_name_servers=68.87.77.134 68.87.72.134 192.168.1.1 +dhcp_lease_time=86400 +network_number=192.168.1.0 +domain_name=hsd1.mn.comcast.net. +ip_address=192.168.1.119 +dhcp_message_type=5 +dhcp_server_identifier=192.168.1.1 +routers=192.168.1.1 +broadcast_address=192.168.1.255 +subnet_mask=255.255.255.0 +expiry=1304349405 + +[proxy] +pac-url=http://networkmanager.com/proxy.pac +pac-script="function FindProxyForURL (url, host) {}" + +[ip4] +addresses=192.168.1.119/24 192.168.1.1 +nameservers=68.87.77.134 68.87.72.134 192.168.1.1 +domains=hsd1.mn.comcast.net. + +[env] +PATH= +CONNECTION_UUID=355653c0-34d3-4777-ad25-f9a498b7ef8e +CONNECTION_DBUS_PATH=/org/freedesktop/NetworkManager/Connections/5 +CONNECTION_ID=Random Connection +CONNECTION_FILENAME=/dispatcher/tests/dispatcher-vpn-down +DEVICE_IFACE=wlan0 +DEVICE_IP_IFACE=tun0 +PROXY_PAC_URL=http://networkmanager.com/proxy.pac +PROXY_PAC_SCRIPT="function FindProxyForURL (url, host) {}" +IP4_ADDRESS_0=192.168.1.119/24 192.168.1.1 +IP4_NUM_ADDRESSES=1 +IP4_NAMESERVERS=68.87.77.134 68.87.72.134 192.168.1.1 +IP4_GATEWAY=192.168.1.1 +IP4_DOMAINS=hsd1.mn.comcast.net. +IP4_NUM_ROUTES=0 +DHCP4_NETBIOS_NAME_SERVERS=0.0.0.0 +DHCP4_DOMAIN_NAME_SERVERS=68.87.77.134 68.87.72.134 192.168.1.1 +DHCP4_DHCP_LEASE_TIME=86400 +DHCP4_NETWORK_NUMBER=192.168.1.0 +DHCP4_DOMAIN_NAME=hsd1.mn.comcast.net. +DHCP4_IP_ADDRESS=192.168.1.119 +DHCP4_DHCP_MESSAGE_TYPE=5 +DHCP4_DHCP_SERVER_IDENTIFIER=192.168.1.1 +DHCP4_ROUTERS=192.168.1.1 +DHCP4_BROADCAST_ADDRESS=192.168.1.255 +DHCP4_SUBNET_MASK=255.255.255.0 +DHCP4_EXPIRY=1304349405 diff --git a/dispatcher/tests/dispatcher-vpn-up b/dispatcher/tests/dispatcher-vpn-up new file mode 100644 index 0000000000..cbafc03131 --- /dev/null +++ b/dispatcher/tests/dispatcher-vpn-up @@ -0,0 +1,64 @@ +[main] +action=vpn-up +expected-iface=tun0 +uuid=355653c0-34d3-4777-ad25-f9a498b7ef8e +id=Random Connection + +[device] +state=100 +ip-interface=tun0 +type=2 +interface=wlan0 +path=/org/freedesktop/NetworkManager/Devices/0 + +[dhcp4] +netbios_name_servers=0.0.0.0 +domain_name_servers=68.87.77.134 68.87.72.134 192.168.1.1 +dhcp_lease_time=86400 +network_number=192.168.1.0 +domain_name=hsd1.mn.comcast.net. +ip_address=192.168.1.119 +dhcp_message_type=5 +dhcp_server_identifier=192.168.1.1 +routers=192.168.1.1 +broadcast_address=192.168.1.255 +subnet_mask=255.255.255.0 +expiry=1304349405 + +[proxy] +pac-url=http://networkmanager.com/proxy.pac +pac-script="function FindProxyForURL (url, host) {}" + +[ip4] +addresses=192.168.1.119/24 192.168.1.1 +nameservers=68.87.77.134 68.87.72.134 192.168.1.1 +domains=hsd1.mn.comcast.net. + +[env] +PATH= +CONNECTION_UUID=355653c0-34d3-4777-ad25-f9a498b7ef8e +CONNECTION_DBUS_PATH=/org/freedesktop/NetworkManager/Connections/5 +CONNECTION_ID=Random Connection +CONNECTION_FILENAME=/dispatcher/tests/dispatcher-vpn-up +DEVICE_IFACE=wlan0 +DEVICE_IP_IFACE=tun0 +PROXY_PAC_URL=http://networkmanager.com/proxy.pac +PROXY_PAC_SCRIPT="function FindProxyForURL (url, host) {}" +IP4_ADDRESS_0=192.168.1.119/24 192.168.1.1 +IP4_NUM_ADDRESSES=1 +IP4_NAMESERVERS=68.87.77.134 68.87.72.134 192.168.1.1 +IP4_GATEWAY=192.168.1.1 +IP4_DOMAINS=hsd1.mn.comcast.net. +IP4_NUM_ROUTES=0 +DHCP4_NETBIOS_NAME_SERVERS=0.0.0.0 +DHCP4_DOMAIN_NAME_SERVERS=68.87.77.134 68.87.72.134 192.168.1.1 +DHCP4_DHCP_LEASE_TIME=86400 +DHCP4_NETWORK_NUMBER=192.168.1.0 +DHCP4_DOMAIN_NAME=hsd1.mn.comcast.net. +DHCP4_IP_ADDRESS=192.168.1.119 +DHCP4_DHCP_MESSAGE_TYPE=5 +DHCP4_DHCP_SERVER_IDENTIFIER=192.168.1.1 +DHCP4_ROUTERS=192.168.1.1 +DHCP4_BROADCAST_ADDRESS=192.168.1.255 +DHCP4_SUBNET_MASK=255.255.255.0 +DHCP4_EXPIRY=1304349405 diff --git a/dispatcher/tests/test-dispatcher-envp.c b/dispatcher/tests/test-dispatcher-envp.c new file mode 100644 index 0000000000..6dd4db07b2 --- /dev/null +++ b/dispatcher/tests/test-dispatcher-envp.c @@ -0,0 +1,671 @@ +/* -*- 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) 2011 Red Hat, Inc. + * + */ + +#include "nm-default.h" + +#include <arpa/inet.h> +#include <stdlib.h> +#include <string.h> + +#include "nm-core-internal.h" +#include "nm-dispatcher-utils.h" +#include "nm-dispatcher-api.h" + +#include "nm-utils/nm-test-utils.h" + +/*****************************************************************************/ + +static gboolean +parse_main (GKeyFile *kf, + const char *filename, + GVariant **out_con_dict, + GVariant **out_con_props, + char **out_expected_iface, + char **out_action, + char **out_connectivity_state, + char **out_vpn_ip_iface, + GError **error) +{ + char *uuid, *id; + NMConnection *connection; + NMSettingConnection *s_con; + GVariantBuilder props; + + *out_expected_iface = g_key_file_get_string (kf, "main", "expected-iface", error); + if (*out_expected_iface == NULL) + return FALSE; + + *out_connectivity_state = g_key_file_get_string (kf, "main", "connectivity-state", NULL); + *out_vpn_ip_iface = g_key_file_get_string (kf, "main", "vpn-ip-iface", NULL); + + *out_action = g_key_file_get_string (kf, "main", "action", error); + if (*out_action == NULL) + return FALSE; + + uuid = g_key_file_get_string (kf, "main", "uuid", error); + if (uuid == NULL) + return FALSE; + id = g_key_file_get_string (kf, "main", "id", error); + if (id == NULL) + return FALSE; + + connection = nm_simple_connection_new (); + g_assert (connection); + s_con = (NMSettingConnection *) nm_setting_connection_new (); + g_assert (s_con); + g_object_set (s_con, + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_ID, id, + NULL); + g_free (uuid); + g_free (id); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + *out_con_dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + g_object_unref (connection); + + g_variant_builder_init (&props, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&props, "{sv}", + NMD_CONNECTION_PROPS_PATH, + g_variant_new_object_path ("/org/freedesktop/NetworkManager/Connections/5")); + + /* Strip out the non-fixed portion of the filename */ + filename = strstr (filename, "/dispatcher"); + g_variant_builder_add (&props, "{sv}", + "filename", + g_variant_new_string (filename)); + + if (g_key_file_get_boolean (kf, "main", "external", NULL)) { + g_variant_builder_add (&props, "{sv}", + "external", + g_variant_new_boolean (TRUE)); + } + + *out_con_props = g_variant_builder_end (&props); + + return TRUE; +} + +static gboolean +parse_device (GKeyFile *kf, GVariant **out_device_props, GError **error) +{ + GVariantBuilder props; + char *tmp; + gint i; + + g_variant_builder_init (&props, G_VARIANT_TYPE ("a{sv}")); + + i = g_key_file_get_integer (kf, "device", "state", error); + if (i == 0) + return FALSE; + g_variant_builder_add (&props, "{sv}", + NMD_DEVICE_PROPS_STATE, + g_variant_new_uint32 (i)); + + i = g_key_file_get_integer (kf, "device", "type", error); + if (i == 0) + return FALSE; + g_variant_builder_add (&props, "{sv}", + NMD_DEVICE_PROPS_TYPE, + g_variant_new_uint32 (i)); + + tmp = g_key_file_get_string (kf, "device", "interface", error); + if (tmp == NULL) + return FALSE; + g_variant_builder_add (&props, "{sv}", + NMD_DEVICE_PROPS_INTERFACE, + g_variant_new_string (tmp)); + g_free (tmp); + + tmp = g_key_file_get_string (kf, "device", "ip-interface", error); + if (tmp == NULL) + return FALSE; + g_variant_builder_add (&props, "{sv}", + NMD_DEVICE_PROPS_IP_INTERFACE, + g_variant_new_string (tmp)); + g_free (tmp); + + tmp = g_key_file_get_string (kf, "device", "path", error); + if (tmp == NULL) + return FALSE; + g_variant_builder_add (&props, "{sv}", + NMD_DEVICE_PROPS_PATH, + g_variant_new_object_path (tmp)); + g_free (tmp); + + *out_device_props = g_variant_builder_end (&props); + return TRUE; +} + +static gboolean +add_uint_array (GKeyFile *kf, + GVariantBuilder *props, + const char *section, + const char *key, + GError **error) +{ + char *tmp; + char **split, **iter; + GArray *items; + + tmp = g_key_file_get_string (kf, section, key, error); + if (tmp == NULL) { + g_clear_error (error); + return TRUE; + } + split = g_strsplit_set (tmp, " ", -1); + g_free (tmp); + + if (g_strv_length (split) > 0) { + items = g_array_sized_new (FALSE, TRUE, sizeof (guint32), g_strv_length (split)); + for (iter = split; iter && *iter; iter++) { + if (strlen (g_strstrip (*iter))) { + guint32 addr; + + g_assert_cmpint (inet_pton (AF_INET, *iter, &addr), ==, 1); + g_array_append_val (items, addr); + } + } + g_variant_builder_add (props, "{sv}", key, + g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + items->data, items->len, + sizeof (guint32))); + g_array_unref (items); + } + g_strfreev (split); + return TRUE; +} + +static gboolean +parse_proxy (GKeyFile *kf, GVariant **out_props, const char *section, GError **error) +{ + GVariantBuilder props; + char *tmp; + + g_variant_builder_init (&props, G_VARIANT_TYPE ("a{sv}")); + + tmp = g_key_file_get_string (kf, section, "pac-url", error); + if (tmp == NULL) + return FALSE; + g_variant_builder_add (&props, "{sv}", + "pac-url", + g_variant_new_string (tmp)); + g_free (tmp); + + tmp = g_key_file_get_string (kf, section, "pac-script", error); + if (tmp == NULL) + return FALSE; + g_variant_builder_add (&props, "{sv}", + "pac-script", + g_variant_new_string (tmp)); + g_free (tmp); + *out_props = g_variant_builder_end (&props); + return TRUE; +} + +static gboolean +parse_ip4 (GKeyFile *kf, GVariant **out_props, const char *section, GError **error) +{ + GVariantBuilder props; + char *tmp; + char **split, **iter; + GPtrArray *addresses, *routes; + const char *gateway = NULL; + + g_variant_builder_init (&props, G_VARIANT_TYPE ("a{sv}")); + + /* search domains */ + /* Use char** for domains. (DBUS_TYPE_G_ARRAY_OF_STRING of NMIP4Config + * becomes G_TYPE_STRV when sending the value over D-Bus) + */ + tmp = g_key_file_get_string (kf, section, "domains", error); + if (tmp == NULL) + return FALSE; + split = g_strsplit_set (tmp, " ", -1); + g_free (tmp); + + if (split && g_strv_length (split) > 0) { + for (iter = split; iter && *iter; iter++) + g_strstrip (*iter); + g_variant_builder_add (&props, "{sv}", "domains", g_variant_new_strv ((gpointer) split, -1)); + } + g_strfreev (split); + + /* nameservers */ + if (!add_uint_array (kf, &props, "ip4", "nameservers", error)) + return FALSE; + /* wins-servers */ + if (!add_uint_array (kf, &props, "ip4", "wins-servers", error)) + return FALSE; + + /* Addresses */ + tmp = g_key_file_get_string (kf, section, "addresses", error); + if (tmp == NULL) + return FALSE; + split = g_strsplit_set (tmp, ",", -1); + g_free (tmp); + + if (split && g_strv_length (split) > 0) { + addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref); + for (iter = split; iter && *iter; iter++) { + NMIPAddress *addr; + char *ip, *prefix; + + if (strlen (g_strstrip (*iter)) == 0) + continue; + + ip = *iter; + + prefix = strchr (ip, '/'); + g_assert (prefix); + *prefix++ = '\0'; + + if (addresses->len == 0) { + gateway = strchr (prefix, ' '); + g_assert (gateway); + gateway++; + } + + addr = nm_ip_address_new (AF_INET, ip, (guint) atoi (prefix), error); + if (!addr) { + g_ptr_array_unref (addresses); + return FALSE; + } + g_ptr_array_add (addresses, addr); + } + + g_variant_builder_add (&props, "{sv}", "addresses", + nm_utils_ip4_addresses_to_variant (addresses, gateway)); + g_ptr_array_unref (addresses); + } + g_strfreev (split); + + /* Routes */ + tmp = g_key_file_get_string (kf, section, "routes", error); + g_clear_error (error); + if (tmp) { + split = g_strsplit_set (tmp, ",", -1); + g_free (tmp); + + if (split && g_strv_length (split) > 0) { + routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_route_unref); + for (iter = split; iter && *iter; iter++) { + NMIPRoute *route; + char *dest, *prefix, *next_hop, *metric; + + if (strlen (g_strstrip (*iter)) == 0) + continue; + + dest = *iter; + + prefix = strchr (dest, '/'); + g_assert (prefix); + *prefix++ = '\0'; + + next_hop = strchr (prefix, ' '); + g_assert (next_hop); + next_hop++; + + metric = strchr (next_hop, ' '); + g_assert (metric); + metric++; + + route = nm_ip_route_new (AF_INET, + dest, (guint) atoi (prefix), + next_hop, (guint) atoi (metric), + error); + if (!route) { + g_ptr_array_unref (routes); + return FALSE; + } + g_ptr_array_add (routes, route); + } + + g_variant_builder_add (&props, "{sv}", "routes", + nm_utils_ip4_routes_to_variant (routes)); + g_ptr_array_unref (routes); + } + g_strfreev (split); + } + + *out_props = g_variant_builder_end (&props); + return TRUE; +} + +static gboolean +parse_dhcp (GKeyFile *kf, + const char *group_name, + GVariant **out_props, + GError **error) +{ + char **keys, **iter, *val; + GVariantBuilder props; + + keys = g_key_file_get_keys (kf, group_name, NULL, error); + if (!keys) + return FALSE; + + g_variant_builder_init (&props, G_VARIANT_TYPE ("a{sv}")); + for (iter = keys; iter && *iter; iter++) { + val = g_key_file_get_string (kf, group_name, *iter, error); + if (!val) { + g_strfreev (keys); + g_variant_builder_clear (&props); + return FALSE; + } + g_variant_builder_add (&props, "{sv}", *iter, g_variant_new_string (val)); + g_free (val); + } + g_strfreev (keys); + + *out_props = g_variant_builder_end (&props); + return TRUE; +} + +static gboolean +get_dispatcher_file (const char *file, + GVariant **out_con_dict, + GVariant **out_con_props, + GVariant **out_device_props, + GVariant **out_device_proxy_props, + GVariant **out_device_ip4_props, + GVariant **out_device_ip6_props, + GVariant **out_device_dhcp4_props, + GVariant **out_device_dhcp6_props, + char **out_connectivity_state, + char **out_vpn_ip_iface, + GVariant **out_vpn_proxy_props, + GVariant **out_vpn_ip4_props, + GVariant **out_vpn_ip6_props, + char **out_expected_iface, + char **out_action, + GHashTable **out_env, + GError **error) +{ + GKeyFile *kf; + gboolean success = FALSE; + char **keys, **iter, *val; + + g_assert (!error || !*error); + g_assert (out_con_dict && !*out_con_dict); + g_assert (out_con_props && !*out_con_props); + g_assert (out_device_props && !*out_device_props); + g_assert (out_device_proxy_props && !*out_device_proxy_props); + g_assert (out_device_ip4_props && !*out_device_ip4_props); + g_assert (out_device_ip6_props && !*out_device_ip6_props); + g_assert (out_device_dhcp4_props && !*out_device_dhcp4_props); + g_assert (out_device_dhcp6_props && !*out_device_dhcp6_props); + g_assert (out_connectivity_state && !*out_connectivity_state); + g_assert (out_vpn_ip_iface && !*out_vpn_ip_iface); + g_assert (out_vpn_proxy_props && !*out_vpn_proxy_props); + g_assert (out_vpn_ip4_props && !*out_vpn_ip4_props); + g_assert (out_vpn_ip6_props && !*out_vpn_ip6_props); + g_assert (out_expected_iface && !*out_expected_iface); + g_assert (out_action && !*out_action); + g_assert (out_env && !*out_env); + + kf = g_key_file_new (); + if (!g_key_file_load_from_file (kf, file, G_KEY_FILE_NONE, error)) + return FALSE; + + if (!parse_main (kf, + file, + out_con_dict, + out_con_props, + out_expected_iface, + out_action, + out_connectivity_state, + out_vpn_ip_iface, + error)) + goto out; + + if (!parse_device (kf, out_device_props, error)) + goto out; + + if (g_key_file_has_group (kf, "proxy")) { + if (!parse_proxy (kf, out_device_proxy_props, "proxy", error)) + goto out; + } + + if (g_key_file_has_group (kf, "ip4")) { + if (!parse_ip4 (kf, out_device_ip4_props, "ip4", error)) + goto out; + } + + if (g_key_file_has_group (kf, "dhcp4")) { + if (!parse_dhcp (kf, "dhcp4", out_device_dhcp4_props, error)) + goto out; + } + + if (g_key_file_has_group (kf, "dhcp6")) { + if (!parse_dhcp (kf, "dhcp6", out_device_dhcp6_props, error)) + goto out; + } + + g_assert (g_key_file_has_group (kf, "env")); + keys = g_key_file_get_keys (kf, "env", NULL, error); + *out_env = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + for (iter = keys; iter && *iter; iter++) { + val = g_key_file_get_string (kf, "env", *iter, error); + if (!val) + goto out; + g_hash_table_insert (*out_env, + g_strdup_printf ("%s=%s", *iter, val), + GUINT_TO_POINTER (1)); + g_free (val); + } + g_strfreev (keys); + + success = TRUE; + +out: + g_key_file_free (kf); + return success; +} + +/*****************************************************************************/ + +static void +test_generic (const char *file, const char *override_vpn_ip_iface) +{ + gs_unref_variant GVariant *con_dict = NULL; + gs_unref_variant GVariant *con_props = NULL; + gs_unref_variant GVariant *device_props = NULL; + gs_unref_variant GVariant *device_proxy_props = NULL; + gs_unref_variant GVariant *device_ip4_props = NULL; + gs_unref_variant GVariant *device_ip6_props = NULL; + gs_unref_variant GVariant *device_dhcp4_props = NULL; + gs_unref_variant GVariant *device_dhcp6_props = NULL; + gs_free char *connectivity_change = NULL; + gs_free char *vpn_ip_iface = NULL; + gs_unref_variant GVariant *vpn_proxy_props = NULL; + gs_unref_variant GVariant *vpn_ip4_props = NULL; + gs_unref_variant GVariant *vpn_ip6_props = NULL; + gs_free char *expected_iface = NULL; + gs_free char *action = NULL; + gs_free char *out_iface = NULL; + const char *error_message = NULL; + gs_unref_hashtable GHashTable *expected_env = NULL; + GError *error = NULL; + gboolean success; + char *p; + gs_strfreev char **denv = NULL; + char **iter; + + /* Read in the test file */ + p = g_build_filename (SRCDIR, file, NULL); + success = get_dispatcher_file (p, + &con_dict, + &con_props, + &device_props, + &device_proxy_props, + &device_ip4_props, + &device_ip6_props, + &device_dhcp4_props, + &device_dhcp6_props, + &connectivity_change, + &vpn_ip_iface, + &vpn_proxy_props, + &vpn_ip4_props, + &vpn_ip6_props, + &expected_iface, + &action, + &expected_env, + &error); + g_free (p); + g_assert_no_error (error); + g_assert (success); + + /* Get the environment from the dispatcher code */ + denv = nm_dispatcher_utils_construct_envp (action, + con_dict, + con_props, + device_props, + device_proxy_props, + device_ip4_props, + device_ip6_props, + device_dhcp4_props, + device_dhcp6_props, + connectivity_change, + override_vpn_ip_iface ? override_vpn_ip_iface : vpn_ip_iface, + vpn_proxy_props, + vpn_ip4_props, + vpn_ip6_props, + &out_iface, + &error_message); + + g_assert ((!denv && error_message) || (denv && !error_message)); + + if (error_message) + g_warning ("%s", error_message); + + /* Print out environment for now */ +#ifdef DEBUG + g_message ("\n******* Generated environment:"); + for (iter = denv; iter && *iter; iter++) + g_message (" %s", *iter); +#endif + +#ifdef DEBUG + { + GHashTableIter k; + const char *key; + + g_message ("\n******* Expected environment:"); + g_hash_table_iter_init (&k, expected_env); + while (g_hash_table_iter_next (&k, (gpointer) &key, NULL)) + g_message (" %s", key); + } +#endif + + g_assert_cmpint (g_strv_length (denv), ==, g_hash_table_size (expected_env)); + + /* Compare dispatcher generated env and expected env */ + for (iter = denv; iter && *iter; iter++) { + gpointer foo; + const char *i_value = *iter; + + if (strstr (i_value, "PATH=") == i_value) { + g_assert_cmpstr (&i_value[strlen("PATH=")], ==, g_getenv ("PATH")); + + /* The path is constructed dynamically. Ignore the actual value. */ + i_value = "PATH="; + } + + foo = g_hash_table_lookup (expected_env, i_value); + if (!foo) + g_warning ("Failed to find %s in environment", i_value); + g_assert (foo); + } + + g_assert_cmpstr (expected_iface, ==, out_iface); +} + +/*****************************************************************************/ + +static void +test_up (void) +{ + test_generic ("dispatcher-up", NULL); +} + +static void +test_down (void) +{ + test_generic ("dispatcher-down", NULL); +} + +static void +test_vpn_up (void) +{ + test_generic ("dispatcher-vpn-up", NULL); +} + +static void +test_vpn_down (void) +{ + test_generic ("dispatcher-vpn-down", NULL); +} + +static void +test_external (void) +{ + test_generic ("dispatcher-external", NULL); +} + +static void +test_connectivity_changed (void) +{ + /* These tests will check that the CONNECTIVITY_STATE environment + * variable is only defined for known states, such as 'full'. */ + test_generic ("dispatcher-connectivity-unknown", NULL); + test_generic ("dispatcher-connectivity-full", NULL); +} + +static void +test_up_empty_vpn_iface (void) +{ + /* Test that an empty VPN iface variable, like is passed through D-Bus + * from NM, is ignored by the dispatcher environment construction code. + */ + test_generic ("dispatcher-up", ""); +} + +/*****************************************************************************/ + +NMTST_DEFINE (); + +int +main (int argc, char **argv) +{ + nmtst_init (&argc, &argv, TRUE); + + g_test_add_func ("/dispatcher/up", test_up); + g_test_add_func ("/dispatcher/down", test_down); + g_test_add_func ("/dispatcher/vpn_up", test_vpn_up); + g_test_add_func ("/dispatcher/vpn_down", test_vpn_down); + g_test_add_func ("/dispatcher/external", test_external); + g_test_add_func ("/dispatcher/connectivity_changed", test_connectivity_changed); + + g_test_add_func ("/dispatcher/up_empty_vpn_iface", test_up_empty_vpn_iface); + + return g_test_run (); +} + |