summary refs log tree commit diff
path: root/include/nm-test-utils.h
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2015-01-22 00:29:39 +0100
committerMichael Biebl <biebl@debian.org>2015-01-22 00:29:39 +0100
commit2c032d8f1c6292c1338a615e6ec40252889ba85c (patch)
tree1f77182220b2b0264288ba4a476ab47e5bc48716 /include/nm-test-utils.h
parent33491bc4279481db8ae47213e34a6d695a0e8830 (diff)
Imported Upstream version 1.0.0 upstream/1.0.0
Diffstat (limited to 'include/nm-test-utils.h')
-rw-r--r--include/nm-test-utils.h465
1 files changed, 448 insertions, 17 deletions
diff --git a/include/nm-test-utils.h b/include/nm-test-utils.h
index 83c4080f..dcfa46eb 100644
--- a/include/nm-test-utils.h
+++ b/include/nm-test-utils.h
@@ -1,5 +1,4 @@
 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-
 /*
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -16,7 +15,7 @@
  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  * Boston, MA 02110-1301 USA.
  *
- * (C) Copyright 2014 Red Hat, Inc.
+ * Copyright 2014 Red Hat, Inc.
  */
 
 #ifndef __NM_TEST_UTILS_H__
@@ -34,7 +33,32 @@
 
 #include "nm-utils.h"
 #include "nm-glib-compat.h"
+#include "gsystem-local-alloc.h"
+
+
+/*******************************************************************************/
+
+/* general purpose functions that have no dependency on other nmtst functions */
+
+inline static void
+nmtst_assert_error (GError *error,
+                    GQuark expect_error_domain,
+                    gint expect_error_code,
+                    const char *expect_error_pattern)
+{
+	if (expect_error_domain)
+		g_assert_error (error, expect_error_domain, expect_error_code);
+	else
+		g_assert (error);
+	g_assert (error->message);
+	if (   expect_error_pattern
+	    && !g_pattern_match_simple (expect_error_pattern, error->message)) {
+		g_error ("error message does not have expected pattern '%s'. Instead it is '%s' (%s, %d)",
+		         expect_error_pattern, error->message, g_quark_to_string (error->domain), error->code);
+	}
+}
 
+/*******************************************************************************/
 
 struct __nmtst_internal
 {
@@ -140,7 +164,6 @@ inline static void
 __nmtst_init (int *argc, char ***argv, gboolean assert_logging, const char *log_level, const char *log_domains)
 {
 	static gsize atexit_registered = 0;
-	GError *error = NULL;
 	const char *nmtst_debug;
 	gboolean is_debug = FALSE;
 	char *c_log_level = NULL, *c_log_domains = NULL;
@@ -243,7 +266,7 @@ __nmtst_init (int *argc, char ***argv, gboolean assert_logging, const char *log_
 
 	if (!__nmtst_internal.assert_logging) {
 		gboolean success = TRUE;
-#ifdef NM_LOGGING_H
+#ifdef __NETWORKMANAGER_LOGGING_H__
 		success = nm_logging_setup (log_level, log_domains, NULL, NULL);
 #endif
 		g_assert (success);
@@ -276,10 +299,6 @@ __nmtst_init (int *argc, char ***argv, gboolean assert_logging, const char *log_
 		g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
 	}
 
-	if (!nm_utils_init (&error))
-		g_error ("failed to initialize libnm-util: %s", error->message);
-	g_assert (!error);
-
 	/* Delay messages until we setup logging. */
 	for (i = 0; i < debug_messages->len; i++)
 		__NMTST_LOG (g_message, "%s", g_array_index (debug_messages, const char *, i));
@@ -292,9 +311,14 @@ __nmtst_init (int *argc, char ***argv, gboolean assert_logging, const char *log_
 		atexit (nmtst_free);
 		g_once_init_leave (&atexit_registered, 1);
 	}
+
+#ifdef __NETWORKMANAGER_UTILS_H__
+	/* ensure that monotonic timestamp is called (because it initially logs a line) */
+	nm_utils_get_monotonic_timestamp_s ();
+#endif
 }
 
-#ifdef NM_LOGGING_H
+#ifdef __NETWORKMANAGER_LOGGING_H__
 inline static void
 nmtst_init_with_logging (int *argc, char ***argv, const char *log_level, const char *log_domains)
 {
@@ -336,14 +360,14 @@ nmtst_is_debug (void)
 #endif
 
 inline static GRand *
-nmtst_get_rand0 ()
+nmtst_get_rand0 (void)
 {
 	g_assert (nmtst_initialized ());
 	return __nmtst_internal.rand0;
 }
 
 inline static GRand *
-nmtst_get_rand ()
+nmtst_get_rand (void)
 {
 	g_assert (nmtst_initialized ());
 
@@ -539,7 +563,7 @@ __nmtst_spawn_sync (const char *working_directory, char **standard_out, char **s
 
 /*******************************************************************************/
 
-#ifdef NM_PLATFORM_H
+#ifdef __NETWORKMANAGER_PLATFORM_H__
 
 inline static NMPlatformIP6Address *
 nmtst_platform_ip6_address (const char *address, const char *peer_address, guint plen)
@@ -556,7 +580,7 @@ nmtst_platform_ip6_address (const char *address, const char *peer_address, guint
 
 inline static NMPlatformIP6Address *
 nmtst_platform_ip6_address_full (const char *address, const char *peer_address, guint plen,
-                                 int ifindex, NMPlatformSource source, guint32 timestamp,
+                                 int ifindex, NMIPConfigSource source, guint32 timestamp,
                                  guint32 lifetime, guint32 preferred, guint flags)
 {
 	NMPlatformIP6Address *addr = nmtst_platform_ip6_address (address, peer_address, plen);
@@ -586,7 +610,7 @@ nmtst_platform_ip6_route (const char *network, guint plen, const char *gateway)
 
 inline static NMPlatformIP6Route *
 nmtst_platform_ip6_route_full (const char *network, guint plen, const char *gateway,
-                               int ifindex, NMPlatformSource source,
+                               int ifindex, NMIPConfigSource source,
                                guint metric, guint mss)
 {
 	NMPlatformIP6Route *route = nmtst_platform_ip6_route (network, plen, gateway);
@@ -644,7 +668,7 @@ nmtst_platform_ip6_routes_equal (const NMPlatformIP6Route *a, const NMPlatformIP
 #endif
 
 
-#ifdef NM_IP4_CONFIG_H
+#ifdef __NETWORKMANAGER_IP4_CONFIG_H__
 
 inline static NMIP4Config *
 nmtst_ip4_config_clone (NMIP4Config *config)
@@ -660,7 +684,7 @@ nmtst_ip4_config_clone (NMIP4Config *config)
 #endif
 
 
-#ifdef NM_IP6_CONFIG_H
+#ifdef __NETWORKMANAGER_IP6_CONFIG_H__
 
 inline static NMIP6Config *
 nmtst_ip6_config_clone (NMIP6Config *config)
@@ -675,6 +699,413 @@ nmtst_ip6_config_clone (NMIP6Config *config)
 
 #endif
 
+#ifdef __NM_SIMPLE_CONNECTION_H__
 
-#endif /* __NM_TEST_UTILS_H__ */
+inline static NMConnection *
+nmtst_create_minimal_connection (const char *id, const char *uuid, const char *type, NMSettingConnection **out_s_con)
+{
+	NMConnection *con;
+	NMSetting *s_base = NULL;
+	NMSettingConnection *s_con;
+	gs_free char *uuid_free = NULL;
+
+	g_assert (id);
+
+	if (uuid)
+		g_assert (nm_utils_is_uuid (uuid));
+	else
+		uuid = uuid_free = nm_utils_uuid_generate ();
+
+	if (type) {
+		GType type_g = nm_setting_lookup_type (type);
+
+		g_assert (type_g != G_TYPE_INVALID);
+
+		s_base = g_object_new (type_g, NULL);
+		g_assert (NM_IS_SETTING (s_base));
+	}
+
+	con = nm_simple_connection_new ();
+	s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
+
+	g_object_set (s_con,
+	              NM_SETTING_CONNECTION_ID, id,
+	              NM_SETTING_CONNECTION_UUID, uuid,
+	              NM_SETTING_CONNECTION_TYPE, type,
+	              NULL);
+	nm_connection_add_setting (con, NM_SETTING (s_con));
+
+	if (s_base)
+		nm_connection_add_setting (con, s_base);
+
+	if (out_s_con)
+		*out_s_con = s_con;
+	return con;
+}
+
+inline static gboolean
+_nmtst_connection_normalize_v (NMConnection *connection, va_list args)
+{
+	GError *error = NULL;
+	gboolean success;
+	gboolean was_modified = FALSE;
+	GHashTable *parameters = NULL;
+	const char *p_name;
+
+	g_assert (NM_IS_CONNECTION (connection));
+
+	while ((p_name = va_arg (args, const char *))) {
+		if (!parameters)
+			parameters =  g_hash_table_new (g_str_hash, g_str_equal);
+		g_hash_table_insert (parameters, (gpointer *) p_name, va_arg (args, gpointer));
+	}
+
+	success = nm_connection_normalize (connection,
+	                                   parameters,
+	                                   &was_modified,
+	                                   &error);
+	g_assert_no_error (error);
+	g_assert (success);
+
+	if (parameters)
+		g_hash_table_destroy (parameters);
+
+	return was_modified;
+}
+
+inline static gboolean
+_nmtst_connection_normalize (NMConnection *connection, ...)
+{
+	gboolean was_modified;
+	va_list args;
+
+	va_start (args, connection);
+	was_modified = _nmtst_connection_normalize_v (connection, args);
+	va_end (args);
+
+	return was_modified;
+}
+#define nmtst_connection_normalize(connection, ...) \
+    _nmtst_connection_normalize(connection, ##__VA_ARGS__, NULL)
+
+inline static NMConnection *
+_nmtst_connection_duplicate_and_normalize (NMConnection *connection, ...)
+{
+	gboolean was_modified;
+	va_list args;
+
+	g_assert (NM_IS_CONNECTION (connection));
+
+	connection = nm_simple_connection_new_clone (connection);
+
+	va_start (args, connection);
+	was_modified = _nmtst_connection_normalize_v (connection, args);
+	va_end (args);
+
+	return connection;
+}
+#define nmtst_connection_duplicate_and_normalize(connection, ...) \
+    _nmtst_connection_duplicate_and_normalize(connection, ##__VA_ARGS__, NULL)
+
+inline static void
+nmtst_assert_connection_equals (NMConnection *a, gboolean normalize_a, NMConnection *b, gboolean normalize_b)
+{
+	gboolean compare;
+	gs_unref_object NMConnection *a2 = NULL;
+	gs_unref_object NMConnection *b2 = NULL;
+	GHashTable *out_settings = NULL;
+
+	g_assert (NM_IS_CONNECTION (a));
+	g_assert (NM_IS_CONNECTION (b));
+
+	if (normalize_a)
+		a = a2 = nmtst_connection_duplicate_and_normalize (a);
+	if (normalize_b)
+		b = b2 = nmtst_connection_duplicate_and_normalize (b);
+
+	compare = nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_EXACT, &out_settings);
+	if (!compare && out_settings) {
+		const char *name, *pname;
+		GHashTable *setting;
+		GHashTableIter iter, iter2;
+
+		g_hash_table_iter_init (&iter, out_settings);
+		while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &setting)) {
+			__NMTST_LOG (g_message, ">>> differences in setting '%s':", name);
+
+			g_hash_table_iter_init (&iter2, out_settings);
+			while (g_hash_table_iter_next (&iter2, (gpointer *) &pname, NULL))
+				__NMTST_LOG (g_message, ">>> differences in setting '%s.%s':", name, pname);
+		}
+	}
+	g_assert (compare);
+	g_assert (!out_settings);
+
+	compare = nm_connection_compare (a, b, NM_SETTING_COMPARE_FLAG_EXACT);
+	g_assert (compare);
+}
+
+inline static void
+nmtst_assert_connection_verifies_without_normalization (NMConnection *con)
+{
+	/* assert that the connection verifies and does not need any normalization */
+
+	GError *error = NULL;
+	gboolean success;
+	gboolean was_modified = FALSE;
+	gs_unref_object NMConnection *clone = NULL;
+
+	g_assert (NM_IS_CONNECTION (con));
+
+	clone = nm_simple_connection_new_clone (con);
+
+	success = nm_connection_verify (con, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+
+	success = nm_connection_normalize (con, NULL, &was_modified, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+	nmtst_assert_connection_equals (con, FALSE, clone, FALSE);
+	g_assert (!was_modified);
+}
+
+inline static void
+nmtst_assert_connection_verifies_and_normalizable (NMConnection *con)
+{
+	/* assert that the connection does verify, but normalization still modifies it */
+	GError *error = NULL;
+	gboolean success;
+	gboolean was_modified = FALSE;
+
+	g_assert (NM_IS_CONNECTION (con));
+
+	success = nm_connection_verify (con, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+	g_clear_error (&error);
+
+	success = nm_connection_normalize (con, NULL, &was_modified, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+	g_assert (was_modified);
+
+	/* again! */
+	nmtst_assert_connection_verifies_without_normalization (con);
+}
+
+inline static void
+nmtst_assert_connection_verifies_after_normalization (NMConnection *con,
+                                                      GQuark expect_error_domain,
+                                                      gint expect_error_code)
+{
+	/* assert that the connection does not verify, but normalization does fix it */
+	GError *error = NULL;
+	gboolean success;
+	gboolean was_modified = FALSE;
+
+	g_assert (NM_IS_CONNECTION (con));
+
+	success = nm_connection_verify (con, &error);
+	nmtst_assert_error (error, expect_error_domain, expect_error_code, NULL);
+	g_assert (!success);
+	g_clear_error (&error);
+
+	success = nm_connection_normalize (con, NULL, &was_modified, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+	g_assert (was_modified);
+
+	/* again! */
+	nmtst_assert_connection_verifies_without_normalization (con);
+}
+
+inline static void
+nmtst_assert_connection_unnormalizable (NMConnection *con,
+                                        GQuark expect_error_domain,
+                                        gint expect_error_code)
+{
+	/* assert that the connection does not verify, and it cannot be fixed by normalization */
+
+	GError *error = NULL;
+	gboolean success;
+	gboolean was_modified = FALSE;
+
+	g_assert (NM_IS_CONNECTION (con));
+
+	success = nm_connection_verify (con, &error);
+	nmtst_assert_error (error, expect_error_domain, expect_error_code, NULL);
+	g_assert (!success);
+	g_clear_error (&error);
+
+	success = nm_connection_normalize (con, NULL, &was_modified, &error);
+	nmtst_assert_error (error, expect_error_domain, expect_error_code, NULL);
+	g_assert (!success);
+	g_assert (!was_modified);
+	g_clear_error (&error);
+}
+
+inline static void
+nmtst_assert_setting_verifies (NMSetting *setting)
+{
+	/* assert that the setting verifies without an error */
+
+	GError *error = NULL;
+	gboolean success;
+
+	g_assert (NM_IS_SETTING (setting));
+
+	success = nm_setting_verify (setting, NULL, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+}
+
+inline static void
+nmtst_assert_setting_verify_fails (NMSetting *setting,
+                                   GQuark expect_error_domain,
+                                   gint expect_error_code)
+{
+	/* assert that the setting verification fails */
+
+	GError *error = NULL;
+	gboolean success;
+
+	g_assert (NM_IS_SETTING (setting));
+
+	success = nm_setting_verify (setting, NULL, &error);
+	nmtst_assert_error (error, expect_error_domain, expect_error_code, NULL);
+	g_assert (!success);
+	g_clear_error (&error);
+}
+
+#endif
+
+#ifdef __NM_UTILS_H__
+static inline void
+nmtst_assert_hwaddr_equals (gconstpointer hwaddr1, gssize hwaddr1_len, const char *expected, const char *loc)
+{
+	guint8 buf2[NM_UTILS_HWADDR_LEN_MAX];
+	gsize hwaddr2_len = 1;
+	const char *p;
+	gboolean success;
+
+	g_assert (hwaddr1_len > 0 && hwaddr1_len <= NM_UTILS_HWADDR_LEN_MAX);
+
+	g_assert (expected);
+	for (p = expected; *p; p++) {
+		if (*p == ':' || *p == '-')
+			hwaddr2_len++;
+	}
+	g_assert (hwaddr2_len <= NM_UTILS_HWADDR_LEN_MAX);
+	g_assert (nm_utils_hwaddr_aton (expected, buf2, hwaddr2_len));
+
+	/* Manually check the entire hardware address instead of using
+	 * nm_utils_hwaddr_matches() because that function doesn't compare
+	 * entire InfiniBand addresses for various (legitimate) reasons.
+	 */
+	success = (hwaddr1_len == hwaddr2_len);
+	if (success)
+		success = !memcmp (hwaddr1, buf2, hwaddr1_len);
+	if (!success) {
+		g_error ("assert: %s: hwaddr '%s' (%zd) expected, but got %s (%zd)",
+		         loc, expected, hwaddr2_len, nm_utils_hwaddr_ntoa (hwaddr1, hwaddr1_len), hwaddr1_len);
+	}
+}
+#define nmtst_assert_hwaddr_equals(hwaddr1, hwaddr1_len, expected) \
+    nmtst_assert_hwaddr_equals (hwaddr1, hwaddr1_len, expected, G_STRLOC)
+#endif
+
+#ifdef __NM_CONNECTION_H__
+
+typedef enum {
+	NMTST_VARIANT_EDITOR_CONNECTION,
+	NMTST_VARIANT_EDITOR_SETTING,
+	NMTST_VARIANT_EDITOR_PROPERTY
+} NmtstVariantEditorPhase;
+
+#define NMTST_VARIANT_EDITOR(__connection_variant, __code) \
+	G_STMT_START { \
+		GVariantIter __connection_iter, *__setting_iter; \
+		GVariantBuilder __connection_builder, __setting_builder; \
+		const char *__cur_setting_name, *__cur_property_name; \
+		GVariant *__property_val; \
+		NmtstVariantEditorPhase __phase; \
+                                                                        \
+		g_variant_builder_init (&__connection_builder, NM_VARIANT_TYPE_CONNECTION); \
+		g_variant_iter_init (&__connection_iter, __connection_variant); \
+		 \
+		__phase = NMTST_VARIANT_EDITOR_CONNECTION; \
+		__cur_setting_name = NULL; \
+		__cur_property_name = NULL; \
+		__code; \
+		while (g_variant_iter_next (&__connection_iter, "{&sa{sv}}", &__cur_setting_name, &__setting_iter)) { \
+			g_variant_builder_init (&__setting_builder, NM_VARIANT_TYPE_SETTING); \
+			__phase = NMTST_VARIANT_EDITOR_SETTING; \
+			__cur_property_name = NULL; \
+			__code; \
+			 \
+			while (   __cur_setting_name \
+			       && g_variant_iter_next (__setting_iter, "{&sv}", &__cur_property_name, &__property_val)) { \
+				__phase = NMTST_VARIANT_EDITOR_PROPERTY; \
+				__code; \
+				 \
+				if (__cur_property_name) { \
+					g_variant_builder_add (&__setting_builder, "{sv}", \
+					                       __cur_property_name, \
+					                       __property_val); \
+				} else \
+					g_variant_unref (__property_val); \
+			} \
+			 \
+			if (__cur_setting_name) \
+				g_variant_builder_add (&__connection_builder, "{sa{sv}}", __cur_setting_name, &__setting_builder); \
+			g_variant_iter_free (__setting_iter); \
+		} \
+		 \
+		g_variant_unref (__connection_variant); \
+		 \
+		__connection_variant = g_variant_builder_end (&__connection_builder); \
+	} G_STMT_END;
 
+#define NMTST_VARIANT_ADD_SETTING(__setting_name, __setting_variant) \
+	G_STMT_START { \
+		if (__phase == NMTST_VARIANT_EDITOR_CONNECTION) \
+			g_variant_builder_add (&__connection_builder, "{s@a{sv}}", __setting_name, __setting_variant); \
+	} G_STMT_END
+
+#define NMTST_VARIANT_DROP_SETTING(__setting_name) \
+	G_STMT_START { \
+		if (__phase == NMTST_VARIANT_EDITOR_SETTING && __cur_setting_name) { \
+			if (!strcmp (__cur_setting_name, __setting_name)) \
+				__cur_setting_name = NULL; \
+		} \
+	} G_STMT_END
+
+#define NMTST_VARIANT_ADD_PROPERTY(__setting_name, __property_name, __format_string, __value) \
+	G_STMT_START { \
+		if (__phase == NMTST_VARIANT_EDITOR_SETTING) { \
+			if (!strcmp (__cur_setting_name, __setting_name)) { \
+				g_variant_builder_add (&__setting_builder, "{sv}", __property_name, \
+				                       g_variant_new (__format_string, __value)); \
+			} \
+		} \
+	} G_STMT_END
+
+#define NMTST_VARIANT_DROP_PROPERTY(__setting_name, __property_name) \
+	G_STMT_START { \
+		if (__phase == NMTST_VARIANT_EDITOR_PROPERTY && __cur_property_name) { \
+			if (   !strcmp (__cur_setting_name, __setting_name) \
+			    && !strcmp (__cur_property_name, __property_name)) \
+				__cur_property_name = NULL; \
+		} \
+	} G_STMT_END
+
+#define NMTST_VARIANT_CHANGE_PROPERTY(__setting_name, __property_name, __format_string, __value) \
+	G_STMT_START { \
+		NMTST_VARIANT_DROP_PROPERTY (__setting_name, __property_name); \
+		NMTST_VARIANT_ADD_PROPERTY (__setting_name, __property_name, __format_string, __value); \
+	} G_STMT_END
+
+#endif /* __NM_CONNECTION_H__ */
+
+#endif /* __NM_TEST_UTILS_H__ */