]>
Commit | Line | Data |
---|---|---|
12919c42 | 1 | #!/usr/bin/env python |
acddc0ed | 2 | # SPDX-License-Identifier: ISC |
12919c42 PG |
3 | |
4 | # | |
5 | # test_bgp_vrf_netns_topo1.py | |
6 | # Part of NetDEF Topology Tests | |
7 | # | |
8 | # Copyright (c) 2018 by 6WIND | |
9 | # | |
12919c42 PG |
10 | |
11 | """ | |
12 | test_bgp_vrf_netns_topo1.py: Test BGP topology with EBGP on NETNS VRF | |
13 | """ | |
14 | ||
15 | import json | |
16 | import os | |
17 | import sys | |
e3060696 | 18 | import functools |
12919c42 | 19 | import pytest |
12919c42 PG |
20 | |
21 | # Save the Current Working Directory to find configuration files. | |
22 | CWD = os.path.dirname(os.path.realpath(__file__)) | |
787e7624 | 23 | sys.path.append(os.path.join(CWD, "../")) |
12919c42 PG |
24 | |
25 | # pylint: disable=C0413 | |
26 | # Import topogen and topotest helpers | |
27 | from lib import topotest | |
28 | from lib.topogen import Topogen, TopoRouter, get_topogen | |
29 | from lib.topolog import logger | |
30 | ||
31 | # Required to instantiate the topology builder class. | |
12919c42 | 32 | |
bf3a0a9a DS |
33 | pytestmark = [pytest.mark.bgpd] |
34 | ||
35 | ||
12919c42 PG |
36 | total_ebgp_peers = 1 |
37 | CustomizeVrfWithNetns = True | |
38 | ||
39 | ##################################################### | |
40 | ## | |
41 | ## Network Topology Definition | |
42 | ## | |
43 | ##################################################### | |
44 | ||
787e7624 | 45 | |
e82b531d CH |
46 | def build_topo(tgen): |
47 | tgen.add_router("r1") | |
12919c42 | 48 | |
e82b531d CH |
49 | # Setup Switches |
50 | switch = tgen.add_switch("s1") | |
51 | switch.add_link(tgen.gears["r1"]) | |
12919c42 | 52 | |
e82b531d CH |
53 | # Add eBGP ExaBGP neighbors |
54 | peer_ip = "10.0.1.101" | |
55 | peer_route = "via 10.0.1.1" | |
56 | peer = tgen.add_exabgp_peer("peer1", ip=peer_ip, defaultRoute=peer_route) | |
57 | switch = tgen.gears["s1"] | |
58 | switch.add_link(peer) | |
12919c42 PG |
59 | |
60 | ||
61 | ##################################################### | |
62 | ## | |
63 | ## Tests starting | |
64 | ## | |
65 | ##################################################### | |
66 | ||
787e7624 | 67 | |
12919c42 | 68 | def setup_module(module): |
e82b531d | 69 | tgen = Topogen(build_topo, module.__name__) |
12919c42 PG |
70 | tgen.start_topology() |
71 | ||
72 | # Get r1 reference | |
787e7624 | 73 | router = tgen.gears["r1"] |
12919c42 PG |
74 | |
75 | # check for zebra capability | |
76 | if CustomizeVrfWithNetns == True: | |
787e7624 | 77 | if router.check_capability(TopoRouter.RD_ZEBRA, "--vrfwnetns") == False: |
78 | return pytest.skip( | |
79 | "Skipping BGP VRF NETNS Test. VRF NETNS backend not available on FRR" | |
80 | ) | |
81 | if os.system("ip netns list") != 0: | |
82 | return pytest.skip( | |
83 | "Skipping BGP VRF NETNS Test. NETNS not available on System" | |
84 | ) | |
12919c42 PG |
85 | # retrieve VRF backend kind |
86 | if CustomizeVrfWithNetns == True: | |
787e7624 | 87 | logger.info("Testing with VRF Namespace support") |
12919c42 | 88 | |
6a95bfc8 CH |
89 | # create VRF r1-bgp-cust1 |
90 | # move r1-eth0 to VRF r1-bgp-cust1 | |
8db751b8 CH |
91 | |
92 | ns = "{}-bgp-cust1".format("r1") | |
93 | router.net.add_netns(ns) | |
94 | router.net.set_intf_netns("r1-eth0", ns, up=True) | |
95 | ||
787e7624 | 96 | # run daemons |
12919c42 PG |
97 | router.load_config( |
98 | TopoRouter.RD_ZEBRA, | |
787e7624 | 99 | os.path.join(CWD, "{}/zebra.conf".format("r1")), |
100 | "--vrfwnetns", | |
12919c42 PG |
101 | ) |
102 | router.load_config( | |
787e7624 | 103 | TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format("r1")) |
12919c42 PG |
104 | ) |
105 | ||
787e7624 | 106 | logger.info("Launching BGP and ZEBRA") |
12919c42 PG |
107 | # BGP and ZEBRA start without underlying VRF |
108 | router.start() | |
109 | # Starting Hosts and init ExaBGP on each of them | |
787e7624 | 110 | logger.info("starting exaBGP on peer1") |
12919c42 | 111 | peer_list = tgen.exabgp_peers() |
e5f0ed14 | 112 | for pname, peer in peer_list.items(): |
12919c42 | 113 | peer_dir = os.path.join(CWD, pname) |
787e7624 | 114 | env_file = os.path.join(CWD, "exabgp.env") |
115 | logger.info("Running ExaBGP peer") | |
12919c42 PG |
116 | peer.start(peer_dir, env_file) |
117 | logger.info(pname) | |
118 | ||
787e7624 | 119 | |
12919c42 PG |
120 | def teardown_module(module): |
121 | tgen = get_topogen() | |
8db751b8 CH |
122 | |
123 | # Move interfaces out of vrf namespace and delete the namespace | |
124 | tgen.net["r1"].reset_intf_netns("r1-eth0") | |
125 | tgen.net["r1"].delete_netns("r1-bgp-cust1") | |
12919c42 PG |
126 | |
127 | tgen.stop_topology() | |
128 | ||
787e7624 | 129 | |
12919c42 PG |
130 | def test_bgp_vrf_learn(): |
131 | "Test daemon learnt VRF context" | |
132 | tgen = get_topogen() | |
133 | ||
134 | # Skip if previous fatal error condition is raised | |
135 | if tgen.routers_have_failure(): | |
136 | pytest.skip(tgen.errors) | |
137 | ||
138 | # Expected result | |
787e7624 | 139 | output = tgen.gears["r1"].vtysh_cmd("show vrf", isjson=False) |
140 | logger.info("output is: {}".format(output)) | |
12919c42 | 141 | |
787e7624 | 142 | output = tgen.gears["r1"].vtysh_cmd("show bgp vrfs", isjson=False) |
143 | logger.info("output is: {}".format(output)) | |
12919c42 | 144 | |
e3060696 | 145 | |
12919c42 PG |
146 | def test_bgp_convergence(): |
147 | "Test for BGP topology convergence" | |
148 | tgen = get_topogen() | |
149 | ||
150 | # uncomment if you want to troubleshoot | |
151 | # tgen.mininet_cli() | |
152 | # Skip if previous fatal error condition is raised | |
153 | if tgen.routers_have_failure(): | |
154 | pytest.skip(tgen.errors) | |
155 | ||
787e7624 | 156 | logger.info("waiting for bgp convergence") |
12919c42 PG |
157 | |
158 | # Expected result | |
787e7624 | 159 | router = tgen.gears["r1"] |
160 | if router.has_version("<", "3.0"): | |
161 | reffile = os.path.join(CWD, "r1/summary20.txt") | |
12919c42 | 162 | else: |
787e7624 | 163 | reffile = os.path.join(CWD, "r1/summary.txt") |
12919c42 PG |
164 | |
165 | expected = json.loads(open(reffile).read()) | |
166 | ||
787e7624 | 167 | test_func = functools.partial( |
a53c08bc CH |
168 | topotest.router_json_cmp, |
169 | router, | |
170 | "show bgp vrf r1-bgp-cust1 summary json", | |
171 | expected, | |
787e7624 | 172 | ) |
e3060696 | 173 | _, res = topotest.run_and_expect(test_func, None, count=90, wait=0.5) |
787e7624 | 174 | assertmsg = "BGP router network did not converge" |
12919c42 PG |
175 | assert res is None, assertmsg |
176 | ||
787e7624 | 177 | |
12919c42 PG |
178 | def test_bgp_vrf_netns(): |
179 | tgen = get_topogen() | |
180 | ||
181 | # Skip if previous fatal error condition is raised | |
182 | if tgen.routers_have_failure(): | |
183 | pytest.skip(tgen.errors) | |
184 | ||
185 | expect = { | |
787e7624 | 186 | "routerId": "10.0.1.1", |
187 | "routes": {}, | |
12919c42 PG |
188 | } |
189 | ||
190 | for subnet in range(0, 10): | |
787e7624 | 191 | netkey = "10.201.{}.0/24".format(subnet) |
192 | expect["routes"][netkey] = [] | |
193 | peer = {"valid": True} | |
194 | expect["routes"][netkey].append(peer) | |
195 | ||
196 | test_func = functools.partial( | |
197 | topotest.router_json_cmp, | |
198 | tgen.gears["r1"], | |
6a95bfc8 | 199 | "show ip bgp vrf r1-bgp-cust1 ipv4 json", |
787e7624 | 200 | expect, |
201 | ) | |
e3060696 | 202 | _, res = topotest.run_and_expect(test_func, None, count=12, wait=0.5) |
6a95bfc8 | 203 | assertmsg = 'expected routes in "show ip bgp vrf r1-bgp-cust1 ipv4" output' |
12919c42 PG |
204 | assert res is None, assertmsg |
205 | ||
787e7624 | 206 | |
207 | if __name__ == "__main__": | |
12919c42 PG |
208 | |
209 | args = ["-s"] + sys.argv[1:] | |
210 | ret = pytest.main(args) | |
211 | ||
212 | sys.exit(ret) |