]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Birdtest: Add bt_assert_fn_in_*
authorPavel Tvrdík <pawel.tvrdik@gmail.cz>
Mon, 13 Apr 2015 08:52:21 +0000 (10:52 +0200)
committerPavel Tvrdík <pawel.tvrdik@gmail.cz>
Mon, 13 Apr 2015 08:52:21 +0000 (10:52 +0200)
- Improved test output formating: aligned, colored [ OK ] / [FAIL]
- A failed assert will not interupt the whole test suite
- bt_assert_fn_in_* are macros for testing input and output from the some
  function

lib/bitops_test.c
lib/buffer_test.c
lib/checksum_test.c
lib/event_test.c
lib/hash_test.c
lib/heap_test.c
lib/ip_test.c
lib/md5_test.c
test/birdtest.c
test/birdtest.h

index 563c1b2d6e59d0e1afce54292304033714ad12e9..6014662566fd70b1356424b6ff728f95dc378962 100644 (file)
@@ -120,7 +120,7 @@ t_log2(void)
     in_out_data[i].in  = pow2(i+1);
     in_out_data[i].out = i+1;
   }
-  bt_check(u32_log2, in_out_data, "%u", "%u");
+  bt_assert_fn_in(u32_log2, in_out_data, "%u", "%u");
 
   u32_log2(0);
 
@@ -142,5 +142,5 @@ main(int argc, char *argv[])
   bt_test_suite(t_masklen, "u32_masklen()");
   bt_test_suite(t_log2, "u32_log2()");
 
-  return 0;
+  return bt_end();
 }
index 0ee9f3b4782b0e54cb8922c0396c50fc4d3369d0..77e161a528d95e3b1616699111e60e68719078f3 100644 (file)
@@ -150,7 +150,7 @@ main(int argc, char *argv[])
   bt_test_suite(t_buffer_resize, "Init a small buffer and try overfill");
   bt_test_suite(t_buffer_flush, "Fill and flush all elements");
 
-  return 0;
+  return bt_end();
 }
 
 
index 868529a65551e85b8cd81dccea5ad2c8993c6067..690cd2e24415f1a997ea4d50cae2a260832b4585 100644 (file)
@@ -94,7 +94,7 @@ main(int argc, char *argv[])
   bt_test_suite(t_calculate, "Checksum of pseudo-random data");
   bt_test_suite(t_verify, "Verification of pseudo-random data.");
 
-  return 0;
+  return bt_end();
 }
 
 /* Mockup */
index 53ffcd3517bca1d0add9ef51fc6265c150dcc029..a461b92efb2ea1acbf176f87261bbed6eb38c61b 100644 (file)
@@ -72,6 +72,6 @@ main(int argc, char *argv[])
 
   bt_test_suite(t_ev_run_list, "Schedule and run 3 events in right order.");
 
-  return 0;
+  return bt_end();
 }
 
index aacc6a7e3940179d88a3f39ab04d8cecbd1f475f..d33765eff6aabb835ff84ae2c14bd991926cbee1 100644 (file)
@@ -301,5 +301,5 @@ main(int argc, char *argv[])
 //bt_test_case(t_walk_delsafe_remove2, "HASH_WALK_DELSAFE and HASH_REMOVE2. HASH_REMOVE2 is HASH_REMOVE and smart auto-resize function");
   bt_test_suite(t_walk_filter,         "HASH_WALK_FILTER");
 
-  return 0;
+  return bt_end();
 }
index 83f6def1e4c43fb30769166078974739cd508f0d..8fde031ec4429d834f466c7afd23ad55b5ebb7b8 100644 (file)
@@ -181,5 +181,5 @@ main(int argc, char *argv[])
   bt_test_suite(t_heap_delete, "Deleting");
   bt_test_suite(t_heap_0, "Is a heap[0] really unused?");
 
-  return 0;
+  return bt_end();
 }
index 1d97391fc6fe02747fe3e2c270f5aa2fd5ae9325..658005763a017006ed3ea571c75fbea3d63afe40 100644 (file)
@@ -62,9 +62,9 @@ t_ip4_pton(void)
       },
   };
 
-  bt_check(ip4_pton_, in_out_data, "%s", "0x%08X");
+  bt_assert_fn_in(ip4_pton_, in_out_data, "%s", "0x%08X");
 
-  return BT_SUCCESS;
+  return bt_test_case_success;
 }
 
 int
@@ -74,6 +74,6 @@ main(int argc, char *argv[])
 
   bt_test_suite(t_ip4_pton, "Converting IPv4 string to ip4_addr struct");
 
-  return 0;
+  return bt_end();
 }
 
index 601c7e2a4b0e1648b8a3a5e2452f6c1e7922ab98..45fb8c8e37f5a5a3bd7e5766034227266ee92a21 100644 (file)
@@ -89,5 +89,5 @@ main(int argc, char *argv[])
 
   bt_test_suite(t_md5, "Test Suite from RFC1321");
 
-  return 0;
+  return bt_end();
 }
index 18560aa18f1c6578effa583455400398a3906899..2e628fbe9081ab6e5d9c4c2975c7aab3e0089372 100644 (file)
@@ -4,14 +4,16 @@
  *     Can be freely distributed and used under the terms of the GNU GPL.
  */
 
+#include <stdarg.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <stdint.h>
 #include <string.h>
-#include <unistd.h>
 #include <signal.h>
+#include <unistd.h>
 #include <execinfo.h>
 
+#include <sys/ioctl.h>
 #include <sys/resource.h>
 #include <sys/wait.h>
 
@@ -28,6 +30,9 @@ int bt_verbose;
 const char *bt_filename;
 const char *bt_test_id;
 
+int bt_success;
+int bt_test_case_success;
+
 int
 bt_rand_num(void)
 {
@@ -40,10 +45,12 @@ bt_init(int argc, char *argv[])
 {
   int c;
 
+  bt_success = 1;
   srandom(BT_RANDOM_SEED);
 
   bt_verbose = 0;
   bt_filename = argv[0];
+  bt_test_id = NULL;
 
   while ((c = getopt(argc, argv, "lcftv")) >= 0)
     switch (c)
@@ -125,10 +132,12 @@ 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_id = test_id;
 
-  bt_note("Starting %s: %s", test_id, dsc);
+  if (bt_verbose >= BT_VERBOSE_DEBUG)
+    bt_log("Starting");
 
   if (!forked)
   {
@@ -172,12 +181,42 @@ bt_test_suite5(int (*test_fn)(void), const char *test_id, const char *dsc, int f
       bt_log("Core dumped");
   }
 
-  if (result != BT_SUCCESS)
+  bt_success &= (result == BT_SUCCESS ? 1 : 0);
+  bt_result((result == BT_SUCCESS ? BT_PROMPT_OK : BT_PROMPT_FAIL), "%s", bt_test_id);
+  bt_test_id = NULL;
+}
+
+static uint
+get_num_terminal_cols(void)
+{
+  struct winsize w;
+  ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
+  return w.ws_col;
+}
+
+void
+bt_result(const char *to_right_align_msg, const char *to_left_align_msg, ...)
+{
+  if (bt_verbose)
   {
-    bt_log("Test case failed");
-    exit(result);
-  }
+    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);
+    vsnprintf(msg_buf + strlen(msg_buf), sizeof(msg_buf), to_left_align_msg, argptr);
+
+    char fmt_buf[BT_BUFFER_SIZE];
+    uint line_len = strlen(msg_buf) + BT_PROMPT_OK_FAIL_LEN;
+    uint left_offset = (line_len / get_num_terminal_cols() + 1) * get_num_terminal_cols() - BT_PROMPT_OK_FAIL_LEN;
+    snprintf(fmt_buf, sizeof(fmt_buf), "%%-%us%%s\n", left_offset);
 
-  bt_note("OK");
+    fprintf(stderr, fmt_buf, msg_buf, to_right_align_msg);
+  }
 }
 
+int
+bt_end(void)
+{
+  return !bt_success;
+}
index d88b112177537294a5e3e756046e5bf5f0489f42..c9c0598e54cbd53c995e618bc79f42f4cc6eec36 100644 (file)
 #include <string.h>
 #include <errno.h>
 
+extern int bt_success;
+extern int bt_test_case_success;
+
 extern int bt_verbose;
+#define BT_VERBOSE_NOTHING             0
+#define BT_VERBOSE_TEST_CASE           1
+#define BT_VERBOSE_DEBUG               2
+
 extern const char *bt_filename;
 extern const char *bt_test_id;
 
 void bt_init(int argc, char *argv[]);
+int  bt_end(void);
 void bt_test_suite5(int (*fn)(void), const char *id, const char *dsc, int forked, int timeout);
 int  bt_rand_num(void);
+void bt_result(const char *result, const char *msg, ...);
+
+#define BT_SUCCESS                     1
+#define BT_FAILURE                     0
 
-#define BT_SUCCESS 0
-#define BT_FAILURE 1
+#define BT_DEFAULT_TIMEOUT             5
+#define BT_DEFAULT_FORKING             1
 
-#define BT_DEFAULT_TIMEOUT 5
-#define BT_DEFAULT_FORKING 1
+#define BT_RANDOM_SEED                         982451653
 
-#define BT_RANDOM_SEED 982451653
+#define BT_BUFFER_SIZE                         1000
 
-#define bt_test_case(fn,dsc) \
-    bt_test_case4(fn, dsc, BT_DEFAULT_FORKING, BT_DEFAULT_TIMEOUT)
+#define BT_PROMPT_GREEN                "\e[1;32m"
+#define BT_PROMPT_RED                  "\e[1;31m"
+#define BT_PROMPT_NORMAL               "\e[0m"
+#define BT_PROMPT_OK                   " [" BT_PROMPT_GREEN " OK " BT_PROMPT_NORMAL "] "
+#define BT_PROMPT_FAIL                 " [" BT_PROMPT_RED   "FAIL" BT_PROMPT_NORMAL "] "
+#define BT_PROMPT_OK_FAIL_LEN          8
+#define BT_PROMPT_FN_GIVES(in_fmt)     "%s(" in_fmt ") gives "
+#define BT_PROMPT_EXPECTING            ", but expecting is "
 
 #define bt_test_suite(fn,dsc) \
     bt_test_suite4(fn, dsc, BT_DEFAULT_FORKING, BT_DEFAULT_TIMEOUT)
@@ -39,13 +56,31 @@ int  bt_rand_num(void);
     bt_test_suite5(fn, #fn, dsc, f, t)
 
 #define bt_log(format, ...) \
-    fprintf(stderr, "%s: " format "\n", bt_filename, ##__VA_ARGS__)
+  do { \
+    if (bt_test_id == NULL) \
+      fprintf(stderr, "%s: " format "\n", bt_filename, ##__VA_ARGS__); \
+    else \
+      fprintf(stderr, "%s: %s: " format "\n", bt_filename, bt_test_id, ##__VA_ARGS__); \
+  } while(0)
 
-#define bt_note(format, ...) \
-    do { if (bt_verbose) bt_log(format, ##__VA_ARGS__); } while (0)
+#define bt_log_test_case(format, ...) \
+    do { if (bt_verbose >= BT_VERBOSE_TEST_CASE) bt_log(format, ##__VA_ARGS__); } while (0)
 
 #define bt_debug(format, ...) \
-    do { if (bt_verbose > 1) printf(format, ##__VA_ARGS__); } while (0)
+    do { if (bt_verbose >= BT_VERBOSE_DEBUG) printf(format, ##__VA_ARGS__); } while (0)
+
+#define bt_result_(result, format, ...)        bt_result(result, "%s: " format, bt_test_id, ##__VA_ARGS__)
+#define bt_result_ok(format, ...)      bt_result_(BT_PROMPT_OK,   format, ##__VA_ARGS__)
+#define bt_result_fail(format, ...)    bt_result_(BT_PROMPT_FAIL, format, ##__VA_ARGS__)
+
+#define bt_result_check(result, format, ...) \
+    do { if (bt_verbose >= BT_VERBOSE_TEST_CASE) bt_result_(result, format, ##__VA_ARGS__); } while (0)
+
+#define bt_result_check_ok(format, ...) \
+  do { if (bt_verbose >= BT_VERBOSE_TEST_CASE) bt_result_ok(format, ##__VA_ARGS__); } while (0)
+
+#define bt_result_check_fail(format, ...) \
+  do { if (bt_verbose >= BT_VERBOSE_TEST_CASE) bt_result_fail(format, ##__VA_ARGS__); } while (0)
 
 #define bt_abort() \
     bt_abort_msg("Aborted at %s:%d", __FILE__, __LINE__)
@@ -56,23 +91,79 @@ int  bt_rand_num(void);
 #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)) bt_abort_msg(format, ##__VA_ARGS__); } while (0)
+#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_syscall(test,format, ...)                   \
+#define bt_syscall(test,format, ...) \
     do { if (test) { bt_log(format ": %s", ##__VA_ARGS__, strerror(errno)); exit(3); } } while (0)
 
-#define bt_check(fn, in_out, in_fmt, out_fmt)                          \
-  do                                                                   \
-  {                                                                    \
-    unsigned int bt_i;                                                 \
-    for (bt_i = 0; bt_i < (sizeof(in_out)/sizeof(in_out[0])); bt_i++)  \
-    {                                                                  \
-      if (fn(in_out[bt_i].in) == in_out[bt_i].out)                     \
-       bt_debug    ("[ OK ] %s(" in_fmt ") got " out_fmt " \n", #fn, in_out[bt_i].in, fn(in_out[bt_i].in)); \
-      else                                                             \
-       bt_abort_msg("[FAIL] %s(" in_fmt ") got " out_fmt ", but was expected " out_fmt " \n", #fn, in_out[bt_i].in, fn(in_out[bt_i].in), in_out[bt_i].out); \
-    }                                                                  \
-  } while(0)
+#define bt_assert_fn_in(fn, in_out, in_fmt, out_fmt)                                   \
+    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); \
+      }                                                                                        \
+    } while (0)
+
+#define bt_assert_fn_in_out(fn, in_out, in_fmt, out_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); \
+      }                                                                                        \
+    } while (0)
+
+#define bt_strcat(buf, str, ...) snprintf(buf + strlen(buf), sizeof(buf), str, ##__VA_ARGS__)
+
+#define bt_dump_struct(buf, data)                                                      \
+    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, "}");                                                             \
+    } while (0)
+
+#define bt_assert_fn_in_out_struct(fn, in_out, in_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); \
+      }                                                                                        \
+    } while (0)
 
 #endif /* _BIRDTEST_H_ */