unit-tests: Add ability to issue a warning message for a test case
authorTobias Brunner <tobias@strongswan.org>
Tue, 26 Sep 2017 12:55:14 +0000 (14:55 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 8 Nov 2017 15:48:10 +0000 (16:48 +0100)
This way we can warn if we e.g. skipped actually doing something due to
dependencies (otherwise the test case would just appear to have succeeded).

src/libstrongswan/tests/test_runner.c
src/libstrongswan/tests/test_suite.c
src/libstrongswan/tests/test_suite.h

index ed77b3c..b9a0fe6 100644 (file)
@@ -386,9 +386,28 @@ static void collect_failure_info(array_t *failures, char *name, int i)
 }
 
 /**
+ * Collect warning information, add failure_t to array
+ */
+static bool collect_warning_info(array_t *warnings, char *name, int i)
+{
+       failure_t warning = {
+               .name = name,
+               .i = i,
+       };
+
+       warning.line = test_warning_get(warning.msg, sizeof(warning.msg),
+                                                                       &warning.file);
+       if (warning.line)
+       {
+               array_insert(warnings, -1, &warning);
+       }
+       return warning.line;
+}
+
+/**
  * Print array of collected failure_t to stderr
  */
-static void print_failures(array_t *failures)
+static void print_failures(array_t *failures, bool warnings)
 {
        failure_t failure;
 
@@ -397,8 +416,16 @@ static void print_failures(array_t *failures)
 
        while (array_remove(failures, 0, &failure))
        {
-               fprintf(stderr, "      %sFailure in '%s': %s (",
-                               TTY(RED), failure.name, failure.msg);
+               if (warnings)
+               {
+                       fprintf(stderr, "      %sWarning in '%s': %s (",
+                                       TTY(YELLOW), failure.name, failure.msg);
+               }
+               else
+               {
+                       fprintf(stderr, "      %sFailure in '%s': %s (",
+                                       TTY(RED), failure.name, failure.msg);
+               }
                if (failure.line)
                {
                        fprintf(stderr, "%s:%d, ", failure.file, failure.line);
@@ -423,9 +450,10 @@ static bool run_case(test_case_t *tcase, test_runner_init_t init, char *cfg)
        enumerator_t *enumerator;
        test_function_t *tfun;
        int passed = 0;
-       array_t *failures;
+       array_t *failures, *warnings;
 
        failures = array_create(sizeof(failure_t), 0);
+       warnings = array_create(sizeof(failure_t), 0);
 
        fprintf(stderr, "    Running case '%s': ", tcase->name);
        fflush(stderr);
@@ -470,7 +498,14 @@ static bool run_case(test_case_t *tcase, test_runner_init_t init, char *cfg)
                                        if (!leaks)
                                        {
                                                rounds++;
-                                               fprintf(stderr, "%s+%s", TTY(GREEN), TTY(DEF));
+                                               if (!collect_warning_info(warnings, tfun->name, i))
+                                               {
+                                                       fprintf(stderr, "%s+%s", TTY(GREEN), TTY(DEF));
+                                               }
+                                               else
+                                               {
+                                                       fprintf(stderr, "%s~%s", TTY(YELLOW), TTY(DEF));
+                                               }
                                        }
                                }
                                else
@@ -497,8 +532,10 @@ static bool run_case(test_case_t *tcase, test_runner_init_t init, char *cfg)
 
        fprintf(stderr, "\n");
 
-       print_failures(failures);
+       print_failures(warnings, TRUE);
+       print_failures(failures, FALSE);
        array_destroy(failures);
+       array_destroy(warnings);
 
        return passed == array_count(tcase->functions);
 }
index 8541cda..412d9fb 100644 (file)
@@ -50,6 +50,21 @@ static backtrace_t *failure_backtrace;
 static bool worker_failed;
 
 /**
+ * Warning message buf
+ */
+static char warning_buf[4096];
+
+/**
+ * Source file warning was issued
+ */
+static const char *warning_file;
+
+/**
+ * Line of source file warning was issued
+ */
+static int warning_line;
+
+/**
  * See header.
  */
 test_suite_t* test_suite_create(const char *name)
@@ -419,6 +434,21 @@ void test_fail_vmsg(const char *file, int line, char *fmt, va_list args)
 
        test_failure();
 }
+
+/**
+ * See header.
+ */
+void test_warn_msg(const char *file, int line, char *fmt, ...)
+{
+       va_list args;
+
+       va_start(args, fmt);
+       vsnprintf(warning_buf, sizeof(warning_buf), fmt, args);
+       warning_line = line;
+       warning_file = file;
+       va_end(args);
+}
+
 /**
  * See header.
  */
@@ -449,6 +479,25 @@ int test_failure_get(char *msg, int len, const char **file)
 /**
  * See header.
  */
+int test_warning_get(char *msg, int len, const char **file)
+{
+       int line = warning_line;
+
+       if (!line)
+       {
+               return 0;
+       }
+       strncpy(msg, warning_buf, len - 1);
+       msg[len - 1] = 0;
+       *file = warning_file;
+       /* reset state */
+       warning_line = 0;
+       return line;
+}
+
+/**
+ * See header.
+ */
 backtrace_t *test_failure_backtrace()
 {
        backtrace_t *bt;
index 97c1b42..9b9fcad 100644 (file)
@@ -220,6 +220,17 @@ void test_setup_timeout(int s);
 int test_failure_get(char *msg, int len, const char **file);
 
 /**
+ * Get info about a warning if one was issued during the test. Resets the
+ * warning state.
+ *
+ * @param msg          buffer receiving warning
+ * @param len          size of msg buffer
+ * @param file         pointer receiving source code file
+ * @return                     source code line number, 0 if no warning issued
+ */
+int test_warning_get(char *msg, int len, const char **file);
+
+/**
  * Get a backtrace for a failure.
  *
  * @return                     allocated backtrace of test failure, if any
@@ -247,6 +258,18 @@ void test_fail_vmsg(const char *file, int line, char *fmt, va_list args);
 void test_fail_msg(const char *file, int line, char *fmt, ...);
 
 /**
+ * Issue a warning for a particular test with a message using printf style
+ * arguments. This does not fail the test, and only the last warning for each
+ * test is kept.
+ *
+ * @param file         source code file name
+ * @param line         source code line number
+ * @param fmt          printf format string
+ * @param ...          arguments for fmt
+ */
+void test_warn_msg(const char *file, int line, char *fmt, ...);
+
+/**
  * Let a test fail if one of the worker threads has failed (only if called from
  * the main thread).
  */
@@ -345,6 +368,7 @@ void test_fail_if_worker_failed();
 #define ck_assert_msg test_assert_msg
 #define ck_assert_str_eq test_str_eq
 #define ck_assert_chunk_eq test_chunk_eq
+#define warn(fmt, ...) test_warn_msg(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
 #define fail(fmt, ...) test_fail_msg(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
 #define fail_if(x, fmt, ...) \
 ({ \