github.com/osrg/gobgp@v2.0.0+incompatible/test/scenario_test/graceful_restart_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  from __future__ import absolute_import
    17  
    18  import sys
    19  import time
    20  import unittest
    21  
    22  from fabric.api import local
    23  import nose
    24  
    25  from lib.noseplugin import OptionParser, parser_option
    26  
    27  from lib import base
    28  from lib.base import (
    29      BGP_FSM_IDLE,
    30      BGP_FSM_ACTIVE,
    31      BGP_FSM_ESTABLISHED,
    32      GRACEFUL_RESTART_TIME,
    33  )
    34  from lib.gobgp import GoBGPContainer
    35  
    36  
    37  class GoBGPTestBase(unittest.TestCase):
    38  
    39      @classmethod
    40      def setUpClass(cls):
    41          gobgp_ctn_image_name = parser_option.gobgp_image
    42          base.TEST_PREFIX = parser_option.test_prefix
    43  
    44          g1 = GoBGPContainer(name='g1', asn=65000, router_id='192.168.0.1',
    45                              ctn_image_name=gobgp_ctn_image_name,
    46                              log_level=parser_option.gobgp_log_level)
    47          g2 = GoBGPContainer(name='g2', asn=65001, router_id='192.168.0.2',
    48                              ctn_image_name=gobgp_ctn_image_name,
    49                              log_level=parser_option.gobgp_log_level)
    50          ctns = [g1, g2]
    51  
    52          initial_wait_time = max(ctn.run() for ctn in ctns)
    53  
    54          time.sleep(initial_wait_time)
    55  
    56          g1.add_route('10.10.10.0/24')
    57          g1.add_route('10.10.20.0/24')
    58  
    59          g1.add_peer(g2, graceful_restart=True)
    60          g2.add_peer(g1, graceful_restart=True)
    61  
    62          cls.bgpds = {'g1': g1, 'g2': g2}
    63  
    64      # test each neighbor state is turned establish
    65      def test_01_neighbor_established(self):
    66          g1 = self.bgpds['g1']
    67          g2 = self.bgpds['g2']
    68          g1.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=g2)
    69  
    70      def test_02_graceful_restart(self):
    71          g1 = self.bgpds['g1']
    72          g2 = self.bgpds['g2']
    73          g1.stop_gobgp()
    74          g2.wait_for(expected_state=BGP_FSM_ACTIVE, peer=g1)
    75          self.assertEqual(len(g2.get_global_rib('10.10.20.0/24')), 1)
    76          self.assertEqual(len(g2.get_global_rib('10.10.10.0/24')), 1)
    77          for d in g2.get_global_rib():
    78              for p in d['paths']:
    79                  self.assertTrue(p['stale'])
    80  
    81          # Confirm the paths on the adj-RIB-in table are synced with the Global
    82          # table.
    83          self.assertEqual(len(g2.get_adj_rib_in(g1, '10.10.20.0/24')), 1)
    84          self.assertEqual(len(g2.get_adj_rib_in(g1, '10.10.10.0/24')), 1)
    85          for p in g2.get_adj_rib_in(g1):
    86              self.assertTrue(p['stale'])
    87  
    88          g1.routes = {}
    89          g1.start_gobgp(graceful_restart=True)
    90          g1.add_route('10.10.20.0/24')
    91  
    92      def test_03_neighbor_established(self):
    93          g1 = self.bgpds['g1']
    94          g2 = self.bgpds['g2']
    95          g1.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=g2)
    96  
    97          # Confirm the restart timer not expired.
    98          self.assertEqual(
    99              g2.local(
   100                  "grep 'graceful restart timer expired' %s/gobgpd.log"
   101                  " | wc -l" % (g2.SHARED_VOLUME), capture=True),
   102              '0')
   103          time.sleep(1)
   104  
   105          self.assertEqual(len(g2.get_global_rib('10.10.20.0/24')), 1)
   106          self.assertEqual(len(g2.get_global_rib('10.10.10.0/24')), 0)
   107          for d in g2.get_global_rib():
   108              for p in d['paths']:
   109                  self.assertFalse(p.get('stale', False))
   110  
   111          # Confirm the stale paths are also removed from the adj-RIB-in table.
   112          # https://github.com/osrg/gobgp/pull/1707
   113          self.assertEqual(len(g2.get_adj_rib_in(g1, '10.10.20.0/24')), 1)
   114          self.assertEqual(len(g2.get_adj_rib_in(g1, '10.10.10.0/24')), 0)
   115          for p in g2.get_adj_rib_in(g1):
   116              self.assertFalse(p.get('stale', False))
   117  
   118      def test_04_add_non_graceful_restart_enabled_peer(self):
   119          g1 = self.bgpds['g1']
   120          # g2 = self.bgpds['g2']
   121          gobgp_ctn_image_name = parser_option.gobgp_image
   122          g3 = GoBGPContainer(name='g3', asn=65002, router_id='192.168.0.3',
   123                              ctn_image_name=gobgp_ctn_image_name,
   124                              log_level=parser_option.gobgp_log_level)
   125          self.bgpds['g3'] = g3
   126          time.sleep(g3.run())
   127          g3.add_route('10.10.30.0/24')
   128          g1.add_peer(g3)
   129          g3.add_peer(g1)
   130          g1.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=g3)
   131          time.sleep(1)
   132          self.assertEqual(len(g3.get_global_rib('10.10.20.0/24')), 1)
   133  
   134      def test_05_graceful_restart(self):
   135          g1 = self.bgpds['g1']
   136          g2 = self.bgpds['g2']
   137          g3 = self.bgpds['g3']
   138          g1.stop_gobgp()
   139          g2.wait_for(expected_state=BGP_FSM_ACTIVE, peer=g1)
   140          self.assertEqual(len(g2.get_global_rib('10.10.20.0/24')), 1)
   141          self.assertEqual(len(g2.get_global_rib('10.10.30.0/24')), 1)
   142          for d in g2.get_global_rib():
   143              for p in d['paths']:
   144                  self.assertTrue(p['stale'])
   145  
   146          self.assertEqual(len(g3.get_global_rib('10.10.20.0/24')), 0)
   147          self.assertEqual(len(g3.get_global_rib('10.10.30.0/24')), 1)
   148  
   149      def test_06_test_restart_timer_expire(self):
   150          time.sleep(GRACEFUL_RESTART_TIME + 5)
   151          g2 = self.bgpds['g2']
   152          self.assertEqual(len(g2.get_global_rib()), 0)
   153  
   154      def test_07_multineighbor_established(self):
   155          g1 = self.bgpds['g1']
   156          g2 = self.bgpds['g2']
   157          g3 = self.bgpds['g3']
   158  
   159          g1.start_gobgp()
   160  
   161          g1.del_peer(g2)
   162          g1.del_peer(g3)
   163          g2.del_peer(g1)
   164          g3.del_peer(g1)
   165          g1.add_peer(g2, graceful_restart=True, llgr=True)
   166          g1.add_peer(g3, graceful_restart=True, llgr=True)
   167          g2.add_peer(g1, graceful_restart=True, llgr=True)
   168          g3.add_peer(g1, graceful_restart=True, llgr=True)
   169  
   170          g2.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=g1)
   171          g3.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=g1)
   172  
   173      def test_08_multineighbor_graceful_restart(self):
   174          g1 = self.bgpds['g1']
   175          g2 = self.bgpds['g2']
   176          g3 = self.bgpds['g3']
   177  
   178          g1.stop_gobgp()
   179          g2.wait_for(expected_state=BGP_FSM_ACTIVE, peer=g1)
   180          g3.wait_for(expected_state=BGP_FSM_ACTIVE, peer=g1)
   181  
   182          g1.start_gobgp(graceful_restart=True)
   183  
   184          count = 0
   185          while (g1.get_neighbor_state(g2) != BGP_FSM_ESTABLISHED
   186                 or g1.get_neighbor_state(g3) != BGP_FSM_ESTABLISHED):
   187              count += 1
   188              # assert connections are not refused
   189              self.assertTrue(g1.get_neighbor_state(g2) != BGP_FSM_IDLE)
   190              self.assertTrue(g1.get_neighbor_state(g3) != BGP_FSM_IDLE)
   191              if count > 120:
   192                  raise Exception('timeout')
   193              time.sleep(1)
   194  
   195  
   196  if __name__ == '__main__':
   197      output = local("which docker 2>&1 > /dev/null ; echo $?", capture=True)
   198      if int(output) is not 0:
   199          print "docker not found"
   200          sys.exit(1)
   201  
   202      nose.main(argv=sys.argv, addplugins=[OptionParser()],
   203                defaultTest=sys.argv[0])