diff options
Diffstat (limited to 'libnm-glib/tests/test-remote-settings-client.c')
-rw-r--r-- | libnm-glib/tests/test-remote-settings-client.c | 406 |
1 files changed, 406 insertions, 0 deletions
diff --git a/libnm-glib/tests/test-remote-settings-client.c b/libnm-glib/tests/test-remote-settings-client.c new file mode 100644 index 000000000..ad62075d4 --- /dev/null +++ b/libnm-glib/tests/test-remote-settings-client.c @@ -0,0 +1,406 @@ +/* -*- 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 - 2011 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-setting-connection.h> +#include <nm-setting-wired.h> +#include <nm-utils.h> + +#include "nm-remote-settings.h" + +static GPid spid = 0; +static NMRemoteSettings *settings = NULL; +DBusGConnection *bus = NULL; +NMRemoteConnection *remote = NULL; + +/*******************************************************************/ + +static void +cleanup (void) +{ + if (settings) + g_object_unref (settings); + kill (spid, SIGTERM); +} + +#define test_assert(condition) \ +do { \ + if (!G_LIKELY (condition)) \ + cleanup (); \ + g_assert (condition); \ +} while (0) + +/*******************************************************************/ + +static void +add_cb (NMRemoteSettings *s, + NMRemoteConnection *connection, + GError *error, + gpointer user_data) +{ + if (error) + g_warning ("Add error: %s", error->message); + + *((gboolean *) user_data) = TRUE; + remote = connection; +} + +#define TEST_CON_ID "blahblahblah" + +static void +test_add_connection (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + char *uuid; + gboolean success; + time_t start, now; + gboolean done = FALSE; + + connection = nm_connection_new (); + + s_con = (NMSettingConnection *) nm_setting_connection_new (); + uuid = nm_utils_uuid_generate (); + g_object_set (G_OBJECT (s_con), + NM_SETTING_CONNECTION_ID, TEST_CON_ID, + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NULL); + g_free (uuid); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + s_wired = (NMSettingWired *) nm_setting_wired_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + success = nm_remote_settings_add_connection (settings, + connection, + add_cb, + &done); + test_assert (success == TRUE); + + start = time (NULL); + do { + now = time (NULL); + g_main_context_iteration (NULL, FALSE); + } while ((done == FALSE) && (now - start < 5)); + test_assert (done == TRUE); + test_assert (remote != NULL); + + /* Make sure the connection is the same as what we added */ + test_assert (nm_connection_compare (connection, + NM_CONNECTION (remote), + NM_SETTING_COMPARE_FLAG_EXACT) == TRUE); +} + +/*******************************************************************/ + +static void +set_visible_cb (DBusGProxy *proxy, + DBusGProxyCall *call, + gpointer user_data) +{ + GError *error = NULL; + gboolean success; + + success = dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + if (!success) + g_warning ("Failed to change connection visibility: %s", error->message); + test_assert (success == TRUE); + test_assert (error == NULL); +} + +static void +invis_removed_cb (NMRemoteConnection *connection, gboolean *done) +{ + *done = TRUE; +} + +static void +invis_has_settings_cb (NMSetting *setting, + const char *key, + const GValue *value, + GParamFlags flags, + gpointer user_data) +{ + *((gboolean *) user_data) = TRUE; +} + +static void +test_make_invisible (void) +{ + time_t start, now; + GSList *list, *iter; + DBusGProxy *proxy; + gboolean done = FALSE, has_settings = FALSE; + char *path; + + test_assert (remote != NULL); + + /* Listen for the remove event when the connection becomes invisible */ + g_signal_connect (remote, "removed", G_CALLBACK (invis_removed_cb), &done); + + path = g_strdup (nm_connection_get_path (NM_CONNECTION (remote))); + proxy = dbus_g_proxy_new_for_name (bus, + NM_DBUS_SERVICE, + path, + NM_DBUS_IFACE_SETTINGS_CONNECTION); + test_assert (proxy != NULL); + + /* Bypass the NMRemoteSettings object so we can test it independently */ + dbus_g_proxy_begin_call (proxy, "SetVisible", set_visible_cb, NULL, NULL, + G_TYPE_BOOLEAN, FALSE, G_TYPE_INVALID); + + /* Wait for the connection to be removed */ + start = time (NULL); + do { + now = time (NULL); + g_main_context_iteration (NULL, FALSE); + } while ((done == FALSE) && (now - start < 5)); + test_assert (done == TRUE); + + /* Ensure NMRemoteSettings no longer has the connection */ + list = nm_remote_settings_list_connections (settings); + for (iter = list; iter; iter = g_slist_next (iter)) { + NMConnection *candidate = NM_CONNECTION (iter->data); + + test_assert ((gpointer) remote != (gpointer) candidate); + test_assert (strcmp (path, nm_connection_get_path (candidate)) != 0); + } + + /* And ensure the invisible connection no longer has any settings */ + nm_connection_for_each_setting_value (NM_CONNECTION (remote), + invis_has_settings_cb, + &has_settings); + test_assert (has_settings == FALSE); + + g_free (path); + g_object_unref (proxy); +} + +/*******************************************************************/ + +static void +vis_new_connection_cb (NMRemoteSettings *foo, + NMRemoteConnection *connection, + NMRemoteConnection **new) +{ + *new = connection; +} + +static void +test_make_visible (void) +{ + time_t start, now; + GSList *list, *iter; + DBusGProxy *proxy; + gboolean found = FALSE; + char *path; + NMRemoteConnection *new = NULL; + + test_assert (remote != NULL); + + /* Wait for the new-connection signal when the connection is visible again */ + g_signal_connect (settings, NM_REMOTE_SETTINGS_NEW_CONNECTION, + G_CALLBACK (vis_new_connection_cb), &new); + + path = g_strdup (nm_connection_get_path (NM_CONNECTION (remote))); + proxy = dbus_g_proxy_new_for_name (bus, + NM_DBUS_SERVICE, + path, + NM_DBUS_IFACE_SETTINGS_CONNECTION); + test_assert (proxy != NULL); + + /* Bypass the NMRemoteSettings object so we can test it independently */ + dbus_g_proxy_begin_call (proxy, "SetVisible", set_visible_cb, NULL, NULL, + G_TYPE_BOOLEAN, TRUE, G_TYPE_INVALID); + + + /* Wait for the settings service to announce the connection again */ + start = time (NULL); + do { + now = time (NULL); + g_main_context_iteration (NULL, FALSE); + } while ((new == NULL) && (now - start < 5)); + + /* Ensure the new connection is the same as the one we made visible again */ + test_assert (new == remote); + + /* Ensure NMRemoteSettings has the connection */ + list = nm_remote_settings_list_connections (settings); + for (iter = list; iter; iter = g_slist_next (iter)) { + NMConnection *candidate = NM_CONNECTION (iter->data); + + if ((gpointer) remote == (gpointer) candidate) { + test_assert (strcmp (path, nm_connection_get_path (candidate)) == 0); + test_assert (strcmp (TEST_CON_ID, nm_connection_get_id (candidate)) == 0); + found = TRUE; + break; + } + } + test_assert (found == TRUE); + + g_free (path); + g_object_unref (proxy); +} + +/*******************************************************************/ + +static void +deleted_cb (DBusGProxy *proxy, + DBusGProxyCall *call, + gpointer user_data) +{ + GError *error = NULL; + gboolean success; + + success = dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + if (!success) + g_warning ("Failed to delete connection: %s", error->message); + test_assert (success == TRUE); + test_assert (error == NULL); +} + +static void +removed_cb (NMRemoteConnection *connection, gboolean *done) +{ + *done = TRUE; +} + +static void +test_remove_connection (void) +{ + NMRemoteConnection *connection; + time_t start, now; + GSList *list, *iter; + DBusGProxy *proxy; + gboolean done = FALSE; + char *path; + + /* Find a connection to delete */ + list = nm_remote_settings_list_connections (settings); + test_assert (g_slist_length (list) > 0); + + connection = NM_REMOTE_CONNECTION (list->data); + path = g_strdup (nm_connection_get_path (NM_CONNECTION (connection))); + g_signal_connect (connection, "removed", G_CALLBACK (removed_cb), &done); + + proxy = dbus_g_proxy_new_for_name (bus, + NM_DBUS_SERVICE, + path, + NM_DBUS_IFACE_SETTINGS_CONNECTION); + test_assert (proxy != NULL); + + /* Bypass the NMRemoteSettings object so we can test it independently */ + dbus_g_proxy_begin_call (proxy, "Delete", deleted_cb, NULL, NULL, G_TYPE_INVALID); + + start = time (NULL); + do { + now = time (NULL); + g_main_context_iteration (NULL, FALSE); + } while ((done == FALSE) && (now - start < 5)); + test_assert (done == TRUE); + + /* Ensure NMRemoteSettings no longer has the connection */ + list = nm_remote_settings_list_connections (settings); + for (iter = list; iter; iter = g_slist_next (iter)) { + NMConnection *candidate = NM_CONNECTION (iter->data); + + test_assert ((gpointer) connection != (gpointer) candidate); + test_assert (strcmp (path, nm_connection_get_path (candidate)) != 0); + } + + g_free (path); + g_object_unref (proxy); +} + +/*******************************************************************/ + +#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) +{ + GTestSuite *suite; + char *service_argv[3] = { NULL, NULL, NULL }; + int ret; + GError *error = NULL; + int i = 100; + + g_assert (argc == 3); + + g_type_init (); + + g_test_init (&argc, &argv, NULL); + + bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + if (!bus) { + g_warning ("Error connecting to D-Bus: %s", error->message); + g_assert (error == NULL); + } + + service_argv[0] = g_strdup_printf ("%s/%s", argv[1], argv[2]); + if (!g_spawn_async (argv[1], service_argv, NULL, 0, NULL, NULL, &spid, &error)) { + g_warning ("Error spawning %s: %s", argv[2], error->message); + g_assert (error == NULL); + } + + /* Wait until the service is registered on the bus */ + while (i > 0) { + g_usleep (G_USEC_PER_SEC / 50); + if (dbus_bus_name_has_owner (dbus_g_connection_get_connection (bus), + "org.freedesktop.NetworkManager", + NULL)) + break; + i--; + } + test_assert (i > 0); + + 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)); + + ret = g_test_run (); + + cleanup (); + + return ret; +} + |