3 # Copyright (c) 2019 by VMware, Inc. ("VMware")
4 # Used Copyright (c) 2018 by Network Device Education Foundation, Inc. ("NetDEF")
7 # Permission to use, copy, modify, and/or distribute this software
8 # for any purpose with or without fee is hereby granted, provided
9 # that the above copyright notice and this permission notice appear
12 # THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
13 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
15 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
16 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
17 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
18 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
23 Following tests are covered to test BGP Gracefull Restart functionality.
24 Basic Common Test steps for all the test case below :
25 - Create topology (setup module)
26 Creating 2 routers topology, r1, r2 in IBGP
28 - Verify for bgp to converge
29 - Configure BGP Garceful Restart on both the routers.
31 1. Transition from Peer-level helper to Global Restarting
32 2. Transition from Peer-level helper to Global inherit helper
33 3. Transition from Peer-level restarting to Global inherit helper
34 4. Default GR functional mode is Helper.
35 5. Verify that the restarting node sets "R" bit while sending the
36 BGP open messages after the node restart, only if GR is enabled.
37 6. Verify if restarting node resets R bit in BGP open message
38 during normal BGP session flaps as well, even when GR restarting
39 mode is enabled. Here link flap happen due to interface UP/DOWN.
40 7. Verify if restarting node resets R bit in BGP
41 open message during normal BGP session flaps when GR is disabled.
42 8. Verify that restarting nodes set "F" bit while sending
43 the BGP open messages after it restarts, only when BGP GR is enabled.
44 9. Verify that only GR helper routers keep the stale
45 route entries, not any GR disabled router.
46 10. Verify that GR helper routers keeps all the routes received
47 from restarting node if both the routers are configured as
49 11. Verify that GR helper routers delete all the routes
50 received from a node if both the routers are configured as GR
52 12. After BGP neighborship is established and GR capability is exchanged,
53 transition restarting router to disabled state and vice versa.
54 13. After BGP neighborship is established and GR capability is exchanged,
55 transition restarting router to disabled state and vice versa.
56 14. Verify that restarting nodes reset "F" bit while sending
57 the BGP open messages after it's restarts, when BGP GR is **NOT** enabled.
58 15. Verify that only GR helper routers keep the stale
59 route entries, not any GR disabled router.
60 16. Transition from Global Restarting to Disable and then Global
61 Disable to Restarting.
62 17. Transition from Global Helper to Disable and then Global
64 18. Transition from Global Restart to Helper and then Global
65 Helper to Restart, Global Mode : GR Restarting
66 PerPeer Mode : GR Helper
67 GR Mode effective : GR Helper
68 19. Transition from Peer-level helper to Global Restarting,
69 Global Mode : GR Restarting
70 PerPeer Mode : GR Restarting
71 GR Mode effective : GR Restarting
72 20. Transition from Peer-level restart to Global Restart
73 Global Mode : GR Restarting
74 PerPeer Mode : GR Restarting
75 GR Mode effective : GR Restarting
76 21. Transition from Peer-level disabled to Global Restart
77 Global Mode : GR Restarting
78 PerPeer Mode : GR Disabled
79 GR Mode effective : GR Disabled
80 22. Peer-level inherit from Global Restarting
81 Global Mode : GR Restart
83 GR Mode effective : GR Restart
84 23. Transition from Peer-level disbale to Global inherit helper
86 PerPeer Mode : GR Disable
87 GR Mode effective : GR Disable
89 These tests have been broken up into 4 sub python scripts because
90 the totality of this run was fairly significant.
98 # Save the Current Working Directory to find configuration files.
99 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
100 sys
.path
.append(os
.path
.join("../"))
101 sys
.path
.append(os
.path
.join("../lib/"))
103 # pylint: disable=C0413
104 # Import topogen and topotest helpers
105 from lib
.topogen
import Topogen
, get_topogen
106 from lib
.topolog
import logger
108 # Required to instantiate the topology builder class.
110 # Import topoJson from lib, to create topology and initial configuration
111 from lib
.topojson
import build_config_from_json
112 from lib
.bgp
import (
115 verify_graceful_restart
,
119 verify_bgp_convergence
,
120 verify_bgp_convergence_from_running_config
,
123 from lib
.common_config
import (
125 reset_config_on_routers
,
128 start_router_daemons
,
133 shutdown_bringup_interface
,
135 get_frr_ipv6_linklocal
,
136 required_linux_kernel_version
,
139 pytestmark
= [pytest
.mark
.bgpd
]
143 NEXT_HOP_IP
= {"ipv4": "192.168.1.10", "ipv6": "fd00:0:0:1::10"}
144 NEXT_HOP_IP_1
= {"ipv4": "192.168.0.1", "ipv6": "fd00::1"}
145 NEXT_HOP_IP_2
= {"ipv4": "192.168.0.2", "ipv6": "fd00::2"}
146 BGP_CONVERGENCE
= False
147 GR_RESTART_TIMER
= 20
148 PREFERRED_NEXT_HOP
= "link_local"
151 def setup_module(mod
):
153 Sets up the pytest environment
160 # Required linux kernel version for this suite to run.
161 result
= required_linux_kernel_version("4.16")
162 if result
is not True:
163 pytest
.skip("Kernel requirements are not met")
165 testsuite_run_time
= time
.asctime(time
.localtime(time
.time()))
166 logger
.info("Testsuite start time: {}".format(testsuite_run_time
))
167 logger
.info("=" * 40)
169 logger
.info("Running setup_module to create topology")
171 # This function initiates the topology build with Topogen...
172 json_file
= "{}/bgp_gr_topojson_topo1.json".format(CWD
)
173 tgen
= Topogen(json_file
, mod
.__name
__)
175 topo
= tgen
.json_topo
176 # ... and here it calls Mininet initialization functions.
178 # Starting topology, create tmp files which are loaded to routers
179 # to start deamons and then start routers
182 # Creating configuration from JSON
183 build_config_from_json(tgen
, topo
)
185 # Don't run this test if we have any failure.
186 if tgen
.routers_have_failure():
187 pytest
.skip(tgen
.errors
)
189 # Api call verify whether BGP is converged
190 ADDR_TYPES
= check_address_types()
192 BGP_CONVERGENCE
= verify_bgp_convergence(tgen
, topo
)
193 assert BGP_CONVERGENCE
is True, "setup_module : Failed \n Error:" " {}".format(
197 logger
.info("Running setup_module() done")
200 def teardown_module(mod
):
202 Teardown the pytest environment
207 logger
.info("Running teardown_module to delete topology")
211 # Stop toplogy and Remove tmp files
215 "Testsuite end time: {}".format(time
.asctime(time
.localtime(time
.time())))
217 logger
.info("=" * 40)
220 def configure_gr_followed_by_clear(tgen
, topo
, input_dict
, tc_name
, dut
, peer
):
222 This function groups the repetitive function calls into one function.
225 result
= create_router_bgp(tgen
, topo
, input_dict
)
226 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
228 for addr_type
in ADDR_TYPES
:
229 neighbor
= topo
["routers"][peer
]["links"]["r1-link1"][addr_type
].split("/")[0]
230 clear_bgp(tgen
, addr_type
, dut
, neighbor
=neighbor
)
232 for addr_type
in ADDR_TYPES
:
233 neighbor
= topo
["routers"][dut
]["links"]["r2-link1"][addr_type
].split("/")[0]
234 clear_bgp(tgen
, addr_type
, peer
, neighbor
=neighbor
)
236 result
= verify_bgp_convergence_from_running_config(tgen
)
237 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
242 def next_hop_per_address_family(
243 tgen
, dut
, peer
, addr_type
, next_hop_dict
, preferred_next_hop
=PREFERRED_NEXT_HOP
246 This function returns link_local or global next_hop per address-family
249 intferface
= topo
["routers"][peer
]["links"]["{}-link1".format(dut
)]["interface"]
250 if addr_type
== "ipv6" and "link_local" in preferred_next_hop
:
251 next_hop
= get_frr_ipv6_linklocal(tgen
, peer
, intf
=intferface
)
253 next_hop
= next_hop_dict
[addr_type
]
258 def test_BGP_GR_TC_8_p1(request
):
260 Test Objective : Verify that restarting nodes set "F" bit while sending
261 the BGP open messages after it restarts, only when BGP GR is enabled.
265 tc_name
= request
.node
.name
266 write_test_header(tc_name
)
268 # Check router status
269 check_router_status(tgen
)
271 # Don't run this test if we have any failure.
272 if tgen
.routers_have_failure():
273 pytest
.skip(tgen
.errors
)
275 # Creating configuration from JSON
276 reset_config_on_routers(tgen
)
279 "[Phase 1] : Test Setup" " [Restart Mode]R1-----R2[Restart Mode] initialized "
282 # Configure graceful-restart
286 "graceful-restart": {"preserve-fw-state": True},
293 "r1-link1": {"graceful-restart": True}
304 "r1-link1": {"graceful-restart": True}
321 "r2-link1": {"graceful-restart": True}
332 "r2-link1": {"graceful-restart": True}
343 configure_gr_followed_by_clear(tgen
, topo
, input_dict
, tc_name
, dut
="r1", peer
="r2")
345 for addr_type
in ADDR_TYPES
:
346 result
= verify_graceful_restart(
347 tgen
, topo
, addr_type
, input_dict
, dut
="r1", peer
="r2"
349 assert result
is True, "Testcase {} : Failed \n Error {}".format(
353 # Verifying BGP RIB routes
356 next_hop
= next_hop_per_address_family(
357 tgen
, dut
, peer
, addr_type
, NEXT_HOP_IP_2
359 input_topo
= {key
: topo
["routers"][key
] for key
in ["r2"]}
360 result
= verify_bgp_rib(tgen
, addr_type
, dut
, input_topo
, next_hop
)
361 assert result
is True, "Testcase {} : Failed \n Error {}".format(
365 # Verifying RIB routes
367 result
= verify_rib(tgen
, addr_type
, dut
, input_topo
, next_hop
, protocol
)
368 assert result
is True, "Testcase {} : Failed \n Error {}".format(
372 logger
.info("[Phase 2] : R1 goes for reload ")
374 kill_router_daemons(tgen
, "r1", ["bgpd"])
376 logger
.info("[Phase 3] : R1 is about to come up now ")
377 start_router_daemons(tgen
, "r1", ["bgpd"])
379 logger
.info("[Phase 4] : R2 is UP now, so time to collect GR stats ")
381 for addr_type
in ADDR_TYPES
:
382 result
= verify_graceful_restart(
383 tgen
, topo
, addr_type
, input_dict
, dut
="r1", peer
="r2"
385 assert result
is True, "Testcase {} : Failed \n Error {}".format(
389 result
= verify_r_bit(tgen
, topo
, addr_type
, input_dict
, dut
="r2", peer
="r1")
390 assert result
is True, "Testcase {} : Failed \n Error {}".format(
394 result
= verify_f_bit(tgen
, topo
, addr_type
, input_dict
, dut
="r2", peer
="r1")
395 assert result
is True, "Testcase {} : Failed \n Error {}".format(
399 write_test_footer(tc_name
)
402 if __name__
== "__main__":
403 args
= ["-s"] + sys
.argv
[1:]
404 sys
.exit(pytest
.main(args
))