From: Pavel TvrdĂ­k Date: Mon, 13 Apr 2015 08:52:21 +0000 (+0200) Subject: Birdtest: Add bt_assert_fn_in_* X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a84b9c62d1765cc881ae8f3fe181d062d2a00c34;p=thirdparty%2Fbird.git Birdtest: Add bt_assert_fn_in_* - 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 --- diff --git a/lib/bitops_test.c b/lib/bitops_test.c index 563c1b2d6..601466256 100644 --- a/lib/bitops_test.c +++ b/lib/bitops_test.c @@ -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(); } diff --git a/lib/buffer_test.c b/lib/buffer_test.c index 0ee9f3b47..77e161a52 100644 --- a/lib/buffer_test.c +++ b/lib/buffer_test.c @@ -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(); } diff --git a/lib/checksum_test.c b/lib/checksum_test.c index 868529a65..690cd2e24 100644 --- a/lib/checksum_test.c +++ b/lib/checksum_test.c @@ -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 */ diff --git a/lib/event_test.c b/lib/event_test.c index 53ffcd351..a461b92ef 100644 --- a/lib/event_test.c +++ b/lib/event_test.c @@ -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(); } diff --git a/lib/hash_test.c b/lib/hash_test.c index aacc6a7e3..d33765eff 100644 --- a/lib/hash_test.c +++ b/lib/hash_test.c @@ -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(); } diff --git a/lib/heap_test.c b/lib/heap_test.c index 83f6def1e..8fde031ec 100644 --- a/lib/heap_test.c +++ b/lib/heap_test.c @@ -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(); } diff --git a/lib/ip_test.c b/lib/ip_test.c index 1d97391fc..658005763 100644 --- a/lib/ip_test.c +++ b/lib/ip_test.c @@ -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(); } diff --git a/lib/md5_test.c b/lib/md5_test.c index 601c7e2a4..45fb8c8e3 100644 --- a/lib/md5_test.c +++ b/lib/md5_test.c @@ -89,5 +89,5 @@ main(int argc, char *argv[]) bt_test_suite(t_md5, "Test Suite from RFC1321"); - return 0; + return bt_end(); } diff --git a/test/birdtest.c b/test/birdtest.c index 18560aa18..2e628fbe9 100644 --- a/test/birdtest.c +++ b/test/birdtest.c @@ -4,14 +4,16 @@ * Can be freely distributed and used under the terms of the GNU GPL. */ +#include +#include #include #include -#include #include -#include #include +#include #include +#include #include #include @@ -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; +} diff --git a/test/birdtest.h b/test/birdtest.h index d88b11217..c9c0598e5 100644 --- a/test/birdtest.h +++ b/test/birdtest.h @@ -13,24 +13,41 @@ #include #include +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_ */