mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-24 09:51:54 +00:00
Birdtest: Improve the testing framework
- 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
This commit is contained in:
parent
84dbe05f93
commit
1ce8d33b80
@ -31,7 +31,7 @@ const char *bt_filename;
|
|||||||
const char *bt_test_id;
|
const char *bt_test_id;
|
||||||
|
|
||||||
int bt_success;
|
int bt_success;
|
||||||
int bt_test_case_success;
|
int bt_test_suite_success;
|
||||||
|
|
||||||
int
|
int
|
||||||
bt_rand_num(void)
|
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;
|
return;
|
||||||
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
bt_test_case_success = 1;
|
bt_test_suite_success = 1;
|
||||||
|
|
||||||
bt_test_id = test_id;
|
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);
|
alarm(timeout);
|
||||||
result = test_fn();
|
result = test_fn();
|
||||||
|
result &= bt_test_suite_success;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -153,6 +154,7 @@ bt_test_suite5(int (*test_fn)(void), const char *test_id, const char *dsc, int f
|
|||||||
{
|
{
|
||||||
alarm(timeout);
|
alarm(timeout);
|
||||||
result = test_fn();
|
result = test_fn();
|
||||||
|
result &= bt_test_suite_success;
|
||||||
_exit(result);
|
_exit(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,11 +201,12 @@ bt_result(const char *to_right_align_msg, const char *to_left_align_msg, ...)
|
|||||||
{
|
{
|
||||||
if (bt_verbose)
|
if (bt_verbose)
|
||||||
{
|
{
|
||||||
va_list argptr;
|
|
||||||
va_start(argptr, to_left_align_msg);
|
|
||||||
char msg_buf[BT_BUFFER_SIZE];
|
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);
|
vsnprintf(msg_buf + strlen(msg_buf), sizeof(msg_buf), to_left_align_msg, argptr);
|
||||||
|
|
||||||
char fmt_buf[BT_BUFFER_SIZE];
|
char fmt_buf[BT_BUFFER_SIZE];
|
||||||
@ -220,3 +223,14 @@ bt_end(void)
|
|||||||
{
|
{
|
||||||
return !bt_success;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
146
test/birdtest.h
146
test/birdtest.h
@ -14,7 +14,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
extern int bt_success;
|
extern int bt_success;
|
||||||
extern int bt_test_case_success;
|
extern int bt_test_suite_success;
|
||||||
|
|
||||||
extern int bt_verbose;
|
extern int bt_verbose;
|
||||||
#define BT_VERBOSE_NOTHING 0
|
#define BT_VERBOSE_NOTHING 0
|
||||||
@ -91,78 +91,114 @@ void bt_result(const char *result, const char *msg, ...);
|
|||||||
#define bt_assert(test) \
|
#define bt_assert(test) \
|
||||||
bt_assert_msg(test, "Assertion (%s) failed at %s:%d", #test, __FILE__, __LINE__)
|
bt_assert_msg(test, "Assertion (%s) failed at %s:%d", #test, __FILE__, __LINE__)
|
||||||
|
|
||||||
#define bt_assert_msg(test, format, ...) \
|
#define bt_equal(a, b) \
|
||||||
do { if (!(test)) { \
|
bt_assert_msg((a) == (b), "Assertion (%s == %s) failed at %s:%d.", #a, #b, __FILE__, __LINE__)
|
||||||
if (bt_verbose) bt_log(format, ##__VA_ARGS__); \
|
|
||||||
bt_success = bt_test_case_success = 0; \
|
#define bt_assert_msg(test, format, ...) \
|
||||||
} } while (0)
|
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, ...) \
|
#define bt_syscall(test,format, ...) \
|
||||||
do { if (test) { bt_log(format ": %s", ##__VA_ARGS__, strerror(errno)); exit(3); } } while (0)
|
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; \
|
||||||
|
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_dump(buf, data, fmt) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (fmt == NULL) \
|
||||||
|
bt_dump_struct(buf, &data); \
|
||||||
|
else \
|
||||||
|
bt_strncat_(buf, sizeof(buf), fmt, data); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#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)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 \
|
do \
|
||||||
{ \
|
{ \
|
||||||
unsigned int i; \
|
unsigned int i; \
|
||||||
for (i = 0; i < (sizeof(in_out)/sizeof(in_out[0])); 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; \
|
typeof(in_out[i].out) fn_out = fn(in_out[i].in); \
|
||||||
bt_test_case_success &= single_test_case_success; \
|
int single_test_case_success = (fn(in_out[i].in) == in_out[i].out); \
|
||||||
if (single_test_case_success) \
|
bt_test_suite_success &= 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)); \
|
bt_print_result_line(fn, in_out[i].in, in_out[i].out, fn_out, in_fmt, out_fmt, single_test_case_success); \
|
||||||
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)
|
} while (0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) \
|
#define bt_assert_fn_in_out(fn, in_out, in_fmt, out_fmt) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
unsigned int i; \
|
unsigned int i; \
|
||||||
for (i = 0; i < (sizeof(in_out)/sizeof(in_out[0])); i++) \
|
for (i = 0; i < (sizeof(in_out)/sizeof(in_out[0])); i++) \
|
||||||
{ \
|
{ \
|
||||||
fn(in_out[i].in, &in_out[i].fn_out); \
|
typeof(in_out[i].out) fn_out; \
|
||||||
int single_test_case_success = !memcmp(&in_out[i].fn_out, &in_out[i].out, sizeof(in_out[i].out)); \
|
memset(&fn_out, '\0', sizeof(fn_out)); \
|
||||||
bt_test_case_success &= single_test_case_success; \
|
fn(in_out[i].in, &fn_out); \
|
||||||
if (single_test_case_success) \
|
int single_test_case_success = !memcmp(&fn_out, &in_out[i].out, sizeof(in_out[i].out)); \
|
||||||
bt_result_check_ok (BT_PROMPT_FN_GIVES(in_fmt) out_fmt, #fn, in_out[i].in, in_out[i].fn_out); \
|
bt_test_suite_success &= single_test_case_success; \
|
||||||
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); \
|
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_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)
|
} while (0)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user