1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
/*
* BIRD -- Unit Test Framework (BIRD Test)
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#ifndef _BIRDTEST_H_
#define _BIRDTEST_H_
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include "nest/bird.h"
extern int bt_result;
extern int bt_suite_result;
extern char bt_out_fmt_buf[1024];
extern uint bt_verbose;
#define BT_VERBOSE_NO 0
#define BT_VERBOSE_SUITE 1
#define BT_VERBOSE_SUITE_CASE 2
#define BT_VERBOSE_ABSOLUTELY_ALL 3
extern const char *bt_filename;
extern const char *bt_test_id;
void bt_init(int argc, char *argv[]);
int bt_exit_value(void);
void bt_reset_suite_case_timer(void);
int bt_test_suite_base(int (*test_fn)(const void *), const char *test_id, const void *test_fn_argument, int forked, int timeout, const char *dsc, ...);
static inline u64 bt_random(void)
{ return ((u64) random() & 0xffffffff) | ((u64) random() << 32); }
static inline u32 bt_random_n(u32 max)
{ return random() % max; }
void bt_log_suite_result(int result, const char *fmt, ...);
void bt_log_suite_case_result(int result, const char *fmt, ...);
#define BT_TIMEOUT 60 /* Default timeout in seconds */
#define BT_FORKING 1 /* Forking is enabled in default */
#define BT_RANDOM_SEED 0x5097d2bb
#define BT_BUFFER_SIZE 10000
#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_OK_NO_COLOR " [" " OK " "] "
#define BT_PROMPT_FAIL " [" BT_PROMPT_RED "FAIL" BT_PROMPT_NORMAL "] "
#define BT_PROMPT_FAIL_NO_COLOR " [" "FAIL" "] "
#define BT_PROMPT_OK_FAIL_STRLEN 8 /* strlen ' [FAIL] ' */
static inline int bt_test_fn_noarg(const void *cp) { return ((int (*)(void)) cp)(); }
#define bt_test_suite(fn, dsc, ...) \
bt_test_suite_extra(fn, BT_FORKING, BT_TIMEOUT, dsc, ##__VA_ARGS__)
#define bt_test_suite_extra(fn, f, t, dsc, ...) \
bt_test_suite_base(bt_test_fn_noarg, #fn, fn, f, t, dsc, ##__VA_ARGS__)
#define bt_test_suite_arg(fn, arg, dsc, ...) \
bt_test_suite_arg_extra(fn, arg, BT_FORKING, BT_TIMEOUT, dsc, ##__VA_ARGS__)
#define bt_test_suite_arg_extra(fn, arg, f, t, dsc, ...) \
bt_test_suite_base(fn, #fn, arg, f, t, dsc, ##__VA_ARGS__)
#define bt_abort() \
bt_abort_msg("Aborted at %s:%d", __FILE__, __LINE__)
#define bt_abort_msg(format, ...) \
do \
{ \
bt_log(format, ##__VA_ARGS__); \
abort(); \
} while (0)
#define bt_log(format, ...) \
do \
{ \
if (bt_test_id) \
printf("%s: %s: " format "\n", bt_filename, bt_test_id, ##__VA_ARGS__); \
else \
printf("%s: " format "\n", bt_filename, ##__VA_ARGS__); \
} while(0)
#define bt_debug(format, ...) \
do \
{ \
if (bt_verbose >= BT_VERBOSE_ABSOLUTELY_ALL) \
printf(format, ##__VA_ARGS__); \
} while (0)
#define bt_assert(test) \
bt_assert_msg(test, "Assertion (%s) at %s:%d", #test, __FILE__, __LINE__)
#define bt_assert_msg(test, format, ...) \
do \
{ \
int bt_suit_case_result = 1; \
if ((test) == 0) \
{ \
bt_result = 0; \
bt_suite_result = 0; \
bt_suit_case_result = 0; \
} \
bt_log_suite_case_result(bt_suit_case_result, format, ##__VA_ARGS__); \
} while (0)
#define bt_syscall(test, format, ...) \
do \
{ \
if (test) \
{ \
bt_log(format ": %s", ##__VA_ARGS__, strerror(errno)); \
exit(3); \
} \
} while (0)
#define bt_sprintf_concat(s, format, ...) \
snprintf(s + strlen(s), sizeof(s) - strlen(s), format, ##__VA_ARGS__)
struct bt_pair {
const void *in;
const void *out;
};
/* Data structure used by bt_assert_batch() function */
struct bt_batch {
/* in_fmt / out_fmt - formating data
* @buf: buffer for write stringified @data
* @size: empty size in @buf
* @data: data for stringify
*
* There are some build-in functions, see bt_fmt_* functions */
void (*in_fmt)(char *buf, size_t size, const void *data);
void (*out_fmt)(char *buf, size_t size, const void *data);
/* Temporary output buffer */
void *out_buf;
/* test_fn - testing function
* @out: output data from tested function
* @in: data for input
* @expected_out: expected data from tested function
*
* Input arguments should not be stringified using in_fmt() or out_fmt()
* function already. This function should return only 0 or 1 */
int (*test_fn)(void *out, const void *in, const void *expected_out);
/* Name of testing function @test_fn */
const char *test_fn_name;
/* Number of items in data */
int ndata;
/* Array of input and expected output pairs */
struct bt_pair *data;
};
void bt_fmt_str(char *buf, size_t size, const void *data);
void bt_fmt_unsigned(char *buf, size_t size, const void *data);
void bt_fmt_ipa(char *buf, size_t size, const void *data);
void bt_format_net(char *buf, size_t size, const void *data);
int bt_assert_batch__(struct bt_batch *opts);
int bt_is_char(byte c);
#define bt_assert_batch(data__, fn__, in_fmt__, out_fmt__) \
bt_assert_batch__(& (struct bt_batch) { \
.data = data__, \
.ndata = ARRAY_SIZE(data__), \
.test_fn = fn__, \
.test_fn_name = #fn__, \
.in_fmt = in_fmt__, \
.out_fmt = out_fmt__, \
.out_buf = bt_out_fmt_buf, /* Global memory for this usage */ \
})
#endif /* _BIRDTEST_H_ */
|