mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-03-11 17:08:46 +00:00
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
This commit is contained in:
parent
947018a7ef
commit
a84b9c62d1
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -89,5 +89,5 @@ main(int argc, char *argv[])
|
||||
|
||||
bt_test_suite(t_md5, "Test Suite from RFC1321");
|
||||
|
||||
return 0;
|
||||
return bt_end();
|
||||
}
|
||||
|
@ -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_log("Test case failed");
|
||||
exit(result);
|
||||
}
|
||||
|
||||
bt_note("OK");
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
fprintf(stderr, fmt_buf, msg_buf, to_right_align_msg);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
bt_end(void)
|
||||
{
|
||||
return !bt_success;
|
||||
}
|
||||
|
143
test/birdtest.h
143
test/birdtest.h
@ -13,24 +13,41 @@
|
||||
#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 0
|
||||
#define BT_FAILURE 1
|
||||
#define BT_SUCCESS 1
|
||||
#define BT_FAILURE 0
|
||||
|
||||
#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_test_case(fn,dsc) \
|
||||
bt_test_case4(fn, dsc, BT_DEFAULT_FORKING, BT_DEFAULT_TIMEOUT)
|
||||
#define BT_BUFFER_SIZE 1000
|
||||
|
||||
#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_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user