Annotation of embedaddon/bird2/filter/trie_test.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  *     Filters: Utility Functions Tests
        !             3:  *
        !             4:  *     (c) 2015 CZ.NIC z.s.p.o.
        !             5:  *
        !             6:  *     Can be freely distributed and used under the terms of the GNU GPL.
        !             7:  */
        !             8: 
        !             9: #include "test/birdtest.h"
        !            10: #include "test/bt-utils.h"
        !            11: 
        !            12: #include "filter/filter.h"
        !            13: #include "filter/data.h"
        !            14: #include "conf/conf.h"
        !            15: 
        !            16: #define TESTS_NUM              10
        !            17: #define PREFIXES_NUM           10
        !            18: #define PREFIX_TESTS_NUM       10000
        !            19: 
        !            20: #define BIG_BUFFER_SIZE                10000
        !            21: 
        !            22: /* Wrapping structure for storing f_prefixes structures in list */
        !            23: struct f_prefix_node {
        !            24:   node n;
        !            25:   struct f_prefix prefix;
        !            26: };
        !            27: 
        !            28: static u32
        !            29: xrandom(u32 max)
        !            30: {
        !            31:   return (bt_random() % max);
        !            32: }
        !            33: 
        !            34: static int
        !            35: is_prefix_included(list *prefixes, struct f_prefix *needle)
        !            36: {
        !            37:   struct f_prefix_node *n;
        !            38:   WALK_LIST(n, *prefixes)
        !            39:   {
        !            40:     ip6_addr cmask = ip6_mkmask(MIN(n->prefix.net.pxlen, needle->net.pxlen));
        !            41: 
        !            42:     ip6_addr ip = net6_prefix(&n->prefix.net);
        !            43:     ip6_addr needle_ip = net6_prefix(&needle->net);
        !            44: 
        !            45:     if ((ipa_compare(ipa_and(ip, cmask), ipa_and(needle_ip, cmask)) == 0) &&
        !            46:        (n->prefix.lo <= needle->net.pxlen) && (needle->net.pxlen <= n->prefix.hi))
        !            47:     {
        !            48:       bt_debug("FOUND\t" PRIip6 "/%d %d-%d\n", ARGip6(net6_prefix(&n->prefix.net)), n->prefix.net.pxlen, n->prefix.lo, n->prefix.hi);
        !            49:       return 1; /* OK */
        !            50:     }
        !            51:   }
        !            52:   return 0; /* FAIL */
        !            53: }
        !            54: 
        !            55: static struct f_prefix
        !            56: get_random_ip6_prefix(void)
        !            57: {
        !            58:   struct f_prefix p;
        !            59:   u8 pxlen = xrandom(120)+8;
        !            60:   ip6_addr ip6 = ip6_build(bt_random(),bt_random(),bt_random(),bt_random());
        !            61:   net_addr_ip6 net6 = NET_ADDR_IP6(ip6, pxlen);
        !            62: 
        !            63:   p.net = *((net_addr*) &net6);
        !            64: 
        !            65:   if (bt_random() % 2)
        !            66:   {
        !            67:     p.lo = 0;
        !            68:     p.hi = p.net.pxlen;
        !            69:   }
        !            70:   else
        !            71:   {
        !            72:     p.lo = p.net.pxlen;
        !            73:     p.hi = net_max_prefix_length[p.net.type];
        !            74:   }
        !            75: 
        !            76:   return p;
        !            77: }
        !            78: 
        !            79: static void
        !            80: generate_random_ipv6_prefixes(list *prefixes)
        !            81: {
        !            82:   int i;
        !            83:   for (i = 0; i < PREFIXES_NUM; i++)
        !            84:   {
        !            85:     struct f_prefix f = get_random_ip6_prefix();
        !            86: 
        !            87:     struct f_prefix_node *px = calloc(1, sizeof(struct f_prefix_node));
        !            88:     px->prefix = f;
        !            89: 
        !            90:     bt_debug("ADD\t" PRIip6 "/%d %d-%d\n", ARGip6(net6_prefix(&px->prefix.net)), px->prefix.net.pxlen, px->prefix.lo, px->prefix.hi);
        !            91:     add_tail(prefixes, &px->n);
        !            92:   }
        !            93: }
        !            94: 
        !            95: static int
        !            96: t_match_net(void)
        !            97: {
        !            98:   bt_bird_init();
        !            99:   bt_config_parse(BT_CONFIG_SIMPLE);
        !           100: 
        !           101:   uint round;
        !           102:   for (round = 0; round < TESTS_NUM; round++)
        !           103:   {
        !           104:     list prefixes; /* of structs f_extended_prefix */
        !           105:     init_list(&prefixes);
        !           106:     struct f_trie *trie = f_new_trie(config->mem, sizeof(struct f_trie_node));
        !           107: 
        !           108:     generate_random_ipv6_prefixes(&prefixes);
        !           109:     struct f_prefix_node *n;
        !           110:     WALK_LIST(n, prefixes)
        !           111:     {
        !           112:       trie_add_prefix(trie, &n->prefix.net, n->prefix.lo, n->prefix.hi);
        !           113:     }
        !           114: 
        !           115:     int i;
        !           116:     for (i = 0; i < PREFIX_TESTS_NUM; i++)
        !           117:     {
        !           118:       struct f_prefix f = get_random_ip6_prefix();
        !           119:       bt_debug("TEST\t" PRIip6 "/%d\n", ARGip6(net6_prefix(&f.net)), f.net.pxlen);
        !           120: 
        !           121:       int should_be = is_prefix_included(&prefixes, &f);
        !           122:       int is_there  = trie_match_net(trie, &f.net);
        !           123:       bt_assert_msg(should_be == is_there, "Prefix " PRIip6 "/%d %s", ARGip6(net6_prefix(&f.net)), f.net.pxlen, (should_be ? "should be found in trie" : "should not be found in trie"));
        !           124:     }
        !           125: 
        !           126:     struct f_prefix_node *nxt;
        !           127:     WALK_LIST_DELSAFE(n, nxt, prefixes)
        !           128:     {
        !           129:       free(n);
        !           130:     }
        !           131:   }
        !           132: 
        !           133:   bt_bird_cleanup();
        !           134:   return 1;
        !           135: }
        !           136: 
        !           137: static int
        !           138: t_trie_same(void)
        !           139: {
        !           140:   bt_bird_init();
        !           141:   bt_config_parse(BT_CONFIG_SIMPLE);
        !           142: 
        !           143:   int round;
        !           144:   for (round = 0; round < TESTS_NUM*4; round++)
        !           145:   {
        !           146:     struct f_trie * trie1 = f_new_trie(config->mem, sizeof(struct f_trie_node));
        !           147:     struct f_trie * trie2 = f_new_trie(config->mem, sizeof(struct f_trie_node));
        !           148: 
        !           149:     list prefixes; /* a list of f_extended_prefix structures */
        !           150:     init_list(&prefixes);
        !           151:     int i;
        !           152:     for (i = 0; i < 100; i++)
        !           153:       generate_random_ipv6_prefixes(&prefixes);
        !           154: 
        !           155:     struct f_prefix_node *n;
        !           156:     WALK_LIST(n, prefixes)
        !           157:     {
        !           158:       trie_add_prefix(trie1, &n->prefix.net, n->prefix.lo, n->prefix.hi);
        !           159:     }
        !           160:     WALK_LIST_BACKWARDS(n, prefixes)
        !           161:     {
        !           162:       trie_add_prefix(trie2, &n->prefix.net, n->prefix.lo, n->prefix.hi);
        !           163:     }
        !           164: 
        !           165:     bt_assert(trie_same(trie1, trie2));
        !           166: 
        !           167:     struct f_prefix_node *nxt;
        !           168:     WALK_LIST_DELSAFE(n, nxt, prefixes)
        !           169:     {
        !           170:       free(n);
        !           171:     }
        !           172:   }
        !           173: 
        !           174:   return 1;
        !           175: }
        !           176: 
        !           177: int
        !           178: main(int argc, char *argv[])
        !           179: {
        !           180:   bt_init(argc, argv);
        !           181: 
        !           182:   bt_test_suite(t_match_net, "Testing random prefix matching");
        !           183:   bt_test_suite(t_trie_same, "A trie filled forward should be same with a trie filled backward.");
        !           184: 
        !           185:   return bt_exit_value();
        !           186: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>