]> git.proxmox.com Git - mirror_frr.git/blame - tests/topotests/bgp_lu_topo2/test_bgp_lu2.py
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / tests / topotests / bgp_lu_topo2 / test_bgp_lu2.py
CommitLineData
8734a29c 1#!/usr/bin/env python
acddc0ed 2# SPDX-License-Identifier: ISC
8734a29c
MS
3#
4# test_bgp_lu2.py
5#
6# Part of FRR/NetDEF Topology Tests
7#
8# Copyright (c) 2020 by Volta Networks
9# Copyright (c) 2021 by Nvidia, Inc.
10#
8734a29c
MS
11
12"""
13test_bgp_lu2.py: Test BGP LU label allocation
14"""
15
16import os
17import sys
18import json
19from functools import partial
20import pytest
21
22# Save the Current Working Directory to find configuration files.
23CWD = os.path.dirname(os.path.realpath(__file__))
24sys.path.append(os.path.join(CWD, "../"))
25
26# pylint: disable=C0413
27# Import topogen and topotest helpers
28from lib import topotest
29from lib.topogen import Topogen, TopoRouter, get_topogen
30from lib.topolog import logger
31
32# Required to instantiate the topology builder class.
33
34pytestmark = [pytest.mark.bgpd]
35
36#
37# Basic scenario for BGP-LU. Nodes are directly connected.
38# Node 3 is advertising routes to 2, which advertises them
39# as BGP-LU to 1; this way we get routes with actual labels, as
40# opposed to implicit-null routes in the 2-node case.
41#
42# R2 is an LER, with MPLS towards R1, and IP towards R3. R1 is an LSR, with
43# MPLS on both sides.
44#
45#
46# AS4 BGP-LU AS1 BGP-LU AS2 iBGP AS2
47# +-----+ +-----+ +-----+ +-----+
48# | |.4 .1| |.1 .2| |.2 .3| |
49# | 4 +-------------+ 1 +----------------+ 2 +-----------------+ 3 |
50# | | 10.0.4.0/24 | | 10.0.0.0/24 | | 10.0.1.0/24 | |
51# +-----+ +-----+ +-----+ +-----+
52#
53#
54
55
56def build_topo(tgen):
57 "Build function"
58
59 # This function's only purpose is to define allocation and relationship
60 # between routers, switches and hosts.
61 #
62 #
63 # Create routers
64 tgen.add_router("R1")
65 tgen.add_router("R2")
66 tgen.add_router("R3")
67 tgen.add_router("R4")
68
69 # R1-R2
70 switch = tgen.add_switch("s1")
71 switch.add_link(tgen.gears["R1"])
72 switch.add_link(tgen.gears["R2"])
73
74 # R2-R3
75 switch = tgen.add_switch("s2")
76 switch.add_link(tgen.gears["R2"])
77 switch.add_link(tgen.gears["R3"])
78
79 # R1-R4
80 switch = tgen.add_switch("s3")
81 switch.add_link(tgen.gears["R1"])
82 switch.add_link(tgen.gears["R4"])
83
84
85def setup_module(mod):
86 "Sets up the pytest environment"
87 # This function initiates the topology build with Topogen...
88 tgen = Topogen(build_topo, mod.__name__)
89
90 # Skip if no mpls support
91 if not tgen.hasmpls:
92 logger.info("MPLS is not available, skipping test")
93 pytest.skip("MPLS is not available, skipping")
94 return
95
96 # ... and here it calls Mininet initialization functions.
97 tgen.start_topology()
98
99 # This is a sample of configuration loading.
100 router_list = tgen.routers()
101
102 # Enable mpls input for routers, so we can ping
103 sval = "net.mpls.conf.{}.input"
104 topotest.sysctl_assure(router_list["R2"], sval.format("R2-eth0"), 1)
105 topotest.sysctl_assure(router_list["R1"], sval.format("R1-eth0"), 1)
106 topotest.sysctl_assure(router_list["R1"], sval.format("R1-eth1"), 1)
107 topotest.sysctl_assure(router_list["R4"], sval.format("R4-eth0"), 1)
108
109 # For all registered routers, load the zebra configuration file
110 for rname, router in router_list.items():
111 router.load_config(
112 TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
113 )
114 router.load_config(
115 TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
116 )
117
118 # Have static config for R3 too
119 if router == router_list["R3"]:
120 router.load_config(
121 TopoRouter.RD_STATIC, os.path.join(CWD, "{}/staticd.conf".format(rname))
122 )
123
124 # After loading the configurations, this function loads configured daemons.
125 tgen.start_router()
126
127
128def teardown_module(mod):
129 "Teardown the pytest environment"
130 tgen = get_topogen()
131
132 # This function tears down the whole topology.
133 tgen.stop_topology()
134
135
136def check_labelpool(router):
137 json_file = "{}/{}/labelpool.summ.json".format(CWD, router.name)
138 expected = json.loads(open(json_file).read())
139
140 test_func = partial(
141 topotest.router_json_cmp, router, "show bgp labelpool summary json", expected
142 )
143 _, result = topotest.run_and_expect(test_func, None, count=20, wait=1)
144 assertmsg = '"{}" JSON output mismatches - Did not converge'.format(router.name)
145 assert result is None, assertmsg
146
147
148def test_converge_bgplu():
149 "Wait for protocol convergence"
150
151 tgen = get_topogen()
152 # Don't run this test if we have any failure.
153 if tgen.routers_have_failure():
154 pytest.skip(tgen.errors)
155
156 # TODO -- enable for debugging
157 # tgen.mininet_cli()
158
159 r1 = tgen.gears["R1"]
160 r2 = tgen.gears["R2"]
161
162 check_labelpool(r1)
163 check_labelpool(r2)
164
165
166def test_ping():
167 "Simple ping tests"
168
169 tgen = get_topogen()
170
171 # Don't run this test if we have any failure.
172 if tgen.routers_have_failure():
173 pytest.skip(tgen.errors)
174
175 #
176 logger.info("Ping from R2 to R3")
177 router = tgen.gears["R2"]
178 output = router.run("ping -c 4 -w 4 {}".format("10.0.1.3"))
179 assert " 0% packet loss" in output, "Ping R2->R3 FAILED"
180 logger.info("Ping from R2 to R3 ... success")
181
182 #
183 logger.info("Ping from R4 to R2")
184 router = tgen.gears["R4"]
185 output = router.run("ping -c 4 -w 4 {}".format("10.0.0.2"))
186 assert " 0% packet loss" in output, "Ping R4->R2 FAILED"
187 logger.info("Ping from R4 to R2 ... success")
188
189 #
190 logger.info("Ping from R4 to R3")
191 router = tgen.gears["R4"]
192 output = router.run("ping -c 4 -w 4 {}".format("10.0.1.3"))
193 assert " 0% packet loss" in output, "Ping R4->R3 FAILED"
194 logger.info("Ping from R4 to R3 ... success")
195
196
197def test_memory_leak():
198 "Run the memory leak test and report results."
199 tgen = get_topogen()
200 if not tgen.is_memleak_enabled():
201 pytest.skip("Memory leak test/report is disabled")
202
203 tgen.report_memory_leaks()
204
205
206if __name__ == "__main__":
207 args = ["-s"] + sys.argv[1:]
208 sys.exit(pytest.main(args))