]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Birdtest: Improve the testing framework
authorPavel Tvrdík <pawel.tvrdik@gmail.cz>
Wed, 15 Apr 2015 09:51:24 +0000 (11:51 +0200)
committerPavel Tvrdík <pawel.tvrdik@gmail.cz>
Wed, 15 Apr 2015 09:51:24 +0000 (11:51 +0200)
- non-blocking asserts, only set bt_test_suite_success
- unification of testing output from bt_assert_fn_in_out and bt_assert_out_fn_in

test/birdtest.c
test/birdtest.h

index 2e628fbe9081ab6e5d9c4c2975c7aab3e0089372..134992690584387cced0a3b7b83523aeb02a9f73 100644 (file)
@@ -31,7 +31,7 @@ const char *bt_filename;
 const char *bt_test_id;
 
 int bt_success;
-int bt_test_case_success;
+int bt_test_suite_success;
 
 int
 bt_rand_num(void)
@@ -132,7 +132,7 @@ bt_test_suite5(int (*test_fn)(void), const char *test_id, const char *dsc, int f
     return;
 
   int result = 0;
-  bt_test_case_success = 1;
+  bt_test_suite_success = 1;
 
   bt_test_id = test_id;
 
@@ -143,6 +143,7 @@ bt_test_suite5(int (*test_fn)(void), const char *test_id, const char *dsc, int f
   {
     alarm(timeout);
     result = test_fn();
+    result &= bt_test_suite_success;
   }
   else
   {
@@ -153,6 +154,7 @@ bt_test_suite5(int (*test_fn)(void), const char *test_id, const char *dsc, int f
     {
       alarm(timeout);
       result = test_fn();
+      result &= bt_test_suite_success;
       _exit(result);
     }
 
@@ -199,11 +201,12 @@ bt_result(const char *to_right_align_msg, const char *to_left_align_msg, ...)
 {
   if (bt_verbose)
   {
-    va_list argptr;
-    va_start(argptr, to_left_align_msg);
     char msg_buf[BT_BUFFER_SIZE];
 
-    snprintf(msg_buf, sizeof(msg_buf), "%s: ", bt_filename);
+    snprintf(msg_buf, sizeof(char)*BT_BUFFER_SIZE, "%s: ", bt_filename);
+
+    va_list argptr;
+    va_start(argptr, to_left_align_msg);
     vsnprintf(msg_buf + strlen(msg_buf), sizeof(msg_buf), to_left_align_msg, argptr);
 
     char fmt_buf[BT_BUFFER_SIZE];
@@ -220,3 +223,14 @@ bt_end(void)
 {
   return !bt_success;
 }
+
+void
+bt_strncat_(char *buf, size_t buf_size, const char *str, ...)
+{
+  if (str != NULL)
+  {
+    va_list argptr;
+    va_start(argptr, str);
+    vsnprintf(buf + strlen(buf), buf_size, str, argptr);
+  }
+}
index c9c0598e54cbd53c995e618bc79f42f4cc6eec36..7edfa52a22ccfd1d2c9d26889538c1f2fd570e3e 100644 (file)
@@ -14,7 +14,7 @@
 #include <errno.h>
 
 extern int bt_success;
-extern int bt_test_case_success;
+extern int bt_test_suite_success;
 
 extern int bt_verbose;
 #define BT_VERBOSE_NOTHING             0
@@ -91,78 +91,114 @@ void bt_result(const char *result, const char *msg, ...);
 #define bt_assert(test) \
     bt_assert_msg(test, "Assertion (%s) failed at %s:%d", #test, __FILE__, __LINE__)
 
-#define bt_assert_msg(test, format, ...) \
-    do { if (!(test)) { \
-      if (bt_verbose) bt_log(format, ##__VA_ARGS__); \
-      bt_success = bt_test_case_success = 0; \
-    } } while (0)
+#define bt_equal(a, b) \
+    bt_assert_msg((a) == (b), "Assertion (%s == %s) failed at %s:%d.", #a, #b, __FILE__, __LINE__)
+
+#define bt_assert_msg(test, format, ...)                                               \
+    do                                                                                         \
+    {                                                                                  \
+      if (!(test))                                                                     \
+      {                                                                                \
+       if (bt_verbose)                                                                 \
+         bt_log(format, ##__VA_ARGS__);                                                \
+       bt_success = bt_test_suite_success = 0;                                         \
+      }                                                                                        \
+    } while (0)
 
 #define bt_syscall(test,format, ...) \
     do { if (test) { bt_log(format ": %s", ##__VA_ARGS__, strerror(errno)); exit(3); } } while (0)
 
-#define bt_assert_fn_in(fn, in_out, in_fmt, out_fmt)                                   \
+
+#define bt_strncat(buf, str, ...) \
+  snprintf(buf + strlen(buf), sizeof(buf), str, ##__VA_ARGS__)
+
+void bt_strncat_(char *buf, size_t buf_size, const char *str, ...);
+
+#define bt_dump_struct(buf, data)                                                      \
     do                                                                                 \
     {                                                                                  \
       unsigned int i;                                                                  \
-      for (i = 0; i < (sizeof(in_out)/sizeof(in_out[0])); i++)                         \
-      {                                                                                        \
-       int single_test_case_success = fn(in_out[i].in) == in_out[i].out;               \
-       bt_test_case_success &= single_test_case_success;                               \
-       if (single_test_case_success)                                                   \
-         bt_result_check_ok(BT_PROMPT_FN_GIVES(in_fmt) out_fmt, #fn, in_out[i].in, fn(in_out[i].in)); \
-       else                                                                            \
-         bt_result_check_fail(BT_PROMPT_FN_GIVES(in_fmt) out_fmt BT_PROMPT_EXPECTING out_fmt, #fn, in_out[i].in, fn(in_out[i].in), in_out[i].out); \
-      }                                                                                        \
+      u32 *pc = (u32*) data;                                                           \
+      bt_strncat(buf, "{");                                                            \
+      for (i = 0; i < (sizeof(*data) / sizeof(typeof(*pc))); i++)                      \
+       bt_strncat(buf, "%s0x%08X", (i ? ", " : ""), pc[i]);                            \
+      bt_strncat(buf, "}");                                                            \
     } while (0)
 
-#define bt_assert_fn_in_out(fn, in_out, in_fmt, out_fmt)                               \
+#define bt_dump(buf, data, fmt)                                                                \
     do                                                                                 \
     {                                                                                  \
-      unsigned int i;                                                                  \
-      for (i = 0; i < (sizeof(in_out)/sizeof(in_out[0])); i++)                         \
-      {                                                                                        \
-       fn(in_out[i].in, &in_out[i].fn_out);                                            \
-       int single_test_case_success = !memcmp(&in_out[i].fn_out, &in_out[i].out, sizeof(in_out[i].out)); \
-       bt_test_case_success &= single_test_case_success;                               \
-       if (single_test_case_success)                                                   \
-         bt_result_check_ok  (BT_PROMPT_FN_GIVES(in_fmt) out_fmt, #fn, in_out[i].in, in_out[i].fn_out); \
-       else                                                                            \
-         bt_result_check_fail(BT_PROMPT_FN_GIVES(in_fmt) out_fmt BT_PROMPT_EXPECTING out_fmt, #fn, in_out[i].in, in_out[i].fn_out, in_out[i].out); \
-      }                                                                                        \
+      if (fmt == NULL)                                                                 \
+       bt_dump_struct(buf, &data);                                                     \
+      else                                                                             \
+       bt_strncat_(buf, sizeof(buf), fmt, data);                                       \
     } while (0)
 
-#define bt_strcat(buf, str, ...) snprintf(buf + strlen(buf), sizeof(buf), str, ##__VA_ARGS__)
+#define bt_print_result_line(fn, in, out, fn_out, in_fmt, out_fmt, result)             \
+    do                                                                                 \
+    {                                                                                  \
+      char buf[BT_BUFFER_SIZE];                                                                \
+      strcpy(buf, "");                                                                 \
+      snprintf(buf, sizeof(buf), "%s(", #fn);                                          \
+      bt_dump(buf, in, in_fmt);                                                                \
+      bt_strncat(buf, ") gives ");                                                     \
+      bt_dump(buf, fn_out, out_fmt);                                                   \
+      if (!result)                                                                     \
+      {                                                                                        \
+       bt_strncat(buf, BT_PROMPT_EXPECTING);                                           \
+       bt_dump(buf, out, out_fmt);                                                     \
+      }                                                                                \
+      bt_result_check((single_test_case_success ? BT_PROMPT_OK : BT_PROMPT_FAIL), "%s", buf); \
+    } while (0)
 
-#define bt_dump_struct(buf, data)                                                      \
+/**
+ * Usage:
+ *     u32 my_function(const char *input_data) { ... }
+ *
+ *     struct in_out {
+ *                     char *in;
+ *             u32  out;
+ *     } in_out[] = { ... };
+ *
+ *     bt_assert_out_fn_in(my_function, in_out, "%s", "%u");
+ */
+#define bt_assert_out_fn_in(fn, in_out, in_fmt, out_fmt)                               \
     do                                                                                 \
     {                                                                                  \
-      unsigned int bt_j;                                                               \
-      u32 *bt_pc = (u32*) data;                                                                \
-      bt_strcat(buf, "{");                                                             \
-      for (bt_j = 0; bt_j < (sizeof(*data) / sizeof(typeof(*bt_pc))); bt_j++)          \
-       bt_strcat(buf, "%s0x%08X", (bt_j ? ", " : ""), bt_pc[bt_j]);                    \
-      bt_strcat(buf, "}");                                                             \
+      unsigned int i;                                                                  \
+      for (i = 0; i < (sizeof(in_out)/sizeof(in_out[0])); i++)                         \
+      {                                                                                        \
+       typeof(in_out[i].out) fn_out = fn(in_out[i].in);                                \
+       int single_test_case_success = (fn(in_out[i].in) == in_out[i].out);             \
+       bt_test_suite_success &= single_test_case_success;                              \
+       bt_print_result_line(fn, in_out[i].in, in_out[i].out, fn_out, in_fmt, out_fmt, single_test_case_success); \
+      }                                                                                        \
     } while (0)
 
-#define bt_assert_fn_in_out_struct(fn, in_out, in_fmt)                                 \
+/**
+ * Usage:
+ *     void my_function(const char *input_data, u32 *output_data) { ... }
+ *
+ *     struct in_out {
+ *                     char *in;
+ *             u32  out;
+ *     } in_out[] = { ... };
+ *
+ *     bt_assert_fn_in_out(my_function, in_out, "%s", "%u");
+ */
+#define bt_assert_fn_in_out(fn, in_out, in_fmt, out_fmt)                               \
     do                                                                                 \
     {                                                                                  \
-      char bt_buf[BT_BUFFER_SIZE];                                                     \
       unsigned int i;                                                                  \
       for (i = 0; i < (sizeof(in_out)/sizeof(in_out[0])); i++)                         \
       {                                                                                        \
-       strcpy(bt_buf, "");                                                             \
-       fn(in_out[i].in, &in_out[i].fn_out);                                            \
-       int single_test_case_success = !memcmp(&in_out[i].fn_out, in_out[i].out, sizeof(in_out[i].out)); \
-       bt_test_case_success &= single_test_case_success;                               \
-       bt_strcat(bt_buf, BT_PROMPT_FN_GIVES(in_fmt), #fn, in_out[i].in);               \
-       bt_dump_struct(bt_buf, &in_out[i].fn_out);                                      \
-       if (!single_test_case_success)                                                  \
-       {                                                                               \
-         bt_strcat(bt_buf, BT_PROMPT_EXPECTING);                                       \
-         bt_dump_struct(bt_buf, &in_out[i].out);                                       \
-       }                                                                               \
-       bt_result_check((single_test_case_success ? BT_PROMPT_OK : BT_PROMPT_FAIL), "%s", bt_buf); \
+       typeof(in_out[i].out) fn_out;                                                   \
+       memset(&fn_out, '\0', sizeof(fn_out));                                          \
+       fn(in_out[i].in, &fn_out);                                                      \
+       int single_test_case_success = !memcmp(&fn_out, &in_out[i].out, sizeof(in_out[i].out)); \
+       bt_test_suite_success &= single_test_case_success;                              \
+                                                                                       \
+       bt_print_result_line(fn, in_out[i].in, in_out[i].out, fn_out, in_fmt, out_fmt, single_test_case_success); \
       }                                                                                        \
     } while (0)