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