summary refs log tree commit diff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/Makefile.am2
-rw-r--r--include/Makefile.in4
-rw-r--r--include/nm-glib-compat.h87
-rw-r--r--include/nm-macros-internal.h (renamed from include/nm-utils-internal.h)78
-rw-r--r--include/nm-test-utils.h123
5 files changed, 279 insertions, 15 deletions
diff --git a/include/Makefile.am b/include/Makefile.am
index 6e84a5b6..ff7eac8c 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -4,6 +4,6 @@ EXTRA_DIST = \
      nm-glib-compat.h \
      nm-gvaluearray-compat.h \
      nm-test-utils.h \
-     nm-utils-internal.h
+     nm-macros-internal.h
 
 CLEANFILES=nm-version.h
diff --git a/include/Makefile.in b/include/Makefile.in
index 016710b6..3dbcc338 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -135,6 +135,7 @@ ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
 AMTAR = @AMTAR@
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AM_TESTS_FD_REDIRECT = @AM_TESTS_FD_REDIRECT@
 AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
@@ -248,6 +249,7 @@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
+LOG_DRIVER = @LOG_DRIVER@
 LTLIBICONV = @LTLIBICONV@
 LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
@@ -397,7 +399,7 @@ EXTRA_DIST = \
      nm-glib-compat.h \
      nm-gvaluearray-compat.h \
      nm-test-utils.h \
-     nm-utils-internal.h
+     nm-macros-internal.h
 
 CLEANFILES = nm-version.h
 all: all-am
diff --git a/include/nm-glib-compat.h b/include/nm-glib-compat.h
index 1dc939fe..dc39d2b9 100644
--- a/include/nm-glib-compat.h
+++ b/include/nm-glib-compat.h
@@ -23,6 +23,7 @@
 
 #include <glib.h>
 #include <glib-object.h>
+#include <string.h>
 
 
 #ifdef __clang__
@@ -163,4 +164,90 @@ q_n##_quark (void)                            \
 }
 #endif
 
+
+static inline gboolean
+nm_g_hash_table_replace (GHashTable *hash, gpointer key, gpointer value)
+{
+	/* glib 2.40 added a return value indicating whether the key already existed
+	 * (910191597a6c2e5d5d460e9ce9efb4f47d9cc63c). */
+#if GLIB_CHECK_VERSION(2, 40, 0)
+	return g_hash_table_replace (hash, key, value);
+#else
+	gboolean contained = g_hash_table_contains (hash, key);
+
+	g_hash_table_replace (hash, key, value);
+	return !contained;
+#endif
+}
+
+
+#if !GLIB_CHECK_VERSION(2, 40, 0) || defined (NM_GLIB_COMPAT_H_TEST)
+static inline void
+_nm_g_ptr_array_insert (GPtrArray *array,
+                        gint       index_,
+                        gpointer   data)
+{
+	g_return_if_fail (array);
+	g_return_if_fail (index_ >= -1);
+	g_return_if_fail (index_ <= (gint) array->len);
+
+	g_ptr_array_add (array, data);
+
+	if (index_ != -1 && index_ != (gint) (array->len - 1)) {
+		memmove (&(array->pdata[index_ + 1]),
+		         &(array->pdata[index_]),
+		         (array->len - index_ - 1) * sizeof (gpointer));
+		array->pdata[index_] = data;
+	}
+}
+#endif
+#if !GLIB_CHECK_VERSION(2, 40, 0)
+#define g_ptr_array_insert(array, index, data) G_STMT_START { _nm_g_ptr_array_insert (array, index, data); } G_STMT_END
+#else
+#define g_ptr_array_insert(array, index, data) \
+	G_STMT_START { \
+		G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
+		g_ptr_array_insert (array, index, data); \
+		G_GNUC_END_IGNORE_DEPRECATIONS \
+	} G_STMT_END
+#endif
+
+
+#if !GLIB_CHECK_VERSION (2, 40, 0)
+inline static gboolean
+_g_key_file_save_to_file (GKeyFile     *key_file,
+                          const gchar  *filename,
+                          GError      **error)
+{
+	gchar *contents;
+	gboolean success;
+	gsize length;
+
+	g_return_val_if_fail (key_file != NULL, FALSE);
+	g_return_val_if_fail (filename != NULL, FALSE);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	contents = g_key_file_to_data (key_file, &length, NULL);
+	g_assert (contents != NULL);
+
+	success = g_file_set_contents (filename, contents, length, error);
+	g_free (contents);
+
+	return success;
+}
+#define g_key_file_save_to_file(key_file, filename, error) \
+	_g_key_file_save_to_file (key_file, filename, error)
+#else
+#define g_key_file_save_to_file(key_file, filename, error) \
+	({ \
+		gboolean _success; \
+		\
+		G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
+		_success = g_key_file_save_to_file (key_file, filename, error); \
+		G_GNUC_END_IGNORE_DEPRECATIONS \
+		_success; \
+	})
+#endif
+
+
 #endif  /* __NM_GLIB_COMPAT_H__ */
diff --git a/include/nm-utils-internal.h b/include/nm-macros-internal.h
index 227a210b..405051f3 100644
--- a/include/nm-utils-internal.h
+++ b/include/nm-macros-internal.h
@@ -19,8 +19,8 @@
  * (C) Copyright 2014 Red Hat, Inc.
  */
 
-#ifndef __NM_UTILS_INTERNAL_H__
-#define __NM_UTILS_INTERNAL_H__
+#ifndef __NM_MACROS_INTERNAL_H__
+#define __NM_MACROS_INTERNAL_H__
 
 
 #include <glib.h>
@@ -100,6 +100,19 @@
         _found;                                                 \
     })
 
+#define NM_PRINT_FMT_QUOTED(cond, prefix, str, suffix, str_else) \
+	(cond) ? (prefix) : "", \
+	(cond) ? (str) : (str_else), \
+	(cond) ? (suffix) : ""
+
+/*****************************************************************************/
+
+#ifdef NM_MORE_ASSERTS
+#define nm_assert(cond) G_STMT_START { g_assert (cond); } G_STMT_END
+#else
+#define nm_assert(cond) G_STMT_START { if (FALSE) { if (cond) { } } } G_STMT_END
+#endif
+
 /*****************************************************************************/
 
 #define NM_DEFINE_SINGLETON_INSTANCE(TYPE) \
@@ -173,4 +186,63 @@ nm_clear_g_source (guint *id)
 
 /*****************************************************************************/
 
-#endif
+/* Determine whether @x is a power of two (@x being an integer type).
+ * For the special cases @x equals zero or one, it also returns true.
+ * For negative @x, always returns FALSE. That only applies, if the data
+ * type of @x is signed. */
+#define nm_utils_is_power_of_two(x) ({ \
+		const typeof(x) __x = (x); \
+		\
+		((__x & (__x - 1)) == 0) && \
+			/* Check if the value is negative. In that case, return FALSE.
+			 * The first expression is a compile time constant, depending on whether
+			 * the type is signed. The second expression is a clumsy way for (__x >= 0),
+			 * which causes a compiler warning for unsigned types. */ \
+			( ( ((typeof(__x)) -1) > ((typeof(__x)) 0) ) || (__x > 0) || (__x == 0) ); \
+	})
+
+/*****************************************************************************/
+
+/* check if @flags has exactly one flag (@check) set. You should call this
+ * only with @check being a compile time constant and a power of two. */
+#define NM_FLAGS_HAS(flags, check)  \
+    ( (G_STATIC_ASSERT_EXPR ( ((check) != 0) && ((check) & ((check)-1)) == 0 )), (NM_FLAGS_ANY ((flags), (check))) )
+
+#define NM_FLAGS_ANY(flags, check)  ( ( ((flags) & (check)) != 0       ) ? TRUE : FALSE )
+#define NM_FLAGS_ALL(flags, check)  ( ( ((flags) & (check)) == (check) ) ? TRUE : FALSE )
+
+#define NM_FLAGS_SET(flags, val)  ({ \
+		const typeof(flags) _flags = (flags); \
+		const typeof(flags) _val = (val); \
+		\
+		_flags | _val; \
+	})
+
+#define NM_FLAGS_UNSET(flags, val)  ({ \
+		const typeof(flags) _flags = (flags); \
+		const typeof(flags) _val = (val); \
+		\
+		_flags & (~_val); \
+	})
+
+#define NM_FLAGS_ASSIGN(flags, val, assign)  ({ \
+		const typeof(flags) _flags = (flags); \
+		const typeof(flags) _val = (val); \
+		\
+		(assign) \
+			? _flags | (_val) \
+			: _flags & (~_val); \
+	})
+
+/*****************************************************************************/
+
+static inline char *
+nm_strstrip (char *str)
+{
+	/* g_strstrip doesn't like NULL. */
+	return str ? g_strstrip (str) : NULL;
+}
+
+/*****************************************************************************/
+
+#endif /* __NM_MACROS_INTERNAL_H__ */
diff --git a/include/nm-test-utils.h b/include/nm-test-utils.h
index 5f83d09d..258d3937 100644
--- a/include/nm-test-utils.h
+++ b/include/nm-test-utils.h
@@ -92,13 +92,14 @@
 #include <errno.h>
 
 #include "nm-utils.h"
-#include "nm-utils-internal.h"
+#include "nm-macros-internal.h"
 #include "nm-glib-compat.h"
 #include "gsystem-local-alloc.h"
 
-
-/* Analog to EXIT_SUCCESS and EXIT_FAILURE. */
-#define EXIT_SKIP (77)
+#ifdef __NETWORKMANAGER_LOGGING_H__
+/* We are running tests under src/ */
+#include "NetworkManagerUtils.h"
+#endif
 
 /*******************************************************************************/
 
@@ -122,6 +123,14 @@ nmtst_assert_error (GError *error,
 	}
 }
 
+inline static void
+_nmtst_assert_success (gboolean success, GError *error, const char *file, int line)
+{
+	if (!success || error)
+		g_error ("(%s:%d) FAILURE success=%d, error=%s", file, line, success, error && error->message ? error->message : "(no error)");
+}
+#define nmtst_assert_success(success, error) _nmtst_assert_success ((success), (error), __FILE__, __LINE__)
+
 /*******************************************************************************/
 
 struct __nmtst_internal
@@ -258,6 +267,11 @@ __nmtst_init (int *argc, char ***argv, gboolean assert_logging, const char *log_
 	g_assert (!argc || (g_strv_length (*argv) == *argc));
 	g_assert (!assert_logging || (!log_level && !log_domains));
 
+#ifdef __NETWORKMANAGER_UTILS_H__
+	if (!nm_utils_get_testing_initialized ())
+		_nm_utils_set_testing (_NM_UTILS_TEST_GENERAL);
+#endif
+
 	if (argc)
 		__nmtst_internal.orig_argv = g_strdupv (*argv);
 
@@ -710,6 +724,39 @@ __nmtst_spawn_sync (const char *working_directory, char **standard_out, char **s
 
 /*******************************************************************************/
 
+inline static char *
+nmtst_file_resolve_relative_path (const char *rel, const char *cwd)
+{
+	gs_free char *cwd_free = NULL;
+
+	g_assert (rel && *rel);
+
+	if (g_path_is_absolute (rel))
+		return g_strdup (rel);
+
+	if (!cwd)
+		cwd = cwd_free = g_get_current_dir ();
+	return g_build_filename (cwd, rel, NULL);
+}
+
+inline static void
+_nmtst_assert_resolve_relative_path_equals (const char *f1, const char *f2, const char *file, int line)
+{
+	gs_free char *p1 = NULL, *p2 = NULL;
+
+	p1 = nmtst_file_resolve_relative_path (f1, NULL);
+	p2 = nmtst_file_resolve_relative_path (f2, NULL);
+	g_assert (p1 && *p1);
+
+	/* Fixme: later we might need to coalesce repeated '/', "./", and "../".
+	 * For now, it's good enough. */
+	if (g_strcmp0 (p1, p2) != 0)
+		g_error ("%s:%d : filenames don't match \"%s\" vs. \"%s\" // \"%s\" - \"%s\"", file, line, f1, f2, p1, p2);
+}
+#define nmtst_assert_resolve_relative_path_equals(f1, f2) _nmtst_assert_resolve_relative_path_equals (f1, f2, __FILE__, __LINE__);
+
+/*******************************************************************************/
+
 #ifdef __NETWORKMANAGER_PLATFORM_H__
 
 inline static NMPlatformIP6Address *
@@ -742,6 +789,38 @@ nmtst_platform_ip6_address_full (const char *address, const char *peer_address,
 	return addr;
 }
 
+inline static NMPlatformIP4Route *
+nmtst_platform_ip4_route (const char *network, guint plen, const char *gateway)
+{
+	static NMPlatformIP4Route route;
+
+	memset (&route, 0, sizeof (route));
+	route.network = nmtst_inet4_from_string (network);
+	route.plen = plen;
+	route.gateway = nmtst_inet4_from_string (gateway);
+
+	return &route;
+}
+
+inline static NMPlatformIP4Route *
+nmtst_platform_ip4_route_full (const char *network, guint plen, const char *gateway,
+                               int ifindex, NMIPConfigSource source,
+                               guint metric, guint mss,
+                               guint8 scope,
+                               const char *pref_src)
+{
+	NMPlatformIP4Route *route = nmtst_platform_ip4_route (network, plen, gateway);
+
+	route->ifindex = ifindex;
+	route->source = source;
+	route->metric = metric;
+	route->mss = mss;
+	route->scope_inv = nm_platform_route_scope_inv (scope);
+	route->pref_src = nmtst_inet4_from_string (pref_src);
+
+	return route;
+}
+
 inline static NMPlatformIP6Route *
 nmtst_platform_ip6_route (const char *network, guint plen, const char *gateway)
 {
@@ -799,9 +878,6 @@ nmtst_platform_ip4_routes_equal (const NMPlatformIP4Route *a, const NMPlatformIP
 			         nmtst_static_1024_02 (nm_platform_ip4_route_to_string (&b[i])));
 			g_assert_not_reached ();
 		}
-
-		/* also check with memcmp, though this might fail for valid programs (due to field alignment) */
-		g_assert_cmpint (memcmp (&a[i], &b[i], sizeof (a[i])), ==, 0);
 	}
 }
 
@@ -834,9 +910,6 @@ nmtst_platform_ip6_routes_equal (const NMPlatformIP6Route *a, const NMPlatformIP
 			         nmtst_static_1024_02 (nm_platform_ip6_route_to_string (&b[i])));
 			g_assert_not_reached ();
 		}
-
-		/* also check with memcmp, though this might fail for valid programs (due to field alignment) */
-		g_assert_cmpint (memcmp (&a[i], &b[i], sizeof (a[i])), ==, 0);
 	}
 }
 
@@ -1193,6 +1266,36 @@ nmtst_assert_hwaddr_equals (gconstpointer hwaddr1, gssize hwaddr1_len, const cha
     nmtst_assert_hwaddr_equals (hwaddr1, hwaddr1_len, expected, G_STRLOC)
 #endif
 
+#if defined(__NM_SIMPLE_CONNECTION_H__) && defined(__NM_SETTING_CONNECTION_H__) && defined(__NM_KEYFILE_INTERNAL_H__)
+
+inline static NMConnection *
+nmtst_create_connection_from_keyfile (const char *keyfile_str, const char *keyfile_name, const char *base_dir)
+{
+	GKeyFile *keyfile;
+	GError *error = NULL;
+	gboolean success;
+	NMConnection *con;
+
+	g_assert (keyfile_str);
+
+	keyfile =  g_key_file_new ();
+	success = g_key_file_load_from_data (keyfile, keyfile_str, strlen (keyfile_str), G_KEY_FILE_NONE, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+
+	con = nm_keyfile_read (keyfile, keyfile_name, base_dir, NULL, NULL, &error);
+	g_assert_no_error (error);
+	g_assert (NM_IS_CONNECTION (con));
+
+	g_key_file_unref (keyfile);
+
+	nmtst_connection_normalize (con);
+
+	return con;
+}
+
+#endif
+
 #ifdef __NM_CONNECTION_H__
 
 typedef enum {