github.com/osrg/gobgp/v3@v3.30.0/test/scenario_test/mup_test.py (about)

     1  # Copyright (C) 2022 Yuya Kusakabe <yuya.kusakabe@gmail.com>
     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  
    17  from itertools import combinations
    18  import sys
    19  import time
    20  import unittest
    21  import logging
    22  log = logging.getLogger(__name__)
    23  
    24  import collections
    25  collections.Callable = collections.abc.Callable
    26  
    27  import nose
    28  
    29  from lib.noseplugin import OptionParser, parser_option
    30  
    31  from lib import base
    32  from lib.base import (
    33      BGP_FSM_ESTABLISHED,
    34      BGP_ATTR_TYPE_EXTENDED_COMMUNITIES,
    35      local,
    36  )
    37  from lib.gobgp import GoBGPContainer
    38  
    39  
    40  class GoBGPTestBase(unittest.TestCase):
    41  
    42      @classmethod
    43      def setUpClass(cls):
    44          gobgp_ctn_image_name = parser_option.gobgp_image
    45          base.TEST_PREFIX = parser_option.test_prefix
    46  
    47          g1 = GoBGPContainer(name='g1', asn=65000, router_id='192.168.0.1',
    48                              ctn_image_name=gobgp_ctn_image_name,
    49                              log_level=parser_option.gobgp_log_level)
    50          g2 = GoBGPContainer(name='g2', asn=65000, router_id='192.168.0.2',
    51                              ctn_image_name=gobgp_ctn_image_name,
    52                              log_level=parser_option.gobgp_log_level)
    53          ctns = [g1, g2]
    54  
    55          initial_wait_time = max(ctn.run() for ctn in ctns)
    56  
    57          time.sleep(initial_wait_time)
    58  
    59          for a, b in combinations(ctns, 2):
    60               a.add_peer(b, mup=True, passwd='mup')
    61               b.add_peer(a, mup=True, passwd='mup')
    62  
    63          cls.g1 = g1
    64          cls.g2 = g2
    65  
    66  
    67      # test each neighbor state is turned establish
    68      def test_01_neighbor_established(self):
    69          self.g1.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=self.g2)
    70  
    71  
    72      def test_02_add_del_mup_route(self):
    73          tests = [
    74                  ('mup_isd_route_ipv4', 'ipv4-mup', 'isd 10.0.0.0/24 rd 100:100 prefix 2001:db8:1:1::/64 locator-node-length 24 function-length 16 behavior ENDM_GTP4E rt 10:10 nexthop 2001::2', '2001::2'),
    75                  ('mup_dsd_route_ipv4', 'ipv4-mup', 'dsd 10.0.0.1 rd 100:100 prefix 2001:db8:2:2::/64 locator-node-length 24 function-length 16 behavior END_DT4 rt 10:10 mup 10:10 nexthop 2001::2', '2001::2'),
    76                  ('mup_t1st_route_ipv4', 'ipv4-mup', 't1st 192.168.0.1/32 rd 100:100 rt 10:10 teid 12345 qfi 9 endpoint 10.0.0.1 nexthop 10.0.0.2', '10.0.0.2'),
    77                  ('mup_t1st_route_ipv4_with_source', 'ipv4-mup', 't1st 192.168.0.1/32 rd 100:100 rt 10:10 teid 12345 qfi 9 endpoint 10.0.0.1 source 10.0.0.3 nexthop 10.0.0.2', '10.0.0.2'),
    78                  ('mup_t1st_route_ipv4_hex_teid', 'ipv4-mup', 't1st 192.168.0.1/32 rd 100:100 rt 10:10 teid 0x00003039 qfi 9 endpoint 10.0.0.1 nexthop 10.0.0.2', '10.0.0.2'),
    79                  ('mup_t1st_route_ipv4_ip_teid', 'ipv4-mup', 't1st 192.168.0.1/32 rd 100:100 rt 10:10 teid 0.0.0.100 qfi 9 endpoint 10.0.0.1 nexthop 10.0.0.2', '10.0.0.2'),
    80                  ('mup_t2st_route_ipv4', 'ipv4-mup', 't2st 10.0.0.1 rd 100:100 rt 10:10 endpoint-address-length 64 teid 12345 mup 10:10 nexthop 10.0.0.2', '10.0.0.2'),
    81                  ('mup_t2st_route_ipv4_hex_teid', 'ipv4-mup', 't2st 10.0.0.1 rd 100:100 rt 10:10 endpoint-address-length 48 teid 0xbeef mup 10:10 nexthop 10.0.0.2', '10.0.0.2'),
    82                  ('mup_t2st_route_ipv4_ip_teid', 'ipv4-mup', 't2st 10.0.0.1 rd 100:100 rt 10:10 endpoint-address-length 64 teid 0.0.0.100 mup 10:10 nexthop 10.0.0.2', '10.0.0.2'),
    83                  ('mup_isd_route_ipv6', 'ipv6-mup', 'isd 2001::/64 rd 100:100 prefix 2001:db8:1:1::/64 locator-node-length 24 function-length 16 behavior ENDM_GTP6E rt 10:10 nexthop 2001::2', '2001::2'),
    84                  ('mup_dsd_route_ipv6', 'ipv6-mup', 'dsd 2001::1 rd 100:100 prefix 2001:db8:2:2::/64 locator-node-length 24 function-length 16 behavior END_DT6 rt 10:10 mup 10:10 nexthop 2001::2', '2001::2'),
    85                  ('mup_t1st_route_ipv6', 'ipv6-mup', 't1st 2001:db8:1:1::1/128 rd 100:100 rt 10:10 teid 12345 qfi 9 endpoint 2001::1 nexthop 10.0.0.2', '10.0.0.2'),
    86                  ('mup_t1st_route_ipv6_with_source', 'ipv6-mup', 't1st 2001:db8:1:1::1/128 rd 100:100 rt 10:10 teid 12345 qfi 9 endpoint 2001::1 source 2001::2 nexthop 10.0.0.2', '10.0.0.2'),
    87                  ('mup_t1st_route_ipv6_hex_teid', 'ipv6-mup', 't1st 2001:db8:1:1::1/128 rd 100:100 rt 10:10 teid 0x00003039 qfi 9 endpoint 2001::1 nexthop 10.0.0.2', '10.0.0.2'),
    88                  ('mup_t1st_route_ipv6_ip_teid', 'ipv6-mup', 't1st 2001:db8:1:1::1/128 rd 100:100 rt 10:10 teid 0.0.0.100 qfi 9 endpoint 2001::1 nexthop 10.0.0.2', '10.0.0.2'),
    89                  ('mup_t2st_route_ipv6', 'ipv6-mup', 't2st 2001::1 rd 100:100 rt 10:10 endpoint-address-length 160 teid 12345 mup 10:10 nexthop 10.0.0.2', '10.0.0.2'),
    90                  ('mup_t2st_route_ipv6_hex_teid', 'ipv6-mup', 't2st 2001::1 rd 100:100 rt 10:10 endpoint-address-length 144 teid 0xbeef mup 10:10 nexthop 10.0.0.2', '10.0.0.2'),
    91                  ('mup_t2st_route_ipv6_ip_teid', 'ipv6-mup', 't2st 2001::1 rd 100:100 rt 10:10 endpoint-address-length 160 teid 0.0.0.100 mup 10:10 nexthop 10.0.0.2', '10.0.0.2'),
    92                  ]
    93          for msg, rf, route, nh in tests:
    94              with self.subTest(msg):
    95                  self.g1.local('gobgp global rib add '
    96                                '-a {} {}'.format(rf, route))
    97                  grib = self.g1.get_global_rib(rf=rf)
    98                  log.debug('grib: {}'.format(grib))
    99                  self.assertEqual(len(grib), 1)
   100                  dst = grib[0]
   101                  self.assertEqual(len(dst['paths']), 1)
   102                  path = dst['paths'][0]
   103                  self.assertEqual(path['nexthop'], nh)
   104  
   105                  interval = 1
   106                  timeout = int(30 / interval)
   107                  done = False
   108                  for _ in range(timeout):
   109                      if done:
   110                          break
   111                      grib = self.g2.get_global_rib(rf=rf)
   112  
   113                      if len(grib) < 1:
   114                          time.sleep(interval)
   115                          continue
   116  
   117                      self.assertEqual(len(grib), 1)
   118                      dst = grib[0]
   119                      self.assertEqual(len(dst['paths']), 1)
   120                      path = dst['paths'][0]
   121                      n_addrs = [i[1].split('/')[0] for i in self.g1.ip_addrs]
   122                      self.assertEqual(path['nexthop'], nh)
   123                      done = True
   124  
   125                  self.g1.local('gobgp global rib del '
   126                                '-a {} {}'.format(rf, route))
   127  
   128                  done = False
   129                  for _ in range(timeout):
   130                      if done:
   131                          break
   132                      grib = self.g2.get_global_rib(rf=rf)
   133  
   134                      if len(grib) > 0:
   135                          time.sleep(interval)
   136                          continue
   137                      done = True
   138  
   139  
   140  if __name__ == '__main__':
   141      output = local("which docker 2>&1 > /dev/null ; echo $?", capture=True)
   142      if int(output) != 0:
   143          print("docker not found")
   144          sys.exit(1)
   145  
   146      nose.main(argv=sys.argv, addplugins=[OptionParser()],
   147                defaultTest=sys.argv[0])