]>
Commit | Line | Data |
---|---|---|
586e15c4 | 1 | #!/usr/bin/env python |
acddc0ed | 2 | # SPDX-License-Identifier: ISC |
586e15c4 MW |
3 | |
4 | # | |
5 | # test_bgp_multiview_topo1.py | |
6 | # Part of NetDEF Topology Tests | |
7 | # | |
8 | # Copyright (c) 2016 by | |
9 | # Network Device Education Foundation, Inc. ("NetDEF") | |
10 | # | |
586e15c4 | 11 | |
21b5cd1d | 12 | r""" |
622c4996 | 13 | test_bgp_multiview_topo1.py: Simple FRR Route-Server Test |
586e15c4 | 14 | |
04df53ab MW |
15 | +----------+ +----------+ +----------+ +----------+ +----------+ |
16 | | peer1 | | peer2 | | peer3 | | peer4 | | peer5 | | |
17 | | AS 65001 | | AS 65002 | | AS 65003 | | AS 65004 | | AS 65005 | | |
18 | +-----+----+ +-----+----+ +-----+----+ +-----+----+ +-----+----+ | |
9188c32f | 19 | | .1 | .2 | .3 | .4 | .5 |
04df53ab | 20 | | ______/ / / _________/ |
9188c32f DA |
21 | \ / ________________/ / / |
22 | | | / _________________________/ / +----------+ | |
04df53ab MW |
23 | | | | / __________________________/ ___| peer6 | |
24 | | | | | / ____________________________/.6 | AS 65006 | | |
25 | | | | | | / _________________________ +----------+ | |
9188c32f | 26 | | | | | | | / __________________ \ +----------+ |
04df53ab MW |
27 | | | | | | | | / \ \___| peer7 | |
28 | | | | | | | | | \ .7 | AS 65007 | | |
29 | ~~~~~~~~~~~~~~~~~~~~~ \ +----------+ | |
30 | ~~ SW1 ~~ \ +----------+ | |
9188c32f | 31 | ~~ Switch ~~ \_____| peer8 | |
04df53ab MW |
32 | ~~ 172.16.1.0/24 ~~ .8 | AS 65008 | |
33 | ~~~~~~~~~~~~~~~~~~~~~ +----------+ | |
34 | | | |
35 | | .254 | |
36 | +---------+---------+ | |
594b1259 | 37 | | FRR R1 | |
04df53ab | 38 | | BGP Multi-View | |
9188c32f | 39 | | Peer 1-3 > View 1 | |
04df53ab MW |
40 | | Peer 4-5 > View 2 | |
41 | | Peer 6-8 > View 3 | | |
42 | +---------+---------+ | |
43 | | .1 | |
44 | | | |
45 | ~~~~~~~~~~~~~ Stub Network is redistributed | |
46 | ~~ SW0 ~~ into each BGP view with different | |
47 | ~~ 172.20.0.1/28 ~~ attributes (using route-map) | |
48 | ~~ Stub Switch ~~ | |
49 | ~~~~~~~~~~~~~ | |
787e7624 | 50 | """ |
586e15c4 | 51 | |
62c608a9 | 52 | import json |
586e15c4 | 53 | import os |
586e15c4 | 54 | import sys |
594b1259 | 55 | import pytest |
6ca12047 | 56 | import json |
594b1259 | 57 | from time import sleep |
586e15c4 | 58 | |
586e15c4 | 59 | from functools import partial |
586e15c4 | 60 | |
594b1259 MW |
61 | sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) |
62 | from lib import topotest | |
e82b531d | 63 | from lib.topogen import get_topogen, Topogen |
62c608a9 | 64 | from lib.common_config import step |
586e15c4 | 65 | |
bf3a0a9a DS |
66 | |
67 | pytestmark = [pytest.mark.bgpd] | |
68 | ||
69 | ||
2cda38e4 MW |
70 | fatal_error = "" |
71 | ||
586e15c4 MW |
72 | |
73 | ##################################################### | |
74 | ## | |
75 | ## Network Topology Definition | |
76 | ## | |
77 | ##################################################### | |
78 | ||
787e7624 | 79 | |
e82b531d CH |
80 | def build_topo(tgen): |
81 | # Setup Routers | |
82 | router = tgen.add_router("r1") | |
586e15c4 | 83 | |
e82b531d CH |
84 | # Setup Provider BGP peers |
85 | peer = {} | |
86 | for i in range(1, 9): | |
87 | peer[i] = tgen.add_exabgp_peer( | |
a53c08bc | 88 | "peer%s" % i, ip="172.16.1.%s/24" % i, defaultRoute="via 172.16.1.254" |
e82b531d | 89 | ) |
586e15c4 | 90 | |
e82b531d CH |
91 | # First switch is for a dummy interface (for local network) |
92 | switch = tgen.add_switch("sw0") | |
93 | switch.add_link(router, nodeif="r1-stub") | |
594b1259 | 94 | |
e82b531d CH |
95 | # Second switch is for connection to all peering routers |
96 | switch = tgen.add_switch("sw1") | |
97 | switch.add_link(router, nodeif="r1-eth0") | |
98 | for j in range(1, 9): | |
99 | switch.add_link(peer[j], nodeif="peer%s-eth0" % j) | |
586e15c4 MW |
100 | |
101 | ||
102 | ##################################################### | |
103 | ## | |
104 | ## Tests starting | |
105 | ## | |
106 | ##################################################### | |
107 | ||
787e7624 | 108 | |
586e15c4 | 109 | def setup_module(module): |
586e15c4 | 110 | thisDir = os.path.dirname(os.path.realpath(__file__)) |
e82b531d CH |
111 | tgen = Topogen(build_topo, module.__name__) |
112 | tgen.start_topology() | |
586e15c4 MW |
113 | |
114 | # Starting Routers | |
e82b531d CH |
115 | router = tgen.net["r1"] |
116 | router.loadConf("zebra", "%s/r1/zebra.conf" % thisDir) | |
117 | router.loadConf("bgpd", "%s/r1/bgpd.conf" % thisDir) | |
118 | tgen.gears["r1"].start() | |
586e15c4 MW |
119 | |
120 | # Starting PE Hosts and init ExaBGP on each of them | |
e82b531d CH |
121 | peer_list = tgen.exabgp_peers() |
122 | for pname, peer in peer_list.items(): | |
123 | peer_dir = os.path.join(thisDir, pname) | |
124 | env_file = os.path.join(thisDir, "exabgp.env") | |
125 | peer.start(peer_dir, env_file) | |
586e15c4 | 126 | |
787e7624 | 127 | |
586e15c4 | 128 | def teardown_module(module): |
e82b531d CH |
129 | tgen = get_topogen() |
130 | tgen.stop_topology() | |
586e15c4 | 131 | |
787e7624 | 132 | |
594b1259 | 133 | def test_router_running(): |
e82b531d | 134 | tgen = get_topogen() |
594b1259 | 135 | |
e82b531d CH |
136 | if tgen.routers_have_failure(): |
137 | pytest.skip(tgen.errors) | |
594b1259 | 138 | |
586e15c4 MW |
139 | |
140 | def test_bgp_converge(): | |
141 | "Check for BGP converged on all peers and BGP views" | |
142 | ||
e82b531d | 143 | tgen = get_topogen() |
586e15c4 | 144 | |
e82b531d CH |
145 | if tgen.routers_have_failure(): |
146 | pytest.skip(tgen.errors) | |
2cda38e4 | 147 | |
586e15c4 | 148 | # Wait for BGP to converge (All Neighbors in either Full or TwoWay State) |
62c608a9 | 149 | step("Verify for BGP to converge") |
6ca12047 | 150 | |
12a939b7 | 151 | timeout = 125 |
586e15c4 MW |
152 | while timeout > 0: |
153 | print("Timeout in %s: " % timeout), | |
154 | sys.stdout.flush() | |
155 | # Look for any node not yet converged | |
156 | for i in range(1, 2): | |
157 | for view in range(1, 4): | |
e82b531d | 158 | notConverged = tgen.net["r%s" % i].cmd( |
37076cae | 159 | r'vtysh -c "show ip bgp view %s summary" 2> /dev/null | grep ^[0-9] | grep -vP " 11\s+(\d+)"' |
787e7624 | 160 | % view |
161 | ) | |
586e15c4 | 162 | if notConverged: |
787e7624 | 163 | print("Waiting for r%s, view %s" % (i, view)) |
586e15c4 MW |
164 | sys.stdout.flush() |
165 | break | |
166 | if notConverged: | |
167 | break | |
168 | if notConverged: | |
169 | sleep(5) | |
170 | timeout -= 5 | |
171 | else: | |
787e7624 | 172 | print("Done") |
586e15c4 MW |
173 | break |
174 | else: | |
175 | # Bail out with error if a router fails to converge | |
a53c08bc CH |
176 | bgpStatus = tgen.net["r%s" % i].cmd( |
177 | 'vtysh -c "show ip bgp view %s summary"' % view | |
178 | ) | |
586e15c4 MW |
179 | assert False, "BGP did not converge:\n%s" % bgpStatus |
180 | ||
e82b531d | 181 | tgen.routers_have_failure() |
586e15c4 | 182 | |
787e7624 | 183 | |
586e15c4 | 184 | def test_bgp_routingTable(): |
e82b531d CH |
185 | tgen = get_topogen() |
186 | ||
187 | if tgen.routers_have_failure(): | |
188 | pytest.skip(tgen.errors) | |
189 | ||
586e15c4 | 190 | thisDir = os.path.dirname(os.path.realpath(__file__)) |
e82b531d | 191 | |
62c608a9 | 192 | step("Verifying BGP Routing Tables") |
50c40bde | 193 | |
62c608a9 MW |
194 | router = tgen.gears["r1"] |
195 | for view in range(1, 4): | |
196 | json_file = "{}/{}/view_{}.json".format(thisDir, router.name, view) | |
197 | expected = json.loads(open(json_file).read()) | |
198 | test_func = partial( | |
a53c08bc CH |
199 | topotest.router_json_cmp, |
200 | router, | |
201 | "show ip bgp view {} json".format(view), | |
202 | expected, | |
787e7624 | 203 | ) |
62c608a9 MW |
204 | _, result = topotest.run_and_expect(test_func, None, count=5, wait=1) |
205 | assertmsg = "Routing Table verification failed for router {}, view {}".format( | |
206 | router.name, view | |
207 | ) | |
208 | assert result is None, assertmsg | |
99561211 | 209 | |
62c608a9 | 210 | tgen.routers_have_failure() |
99561211 | 211 | |
586e15c4 | 212 | |
50c40bde | 213 | def test_shutdown_check_memleak(): |
e82b531d CH |
214 | tgen = get_topogen() |
215 | if not tgen.is_memleak_enabled(): | |
216 | pytest.skip("Memory leak test/report is disabled") | |
50c40bde | 217 | |
e82b531d | 218 | tgen.report_memory_leaks() |
50c40bde MW |
219 | |
220 | ||
787e7624 | 221 | if __name__ == "__main__": |
2cda38e4 MW |
222 | # To suppress tracebacks, either use the following pytest call or add "--tb=no" to cli |
223 | # retval = pytest.main(["-s", "--tb=no"]) | |
586e15c4 MW |
224 | retval = pytest.main(["-s"]) |
225 | sys.exit(retval) |