From 4fb506466c7635dce2bded4e5e6a980ce31e5654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Tvrd=C3=ADk?= Date: Thu, 27 Aug 2015 09:25:28 +0200 Subject: [PATCH] Birdtest: filter/trie Thanks to Santiago for reuse here his code. bt_rand_num() -> bt_random() --- filter/tree_test.c | 6 +- filter/trie_test.c | 187 ++++++++++++++++++++++++++++++++++++++++++++ lib/bitops_test.c | 4 +- lib/buffer_test.c | 4 +- lib/checksum_test.c | 4 +- lib/hash_test.c | 2 +- lib/heap_test.c | 2 +- test/birdtest.c | 2 +- test/birdtest.h | 3 +- test/bt-utils.h | 15 ++++ 10 files changed, 216 insertions(+), 13 deletions(-) create mode 100644 filter/trie_test.c diff --git a/filter/tree_test.c b/filter/tree_test.c index de022416..0b455bf3 100644 --- a/filter/tree_test.c +++ b/filter/tree_test.c @@ -104,7 +104,7 @@ get_random_degenerated_left_tree(uint nodes_count) { uint selected_idx; do { - selected_idx = bt_rand_num() % nodes_count; + selected_idx = bt_random() % nodes_count; } while(avaible_indexes[selected_idx] != 0); avaible_indexes[selected_idx] = 1; @@ -127,7 +127,7 @@ get_balanced_tree_with_ranged_values(uint nodes_count) { n->from.type = n->to.type = T_INT; n->from.val.i = idx; - idx += (uint)bt_rand_num() / nodes_count; /* (... / nodes_count) preventing overflow an uint idx */ + idx += (uint)bt_random() / nodes_count; /* (... / nodes_count) preventing overflow an uint idx */ n->to.val.i = idx++; } @@ -250,7 +250,7 @@ t_find_ranges(void) struct f_val looking_up_value = { .type = T_INT }; - for(looking_up_value.val.i = 0; looking_up_value.val.i <= max_value; looking_up_value.val.i += ((uint)bt_rand_num()/nodes_count)) + for(looking_up_value.val.i = 0; looking_up_value.val.i <= max_value; looking_up_value.val.i += ((uint)bt_random()/nodes_count)) { struct f_tree *found_tree = find_tree(tree, looking_up_value); bt_debug("searching: %u \n", looking_up_value.val.i); diff --git a/filter/trie_test.c b/filter/trie_test.c new file mode 100644 index 00000000..83c3a60c --- /dev/null +++ b/filter/trie_test.c @@ -0,0 +1,187 @@ +/* + * Filters: Utility Functions Tests + * + * (c) 2015 CZ.NIC z.s.p.o. + * + * Can be freely distributed and used under the terms of the GNU GPL. + */ + +#include "test/birdtest.h" +#include "test/bt-utils.h" + +#include "filter/filter.h" + +#define TESTS_NUM 10 +#define PREFIXES_NUM 10 +#define PREFIX_TESTS_NUM 10000 + +#define BIG_BUFFER_SIZE 10000 + +struct f_extended_prefix { + node n; /* node in prefixes list */ + struct f_prefix prefix; + int l; + int h; +}; + +static u32 +xrandom(u32 max) +{ + return ((u32)bt_random() % max); +} + +static int +is_prefix_included(list *prefixes, struct f_prefix *needle) +{ + struct f_extended_prefix *n; + WALK_LIST(n, *prefixes) + { + ip_addr cmask = ipa_mkmask(MIN(n->prefix.len, needle->len)); + + if ((ipa_compare(ipa_and(n->prefix.ip, cmask), ipa_and(needle->ip, cmask)) == 0) && + (n->l <= needle->len) && (needle->len <= n->h)) + { + bt_debug("FOUND\t" PRIipa "/%d %d-%d\n", ARGipa(n->prefix.ip), n->prefix.len, n->l, n->h); + return 1; /* OK */ + } + } + return 0; /* FAIL */ +} + +static struct f_prefix +get_random_prefix(void) +{ + struct f_prefix f = { +#ifdef IPV6 + .ip = ipa_build6(bt_random(), bt_random(), bt_random(), bt_random()), + .len = xrandom(120)+8, +#else + .ip = ipa_build4(xrandom(256), xrandom(256), xrandom(256), xrandom(256)), + .len = xrandom(25)+8, +#endif + }; + + return f; +} + +static void +generate_random_prefixes(list *prefixes) +{ + int l, h, x, i; + for (i = 0; i < PREFIXES_NUM; i++) + { + struct f_prefix f = get_random_prefix(); + +#ifdef IPV6 + l = xrandom(129); + h = xrandom(129); +#else + l = xrandom(33); + h = xrandom(33); +#endif + if (h < l) + { + x = l; + l = h; + h = x; + } + + struct f_extended_prefix *px = calloc(1, sizeof(struct f_extended_prefix)); + px->prefix = f; + px->l = l; + px->h = h; + + bt_debug("ADD\t" PRIipa "/%d %d-%d\n", ARGipa(px->prefix.ip), px->prefix.len, px->l, px->h); + add_tail(prefixes, &px->n); + } +} + +static int +t_match_prefix(void) +{ + bt_bird_init_with_simple_configuration(); + + uint round; + for (round = 0; round < TESTS_NUM; round++) + { + list prefixes; /* of structs f_extended_prefix */ + init_list(&prefixes); + struct f_trie *trie = f_new_trie(config->mem, sizeof(struct f_trie_node)); + + generate_random_prefixes(&prefixes); + struct f_extended_prefix *n; + WALK_LIST(n, prefixes) + { + trie_add_prefix(trie, n->prefix.ip, n->prefix.len, n->l, n->h); + } + + int i; + for (i = 0; i < PREFIX_TESTS_NUM; i++) + { + struct f_prefix f = get_random_prefix(); + bt_debug("TEST\t" PRIipa "/%d\n", ARGipa(f.ip), f.len); + + int should_be = is_prefix_included(&prefixes, &f); + int is_there = trie_match_prefix(trie, f.ip, f.len); + bt_assert_msg(should_be == is_there, "Prefix " PRIipa "/%d %s", ARGipa(f.ip), f.len, (should_be ? "should be founded but was not founded in trie" : "is not inside trie but searching was false positive.")); + } + + struct f_extended_prefix *nxt; + WALK_LIST_DELSAFE(n, nxt, prefixes) + { + free(n); + } + } + + return BT_SUCCESS; +} + +static int +t_trie_same(void) +{ + bt_bird_init_with_simple_configuration(); + + int round; + for (round = 0; round < TESTS_NUM*4; round++) + { + struct f_trie * trie1 = f_new_trie(config->mem, sizeof(struct f_trie_node)); + struct f_trie * trie2 = f_new_trie(config->mem, sizeof(struct f_trie_node)); + + list prefixes; /* of structs f_extended_prefix */ + init_list(&prefixes); + int i; + for (i = 0; i < 100; i++) + generate_random_prefixes(&prefixes); + + struct f_extended_prefix *n; + WALK_LIST(n, prefixes) + { + trie_add_prefix(trie1, n->prefix.ip, n->prefix.len, n->l, n->h); + } + WALK_LIST_BACKWARDS(n, prefixes) + { + trie_add_prefix(trie2, n->prefix.ip, n->prefix.len, n->l, n->h); + } + + bt_assert_msg(trie_same(trie1, trie2), "Trie1 and trie2 (backward fullfill) are not same!"); + + struct f_extended_prefix *nxt; + WALK_LIST_DELSAFE(n, nxt, prefixes) + { + free(n); + } + } + + return BT_SUCCESS; +} + +int +main(int argc, char *argv[]) +{ + bt_init(argc, argv); + + bt_test_suite(t_match_prefix, "Testing random prefix matching"); + bt_test_suite(t_trie_same, "A trie filled forward should be same with a trie filled backward."); + + return bt_end(); +} diff --git a/lib/bitops_test.c b/lib/bitops_test.c index 2699fed0..c853e931 100644 --- a/lib/bitops_test.c +++ b/lib/bitops_test.c @@ -75,7 +75,7 @@ t_masklen(void) check_mask(((u32) (0xffffffff << (32-i))) & 0xffffffff); for (i = 0; i <= MAX_NUM; i++) - check_mask(bt_rand_num()); + check_mask(bt_random()); return BT_SUCCESS; } @@ -114,7 +114,7 @@ t_log2(void) check_log2(i); for (i = 1; i < MAX_NUM; i++) - check_log2(bt_rand_num() % 0xffff); + check_log2(bt_random() % 0xffff); return BT_SUCCESS; } diff --git a/lib/buffer_test.c b/lib/buffer_test.c index 2c671f16..cfed9b9d 100644 --- a/lib/buffer_test.c +++ b/lib/buffer_test.c @@ -36,7 +36,7 @@ fill_expected_array(void) int i; for (i = 0; i < MAX_NUM; i++) - expected[i] = bt_rand_num(); + expected[i] = bt_random(); } static void @@ -86,7 +86,7 @@ t_buffer_pop(void) for (i = MAX_NUM-1; i >= MAX_NUM/2; i--) BUFFER_POP(buffer); for (i = MAX_NUM/2; i < MAX_NUM; i++) - BUFFER_PUSH(buffer) = expected[i] = bt_rand_num(); + BUFFER_PUSH(buffer) = expected[i] = bt_random(); is_buffer_as_expected(&buffer); /* POP all of elements */ diff --git a/lib/checksum_test.c b/lib/checksum_test.c index 52cecb13..3e01241c 100644 --- a/lib/checksum_test.c +++ b/lib/checksum_test.c @@ -48,7 +48,7 @@ t_calculate(void) int i; for (i = 0; i < MAX_NUM; i++) - a[i] = bt_rand_num(); + a[i] = bt_random(); u16 sum_calculated = ipsum_calculate(a, sizeof(a), NULL); u16 sum_calculated_2 = ipsum_calculate(&a[0], sizeof(u32)*(MAX_NUM/2), &a[MAX_NUM/2], sizeof(u32)*(MAX_NUM - MAX_NUM/2), NULL); @@ -71,7 +71,7 @@ t_verify(void) int i; for (i = 0; i < MAX_NUM; i++) - a[i] = bt_rand_num(); + a[i] = bt_random(); u16 sum = ipsum_calculate_expected(a); diff --git a/lib/hash_test.c b/lib/hash_test.c index 18fdc466..be9a526e 100644 --- a/lib/hash_test.c +++ b/lib/hash_test.c @@ -141,7 +141,7 @@ t_insert_find_random(void) struct test_node *node; for (i = 0; i < MAX_NUM; i++) { - nodes[i].key = bt_rand_num(); + nodes[i].key = bt_random(); node = &nodes[i]; HASH_INSERT(hash, TEST, node); } diff --git a/lib/heap_test.c b/lib/heap_test.c index 2e324ec9..8e1cee0e 100644 --- a/lib/heap_test.c +++ b/lib/heap_test.c @@ -152,7 +152,7 @@ t_heap_insert_random(void) for (i = 1; i <= MAX_NUM; i++) { - heap[i] = expected[i] = bt_rand_num(); + heap[i] = expected[i] = bt_random(); HEAP_INSERT(heap, ++num, int, MY_CMP, MY_HEAP_SWAP); show_heap(); bt_assert(is_heap_valid(heap, num)); diff --git a/test/birdtest.c b/test/birdtest.c index e5974966..0e97f752 100644 --- a/test/birdtest.c +++ b/test/birdtest.c @@ -37,7 +37,7 @@ uint bt_success; uint bt_test_suite_success; long int -bt_rand_num(void) +bt_random(void) { /* Seeded in bt_init() */ long int rand_low, rand_high; diff --git a/test/birdtest.h b/test/birdtest.h index f7e4b312..c5170ff9 100644 --- a/test/birdtest.h +++ b/test/birdtest.h @@ -12,6 +12,7 @@ #include #include #include +#include extern uint bt_success; extern uint bt_test_suite_success; @@ -28,7 +29,7 @@ extern const char *bt_test_id; void bt_init(int argc, char *argv[]); int bt_end(void); void 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, ...); -long int bt_rand_num(void); +long int bt_random(void); void bt_result(const char *result, const char *msg, ...); #define BT_SUCCESS 0 diff --git a/test/bt-utils.h b/test/bt-utils.h index cbe1e2e1..6bdcede7 100644 --- a/test/bt-utils.h +++ b/test/bt-utils.h @@ -11,6 +11,21 @@ #include "sysdep/config.h" +#define PRIip4 "%d.%d.%d.%d" +#define ARGip4(x) ((x).addr >> 24) & 0xff, ((x).addr >> 16) & 0xff, ((x).addr >> 8) & 0xff, (x).addr & 0xff +#define PRIip6 "%04X:%04X:%04X:%04X:%04X:%04X:%04X:%04X" +#define ARGip6_HIGH(x,i) (((x).addr[(i)] >> 16) & 0xffff) +#define ARGip6_LOW(x,i) ((x).addr[(i)] & 0xffff) +#define ARGip6_BOTH(x,i) ARGip6_HIGH(x,i), ARGip6_LOW(x,i) +#define ARGip6(x) ARGip6_BOTH((x), 0), ARGip6_BOTH((x), 1), ARGip6_BOTH((x), 2), ARGip6_BOTH((x), 3) +#ifdef IPV6 +#define PRIipa PRIip6 +#define ARGipa(x) ARGip6(x) +#else +#define PRIipa PRIip4 +#define ARGipa(x) ARGip4(x) +#endif + #define BT_CONFIG_PARSE_ROUTER_ID "router id 10.0.0.1; \n" #define BT_CONFIG_PARSE_KERNEL_DEVICE "protocol device {} \n" #define BT_CONFIG_SIMPLE BT_CONFIG_PARSE_ROUTER_ID BT_CONFIG_PARSE_KERNEL_DEVICE