[netfilter-cvslog] r3494 - trunk/nfsim/core

rusty at netfilter.org rusty at netfilter.org
Thu Dec 23 01:57:55 CET 2004


Author: rusty at netfilter.org
Date: 2004-12-23 01:57:55 +0100 (Thu, 23 Dec 2004)
New Revision: 3494

Modified:
   trunk/nfsim/core/failtest.c
Log:
Report ignoring failures in a more useful way: what line of script, and what failures/successes.
Involved changing to linked-list (which should also be faster) for easy manipulation.


Modified: trunk/nfsim/core/failtest.c
===================================================================
--- trunk/nfsim/core/failtest.c	2004-12-22 06:42:45 UTC (rev 3493)
+++ trunk/nfsim/core/failtest.c	2004-12-23 00:57:55 UTC (rev 3494)
@@ -31,8 +31,16 @@
 static unsigned int fails = 0;
 unsigned int failpoints = 0;
 
-/* Failures pattern so far. */
-static char *faillist;
+struct fail_decision
+{
+	struct list_head list;
+	char *location;
+	unsigned int tui_line;
+	bool failed;
+};
+
+static LIST_HEAD(decisions);
+
 /* Failure pattern to follow (initialized by --failpattern). */
 static const char *failpattern = NULL, *orig_failpattern;
 
@@ -128,22 +136,54 @@
 	}
 }
 
+static char *failpath_string_for_line(struct fail_decision *dec)
+{
+	char *ret = NULL;
+	struct fail_decision *i, *prev;
+	unsigned int linenum = dec->tui_line;
+
+	/* Find first one on this line. */
+	list_for_each_entry_reverse(prev, &dec->list, list)
+		if (&prev->list == &decisions || prev->tui_line != linenum)
+			break;
+
+	list_for_each_entry(i, &prev->list, list) {
+		if (i->tui_line != linenum)
+			break;
+		ret = talloc_asprintf_append(ret, "[%s]:%c",
+					     i->location,
+					     i->failed ? 'F' : 'S');
+	}
+	return ret;
+}
+
 static void warn_failure(void)
 {
-	char *warning = NULL, *p;
+	char *warning;
+	struct fail_decision *i;
 
-	/* Only report failures, with linenumber*/
-	for (p = strstr(faillist, ":F"); p; p = strstr(p + 1, ":F")) {
-		char *start, *line;
+	nfsim_log(LOG_ALWAYS, "WARNING: test ignores failures");
 
-		for (start = p; *start != '['; start--);
-		for (line = p-1; *line != ':'; line--);
-		warning = talloc_asprintf_append(warning, "%.*s line %.*s, ",
-						 line - start - 2, start+1,
-						 p - line - 1, line+1);
+	list_for_each_entry(i, &decisions, list) {
+		if (i->failed) {
+			warning = failpath_string_for_line(i);
+			nfsim_log(LOG_ALWAYS, " Line %i: %s",
+				  i->tui_line, warning);
+			talloc_free(warning);
+		}
 	}
+}
 
-	nfsim_log(LOG_ALWAYS, "WARNING: test ignores failures: %s", warning);
+static char *failpath_string(void)
+{
+	char *ret = NULL;
+	struct fail_decision *i;
+
+	list_for_each_entry(i, &decisions, list)
+		ret = talloc_asprintf_append(ret, "[%s]:%i:%c",
+					     i->location, i->tui_line,
+					     i->failed ? 'F' : 'S');
+	return ret;
 }
 
 /* Should I fail at this point?  Once only: it would be too expensive
@@ -151,6 +191,7 @@
 bool should_i_fail_once(const char *location)
 {
 	char *p;
+	struct fail_decision *i;
 
 	if (suppress_failtest)
 		return false;
@@ -164,11 +205,10 @@
 		return do_failpattern(location);
 	}
 
-	p = strstr(faillist ?: "", location);
-	if (p && p[-1] == '[' && p[strlen(location)] == ']')
-		return false;
+	list_for_each_entry(i, &decisions, list)
+		if (streq(location, i->location))
+			return false;
 
-
 	return should_i_fail(location);
 }
 
@@ -177,6 +217,7 @@
 {
 	pid_t child;
 	int status;
+	struct fail_decision *dec;
 
 	if (suppress_failtest)
 		return false;
@@ -196,6 +237,11 @@
 			warn_failure();
 	}
 
+	dec = talloc(NULL, struct fail_decision);
+	dec->location = talloc_strdup(dec, func);
+	dec->tui_line = tui_linenum;
+	list_add_tail(&dec->list, &decisions);
+
 	fflush(stdout);
 	child = fork();
 	if (child == -1)
@@ -204,16 +250,14 @@
 	/* The child actually fails.  The script will screw up at this
 	 * point, but should not crash. */
 	if (child == 0) {
+		dec->failed = true;
+		fails++;
 		/* If we're talking to iptables, it has to fork too. */
-		faillist = talloc_asprintf_append(faillist, "[%s]:%i:F", func,
-						  tui_linenum);
-		fails++;
 		fork_other_program();
 		return true;
 	}
 
-	faillist = talloc_asprintf_append(faillist, "[%s]:%i:S", func,
-					  tui_linenum);
+	dec->failed = false;
 	if (waitpid(child, &status, 0) != child)
 		barf_perror("failtest waitpid failed for child %i",(int)child);
 
@@ -224,10 +268,12 @@
 
 	/* Report unless child already reported it. */
 	if (!WIFEXITED(status) || WEXITSTATUS(status) == EXIT_SILENT) {
-		nfsim_log(LOG_ALWAYS, "Child %s %i on failure path: %s[%s]F",
+		/* Reproduce child's path */
+		dec->failed = true;
+		nfsim_log(LOG_ALWAYS, "Child %s %i on failure path: %s",
 			  WIFEXITED(status) ? "exited" : "signalled",
 			  WIFEXITED(status) ? WEXITSTATUS(status)
-			  : WTERMSIG(status), faillist, func);
+			  : WTERMSIG(status), failpath_string());
 	}
 	exit(EXIT_SILENT);
 }




More information about the netfilter-cvslog mailing list