| 
									
										
										
										
											2016-11-09 16:36:34 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *	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); | 
					
						
							| 
									
										
										
										
											2021-09-25 16:00:30 +02:00
										 |  |  | void bt_reset_suite_case_timer(void); | 
					
						
							| 
									
										
										
										
											2016-11-09 16:36:34 +01:00
										 |  |  | 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, ...); | 
					
						
							| 
									
										
										
										
											2019-07-09 14:34:26 +02:00
										 |  |  | static inline u64 bt_random(void) | 
					
						
							|  |  |  | { return ((u64) random() & 0xffffffff) | ((u64) random() << 32); } | 
					
						
							| 
									
										
										
										
											2016-11-09 16:36:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | void bt_log_suite_result(int result, const char *fmt, ...); | 
					
						
							|  |  |  | void bt_log_suite_case_result(int result, const char *fmt, ...); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define BT_TIMEOUT 			5	/* Default timeout in seconds */
 | 
					
						
							|  |  |  | #define BT_FORKING 			1	/* Forking is enabled in default */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-09 14:34:26 +02:00
										 |  |  | #define BT_RANDOM_SEED 			0x5097d2bb
 | 
					
						
							| 
									
										
										
										
											2016-11-09 16:36:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #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] ' */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-08 11:19:04 +01:00
										 |  |  | static inline int bt_test_fn_noarg(const void *cp) { return ((int (*)(void)) cp)(); } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-09 16:36:34 +01:00
										 |  |  | #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, ...) \
 | 
					
						
							| 
									
										
										
										
											2019-02-08 11:19:04 +01:00
										 |  |  |   bt_test_suite_base(bt_test_fn_noarg, #fn, fn, f, t, dsc, ##__VA_ARGS__) | 
					
						
							| 
									
										
										
										
											2016-11-09 16:36:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #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									\ | 
					
						
							|  |  |  |   {									\ | 
					
						
							| 
									
										
										
										
											2019-12-17 00:01:53 +01:00
										 |  |  |     int bt_suit_case_result = 1;					\ | 
					
						
							| 
									
										
										
										
											2016-11-09 16:36:34 +01:00
										 |  |  |     if ((test) == 0) 							\ | 
					
						
							|  |  |  |     {									\ | 
					
						
							| 
									
										
										
										
											2019-12-17 00:01:53 +01:00
										 |  |  |       bt_result = 0;							\ | 
					
						
							|  |  |  |       bt_suite_result = 0;						\ | 
					
						
							|  |  |  |       bt_suit_case_result = 0;						\ | 
					
						
							| 
									
										
										
										
											2016-11-09 16:36:34 +01:00
										 |  |  |     }									\ | 
					
						
							|  |  |  |     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() | 
					
						
							| 
									
										
										
										
											2016-11-11 17:43:09 +01:00
										 |  |  |    * function already. This function should return only 0 or 1 */ | 
					
						
							| 
									
										
										
										
											2016-11-09 16:36:34 +01:00
										 |  |  |   int (*test_fn)(void *out, const void *in, const void *expected_out); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Name of testing function @test_fn */ | 
					
						
							|  |  |  |   const char *test_fn_name; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-11 17:43:09 +01:00
										 |  |  |   /* Number of items in data */ | 
					
						
							| 
									
										
										
										
											2016-11-09 16:36:34 +01:00
										 |  |  |   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); | 
					
						
							| 
									
										
										
										
											2020-04-21 13:49:29 +02:00
										 |  |  | void bt_format_net(char *buf, size_t size, const void *data); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-09 16:36:34 +01:00
										 |  |  | 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_ */
 |