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