github.com/osrg/gobgp@v2.0.0+incompatible/test/scenario_test/long_lived_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  from itertools import chain
    19  import sys
    20  import time
    21  import unittest
    22  
    23  from fabric.api import local
    24  import nose
    25  
    26  from lib.noseplugin import OptionParser, parser_option
    27  
    28  from lib import base
    29  from lib.base import (
    30      BGP_FSM_ACTIVE,
    31      BGP_FSM_ESTABLISHED,
    32      LONG_LIVED_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          g3 = GoBGPContainer(name='g3', asn=65002, router_id='192.168.0.3',
    51                              ctn_image_name=gobgp_ctn_image_name,
    52                              log_level=parser_option.gobgp_log_level)
    53          g4 = GoBGPContainer(name='g4', asn=65003, router_id='192.168.0.4',
    54                              ctn_image_name=gobgp_ctn_image_name,
    55                              log_level=parser_option.gobgp_log_level)
    56          ctns = [g1, g2, g3, g4]
    57  
    58          initial_wait_time = max(ctn.run() for ctn in ctns)
    59  
    60          time.sleep(initial_wait_time)
    61  
    62          g1.add_peer(g2, graceful_restart=True, llgr=True)
    63          g2.add_peer(g1, graceful_restart=True, llgr=True)
    64          g1.add_peer(g3, graceful_restart=True, llgr=True)
    65          g3.add_peer(g1, graceful_restart=True, llgr=True)
    66          g1.add_peer(g4, graceful_restart=True)
    67          g4.add_peer(g1, graceful_restart=True)
    68  
    69          cls.bgpds = {'g1': g1, 'g2': g2, 'g3': g3, 'g4': g4}
    70  
    71      # test each neighbor state is turned establish
    72      def test_01_neighbor_established(self):
    73          g1 = self.bgpds['g1']
    74          g2 = self.bgpds['g2']
    75          g3 = self.bgpds['g3']
    76          g4 = self.bgpds['g4']
    77          g1.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=g2)
    78          g1.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=g3)
    79          g1.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=g4)
    80  
    81      def test_02_graceful_restart(self):
    82          g1 = self.bgpds['g1']
    83          g2 = self.bgpds['g2']
    84          g3 = self.bgpds['g3']
    85          g4 = self.bgpds['g4']
    86  
    87          g2.local('gobgp global rib add 10.0.0.0/24')
    88          g2.local('gobgp global rib add 10.10.0.0/24 community no-llgr')
    89  
    90          time.sleep(1)
    91  
    92          g2.stop_gobgp()
    93          g1.wait_for(expected_state=BGP_FSM_ACTIVE, peer=g2)
    94  
    95          time.sleep(1)
    96  
    97          self.assertEqual(len(g1.get_global_rib('10.0.0.0/24')), 1)
    98          # 10.10.0.0/24 is announced with no-llgr community
    99          # must not exist in the rib
   100          self.assertEqual(len(g1.get_global_rib('10.10.0.0/24')), 0)
   101          for d in g1.get_global_rib():
   102              for p in d['paths']:
   103                  self.assertTrue(p['stale'])
   104  
   105          self.assertEqual(len(g3.get_global_rib('10.0.0.0/24')), 1)
   106          # check llgr-stale community is added to 10.0.0.0/24
   107          r = g3.get_global_rib('10.0.0.0/24')[0]['paths'][0]
   108          comms = list(chain.from_iterable([attr['communities'] for attr in r['attrs'] if attr['type'] == 8]))
   109          self.assertTrue(0xffff0006 in comms)
   110          # g4 is not llgr capable, llgr-stale route must be
   111          # withdrawn
   112          self.assertEqual(len(g4.get_global_rib('10.0.0.0/24')), 0)
   113  
   114          g2.start_gobgp(graceful_restart=True)
   115          g2.local('gobgp global rib add 10.0.0.0/24')
   116          g2.local('gobgp global rib add 10.10.0.0/24')
   117  
   118      def test_03_neighbor_established(self):
   119          g1 = self.bgpds['g1']
   120          g2 = self.bgpds['g2']
   121          # g3 = self.bgpds['g3']
   122          # g4 = self.bgpds['g4']
   123          g1.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=g2)
   124          time.sleep(1)
   125          self.assertEqual(len(g1.get_global_rib('10.0.0.0/24')), 1)
   126          self.assertEqual(len(g1.get_global_rib('10.10.0.0/24')), 1)
   127          for d in g1.get_global_rib():
   128              for p in d['paths']:
   129                  self.assertFalse(p.get('stale', False))
   130  
   131      def test_04_llgr_stale_route_depreferenced(self):
   132          g1 = self.bgpds['g1']
   133          g2 = self.bgpds['g2']
   134          g3 = self.bgpds['g3']
   135          g4 = self.bgpds['g4']
   136          g4.local('gobgp global rib add 10.0.0.0/24 med 100')
   137          time.sleep(1)
   138          # check g2's path is chosen as best and advertised
   139          rib = g3.get_global_rib('10.0.0.0/24')
   140          self.assertEqual(len(rib), 1)
   141          self.assertTrue(g2.asn in rib[0]['paths'][0]['aspath'])
   142  
   143          g2.stop_gobgp()
   144          g1.wait_for(expected_state=BGP_FSM_ACTIVE, peer=g2)
   145  
   146          time.sleep(1)
   147  
   148          # llgr_stale route depreference must happend
   149          # check g4's path is chosen as best and advertised
   150          rib = g3.get_global_rib('10.0.0.0/24')
   151          self.assertEqual(len(rib), 1)
   152          self.assertTrue(g4.asn in rib[0]['paths'][0]['aspath'])
   153  
   154          # if no candidate exists, llgr_stale route will be chosen as best
   155          rib = g3.get_global_rib('10.10.0.0/24')
   156          self.assertEqual(len(rib), 1)
   157          self.assertTrue(g2.asn in rib[0]['paths'][0]['aspath'])
   158  
   159      def test_05_llgr_restart_timer_expire(self):
   160          time.sleep(LONG_LIVED_GRACEFUL_RESTART_TIME + 5)
   161          g3 = self.bgpds['g3']
   162          rib = g3.get_global_rib('10.10.0.0/24')
   163          self.assertEqual(len(rib), 0)
   164  
   165  
   166  if __name__ == '__main__':
   167      output = local("which docker 2>&1 > /dev/null ; echo $?", capture=True)
   168      if int(output) is not 0:
   169          print "docker not found"
   170          sys.exit(1)
   171  
   172      nose.main(argv=sys.argv, addplugins=[OptionParser()],
   173                defaultTest=sys.argv[0])