]>
Commit | Line | Data |
---|---|---|
ac1087fa MW |
1 | #!/usr/bin/env python |
2 | ||
3 | # | |
4 | # test_bgp_ecmp_topo1.py | |
5 | # Part of NetDEF Topology Tests | |
6 | # | |
7 | # Copyright (c) 2017 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 | """ | |
26 | test_bgp_ecmp_topo1.py: Test BGP topology with ECMP (Equal Cost MultiPath). | |
27 | """ | |
28 | ||
35a00f24 | 29 | import json |
ab4d1656 | 30 | import functools |
ac1087fa | 31 | import os |
ac1087fa MW |
32 | import sys |
33 | import pytest | |
ac1087fa | 34 | |
91a44157 RZ |
35 | # Save the Current Working Directory to find configuration files. |
36 | CWD = os.path.dirname(os.path.realpath(__file__)) | |
37 | sys.path.append(os.path.join(CWD, '../')) | |
ac1087fa | 38 | |
91a44157 RZ |
39 | # pylint: disable=C0413 |
40 | # Import topogen and topotest helpers | |
ac1087fa | 41 | from lib import topotest |
91a44157 RZ |
42 | from lib.topogen import Topogen, TopoRouter, get_topogen |
43 | from lib.topolog import logger | |
ac1087fa | 44 | |
91a44157 RZ |
45 | # Required to instantiate the topology builder class. |
46 | from mininet.topo import Topo | |
ac1087fa MW |
47 | |
48 | total_ebgp_peers = 20 | |
49 | ||
50 | ##################################################### | |
51 | ## | |
52 | ## Network Topology Definition | |
53 | ## | |
54 | ##################################################### | |
55 | ||
91a44157 | 56 | class BGPECMPTopo1(Topo): |
ac1087fa MW |
57 | "BGP ECMP Topology 1" |
58 | ||
59 | def build(self, **_opts): | |
91a44157 | 60 | tgen = get_topogen(self) |
ac1087fa | 61 | |
91a44157 RZ |
62 | # Create the BGP router |
63 | router = tgen.add_router('r1') | |
ac1087fa MW |
64 | |
65 | # Setup Switches - 1 switch per 5 peering routers | |
ac1087fa | 66 | for swNum in range(1, (total_ebgp_peers+4)/5 +1): |
91a44157 RZ |
67 | switch = tgen.add_switch('s{}'.format(swNum)) |
68 | switch.add_link(router) | |
ac1087fa MW |
69 | |
70 | # Add 'total_ebgp_peers' number of eBGP ExaBGP neighbors | |
ac1087fa MW |
71 | for peerNum in range(1, total_ebgp_peers+1): |
72 | swNum = ((peerNum -1) / 5 + 1) | |
73 | ||
91a44157 RZ |
74 | peer_ip = '10.0.{}.{}'.format(swNum, peerNum + 100) |
75 | peer_route = 'via 10.0.{}.1'.format(swNum) | |
76 | peer = tgen.add_exabgp_peer('peer{}'.format(peerNum), | |
77 | ip=peer_ip, defaultRoute=peer_route) | |
78 | ||
79 | switch = tgen.gears['s{}'.format(swNum)] | |
80 | switch.add_link(peer) | |
ac1087fa MW |
81 | |
82 | ||
83 | ##################################################### | |
84 | ## | |
85 | ## Tests starting | |
86 | ## | |
87 | ##################################################### | |
88 | ||
89 | def setup_module(module): | |
91a44157 RZ |
90 | tgen = Topogen(BGPECMPTopo1, module.__name__) |
91 | tgen.start_topology() | |
ac1087fa MW |
92 | |
93 | # Starting Routers | |
91a44157 RZ |
94 | router_list = tgen.routers() |
95 | for rname, router in router_list.iteritems(): | |
96 | router.load_config( | |
97 | TopoRouter.RD_ZEBRA, | |
98 | os.path.join(CWD, '{}/zebra.conf'.format(rname)) | |
99 | ) | |
100 | router.load_config( | |
101 | TopoRouter.RD_BGP, | |
102 | os.path.join(CWD, '{}/bgpd.conf'.format(rname)) | |
103 | ) | |
104 | router.start() | |
ac1087fa MW |
105 | |
106 | # Starting Hosts and init ExaBGP on each of them | |
62271fe3 | 107 | topotest.sleep(10, 'starting BGP on all {} peers'.format(total_ebgp_peers)) |
91a44157 RZ |
108 | peer_list = tgen.exabgp_peers() |
109 | for pname, peer in peer_list.iteritems(): | |
110 | peer_dir = os.path.join(CWD, pname) | |
111 | env_file = os.path.join(CWD, 'exabgp.env') | |
112 | peer.start(peer_dir, env_file) | |
113 | logger.info(pname) | |
ac1087fa MW |
114 | |
115 | def teardown_module(module): | |
91a44157 RZ |
116 | tgen = get_topogen() |
117 | tgen.stop_topology() | |
ac1087fa | 118 | |
35a00f24 RZ |
119 | def test_bgp_convergence(): |
120 | "Test for BGP topology convergence" | |
121 | tgen = get_topogen() | |
122 | ||
123 | # Skip if previous fatal error condition is raised | |
124 | if tgen.routers_have_failure(): | |
125 | pytest.skip(tgen.errors) | |
126 | ||
35a00f24 | 127 | # Expected result |
9a950d76 | 128 | router = tgen.gears['r1'] |
a018893f | 129 | if router.has_version('<', '3.0'): |
9a950d76 RZ |
130 | reffile = os.path.join(CWD, 'r1/summary20.txt') |
131 | else: | |
132 | reffile = os.path.join(CWD, 'r1/summary.txt') | |
133 | ||
35a00f24 RZ |
134 | expected = json.loads(open(reffile).read()) |
135 | ||
ab4d1656 RZ |
136 | test_func = functools.partial( |
137 | topotest.router_json_cmp, router, 'show ip bgp summary json', expected) | |
138 | _, res = topotest.run_and_expect(test_func, None, count=60, wait=0.5) | |
35a00f24 RZ |
139 | assertmsg = 'BGP router network did not converge' |
140 | assert res is None, assertmsg | |
141 | ||
1f4c4aec RZ |
142 | def test_bgp_ecmp(): |
143 | tgen = get_topogen() | |
144 | ||
145 | # Skip if previous fatal error condition is raised | |
146 | if tgen.routers_have_failure(): | |
147 | pytest.skip(tgen.errors) | |
148 | ||
149 | expect = { | |
150 | 'routerId': '10.0.255.1', | |
151 | 'routes': { | |
152 | }, | |
153 | } | |
154 | ||
155 | for net in range(1, 5): | |
156 | for subnet in range(0, 10): | |
157 | netkey = '10.20{}.{}.0/24'.format(net, subnet) | |
158 | expect['routes'][netkey] = [] | |
159 | for _ in range(0, 10): | |
160 | peer = {'multipath': True, 'valid': True} | |
161 | expect['routes'][netkey].append(peer) | |
162 | ||
ab4d1656 RZ |
163 | test_func = functools.partial(topotest.router_json_cmp, |
164 | tgen.gears['r1'], 'show ip bgp json', expect) | |
165 | _, res = topotest.run_and_expect(test_func, None, count=10, wait=0.5) | |
1f4c4aec RZ |
166 | assertmsg = 'expected multipath routes in "show ip bgp" output' |
167 | assert res is None, assertmsg | |
168 | ||
ac1087fa | 169 | if __name__ == '__main__': |
91a44157 RZ |
170 | args = ["-s"] + sys.argv[1:] |
171 | sys.exit(pytest.main(args)) |