LCOV - code coverage report
Current view: top level - tests/testcases/bgpd - test_mpath.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 165 185 89.2 %
Date: 2015-11-19 Functions: 17 17 100.0 %

          Line data    Source code
       1             : /* $QuaggaId: Format:%an, %ai, %h$ $
       2             :  *
       3             :  * BGP Multipath Unit Test
       4             :  * Copyright (C) 2010 Google Inc.
       5             :  *
       6             :  * This file is part of Quagga
       7             :  *
       8             :  * Quagga is free software; you can redistribute it and/or modify it
       9             :  * under the terms of the GNU General Public License as published by the
      10             :  * Free Software Foundation; either version 2, or (at your option) any
      11             :  * later version.
      12             :  *
      13             :  * Quagga is distributed in the hope that it will be useful, but
      14             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU General Public License
      19             :  * along with Quagga; see the file COPYING.  If not, write to the Free
      20             :  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
      21             :  * 02111-1307, USA.
      22             :  */
      23             : 
      24             : #include <zebra.h>
      25             : 
      26             : #include "vty.h"
      27             : #include "stream.h"
      28             : #include "privs.h"
      29             : #include "linklist.h"
      30             : #include "memory.h"
      31             : #include "zclient.h"
      32             : 
      33             : #include "bgpd/bgpd.h"
      34             : #include "bgpd/bgp_table.h"
      35             : #include "bgpd/bgp_route.h"
      36             : #include "bgpd/bgp_attr.h"
      37             : #include "bgpd/bgp_mpath.h"
      38             : 
      39             : #define VT100_RESET "\x1b[0m"
      40             : #define VT100_RED "\x1b[31m"
      41             : #define VT100_GREEN "\x1b[32m"
      42             : #define VT100_YELLOW "\x1b[33m"
      43             : #define OK VT100_GREEN "OK" VT100_RESET
      44             : #define FAILED VT100_RED "failed" VT100_RESET
      45             : 
      46             : #define TEST_PASSED 0
      47             : #define TEST_FAILED -1
      48             : 
      49             : #define EXPECT_TRUE(expr, res)                                          \
      50             :   if (!(expr))                                                          \
      51             :     {                                                                   \
      52             :       printf ("Test failure in %s line %u: %s\n",                       \
      53             :               __FUNCTION__, __LINE__, #expr);                           \
      54             :       (res) = TEST_FAILED;                                              \
      55             :     }
      56             : 
      57             : typedef struct testcase_t__ testcase_t;
      58             : 
      59             : typedef int (*test_setup_func)(testcase_t *);
      60             : typedef int (*test_run_func)(testcase_t *);
      61             : typedef int (*test_cleanup_func)(testcase_t *);
      62             : 
      63             : struct testcase_t__ {
      64             :   const char *desc;
      65             :   void *test_data;
      66             :   void *verify_data;
      67             :   void *tmp_data;
      68             :   test_setup_func setup;
      69             :   test_run_func run;
      70             :   test_cleanup_func cleanup;
      71             : };
      72             : 
      73             : /* need these to link in libbgp */
      74             : struct thread_master *master = NULL;
      75             : struct zclient *zclient;
      76             : struct zebra_privs_t bgpd_privs =
      77             : {
      78             :   .user = NULL,
      79             :   .group = NULL,
      80             :   .vty_group = NULL,
      81             : };
      82             : 
      83             : static int tty = 0;
      84             : 
      85             : /* Create fake bgp instance */
      86             : static struct bgp *
      87           1 : bgp_create_fake (as_t *as, const char *name)
      88             : {
      89             :   struct bgp *bgp;
      90             :   afi_t afi;
      91             :   safi_t safi;
      92             : 
      93           1 :   if ( (bgp = XCALLOC (MTYPE_BGP, sizeof (struct bgp))) == NULL)
      94           0 :     return NULL;
      95             : 
      96           1 :   bgp_lock (bgp);
      97             :   //bgp->peer_self = peer_new (bgp);
      98             :   //bgp->peer_self->host = XSTRDUP (MTYPE_BGP_PEER_HOST, "Static announcement");
      99             : 
     100           1 :   bgp->peer = list_new ();
     101             :   //bgp->peer->cmp = (int (*)(void *, void *)) peer_cmp;
     102             : 
     103           1 :   bgp->group = list_new ();
     104             :   //bgp->group->cmp = (int (*)(void *, void *)) peer_group_cmp;
     105             : 
     106           1 :   bgp->rsclient = list_new ();
     107             :   //bgp->rsclient->cmp = (int (*)(void*, void*)) peer_cmp;
     108             : 
     109           3 :   for (afi = AFI_IP; afi < AFI_MAX; afi++)
     110          10 :     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
     111             :       {
     112           8 :         bgp->route[afi][safi] = bgp_table_init (afi, safi);
     113           8 :         bgp->aggregate[afi][safi] = bgp_table_init (afi, safi);
     114           8 :         bgp->rib[afi][safi] = bgp_table_init (afi, safi);
     115           8 :         bgp->maxpaths[afi][safi].maxpaths_ebgp = BGP_DEFAULT_MAXPATHS;
     116           8 :         bgp->maxpaths[afi][safi].maxpaths_ibgp = BGP_DEFAULT_MAXPATHS;
     117             :       }
     118             : 
     119           1 :   bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
     120           1 :   bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
     121           1 :   bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
     122           1 :   bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
     123           1 :   bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME;
     124             : 
     125           1 :   bgp->as = *as;
     126             : 
     127           1 :   if (name)
     128           0 :     bgp->name = strdup (name);
     129             : 
     130           1 :   return bgp;
     131             : }
     132             : 
     133             : /*=========================================================
     134             :  * Testcase for maximum-paths configuration
     135             :  */
     136             : static int
     137           1 : setup_bgp_cfg_maximum_paths (testcase_t *t)
     138             : {
     139           1 :   as_t asn = 1;
     140           1 :   t->tmp_data = bgp_create_fake (&asn, NULL);
     141           1 :   if (!t->tmp_data)
     142           0 :     return -1;
     143           1 :   return 0;
     144             : }
     145             : 
     146             : static int
     147           1 : run_bgp_cfg_maximum_paths (testcase_t *t)
     148             : {
     149             :   afi_t afi;
     150             :   safi_t safi;
     151             :   struct bgp *bgp;
     152             :   int api_result;
     153           1 :   int test_result = TEST_PASSED;
     154             : 
     155           1 :   bgp = t->tmp_data;
     156           3 :   for (afi = AFI_IP; afi < AFI_MAX; afi++)
     157          10 :     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
     158             :       {
     159             :         /* test bgp_maximum_paths_set */
     160           8 :         api_result = bgp_maximum_paths_set (bgp, afi, safi, BGP_PEER_EBGP, 10);
     161           8 :         EXPECT_TRUE (api_result == 0, test_result);
     162           8 :         api_result = bgp_maximum_paths_set (bgp, afi, safi, BGP_PEER_IBGP, 10);
     163           8 :         EXPECT_TRUE (api_result == 0, test_result);
     164           8 :         EXPECT_TRUE (bgp->maxpaths[afi][safi].maxpaths_ebgp == 10, test_result);
     165           8 :         EXPECT_TRUE (bgp->maxpaths[afi][safi].maxpaths_ibgp == 10, test_result);
     166             : 
     167             :         /* test bgp_maximum_paths_unset */
     168           8 :         api_result = bgp_maximum_paths_unset (bgp, afi, safi, BGP_PEER_EBGP);
     169           8 :         EXPECT_TRUE (api_result == 0, test_result);
     170           8 :         api_result = bgp_maximum_paths_unset (bgp, afi, safi, BGP_PEER_IBGP);
     171           8 :         EXPECT_TRUE (api_result == 0, test_result);
     172           8 :         EXPECT_TRUE ((bgp->maxpaths[afi][safi].maxpaths_ebgp ==
     173             :                       BGP_DEFAULT_MAXPATHS), test_result);
     174           8 :         EXPECT_TRUE ((bgp->maxpaths[afi][safi].maxpaths_ibgp ==
     175             :                       BGP_DEFAULT_MAXPATHS), test_result);
     176             :       }
     177             : 
     178           1 :   return test_result;
     179             : }
     180             : 
     181             : static int
     182           1 : cleanup_bgp_cfg_maximum_paths (testcase_t *t)
     183             : {
     184           1 :   return bgp_delete ((struct bgp *)t->tmp_data);
     185             : }
     186             : 
     187             : testcase_t test_bgp_cfg_maximum_paths = {
     188             :   .desc = "Test bgp maximum-paths config",
     189             :   .setup = setup_bgp_cfg_maximum_paths,
     190             :   .run = run_bgp_cfg_maximum_paths,
     191             :   .cleanup = cleanup_bgp_cfg_maximum_paths,
     192             : };
     193             : 
     194             : /*=========================================================
     195             :  * Testcase for bgp_mp_list
     196             :  */
     197             : struct peer test_mp_list_peer[] = {
     198             :   { .local_as = 1, .as = 2 },
     199             :   { .local_as = 1, .as = 2 },
     200             :   { .local_as = 1, .as = 2 },
     201             :   { .local_as = 1, .as = 2 },
     202             :   { .local_as = 1, .as = 2 },
     203             : };
     204             : int test_mp_list_peer_count = sizeof (test_mp_list_peer)/ sizeof (struct peer);
     205             : struct attr test_mp_list_attr[4];
     206             : struct bgp_info test_mp_list_info[] = {
     207             :   { .peer = &test_mp_list_peer[0], .attr = &test_mp_list_attr[0] },
     208             :   { .peer = &test_mp_list_peer[1], .attr = &test_mp_list_attr[1] },
     209             :   { .peer = &test_mp_list_peer[2], .attr = &test_mp_list_attr[1] },
     210             :   { .peer = &test_mp_list_peer[3], .attr = &test_mp_list_attr[2] },
     211             :   { .peer = &test_mp_list_peer[4], .attr = &test_mp_list_attr[3] },
     212             : };
     213             : int test_mp_list_info_count =
     214             :   sizeof (test_mp_list_info)/sizeof (struct bgp_info);
     215             : 
     216             : static int
     217           2 : setup_bgp_mp_list (testcase_t *t)
     218             : {
     219           2 :   test_mp_list_attr[0].nexthop.s_addr = 0x01010101;
     220           2 :   test_mp_list_attr[1].nexthop.s_addr = 0x02020202;
     221           2 :   test_mp_list_attr[2].nexthop.s_addr = 0x03030303;
     222           2 :   test_mp_list_attr[3].nexthop.s_addr = 0x04040404;
     223             : 
     224           2 :   if ((test_mp_list_peer[0].su_remote = sockunion_str2su ("1.1.1.1")) == NULL)
     225           0 :     return -1;
     226           2 :   if ((test_mp_list_peer[1].su_remote = sockunion_str2su ("2.2.2.2")) == NULL)
     227           0 :     return -1;
     228           2 :   if ((test_mp_list_peer[2].su_remote = sockunion_str2su ("3.3.3.3")) == NULL)
     229           0 :     return -1;
     230           2 :   if ((test_mp_list_peer[3].su_remote = sockunion_str2su ("4.4.4.4")) == NULL)
     231           0 :     return -1;
     232           2 :   if ((test_mp_list_peer[4].su_remote = sockunion_str2su ("5.5.5.5")) == NULL)
     233           0 :     return -1;
     234             : 
     235           2 :   return 0;
     236             : }
     237             : 
     238             : static int
     239           1 : run_bgp_mp_list (testcase_t *t)
     240             : {
     241             :   struct list mp_list;
     242             :   struct listnode *mp_node;
     243             :   struct bgp_info *info;
     244             :   int i;
     245           1 :   int test_result = TEST_PASSED;
     246           1 :   bgp_mp_list_init (&mp_list);
     247           1 :   EXPECT_TRUE (listcount(&mp_list) == 0, test_result);
     248             : 
     249           1 :   bgp_mp_list_add (&mp_list, &test_mp_list_info[1]);
     250           1 :   bgp_mp_list_add (&mp_list, &test_mp_list_info[4]);
     251           1 :   bgp_mp_list_add (&mp_list, &test_mp_list_info[2]);
     252           1 :   bgp_mp_list_add (&mp_list, &test_mp_list_info[3]);
     253           1 :   bgp_mp_list_add (&mp_list, &test_mp_list_info[0]);
     254             : 
     255           7 :   for (i = 0, mp_node = listhead(&mp_list); i < test_mp_list_info_count;
     256           5 :        i++, mp_node = listnextnode(mp_node))
     257             :     {
     258           5 :       info = listgetdata(mp_node);
     259           5 :       EXPECT_TRUE (info == &test_mp_list_info[i], test_result);
     260             :     }
     261             : 
     262           1 :   bgp_mp_list_clear (&mp_list);
     263           1 :   EXPECT_TRUE (listcount(&mp_list) == 0, test_result);
     264             : 
     265           1 :   return test_result;
     266             : }
     267             : 
     268             : static int
     269           1 : cleanup_bgp_mp_list (testcase_t *t)
     270             : {
     271             :   int i;
     272             : 
     273           6 :   for (i = 0; i < test_mp_list_peer_count; i++)
     274           5 :     sockunion_free (test_mp_list_peer[i].su_remote);
     275             : 
     276           1 :   return 0;
     277             : }
     278             : 
     279             : testcase_t test_bgp_mp_list = {
     280             :   .desc = "Test bgp_mp_list",
     281             :   .setup = setup_bgp_mp_list,
     282             :   .run = run_bgp_mp_list,
     283             :   .cleanup = cleanup_bgp_mp_list,
     284             : };
     285             : 
     286             : /*=========================================================
     287             :  * Testcase for bgp_info_mpath_update
     288             :  */
     289             : 
     290             : struct bgp_node test_rn;
     291             : 
     292             : static int
     293           1 : setup_bgp_info_mpath_update (testcase_t *t)
     294             : {
     295             :   int i;
     296           1 :   str2prefix ("42.1.1.0/24", &test_rn.p);
     297           1 :   setup_bgp_mp_list (t);
     298           6 :   for (i = 0; i < test_mp_list_info_count; i++)
     299           5 :     bgp_info_add (&test_rn, &test_mp_list_info[i]);
     300           1 :   return 0;
     301             : }
     302             : 
     303             : static int
     304           1 : run_bgp_info_mpath_update (testcase_t *t)
     305             : {
     306             :   struct bgp_info *new_best, *old_best, *mpath;
     307             :   struct list mp_list;
     308           1 :   struct bgp_maxpaths_cfg mp_cfg = { 3, 3 };
     309           1 :   int test_result = TEST_PASSED;
     310           1 :   bgp_mp_list_init (&mp_list);
     311           1 :   bgp_mp_list_add (&mp_list, &test_mp_list_info[4]);
     312           1 :   bgp_mp_list_add (&mp_list, &test_mp_list_info[3]);
     313           1 :   bgp_mp_list_add (&mp_list, &test_mp_list_info[0]);
     314           1 :   bgp_mp_list_add (&mp_list, &test_mp_list_info[1]);
     315           1 :   new_best = &test_mp_list_info[3];
     316           1 :   old_best = NULL;
     317           1 :   bgp_info_mpath_update (&test_rn, new_best, old_best, &mp_list, &mp_cfg);
     318           1 :   bgp_mp_list_clear (&mp_list);
     319           1 :   EXPECT_TRUE (bgp_info_mpath_count (new_best) == 2, test_result);
     320           1 :   mpath = bgp_info_mpath_first (new_best);
     321           1 :   EXPECT_TRUE (mpath == &test_mp_list_info[0], test_result);
     322           1 :   EXPECT_TRUE (CHECK_FLAG (mpath->flags, BGP_INFO_MULTIPATH), test_result);
     323           1 :   mpath = bgp_info_mpath_next (mpath);
     324           1 :   EXPECT_TRUE (mpath == &test_mp_list_info[1], test_result);
     325           1 :   EXPECT_TRUE (CHECK_FLAG (mpath->flags, BGP_INFO_MULTIPATH), test_result);
     326             : 
     327           1 :   bgp_mp_list_add (&mp_list, &test_mp_list_info[0]);
     328           1 :   bgp_mp_list_add (&mp_list, &test_mp_list_info[1]);
     329           1 :   new_best = &test_mp_list_info[0];
     330           1 :   old_best = &test_mp_list_info[3];
     331           1 :   bgp_info_mpath_update (&test_rn, new_best, old_best, &mp_list, &mp_cfg);
     332           1 :   bgp_mp_list_clear (&mp_list);
     333           1 :   EXPECT_TRUE (bgp_info_mpath_count (new_best) == 1, test_result);
     334           1 :   mpath = bgp_info_mpath_first (new_best);
     335           1 :   EXPECT_TRUE (mpath == &test_mp_list_info[1], test_result);
     336           1 :   EXPECT_TRUE (CHECK_FLAG (mpath->flags, BGP_INFO_MULTIPATH), test_result);
     337           1 :   EXPECT_TRUE (!CHECK_FLAG (test_mp_list_info[0].flags, BGP_INFO_MULTIPATH),
     338             :                test_result);
     339             : 
     340           1 :   return test_result;
     341             : }
     342             : 
     343             : static int
     344           1 : cleanup_bgp_info_mpath_update (testcase_t *t)
     345             : {
     346             :   int i;
     347             : 
     348           6 :   for (i = 0; i < test_mp_list_peer_count; i++)
     349           5 :     sockunion_free (test_mp_list_peer[i].su_remote);
     350             : 
     351           1 :   return 0;
     352             : }
     353             : 
     354             : testcase_t test_bgp_info_mpath_update = {
     355             :   .desc = "Test bgp_info_mpath_update",
     356             :   .setup = setup_bgp_info_mpath_update,
     357             :   .run = run_bgp_info_mpath_update,
     358             :   .cleanup = cleanup_bgp_info_mpath_update,
     359             : };
     360             : 
     361             : /*=========================================================
     362             :  * Set up testcase vector
     363             :  */
     364             : testcase_t *all_tests[] = {
     365             :   &test_bgp_cfg_maximum_paths,
     366             :   &test_bgp_mp_list,
     367             :   &test_bgp_info_mpath_update,
     368             : };
     369             : 
     370             : int all_tests_count = (sizeof(all_tests)/sizeof(testcase_t *));
     371             : 
     372             : /*=========================================================
     373             :  * Test Driver Functions
     374             :  */
     375             : static int
     376           1 : global_test_init (void)
     377             : {
     378           1 :   master = thread_master_create ();
     379           1 :   zclient = zclient_new ();
     380           1 :   bgp_master_init ();
     381           1 :   bgp_option_set (BGP_OPT_NO_LISTEN);
     382             :   
     383           1 :   if (fileno (stdout) >= 0)
     384           1 :     tty = isatty (fileno (stdout));
     385           1 :   return 0;
     386             : }
     387             : 
     388             : static int
     389           1 : global_test_cleanup (void)
     390             : {
     391           1 :   zclient_free (zclient);
     392           1 :   thread_master_free (master);
     393           1 :   return 0;
     394             : }
     395             : 
     396             : static void
     397           3 : display_result (testcase_t *test, int result)
     398             : {
     399           3 :   if (tty)
     400           3 :     printf ("%s: %s\n", test->desc, result == TEST_PASSED ? OK : FAILED);
     401             :   else
     402           0 :     printf ("%s: %s\n", test->desc, result == TEST_PASSED ? "OK" : "FAILED");
     403           3 : }
     404             : 
     405             : static int
     406           3 : setup_test (testcase_t *t)
     407             : {
     408           3 :   int res = 0;
     409           3 :   if (t->setup)
     410           3 :     res = t->setup (t);
     411           3 :   return res;
     412             : }
     413             : 
     414             : static int
     415           3 : cleanup_test (testcase_t *t)
     416             : {
     417           3 :   int res = 0;
     418           3 :   if (t->cleanup)
     419           3 :     res = t->cleanup (t);
     420           3 :   return res;
     421             : }
     422             : 
     423             : static void
     424           1 : run_tests (testcase_t *tests[], int num_tests, int *pass_count, int *fail_count)
     425             : {
     426             :   int test_index, result;
     427             :   testcase_t *cur_test;
     428             : 
     429           1 :   *pass_count = *fail_count = 0;
     430             : 
     431           4 :   for (test_index = 0; test_index < num_tests; test_index++)
     432             :     {
     433           3 :       cur_test = tests[test_index];
     434           3 :       if (!cur_test->desc)
     435             :         {
     436           0 :           printf ("error: test %d has no description!\n", test_index);
     437           0 :           continue;
     438             :         }
     439           3 :       if (!cur_test->run)
     440             :         {
     441           0 :           printf ("error: test %s has no run function!\n", cur_test->desc);
     442           0 :           continue;
     443             :         }
     444           3 :       if (setup_test (cur_test) != 0)
     445             :         {
     446           0 :           printf ("error: setup failed for test %s\n", cur_test->desc);
     447           0 :           continue;
     448             :         }
     449           3 :       result = cur_test->run (cur_test);
     450           3 :       if (result == TEST_PASSED)
     451           3 :         *pass_count += 1;
     452             :       else
     453           0 :         *fail_count += 1;
     454           3 :       display_result (cur_test, result);
     455           3 :       if (cleanup_test (cur_test) != 0)
     456             :         {
     457           0 :           printf ("error: cleanup failed for test %s\n", cur_test->desc);
     458           0 :           continue;
     459             :         }
     460             :     }
     461           1 : }
     462             : 
     463             : int
     464           1 : main (void)
     465             : {
     466             :   int pass_count, fail_count;
     467             :   time_t cur_time;
     468             : 
     469           1 :   time (&cur_time);
     470           1 :   printf("BGP Multipath Tests Run at %s", ctime(&cur_time));
     471           1 :   if (global_test_init () != 0)
     472             :     {
     473           0 :       printf("Global init failed. Terminating.\n");
     474           0 :       exit(1);
     475             :     }
     476           1 :   run_tests (all_tests, all_tests_count, &pass_count, &fail_count);
     477           1 :   global_test_cleanup ();
     478           1 :   printf("Total pass/fail: %d/%d\n", pass_count, fail_count);
     479           1 :   return fail_count;
     480             : }

Generated by: LCOV version 1.10