summary refs log tree commit diff
path: root/src/platform/tests/test-common.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2015-05-05 17:48:57 +0200
committerMichael Biebl <biebl@debian.org>2015-05-05 17:48:57 +0200
commitf408e27bccfacf347605a8d98649975a68f38a17 (patch)
tree654fd6695c31511baf919b1c0870d119a352ed75 /src/platform/tests/test-common.c
parent2c032d8f1c6292c1338a615e6ec40252889ba85c (diff)
Imported Upstream version 1.0.2 upstream/1.0.2
Diffstat (limited to 'src/platform/tests/test-common.c')
-rw-r--r--src/platform/tests/test-common.c115
1 files changed, 112 insertions, 3 deletions
diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c
index ab40f652..1980282d 100644
--- a/src/platform/tests/test-common.c
+++ b/src/platform/tests/test-common.c
@@ -125,6 +125,113 @@ link_callback (NMPlatform *platform, int ifindex, NMPlatformLink *received, NMPl
 		g_error ("Added/changed link not found in the local cache.");
 }
 
+gboolean
+ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 metric)
+{
+	gs_free char *arg_network = NULL;
+	const char *argv[] = {
+		NULL,
+		"route",
+		"list",
+		"dev",
+		ifname,
+		"exact",
+		NULL,
+		NULL,
+	};
+	int exit_status;
+	gs_free char *std_out = NULL, *std_err = NULL;
+	char *out;
+	gboolean success;
+	gs_free_error GError *error = NULL;
+	gs_free char *metric_pattern = NULL;
+
+	g_assert (ifname && nm_utils_iface_valid_name (ifname));
+	g_assert (!strstr (ifname, " metric "));
+	g_assert (plen >= 0 && plen <= 32);
+
+	if (!NM_IS_LINUX_PLATFORM (nm_platform_get ())) {
+		/* If we don't test against linux-platform, we don't actually configure any
+		 * routes in the system. */
+		return -1;
+	}
+
+	argv[0] = nm_utils_file_search_in_paths ("ip", NULL,
+	                                         (const char *[]) { "/sbin", "/usr/sbin", NULL },
+	                                         G_FILE_TEST_IS_EXECUTABLE, NULL, NULL, NULL);
+	argv[6] = arg_network = g_strdup_printf ("%s/%d", nm_utils_inet4_ntop (network, NULL), plen);
+
+	if (!argv[0]) {
+		/* Hm. There is no 'ip' binary. Return *unknown* */
+		return -1;
+	}
+
+	success = g_spawn_sync (NULL,
+	                        (char **) argv,
+	                        (char *[]) { NULL },
+	                        0,
+	                        NULL,
+	                        NULL,
+	                        &std_out,
+	                        &std_err,
+	                        &exit_status,
+	                        &error);
+	g_assert_no_error (error);
+	g_assert (success);
+	g_assert_cmpstr (std_err, ==, "");
+	g_assert (std_out);
+
+	metric_pattern = g_strdup_printf (" metric %u", metric);
+	out = std_out;
+	while (out) {
+		char *eol = strchr (out, '\n');
+		gs_free char *line = eol ? g_strndup (out, eol - out) : g_strdup (out);
+		const char *p;
+
+		out = eol ? &eol[1] : NULL;
+		if (!line[0])
+			continue;
+
+		if (metric == 0) {
+			if (!strstr (line, " metric "))
+				return TRUE;
+		}
+		p = strstr (line, metric_pattern);
+		if (p && NM_IN_SET (p[strlen (metric_pattern)], ' ', '\0'))
+			return TRUE;
+	}
+	return FALSE;
+}
+
+void
+_assert_ip4_route_exists (const char *file, guint line, const char *func, gboolean exists, const char *ifname, guint32 network, int plen, guint32 metric)
+{
+	int ifindex;
+	gboolean exists_checked;
+
+	/* Check for existance of the route by spawning iproute2. Do this because platform
+	 * code might be entirely borked, but we expect ip-route to give a correct result.
+	 * If the ip command cannot be found, we accept this as success. */
+	exists_checked = ip4_route_exists (ifname, network, plen, metric);
+	if (exists_checked != -1 && !exists_checked != !exists) {
+		g_error ("[%s:%u] %s(): We expect the ip4 route %s/%d metric %u %s, but it %s",
+		         file, line, func,
+		         nm_utils_inet4_ntop (network, NULL), plen, metric,
+		         exists ? "to exist" : "not to exist",
+		         exists ? "doesn't" : "does");
+	}
+
+	ifindex = nm_platform_link_get_ifindex (ifname);
+	g_assert (ifindex > 0);
+	if (!nm_platform_ip4_route_exists (ifindex, network, plen, metric) != !exists) {
+		g_error ("[%s:%u] %s(): The ip4 route %s/%d metric %u %s, but platform thinks %s",
+		         file, line, func,
+		         nm_utils_inet4_ntop (network, NULL), plen, metric,
+		         exists ? "exists" : "does not exist",
+		         exists ? "it doesn't" : "it does");
+	}
+}
+
 void
 run_command (const char *format, ...)
 {
@@ -148,20 +255,22 @@ main (int argc, char **argv)
 	int result;
 	const char *program = *argv;
 
-	nmtst_init_with_logging (&argc, &argv, NULL, "ALL");
+	init_tests (&argc, &argv);
 
+	NM_PRAGMA_WARNING_DISABLE("-Wtautological-compare")
 	if (SETUP == nm_linux_platform_setup && getuid() != 0) {
 		/* Try to exec as sudo, this function does not return, if a sudo-cmd is set. */
 		nmtst_reexec_sudo ();
 
 #ifdef REQUIRE_ROOT_TESTS
-		g_message ("Fail test: requires root privileges (%s)", program);
+		g_print ("Fail test: requires root privileges (%s)\n", program);
 		return EXIT_FAILURE;
 #else
-		g_message ("Skipping test: requires root privileges (%s)", program);
+		g_print ("Skipping test: requires root privileges (%s)\n", program);
 		return 77;
 #endif
 	}
+	NM_PRAGMA_WARNING_REENABLE
 
 	SETUP ();