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