mirror of
				https://gitlab.labs.nic.cz/labs/bird.git
				synced 2024-05-11 16:54:54 +00:00 
			
		
		
		
	Basic fib_get() / fib_find() test for random prefixes, FIB_WALK() test, and benchmark for fib_find(). Also generalize and reuse some code from trie tests.
		
			
				
	
	
		
			190 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			190 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  *	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_ */
 |