]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/pim_basic/test_pim.py
Merge pull request #9410 from idryzhov/static-show-run-nb
[mirror_frr.git] / tests / topotests / pim_basic / test_pim.py
1 #!/usr/bin/env python
2
3 #
4 # test_pim.py
5 #
6 # Copyright (c) 2018 Cumulus Networks, Inc.
7 # Donald Sharp
8 #
9 # Permission to use, copy, modify, and/or distribute this software
10 # for any purpose with or without fee is hereby granted, provided
11 # that the above copyright notice and this permission notice appear
12 # in all copies.
13 #
14 # THE SOFTWARE IS PROVIDED "AS IS" AND Cumulus Networks DISCLAIMS ALL WARRANTIES
15 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
17 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
18 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
20 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21 # OF THIS SOFTWARE.
22 #
23
24 """
25 test_pim.py: Test pim
26 """
27
28 import os
29 import sys
30 import pytest
31 import json
32 from functools import partial
33
34 pytestmark = pytest.mark.pimd
35
36 CWD = os.path.dirname(os.path.realpath(__file__))
37 sys.path.append(os.path.join(CWD, "../"))
38
39 # pylint: disable=C0413
40 from lib import topotest
41 from lib.topogen import Topogen, TopoRouter, get_topogen
42 from lib.topolog import logger
43
44
45 pytestmark = [pytest.mark.pimd]
46
47
48 def build_topo(tgen):
49 "Build function"
50
51 for routern in range(1, 4):
52 tgen.add_router("r{}".format(routern))
53
54 tgen.add_router("rp")
55
56 # rp ------ r1 -------- r2
57 # \
58 # --------- r3
59 # r1 -> .1
60 # r2 -> .2
61 # rp -> .3
62 # r3 -> .4
63 # loopback network is 10.254.0.X/32
64 #
65 # r1 <- sw1 -> r2
66 # r1-eth0 <-> r2-eth0
67 # 10.0.20.0/24
68 sw = tgen.add_switch("sw1")
69 sw.add_link(tgen.gears["r1"])
70 sw.add_link(tgen.gears["r2"])
71
72 # r1 <- sw2 -> rp
73 # r1-eth1 <-> rp-eth0
74 # 10.0.30.0/24
75 sw = tgen.add_switch("sw2")
76 sw.add_link(tgen.gears["r1"])
77 sw.add_link(tgen.gears["rp"])
78
79 # 10.0.40.0/24
80 sw = tgen.add_switch("sw3")
81 sw.add_link(tgen.gears["r1"])
82 sw.add_link(tgen.gears["r3"])
83
84
85 def setup_module(mod):
86 "Sets up the pytest environment"
87 tgen = Topogen(build_topo, mod.__name__)
88 tgen.start_topology()
89
90 # For all registered routers, load the zebra configuration file
91 for rname, router in tgen.routers().items():
92 router.load_config(
93 TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
94 )
95 router.load_config(
96 TopoRouter.RD_PIM, os.path.join(CWD, "{}/pimd.conf".format(rname))
97 )
98 router.load_config(
99 TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
100 )
101
102 # After loading the configurations, this function loads configured daemons.
103 tgen.start_router()
104 # tgen.mininet_cli()
105
106
107 def teardown_module(mod):
108 "Teardown the pytest environment"
109 tgen = get_topogen()
110
111 # This function tears down the whole topology.
112 tgen.stop_topology()
113
114
115 def test_pim_rp_setup():
116 "Ensure basic routing has come up and the rp has an outgoing interface"
117 # Ensure rp and r1 establish pim neighbor ship and bgp has come up
118 # Finally ensure that the rp has an outgoing interface on r1
119 tgen = get_topogen()
120
121 r1 = tgen.gears["r1"]
122 json_file = "{}/{}/rp-info.json".format(CWD, r1.name)
123 expected = json.loads(open(json_file).read())
124
125 test_func = partial(
126 topotest.router_json_cmp, r1, "show ip pim rp-info json", expected
127 )
128 _, result = topotest.run_and_expect(test_func, None, count=15, wait=5)
129 assertmsg = '"{}" JSON output mismatches'.format(r1.name)
130 assert result is None, assertmsg
131 # tgen.mininet_cli()
132
133
134 def test_pim_send_mcast_stream():
135 "Establish a Multicast stream from r2 -> r1 and then ensure S,G is created as appropriate"
136 logger.info("Establish a Mcast stream from r2->r1 and then ensure S,G created")
137
138 tgen = get_topogen()
139
140 if tgen.routers_have_failure():
141 pytest.skip(tgen.errors)
142
143 rp = tgen.gears["rp"]
144 r3 = tgen.gears["r3"]
145 r2 = tgen.gears["r2"]
146 r1 = tgen.gears["r1"]
147
148 # Let's establish a S,G stream from r2 -> r1
149 CWD = os.path.dirname(os.path.realpath(__file__))
150 r2.run(
151 "{}/mcast-tx.py --ttl 5 --count 5 --interval 10 229.1.1.1 r2-eth0 > /tmp/bar".format(
152 CWD
153 )
154 )
155 # And from r3 -> r1
156 r3.run(
157 "{}/mcast-tx.py --ttl 5 --count 5 --interval 10 229.1.1.1 r3-eth0 > /tmp/bar".format(
158 CWD
159 )
160 )
161
162 # Let's see that it shows up and we have established some basic state
163 out = r1.vtysh_cmd("show ip pim upstream json", isjson=True)
164 expected = {
165 "229.1.1.1": {
166 "10.0.20.2": {
167 "firstHopRouter": 1,
168 "joinState": "NotJoined",
169 "regState": "RegPrune",
170 "inboundInterface": "r1-eth0",
171 }
172 }
173 }
174
175 assert topotest.json_cmp(out, expected) is None, "failed to converge pim"
176 # tgen.mininet_cli()
177
178
179 def test_pim_rp_sees_stream():
180 "Ensure that the RP sees the stream and has acted accordingly"
181 tgen = get_topogen()
182
183 rp = tgen.gears["rp"]
184 json_file = "{}/{}/upstream.json".format(CWD, rp.name)
185 expected = json.loads(open(json_file).read())
186
187 test_func = partial(
188 topotest.router_json_cmp, rp, "show ip pim upstream json", expected
189 )
190 _, result = topotest.run_and_expect(test_func, None, count=20, wait=0.5)
191 assertmsg = '"{}" JSON output mismatches'.format(rp.name)
192 assert result is None, assertmsg
193
194
195 def test_pim_igmp_report():
196 "Send a igmp report from r2->r1 and ensure that the *,G state is created on r1"
197 logger.info("Send a igmp report from r2-r1 and ensure *,G created")
198
199 tgen = get_topogen()
200
201 if tgen.routers_have_failure():
202 pytest.skip(tgen.errors)
203
204 r2 = tgen.gears["r2"]
205 r1 = tgen.gears["r1"]
206
207 # Let's send a igmp report from r2->r1
208 cmd = [os.path.join(CWD, "mcast-rx.py"), "229.1.1.2", "r2-eth0"]
209 p = r2.popen(cmd)
210 try:
211 expected = {
212 "229.1.1.2": {
213 "*": {
214 "sourceIgmp": 1,
215 "joinState": "Joined",
216 "regState": "RegNoInfo",
217 "sptBit": 0,
218 }
219 }
220 }
221 test_func = partial(
222 topotest.router_json_cmp, r1, "show ip pim upstream json", expected
223 )
224 _, result = topotest.run_and_expect(test_func, None, count=5, wait=0.5)
225 assertmsg = '"{}" JSON output mismatches'.format(r1.name)
226 assert result is None, assertmsg
227 finally:
228 if p:
229 p.terminate()
230 p.wait()
231
232
233 def test_memory_leak():
234 "Run the memory leak test and report results."
235 tgen = get_topogen()
236 if not tgen.is_memleak_enabled():
237 pytest.skip("Memory leak test/report is disabled")
238
239 tgen.report_memory_leaks()
240
241
242 if __name__ == "__main__":
243 args = ["-s"] + sys.argv[1:]
244 sys.exit(pytest.main(args))