github.com/osrg/gobgp@v2.0.0+incompatible/test/scenario_test/addpath_test.py (about)

     1  # Copyright (C) 2016 Nippon Telegraph and Telephone Corporation.
     2  #
     3  # Licensed under the Apache License, Version 2.0 (the "License");
     4  # you may not use this file except in compliance with the License.
     5  # You may obtain a copy of the License at
     6  #
     7  #    http://www.apache.org/licenses/LICENSE-2.0
     8  #
     9  # Unless required by applicable law or agreed to in writing, software
    10  # distributed under the License is distributed on an "AS IS" BASIS,
    11  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
    12  # implied.
    13  # See the License for the specific language governing permissions and
    14  # limitations under the License.
    15  
    16  import sys
    17  import time
    18  import unittest
    19  
    20  import nose
    21  from fabric.api import local
    22  
    23  from lib import base
    24  from lib.base import (
    25      BGP_FSM_ESTABLISHED,
    26      assert_several_times,
    27  )
    28  from lib.gobgp import GoBGPContainer
    29  from lib.exabgp import ExaBGPContainer
    30  from lib.noseplugin import OptionParser, parser_option
    31  
    32  
    33  class GoBGPTestBase(unittest.TestCase):
    34  
    35      @classmethod
    36      def setUpClass(cls):
    37          gobgp_ctn_image_name = parser_option.gobgp_image
    38          base.TEST_PREFIX = parser_option.test_prefix
    39  
    40          g1 = GoBGPContainer(name='g1', asn=65000, router_id='192.168.0.1',
    41                              ctn_image_name=gobgp_ctn_image_name,
    42                              log_level=parser_option.gobgp_log_level)
    43          g2 = GoBGPContainer(name='g2', asn=65000, router_id='192.168.0.2',
    44                              ctn_image_name=gobgp_ctn_image_name,
    45                              log_level=parser_option.gobgp_log_level)
    46          g3 = GoBGPContainer(name='g3', asn=65000, router_id='192.168.0.3',
    47                              ctn_image_name=gobgp_ctn_image_name,
    48                              log_level=parser_option.gobgp_log_level)
    49          e1 = ExaBGPContainer(name='e1', asn=65000, router_id='192.168.0.4')
    50  
    51          ctns = [g1, g2, g3, e1]
    52          initial_wait_time = max(ctn.run() for ctn in ctns)
    53  
    54          time.sleep(initial_wait_time)
    55  
    56          g1.add_peer(e1, addpath=True)
    57          e1.add_peer(g1, addpath=True)
    58  
    59          g1.add_peer(g2, addpath=False, is_rr_client=True)
    60          g2.add_peer(g1, addpath=False)
    61  
    62          g1.add_peer(g3, addpath=True, is_rr_client=True)
    63          g3.add_peer(g1, addpath=True)
    64  
    65          cls.g1 = g1
    66          cls.g2 = g2
    67          cls.g3 = g3
    68          cls.e1 = e1
    69  
    70      # test each neighbor state is turned establish
    71      def test_00_neighbor_established(self):
    72          self.g1.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=self.g2)
    73          self.g1.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=self.e1)
    74  
    75      # prepare routes with path_id (no error check)
    76      def test_01_prepare_add_paths_routes(self):
    77          self.e1.add_route(route='192.168.100.0/24', identifier=10, aspath=[100, 200, 300])
    78          self.e1.add_route(route='192.168.100.0/24', identifier=20, aspath=[100, 200])
    79          self.e1.add_route(route='192.168.100.0/24', identifier=30, aspath=[100])
    80  
    81      # test three routes are installed to the rib due to add-path feature
    82      def test_02_check_g1_global_rib(self):
    83          def f():
    84              rib = self.g1.get_global_rib()
    85              self.assertEqual(len(rib), 1)
    86              self.assertEqual(len(rib[0]['paths']), 3)
    87  
    88          assert_several_times(f)
    89  
    90      # test only the best path is advertised to g2
    91      def test_03_check_g2_global_rib(self):
    92          def f():
    93              rib = self.g2.get_global_rib()
    94              self.assertEqual(len(rib), 1)
    95              self.assertEqual(len(rib[0]['paths']), 1)
    96              self.assertEqual(rib[0]['paths'][0]['aspath'], [100])
    97  
    98          assert_several_times(f)
    99  
   100      # test three routes are advertised to g3
   101      def test_04_check_g3_global_rib(self):
   102          def f():
   103              rib = self.g3.get_global_rib()
   104              self.assertEqual(len(rib), 1)
   105              self.assertEqual(len(rib[0]['paths']), 3)
   106  
   107          assert_several_times(f)
   108  
   109      # withdraw a route with path_id (no error check)
   110      def test_05_withdraw_route_with_path_id(self):
   111          self.e1.del_route(route='192.168.100.0/24', identifier=30)
   112  
   113      # test the withdrawn route is removed from the rib
   114      def test_06_check_g1_global_rib(self):
   115          def f():
   116              rib = self.g1.get_global_rib()
   117              self.assertEqual(len(rib), 1)
   118              self.assertEqual(len(rib[0]['paths']), 2)
   119              for path in rib[0]['paths']:
   120                  self.assertIn(path['aspath'], ([100, 200, 300],
   121                                                 [100, 200]))
   122  
   123          assert_several_times(f)
   124  
   125      # test the best path is replaced due to the removal from g1 rib
   126      def test_07_check_g2_global_rib(self):
   127          def f():
   128              rib = self.g2.get_global_rib()
   129              self.assertEqual(len(rib), 1)
   130              self.assertEqual(len(rib[0]['paths']), 1)
   131              self.assertEqual(rib[0]['paths'][0]['aspath'], [100, 200])
   132  
   133          assert_several_times(f)
   134  
   135      # test the withdrawn route is removed from the rib of g3
   136      def test_08_check_g3_global_rib(self):
   137          def f():
   138              rib = self.g3.get_global_rib()
   139              self.assertEqual(len(rib), 1)
   140              self.assertEqual(len(rib[0]['paths']), 2)
   141              for path in rib[0]['paths']:
   142                  self.assertIn(path['aspath'], ([100, 200, 300],
   143                                                 [100, 200]))
   144  
   145          assert_several_times(f)
   146  
   147      # install a route with path_id via GoBGP CLI (no error check)
   148      def test_09_install_add_paths_route_via_cli(self):
   149          # identifier is duplicated with the identifier of the route from e1
   150          self.g1.add_route(route='192.168.100.0/24', identifier=10, local_pref=500)
   151  
   152      # test the route from CLI is installed to the rib
   153      def test_10_check_g1_global_rib(self):
   154          def f():
   155              rib = self.g1.get_global_rib()
   156              self.assertEqual(len(rib), 1)
   157              self.assertEqual(len(rib[0]['paths']), 3)
   158              for path in rib[0]['paths']:
   159                  self.assertIn(path['aspath'], ([100, 200, 300],
   160                                                 [100, 200],
   161                                                 []))
   162                  if not path['aspath']:  # path['aspath'] == []
   163                      self.assertEqual(path['local-pref'], 500)
   164  
   165          assert_several_times(f)
   166  
   167      # test the best path is replaced due to the CLI route from g1 rib
   168      def test_11_check_g2_global_rib(self):
   169          def f():
   170              rib = self.g2.get_global_rib()
   171              self.assertEqual(len(rib), 1)
   172              self.assertEqual(len(rib[0]['paths']), 1)
   173              self.assertEqual(rib[0]['paths'][0]['aspath'], [])
   174  
   175          assert_several_times(f)
   176  
   177      # test the route from CLI is advertised from g1
   178      def test_12_check_g3_global_rib(self):
   179          def f():
   180              rib = self.g3.get_global_rib()
   181              self.assertEqual(len(rib), 1)
   182              self.assertEqual(len(rib[0]['paths']), 3)
   183              for path in rib[0]['paths']:
   184                  self.assertIn(path['aspath'], ([100, 200, 300],
   185                                                 [100, 200],
   186                                                 []))
   187                  if not path['aspath']:  # path['aspath'] == []
   188                      self.assertEqual(path['local-pref'], 500)
   189  
   190          assert_several_times(f)
   191  
   192      # remove non-existing route with path_id via GoBGP CLI (no error check)
   193      def test_13_remove_non_existing_add_paths_route_via_cli(self):
   194          # specify locally non-existing identifier which has the same value
   195          # with the identifier of the route from e1
   196          self.g1.del_route(route='192.168.100.0/24', identifier=20)
   197  
   198      # test none of route is removed by non-existing path_id via CLI
   199      def test_14_check_g1_global_rib(self):
   200          def f():
   201              rib = self.g1.get_global_rib()
   202              self.assertEqual(len(rib), 1)
   203              self.assertEqual(len(rib[0]['paths']), 3)
   204              for path in rib[0]['paths']:
   205                  self.assertIn(path['aspath'], ([100, 200, 300],
   206                                                 [100, 200],
   207                                                 []))
   208                  if not path['aspath']:  # path['aspath'] == []
   209                      self.assertEqual(path['local-pref'], 500)
   210  
   211          assert_several_times(f)
   212  
   213      # remove route with path_id via GoBGP CLI (no error check)
   214      def test_15_remove_add_paths_route_via_cli(self):
   215          self.g1.del_route(route='192.168.100.0/24', identifier=10)
   216  
   217      # test the route is removed from the rib via CLI
   218      def test_16_check_g1_global_rib(self):
   219          def f():
   220              rib = self.g1.get_global_rib()
   221              self.assertEqual(len(rib), 1)
   222              self.assertEqual(len(rib[0]['paths']), 2)
   223              for path in rib[0]['paths']:
   224                  self.assertIn(path['aspath'], ([100, 200, 300],
   225                                                 [100, 200]))
   226  
   227          assert_several_times(f)
   228  
   229      # test the best path is replaced the removal from g1 rib
   230      def test_17_check_g2_global_rib(self):
   231          def f():
   232              rib = self.g2.get_global_rib()
   233              self.assertEqual(len(rib), 1)
   234              self.assertEqual(len(rib[0]['paths']), 1)
   235              self.assertEqual(rib[0]['paths'][0]['aspath'], [100, 200])
   236  
   237          assert_several_times(f)
   238  
   239      # test the removed route from CLI is withdrawn by g1
   240      def test_18_check_g3_global_rib(self):
   241          def f():
   242              rib = self.g3.get_global_rib()
   243              self.assertEqual(len(rib), 1)
   244              self.assertEqual(len(rib[0]['paths']), 2)
   245              for path in rib[0]['paths']:
   246                  self.assertIn(path['aspath'], ([100, 200, 300],
   247                                                 [100, 200]))
   248  
   249          assert_several_times(f)
   250  
   251  
   252  if __name__ == '__main__':
   253      output = local("which docker 2>&1 > /dev/null ; echo $?", capture=True)
   254      if int(output) is not 0:
   255          print "docker not found"
   256          sys.exit(1)
   257  
   258      nose.main(argv=sys.argv, addplugins=[OptionParser()],
   259                defaultTest=sys.argv[0])