]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py
Merge pull request #12318 from gpnaveen/bgp_unique_rid
[mirror_frr.git] / tests / topotests / multicast_pim_static_rp_topo1 / test_multicast_pim_static_rp.py
1 #!/usr/bin/env python
2
3 #
4 # Copyright (c) 2019 by VMware, Inc. ("VMware")
5 # Used Copyright (c) 2018 by Network Device Education Foundation,
6 # Inc. ("NetDEF") in this file.
7 #
8 # Permission to use, copy, modify, and/or distribute this software
9 # for any purpose with or without fee is hereby granted, provided
10 # that the above copyright notice and this permission notice appear
11 # in all copies.
12 #
13 # THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
14 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
16 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
17 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
19 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 # OF THIS SOFTWARE.
21 #
22
23 """
24 Following tests are covered to test Multicast basic functionality:
25
26 Topology:
27
28 _______r2_____
29 | |
30 iperf | | iperf
31 r0-----r1-------------r3-----r5
32 | |
33 |_____________|
34 r4
35
36 Test steps
37 - Create topology (setup module)
38 - Bring up topology
39
40 TC_1 : Verify upstream interfaces(IIF) and join state are updated properly
41 after adding and deleting the static RP
42 TC_2 : Verify IIF and OIL in "show ip pim state" updated properly after
43 adding and deleting the static RP
44 TC_3: (*, G) Mroute entry are cleared when static RP gets deleted
45 TC_4: Verify (*,G) prune is send towards the RP after deleting the static RP
46 TC_5: Verify OIF entry for RP is cleared when RP becomes unreachable
47 TC_6: Verify IIF and OIL in "show ip pim state" updated properly when RP
48 becomes unreachable
49 TC_7 : Verify upstream interfaces(IIF) and join state are updated properly
50 after adding and deleting the static RP
51 TC_8: Verify (*,G) prune is send towards the RP when RP becomes unreachable
52 TC_9 : Verify RP configured after IGMP join received, PIM join towards RP is
53 sent immediately
54 TC_10 : Verify RP becomes reachable after IGMP join received, PIM join
55 towards RP is sent immediately
56 TC_11 : Verify PIM join send towards the higher preferred RP
57 TC_12 : Verify PIM prune send towards the lower preferred RP
58 TC_13 : Verify RPF interface is updated in mroute (kernel) when higher
59 preferred overlapping RP configured
60 TC_14 : Verify IIF and OIL in "show ip pim state" updated properly when higher
61 preferred overlapping RP configured
62 TC_15 : Verify upstream interfaces(IIF) and join state are updated when higher
63 preferred overlapping RP is configured
64 TC_16 : Verify join is send to lower preferred RP, when higher preferred RP
65 gets deleted
66 TC_17 : Verify prune is send to higher preferred RP when higher preferred RP
67 gets deleted
68 TC_18 : Verify RPF interface updated in mroute when higher preferred RP gets
69 deleted
70 TC_19 : Verify IIF and OIL in "show ip pim state" updated when higher
71 preferred overlapping RP is deleted
72 TC_20 : Verify PIM upstream IIF updated when higher preferred overlapping RP
73 deleted
74 TC_21_1 : Verify OIF and RFP for (*,G) and (S,G) when static RP configure in
75 LHR router
76 TC_21_2 : Verify OIF and RFP for (*,G) and (S,G) when static RP configure in
77 LHR router
78 TC_22_1 : Verify OIF and RPF for (*,G) and (S,G) when static RP configure in
79 FHR router
80 TC_22_2 : Verify OIF and RPF for (*,G) and (S,G) when static RP configure in
81 FHR router
82 TC_23 : Verify (*,G) and (S,G) populated correctly when RPT and SPT path are
83 different
84 TC_24 : Verify (*,G) and (S,G) populated correctly when SPT and RPT share the
85 same path
86 TC_25 : Verify (*,G) and (S,G) populated correctly after clearing the PIM ,
87 IGMP and mroutes joins
88 TC_26 : Restart the PIMd process and verify PIM joins , and mroutes entries
89 TC_27 : Configure multiple groups (10 grps) with same RP address
90 TC_28 : Configure multiple groups (10 grps) with different RP address
91 TC_29 : Verify IIF and OIL in updated in mroute when upstream interface
92 configure as RP
93 TC_30 : Verify IIF and OIL change to other path after shut the primary path
94 TC_31 : Verify RP info and (*,G) mroute after deleting the RP and shut / no
95 shut the RPF interface.
96 TC_32 : Verify RP info and (*,G) mroute after deleting the RP and shut / no
97 shut the RPF interface
98 """
99
100 import os
101 import sys
102 import time
103 from time import sleep
104 import datetime
105 import pytest
106
107 # Save the Current Working Directory to find configuration files.
108 CWD = os.path.dirname(os.path.realpath(__file__))
109 sys.path.append(os.path.join(CWD, "../"))
110 sys.path.append(os.path.join(CWD, "../lib/"))
111
112 # Required to instantiate the topology builder class.
113
114 # pylint: disable=C0413
115 # Import topogen and topotest helpers
116
117 from lib.topogen import Topogen, get_topogen
118 from lib.topolog import logger
119 from lib.topojson import build_topo_from_json, build_config_from_json
120
121 from lib.common_config import (
122 start_topology,
123 write_test_header,
124 write_test_footer,
125 reset_config_on_routers,
126 step,
127 shutdown_bringup_interface,
128 kill_router_daemons,
129 start_router_daemons,
130 create_static_routes,
131 topo_daemons,
132 )
133 from lib.pim import (
134 create_pim_config,
135 verify_igmp_groups,
136 verify_upstream_iif,
137 verify_join_state_and_timer,
138 verify_mroutes,
139 verify_pim_neighbors,
140 get_pim_interface_traffic,
141 verify_pim_rp_info,
142 verify_pim_state,
143 clear_pim_interface_traffic,
144 clear_igmp_interfaces,
145 clear_pim_interfaces,
146 clear_mroute,
147 clear_mroute_verify,
148 McastTesterHelper,
149 )
150
151 pytestmark = [pytest.mark.pimd, pytest.mark.staticd]
152
153
154 # Global variables
155 GROUP_RANGE_ALL = "224.0.0.0/4"
156 GROUP_RANGE = "225.1.1.1/32"
157 GROUP_RANGE_LIST_1 = [
158 "225.1.1.1/32",
159 "225.1.1.2/32",
160 "225.1.1.3/32",
161 "225.1.1.4/32",
162 "225.1.1.5/32",
163 ]
164 GROUP_RANGE_LIST_2 = [
165 "225.1.1.6/32",
166 "225.1.1.7/32",
167 "225.1.1.8/32",
168 "225.1.1.9/32",
169 "225.1.1.10/32",
170 ]
171 GROUP_ADDRESS = "225.1.1.1"
172 GROUP_ADDRESS_LIST_1 = ["225.1.1.1", "225.1.1.2", "225.1.1.3", "225.1.1.4", "225.1.1.5"]
173 GROUP_ADDRESS_LIST_2 = [
174 "225.1.1.6",
175 "225.1.1.7",
176 "225.1.1.8",
177 "225.1.1.9",
178 "225.1.1.10",
179 ]
180 STAR = "*"
181 SOURCE_ADDRESS = "10.0.6.2"
182 SOURCE = "Static"
183
184
185 def build_topo(tgen):
186 """Build function"""
187
188 # Building topology from json file
189 build_topo_from_json(tgen, TOPO)
190
191
192 def setup_module(mod):
193 """
194 Sets up the pytest environment
195
196 * `mod`: module name
197 """
198
199 testsuite_run_time = time.asctime(time.localtime(time.time()))
200 logger.info("Testsuite start time: %s", testsuite_run_time)
201 logger.info("=" * 40)
202
203 topology = """
204
205 _______r2_____
206 | |
207 iperf | | iperf
208 r0-----r1-------------r3-----r5
209 | |
210 |_____________|
211 r4
212
213 """
214 logger.info("Master Topology: \n %s", topology)
215
216 logger.info("Running setup_module to create topology")
217
218 # This function initiates the topology build with Topogen...
219 json_file = "{}/multicast_pim_static_rp.json".format(CWD)
220 tgen = Topogen(json_file, mod.__name__)
221 global TOPO
222 TOPO = tgen.json_topo
223
224 # ... and here it calls Mininet initialization functions.
225
226 # Starting topology, create tmp files which are loaded to routers
227 # to start daemons and then start routers
228 start_topology(tgen)
229
230 # Don"t run this test if we have any failure.
231 if tgen.routers_have_failure():
232 pytest.skip(tgen.errors)
233
234 # Creating configuration from JSON
235 build_config_from_json(tgen, TOPO)
236
237 # Verify PIM neighbors
238 result = verify_pim_neighbors(tgen, TOPO)
239 assert result is True, "setup_module :Failed \n Error:" " {}".format(result)
240
241 # XXX Replace this using "with McastTesterHelper()... " in each test if possible.
242 global app_helper
243 app_helper = McastTesterHelper(tgen)
244
245 logger.info("Running setup_module() done")
246
247
248 def teardown_module():
249 """Teardown the pytest environment"""
250
251 logger.info("Running teardown_module to delete topology")
252
253 tgen = get_topogen()
254
255 app_helper.cleanup()
256
257 # Stop toplogy and Remove tmp files
258 tgen.stop_topology()
259
260 logger.info("Testsuite end time: %s", time.asctime(time.localtime(time.time())))
261 logger.info("=" * 40)
262
263
264 #####################################################
265 #
266 # Testcases
267 #
268 #####################################################
269
270
271 def verify_mroute_repopulated(uptime_before, uptime_after):
272 """
273 API to compare uptime for mroutes
274
275 Parameters
276 ----------
277 * `uptime_before` : Uptime dictionary for any particular instance
278 * `uptime_after` : Uptime dictionary for any particular instance
279 """
280
281 for group in uptime_before.keys():
282 for source in uptime_before[group].keys():
283 if set(uptime_before[group]) != set(uptime_after[group]):
284 errormsg = (
285 "mroute (%s, %s) has not come"
286 " up after mroute clear [FAILED!!]" % (source, group)
287 )
288 return errormsg
289
290 d_1 = datetime.datetime.strptime(uptime_before[group][source], "%H:%M:%S")
291 d_2 = datetime.datetime.strptime(uptime_after[group][source], "%H:%M:%S")
292 if d_2 >= d_1:
293 errormsg = "mroute (%s, %s) is not " "repopulated [FAILED!!]" % (
294 source,
295 group,
296 )
297 return errormsg
298
299 logger.info("mroute (%s, %s) is " "repopulated [PASSED!!]", source, group)
300
301 return True
302
303
304 def verify_state_incremented(state_before, state_after):
305 """
306 API to compare interface traffic state incrementing
307
308 Parameters
309 ----------
310 * `state_before` : State dictionary for any particular instance
311 * `state_after` : State dictionary for any particular instance
312 """
313
314 for router, state_data in state_before.items():
315 for state, _ in state_data.items():
316 if state_before[router][state] >= state_after[router][state]:
317 errormsg = (
318 "[DUT: %s]: state %s value has not"
319 " incremented, Initial value: %s, "
320 "Current value: %s [FAILED!!]"
321 % (
322 router,
323 state,
324 state_before[router][state],
325 state_after[router][state],
326 )
327 )
328 return errormsg
329
330 logger.info(
331 "[DUT: %s]: State %s value is "
332 "incremented, Initial value: %s, Current value: %s"
333 " [PASSED!!]",
334 router,
335 state,
336 state_before[router][state],
337 state_after[router][state],
338 )
339
340 return True
341
342
343 def test_add_delete_static_RP_p0(request):
344 """
345 TC_1_P0 : Verify upstream interfaces(IIF) and join state are updated
346 properly after adding and deleting the static RP
347 TC_2_P0 : Verify IIF and OIL in "show ip pim state" updated properly
348 after adding and deleting the static RP
349 TC_3_P0: (*, G) Mroute entry are cleared when static RP gets deleted
350 TC_4_P0: Verify (*,G) prune is send towards the RP after deleting the
351 static RP
352
353 Topology used:
354 r0------r1-----r2
355 iperf DUT RP
356 """
357
358 tgen = get_topogen()
359 tc_name = request.node.name
360 write_test_header(tc_name)
361
362 # Don"t run this test if we have any failure.
363 if tgen.routers_have_failure():
364 pytest.skip(tgen.errors)
365
366 step("pre-configuration to send IGMP join and multicast traffic")
367
368 step("Enable IGMP on r1 interface and send IGMP " "join (225.1.1.1) to r1")
369 step("Configure r2 loopback interface as RP")
370 step("Enable PIM between r1 and r3")
371
372 step("r1: Verify show ip igmp group without any IGMP join")
373 dut = "r1"
374 interface = "r1-r0-eth0"
375 result = verify_igmp_groups(tgen, dut, interface, GROUP_ADDRESS, expected=False)
376 assert result is not True, (
377 "Testcase {} : Failed \n "
378 "r1: igmp group present without any IGMP join \n Error: {}".format(
379 tc_name, result
380 )
381 )
382
383 step("r1: Verify show ip pim interface traffic without any IGMP join")
384 state_dict = {"r1": {"r1-r2-eth1": ["pruneTx"]}}
385
386 state_before = get_pim_interface_traffic(tgen, state_dict)
387 assert isinstance(
388 state_before, dict
389 ), "Testcase {} : Failed \n state_before is not dictionary\n Error: {}".format(
390 tc_name, result
391 )
392
393 step("r0 : Send IGMP join")
394 result = app_helper.run_join("r0", GROUP_ADDRESS, "r1")
395 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
396
397 step("r1: Verify IGMP groups")
398 oif = "r1-r0-eth0"
399 result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS)
400 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
401
402 step("r1: Verify RP info")
403 dut = "r1"
404 iif = "r1-r2-eth1"
405 rp_address = "1.0.2.17"
406 result = verify_pim_rp_info(
407 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE
408 )
409 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
410
411 step("r1: Verify upstream IIF interface")
412 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
413 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
414
415 step("r1: Verify upstream join state and join timer")
416 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
417 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
418 step("r1: Verify ip mroutes")
419 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
420 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
421
422 step("r1: Verify ip pim join")
423 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
424 step("r1: Delete RP configuration")
425
426 # Delete RP configuration
427 input_dict = {
428 "r1": {
429 "pim": {
430 "rp": [
431 {
432 "rp_addr": "1.0.2.17",
433 "group_addr_range": GROUP_RANGE_ALL,
434 "delete": True,
435 }
436 ]
437 }
438 }
439 }
440
441 result = create_pim_config(tgen, TOPO, input_dict)
442 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
443
444 step("r1: Verify RP info")
445 result = verify_pim_rp_info(
446 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE, expected=False
447 )
448 assert (
449 result is not True
450 ), "Testcase {} : Failed \n " "r1: RP info present \n Error: {}".format(
451 tc_name, result
452 )
453
454 step("r1: Verify upstream IIF interface")
455 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False)
456 assert result is not True, (
457 "Testcase {} : Failed \n "
458 "r1: upstream IIF interface present \n Error: {}".format(tc_name, result)
459 )
460
461 step("r1: Verify upstream join state and join timer")
462 result = verify_join_state_and_timer(
463 tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False
464 )
465 assert result is not True, (
466 "Testcase {} : Failed \n "
467 "r1: upstream join state is up and join timer is running \n Error: {}".format(
468 tc_name, result
469 )
470 )
471
472 # 20
473 step("r1: Verify PIM state")
474 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False)
475 assert result is not True, "Testcase {} :Failed \n Error: {}".format(
476 tc_name, result
477 )
478
479 step("r1: Verify ip mroutes")
480 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
481 assert (
482 result is not True
483 ), "Testcase {} : Failed \n " "r1: mroutes are still present \n Error: {}".format(
484 tc_name, result
485 )
486
487 step("r1: Verify show ip pim interface traffic without any IGMP join")
488 state_after = get_pim_interface_traffic(tgen, state_dict)
489 assert isinstance(
490 state_after, dict
491 ), "Testcase {} : Failed \n state_before is not dictionary \n Error: {}".format(
492 tc_name, result
493 )
494
495 result = verify_state_incremented(state_before, state_after)
496 assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result)
497
498 # Uncomment next line for debugging
499 # tgen.mininet_cli()
500
501 write_test_footer(tc_name)
502
503
504 def test_SPT_RPT_path_same_p1(request):
505 """
506 TC_24_P1 : Verify (*,G) and (S,G) populated correctly when SPT and RPT
507 share the same path
508
509 Topology used:
510 ________r2_____
511 | |
512 iperf | | iperf
513 r0-----r1 r3-----r5
514
515 r1 : LHR
516 r2 : RP
517 r3 : FHR
518 """
519
520 tgen = get_topogen()
521 tc_name = request.node.name
522 write_test_header(tc_name)
523
524 # Don"t run this test if we have any failure.
525 if tgen.routers_have_failure():
526 pytest.skip(tgen.errors)
527
528 step("Creating configuration from JSON")
529 reset_config_on_routers(tgen)
530 app_helper.stop_all_hosts()
531 clear_mroute(tgen)
532 clear_pim_interface_traffic(tgen, TOPO)
533
534 dut = "r1"
535 intf = "r1-r3-eth2"
536 shutdown_bringup_interface(tgen, dut, intf, False)
537 intf = "r1-r4-eth3"
538 shutdown_bringup_interface(tgen, dut, intf, False)
539
540 dut = "r3"
541 intf = "r3-r1-eth0"
542 shutdown_bringup_interface(tgen, dut, intf, False)
543 intf = "r3-r4-eth2"
544 shutdown_bringup_interface(tgen, dut, intf, False)
545
546 step("Enable IGMP on r1 interface and send IGMP join (225.1.1.1) to R1")
547 step("Configure RP on r2 (loopback interface) for the group range" " 224.0.0.0/4")
548 step("Enable the PIM on all the interfaces of r1, r2, r3 and r4 routers")
549 step("Send multicast traffic from R3")
550
551 step("r2: Verify RP info")
552 dut = "r2"
553 rp_address = "1.0.2.17"
554 iif = "lo"
555 result = verify_pim_rp_info(
556 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE
557 )
558 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
559
560 step("r0: Send IGMP join")
561 result = app_helper.run_join("r0", GROUP_ADDRESS, "r1")
562 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
563
564 step("r1: Verify IGMP groups")
565 dut = "r1"
566 oif = "r1-r0-eth0"
567 result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS)
568 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
569
570 step("r5: Send multicast traffic for group 225.1.1.1")
571 result = app_helper.run_traffic("r5", GROUP_ADDRESS, "r3")
572 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
573
574 step("r1: Verify (*, G) upstream IIF interface")
575 dut = "r1"
576 iif = "r1-r2-eth1"
577 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
578 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
579
580 step("r1: Verify (*, G) upstream join state and join timer")
581 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
582 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
583
584 step("r1: Verify (*, G) ip mroutes")
585 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
586 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
587
588 step("r1: Verify (S, G) upstream IIF interface")
589 iif = "r1-r2-eth1"
590 result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
591 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
592
593 step("r1: Verify (S, G) upstream join state and join timer")
594 result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
595 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
596
597 step("r1: Verify (S, G) ip mroutes")
598 result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif)
599 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
600
601 step("r2: Verify (*, G) upstream IIF interface")
602 dut = "r2"
603 iif = "lo"
604 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
605 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
606
607 step("r2: Verify (*, G) upstream join state and join timer")
608 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
609 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
610
611 step("r2: Verify (*, G) ip mroutes")
612 oif = "r2-r1-eth0"
613 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
614 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
615
616 step("r2: Verify (S, G) upstream IIF interface")
617 iif = "r2-r3-eth1"
618 result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
619 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
620
621 step("r2: Verify (S, G) upstream join state and join timer")
622 result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
623 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
624
625 step("r2: Verify (S, G) ip mroutes")
626 result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif)
627 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
628
629 step("r3: Verify (S, G) upstream IIF interface")
630 dut = "r3"
631 iif = "r3-r5-eth3"
632 result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
633 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
634
635 step("r3: Verify (S, G) upstream join state and join timer")
636 result = verify_join_state_and_timer(
637 tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False
638 )
639 assert result is not True, (
640 "Testcase {} : Failed \n "
641 "r3: (S, G) upstream join state is up and join timer is running\n Error: {}".format(
642 tc_name, result
643 )
644 )
645
646 step("r3: Verify (S, G) ip mroutes")
647 oif = "r3-r2-eth1"
648 result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif)
649 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
650
651 # Uncomment next line for debugging
652 # tgen.mininet_cli()
653
654 write_test_footer(tc_name)
655
656
657 def test_not_reachable_static_RP_p0(request):
658 """
659 TC_5_P0: Verify OIF entry for RP is cleared when RP becomes unreachable
660 TC_6_P0: Verify IIF and OIL in "show ip pim state" updated properly when
661 RP becomes unreachable
662 TC_7_P0 : Verify upstream interfaces(IIF) and join state are updated
663 properly after adding and deleting the static RP
664 TC_8_P0: Verify (*,G) prune is send towards the RP when RP becomes
665 unreachable
666
667 Topology used:
668 r0------r1-----r2
669 iperf DUT RP
670 """
671
672 tgen = get_topogen()
673 tc_name = request.node.name
674 write_test_header(tc_name)
675
676 # Don"t run this test if we have any failure.
677 if tgen.routers_have_failure():
678 pytest.skip(tgen.errors)
679
680 step("Creating configuration from JSON")
681 reset_config_on_routers(tgen)
682 app_helper.stop_all_hosts()
683 clear_mroute(tgen)
684 clear_pim_interface_traffic(tgen, TOPO)
685
686 dut = "r1"
687 intf = "r1-r3-eth2"
688 shutdown_bringup_interface(tgen, dut, intf, False)
689
690 dut = "r1"
691 intf = "r1-r4-eth3"
692 shutdown_bringup_interface(tgen, dut, intf, False)
693
694 step(
695 "r1: (*,G) prune is not sent towards the RP interface, verify using"
696 "show ip pim interface traffic"
697 )
698 state_dict = {"r1": {"r1-r2-eth1": ["pruneTx"]}}
699 state_before = get_pim_interface_traffic(tgen, state_dict)
700 assert isinstance(
701 state_before, dict
702 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
703 tc_name, state_before
704 )
705
706 step("Enable IGMP on r1 interface and send IGMP " "join (225.1.1.1) to r1")
707 step("Configure r2 loopback interface as RP")
708 step("Enable PIM between r1 and r2")
709
710 step("r0 : Send IGMP join")
711 result = app_helper.run_join("r0", GROUP_ADDRESS, "r1")
712 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
713
714 step("r1 : Verify rp info")
715 dut = "r1"
716 iif = "r1-r2-eth1"
717 rp_address = "1.0.2.17"
718 result = verify_pim_rp_info(
719 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE
720 )
721 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
722
723 step("r1: Verify IGMP groups")
724 oif = "r1-r0-eth0"
725 result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS)
726 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
727
728 step("r1: Verify PIM state")
729 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS)
730 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
731
732 step("r1: Verify upstream IIF interface")
733 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
734 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
735
736 step("r1: Verify upstream join state and join timer")
737 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
738 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
739
740 step("r1 :Verify ip mroutes")
741 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
742 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
743
744 step("r1: Make RP un-reachable")
745 dut = "r1"
746 input_dict = {
747 dut: {
748 "static_routes": [
749 {"network": "1.0.2.17/32", "next_hop": "10.0.1.2", "delete": True}
750 ]
751 }
752 }
753
754 result = create_static_routes(tgen, input_dict)
755 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
756
757 step("r1: Check RP detail using show ip pim rp-info OIF should be unknown")
758 result = verify_pim_rp_info(
759 tgen, TOPO, dut, GROUP_RANGE_ALL, "Unknown", rp_address, SOURCE
760 )
761 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
762
763 step(
764 "r1 : OIL should be same and IIF should be cleared on R1 verify"
765 "using show ip pim state"
766 )
767 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False)
768 assert result is not True, (
769 "Testcase {} : Failed \n "
770 "OIL is not same and IIF is not cleared on R1 \n Error: {}".format(
771 tc_name, result
772 )
773 )
774
775 step("r1: upstream IIF should be unknown , verify using show ip pim" "upstream")
776 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False)
777 assert result is not True, (
778 "Testcase {} : Failed \n "
779 "r1: upstream IIF is not unknown \n Error: {}".format(tc_name, result)
780 )
781
782 step(
783 "r1: join state should not be joined and join timer should stop,"
784 "verify using show ip pim upstream"
785 )
786 result = verify_join_state_and_timer(
787 tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False
788 )
789 assert result is not True, (
790 "Testcase {} : Failed \n "
791 "r1: join state is joined and timer is not stopped \n Error: {}".format(
792 tc_name, result
793 )
794 )
795
796 step(
797 "r1: (*,G) prune is sent towards the RP interface, verify using"
798 "show ip pim interface traffic"
799 )
800 state_after = get_pim_interface_traffic(tgen, state_dict)
801 assert isinstance(
802 state_after, dict
803 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
804 tc_name, result
805 )
806
807 result = verify_state_incremented(state_before, state_after)
808 assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result)
809
810 step("r1: (*, G) cleared from mroute table using show ip mroute")
811 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
812 assert result is not True, (
813 "Testcase {} : Failed \n "
814 "r1: (*, G) are not cleared from mroute table \n Error: {}".format(
815 tc_name, result
816 )
817 )
818 logger.info("Expected behavior: %s", result)
819
820 # Uncomment next line for debugging
821 # tgen.mininet_cli()
822
823 write_test_footer(tc_name)
824
825
826 def test_add_RP_after_join_received_p1(request):
827 """
828 TC_9_P1 : Verify RP configured after IGMP join received, PIM join towards
829 RP is sent immediately
830
831 Topology used:
832 r0------r1-----r2
833 iperf DUT RP
834 """
835
836 tgen = get_topogen()
837 tc_name = request.node.name
838 write_test_header(tc_name)
839
840 # Don"t run this test if we have any failure.
841 if tgen.routers_have_failure():
842 pytest.skip(tgen.errors)
843
844 step("Creating configuration from JSON")
845 reset_config_on_routers(tgen)
846 app_helper.stop_all_hosts()
847 clear_mroute(tgen)
848 clear_pim_interface_traffic(tgen, TOPO)
849
850 step("Enable IGMP on R1 interface")
851 step("Configure r2 loopback interface as RP")
852 step("Enable PIM between r1 and r2")
853 step("Delete RP configuration from r1")
854
855 step("r1: Delete RP configuration")
856 input_dict = {
857 "r1": {
858 "pim": {
859 "rp": [
860 {
861 "rp_addr": "1.0.2.17",
862 "group_addr_range": GROUP_RANGE_ALL,
863 "delete": True,
864 }
865 ]
866 }
867 }
868 }
869
870 result = create_pim_config(tgen, TOPO, input_dict)
871 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
872
873 step("r1: Verify rp-info")
874 dut = "r1"
875 rp_address = "1.0.2.17"
876 iif = "r1-r2-eth1"
877 result = verify_pim_rp_info(
878 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE, expected=False
879 )
880 assert (
881 result is not True
882 ), "Testcase {} : Failed \n " "r1: rp-info is present \n Error: {}".format(
883 tc_name, result
884 )
885
886 step("joinTx value before join sent")
887 state_dict = {"r1": {"r1-r2-eth1": ["joinTx"]}}
888 state_before = get_pim_interface_traffic(tgen, state_dict)
889 assert isinstance(
890 state_before, dict
891 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
892 tc_name, result
893 )
894
895 step("r0 : Send IGMP join (225.1.1.1) to r1, when rp is not configured" "in r1")
896 result = app_helper.run_join("r0", GROUP_ADDRESS, "r1")
897 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
898
899 step("r1: IGMP group is received on R1 verify using show ip igmp groups")
900 oif = "r1-r0-eth0"
901 result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS)
902 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
903
904 step("r1: Verify upstream IIF interface")
905 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False)
906 assert result is not True, (
907 "Testcase {} : Failed \n "
908 "r1: upstream IFF interface is present \n Error: {}".format(tc_name, result)
909 )
910
911 step("r1: Verify upstream join state and join timer")
912
913 result = verify_join_state_and_timer(
914 tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False
915 )
916 assert result is not True, (
917 "Testcase {} : Failed \n "
918 "r1: upstream join state is joined and timer is running \n Error: {}".format(
919 tc_name, result
920 )
921 )
922
923 step("r1: Verify PIM state")
924 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False)
925 assert (
926 result is not True
927 ), "Testcase {} : Failed \n " "r1: PIM state is up\n Error: {}".format(
928 tc_name, result
929 )
930
931 step("r1: Verify ip mroutes")
932 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
933 assert (
934 result is not True
935 ), "Testcase {} : Failed \n " "r1: mroutes are still present\n Error: {}".format(
936 tc_name, result
937 )
938
939 step("r1: Configure static RP")
940 input_dict = {
941 "r1": {
942 "pim": {
943 "rp": [
944 {
945 "rp_addr": "1.0.2.17",
946 "group_addr_range": GROUP_RANGE_ALL,
947 }
948 ]
949 }
950 }
951 }
952
953 result = create_pim_config(tgen, TOPO, input_dict)
954 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
955
956 step("r1: Verify rp-info")
957 result = verify_pim_rp_info(
958 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE
959 )
960 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
961
962 step("r1: Verify upstream IIF interface")
963 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
964 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
965
966 step("r1 : Verify upstream join state and join timer")
967 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
968 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
969
970 step("r1: Verify PIM state")
971 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS)
972 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
973
974 step("r1 : Verify ip mroutes")
975 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
976 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
977 logger.info("Expected behavior: %s", result)
978
979 state_after = get_pim_interface_traffic(tgen, state_dict)
980 assert isinstance(
981 state_after, dict
982 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
983 tc_name, result
984 )
985
986 result = verify_state_incremented(state_before, state_after)
987 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
988
989 # Uncomment next line for debugging
990 # tgen.mininet_cli()
991
992 write_test_footer(tc_name)
993
994
995 def test_reachable_static_RP_after_join_p0(request):
996 """
997 TC_10_P0 : Verify RP becomes reachable after IGMP join received, PIM join
998 towards RP is sent immediately
999
1000 Topology used:
1001 r0------r1-----r3
1002 iperf DUT RP
1003 """
1004 tgen = get_topogen()
1005 tc_name = request.node.name
1006 write_test_header(tc_name)
1007
1008 # Don"t run this test if we have any failure.
1009 if tgen.routers_have_failure():
1010 pytest.skip(tgen.errors)
1011
1012 step("Creating configuration from JSON")
1013 reset_config_on_routers(tgen)
1014 app_helper.stop_all_hosts()
1015 clear_mroute(tgen)
1016 clear_pim_interface_traffic(tgen, TOPO)
1017
1018 step("Enable IGMP on r1 interface and send IGMP " "join (225.1.1.1) to r1")
1019 step("Configure r2 loopback interface as RP")
1020 step("Enable PIM between r1 and r2")
1021
1022 step("r1 : Verify pim interface traffic")
1023 state_dict = {"r1": {"r1-r2-eth1": ["joinTx"]}}
1024 state_before = get_pim_interface_traffic(tgen, state_dict)
1025 assert isinstance(
1026 state_before, dict
1027 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1028 tc_name, state_before
1029 )
1030
1031 step("r1: Make RP un-reachable")
1032 dut = "r1"
1033 intf = "r1-r2-eth1"
1034 shutdown_bringup_interface(tgen, dut, intf, False)
1035 intf = "r1-r3-eth2"
1036 shutdown_bringup_interface(tgen, dut, intf, False)
1037 intf = "r1-r4-eth3"
1038 shutdown_bringup_interface(tgen, dut, intf, False)
1039
1040 step("r1: Verify rp-info")
1041 rp_address = "1.0.2.17"
1042 result = verify_pim_rp_info(
1043 tgen, TOPO, dut, GROUP_ADDRESS, "Unknown", rp_address, SOURCE
1044 )
1045 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1046
1047 step("r1 : Send IGMP join for 225.1.1.1")
1048 result = app_helper.run_join("r0", GROUP_ADDRESS, "r1")
1049 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1050
1051 step("r1 : Verify IGMP groups")
1052 oif = "r1-r0-eth0"
1053 result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS)
1054 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1055
1056 step("r1 : Verify upstream IIF interface")
1057 iif = "r1-r2-eth1"
1058 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False)
1059 assert result is not True, (
1060 "Testcase {} : Failed \n "
1061 "r1: upstream IIF interface is present\n Error: {}".format(tc_name, result)
1062 )
1063
1064 step("r1 : Verify upstream join state and join timer")
1065 result = verify_join_state_and_timer(
1066 tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False
1067 )
1068 assert result is not True, (
1069 "Testcase {} : Failed \n "
1070 "r1: upstream join state is joined and timer is running\n Error: {}".format(
1071 tc_name, result
1072 )
1073 )
1074
1075 step("r1 : Verify PIM state")
1076 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False)
1077 assert (
1078 result is not True
1079 ), "Testcase {} : Failed \n " "r1: PIM state is up\n Error: {}".format(
1080 tc_name, result
1081 )
1082
1083 step("r1 : Verify ip mroutes")
1084 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
1085 assert (
1086 result is not True
1087 ), "Testcase {} : Failed \n " "r1: mroutes are still present\n Error: {}".format(
1088 tc_name, result
1089 )
1090
1091 step("r1: Make RP reachable")
1092 intf = "r1-r2-eth1"
1093 shutdown_bringup_interface(tgen, dut, intf, True)
1094 intf = "r1-r3-eth2"
1095 shutdown_bringup_interface(tgen, dut, intf, True)
1096 intf = "r1-r4-eth3"
1097 shutdown_bringup_interface(tgen, dut, intf, True)
1098
1099 step("r1 : Verify rp-info")
1100 result = verify_pim_rp_info(
1101 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE
1102 )
1103 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1104
1105 step("r1: Verify upstream IIF interface")
1106 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
1107 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1108
1109 step("r1 : Verify upstream join state and join timer")
1110 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
1111 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1112
1113 step("r1 : Verify PIM state")
1114 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS)
1115 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1116
1117 step("r1 : Verify ip mroutes")
1118 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
1119 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1120 logger.info("Expected behavior: %s", result)
1121
1122 step("r1 : Verify pim interface traffic")
1123 state_after = get_pim_interface_traffic(tgen, state_dict)
1124 assert isinstance(
1125 state_after, dict
1126 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1127 tc_name, result
1128 )
1129
1130 result = verify_state_incremented(state_before, state_after)
1131 assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result)
1132
1133 # Uncomment next line for debugging
1134 # tgen.mininet_cli()
1135
1136 write_test_footer(tc_name)
1137
1138
1139 def test_send_join_on_higher_preffered_rp_p1(request):
1140 """
1141 TC_11_P1 : Verify PIM join send towards the higher preferred RP
1142 TC_12_P1 : Verify PIM prune send towards the lower preferred RP
1143 TC_13_P1 : Verify RPF interface is updated in mroute (kernel) when higher
1144 preferred overlapping RP configured
1145 TC_14_P1 : Verify IIF and OIL in "show ip pim state" updated properly when
1146 higher preferred overlapping RP configured
1147 TC_15_P1 : Verify upstream interfaces(IIF) and join state are updated when
1148 higher preferred overlapping RP is configured
1149 TC_16_P1 : Verify join is send to lower preferred RP, when higher
1150 preferred RP gets deleted
1151 TC_17_P1 : Verify prune is send to higher preferred RP when higher
1152 preferred RP gets deleted
1153 TC_18_P1 : Verify RPF interface updated in mroute when higher preferred RP
1154 gets deleted
1155 TC_19_P1 : Verify IIF and OIL in "show ip pim state" updated when higher
1156 preferred overlapping RP is deleted
1157 TC_20_P1 : Verify PIM upstream IIF updated when higher preferred
1158 overlapping RP deleted
1159
1160 Topology used:
1161 _______r2
1162 |
1163 iperf |
1164 r0-----r1
1165 |
1166 |_______r4
1167 """
1168
1169 tgen = get_topogen()
1170 tc_name = request.node.name
1171 write_test_header(tc_name)
1172
1173 # Don"t run this test if we have any failure.
1174 if tgen.routers_have_failure():
1175 pytest.skip(tgen.errors)
1176
1177 step("Creating configuration from JSON")
1178 reset_config_on_routers(tgen)
1179 app_helper.stop_all_hosts()
1180 clear_mroute(tgen)
1181 clear_pim_interface_traffic(tgen, TOPO)
1182
1183 step("Enable IGMP on r1 interface")
1184 step("Configure RP on r2 (loopback interface) for the group range " "224.0.0.0/4")
1185 step("Configure RP on r4 (loopback interface) for the group range " "225.1.1.1/32")
1186
1187 step("r3 : Make all interface not reachable")
1188 dut = "r3"
1189 intf = "r3-r1-eth0"
1190 shutdown_bringup_interface(tgen, dut, intf, False)
1191 intf = "r3-r2-eth1"
1192 shutdown_bringup_interface(tgen, dut, intf, False)
1193 intf = "r3-r4-eth2"
1194 shutdown_bringup_interface(tgen, dut, intf, False)
1195
1196 dut = "r2"
1197 intf = "r2-r3-eth1"
1198 shutdown_bringup_interface(tgen, dut, intf, False)
1199
1200 dut = "r4"
1201 intf = "r4-r3-eth1"
1202 shutdown_bringup_interface(tgen, dut, intf, False)
1203
1204 dut = "r1"
1205 intf = "r1-r3-eth2"
1206 shutdown_bringup_interface(tgen, dut, intf, False)
1207
1208 step("r1 : Verify joinTx count before sending join")
1209 state_dict = {"r1": {"r1-r4-eth3": ["joinTx"], "r1-r2-eth1": ["pruneTx"]}}
1210
1211 state_before = get_pim_interface_traffic(tgen, state_dict)
1212 assert isinstance(
1213 state_before, dict
1214 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1215 tc_name, state_before
1216 )
1217
1218 step("r0 : Send IGMP join for 225.1.1.1")
1219 result = app_helper.run_join("r0", GROUP_ADDRESS, "r1")
1220 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1221
1222 step("r1 : Verify IGMP groups")
1223 dut = "r1"
1224 oif = "r1-r0-eth0"
1225 result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS)
1226 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1227
1228 step("Configure static RP for group 225.1.1.1/32")
1229 input_dict = {
1230 "r4": {
1231 "pim": {
1232 "rp": [
1233 {
1234 "rp_addr": "1.0.4.17",
1235 "group_addr_range": ["225.1.1.1/32"],
1236 }
1237 ]
1238 }
1239 }
1240 }
1241
1242 result = create_pim_config(tgen, TOPO, input_dict)
1243 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1244
1245 step("r1 : Verify RP info for group 224.0.0.0/4")
1246 rp_address_1 = "1.0.2.17"
1247 iif = "r1-r2-eth1"
1248 result = verify_pim_rp_info(
1249 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address_1, SOURCE
1250 )
1251 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1252
1253 step("r1 : Verify RP info for group 225.1.1.1")
1254 rp_address_2 = "1.0.4.17"
1255 iif = "r1-r4-eth3"
1256 result = verify_pim_rp_info(tgen, TOPO, dut, GROUP_RANGE, iif, rp_address_2, SOURCE)
1257 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1258
1259 step("r1 : Verify join is sent to higher preferred RP")
1260 step("r1 : Verify prune is sent to lower preferred RP")
1261 state_after = get_pim_interface_traffic(tgen, state_dict)
1262 assert isinstance(
1263 state_after, dict
1264 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1265 tc_name, result
1266 )
1267
1268 result = verify_state_incremented(state_before, state_after)
1269 assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result)
1270
1271 step("r1 : Verify ip mroutes")
1272 iif = "r1-r4-eth3"
1273 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
1274 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1275
1276 step("r1 : Verify PIM state")
1277 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS)
1278 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1279
1280 step("r1 : Verify upstream IIF interface")
1281 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
1282 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1283
1284 step("r1 : Verify upstream join state and join timer")
1285 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
1286 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1287
1288 clear_pim_interface_traffic(tgen, TOPO)
1289
1290 step("r1 : Verify joinTx, pruneTx count before RP gets deleted")
1291 state_dict = {"r1": {"r1-r2-eth1": ["joinTx"], "r1-r4-eth3": ["pruneTx"]}}
1292
1293 state_before = get_pim_interface_traffic(tgen, state_dict)
1294 assert isinstance(
1295 state_before, dict
1296 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1297 tc_name, result
1298 )
1299
1300 step("r1 : Delete RP configuration for 225.1.1.1")
1301 input_dict = {
1302 "r1": {
1303 "pim": {
1304 "rp": [
1305 {
1306 "rp_addr": "1.0.4.17",
1307 "group_addr_range": ["225.1.1.1/32"],
1308 "delete": True,
1309 }
1310 ]
1311 }
1312 }
1313 }
1314
1315 result = create_pim_config(tgen, TOPO, input_dict)
1316 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1317
1318 step("r1 : Verify rp-info for group 224.0.0.0/4")
1319 iif = "r1-r2-eth1"
1320 result = verify_pim_rp_info(
1321 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address_1, SOURCE
1322 )
1323 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1324
1325 step("r1 : Verify rp-info for group 225.1.1.1")
1326 iif = "r1-r4-eth3"
1327 result = verify_pim_rp_info(
1328 tgen, TOPO, dut, GROUP_RANGE, oif, rp_address_2, SOURCE, expected=False
1329 )
1330 assert result is not True, (
1331 "Testcase {} : Failed \n "
1332 "r1: rp-info is present for group 225.1.1.1 \n Error: {}".format(
1333 tc_name, result
1334 )
1335 )
1336
1337 step(
1338 "r1 : Verify RPF interface updated in mroute when higher preferred"
1339 "RP gets deleted"
1340 )
1341 iif = "r1-r2-eth1"
1342 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
1343 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1344 logger.info("Expected behavior: %s", result)
1345
1346 step(
1347 "r1 : Verify IIF and OIL in show ip pim state updated when higher"
1348 "preferred overlapping RP is deleted"
1349 )
1350 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS)
1351 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1352
1353 step(
1354 "r1 : Verify upstream IIF updated when higher preferred overlapping"
1355 "RP deleted"
1356 )
1357 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
1358 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1359
1360 step(
1361 "r1 : Verify upstream join state and join timer updated when higher"
1362 "preferred overlapping RP deleted"
1363 )
1364 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
1365 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1366
1367 step(
1368 "r1 : Verify join is sent to lower preferred RP, when higher"
1369 "preferred RP gets deleted"
1370 )
1371 step(
1372 "r1 : Verify prune is sent to higher preferred RP when higher"
1373 " preferred RP gets deleted"
1374 )
1375 state_after = get_pim_interface_traffic(tgen, state_dict)
1376 assert isinstance(
1377 state_after, dict
1378 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1379 tc_name, result
1380 )
1381
1382 result = verify_state_incremented(state_before, state_after)
1383 assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result)
1384
1385 # Uncomment next line for debugging
1386 # tgen.mininet_cli()
1387
1388 write_test_footer(tc_name)
1389
1390
1391 if __name__ == "__main__":
1392 ARGS = ["-s"] + sys.argv[1:]
1393 sys.exit(pytest.main(ARGS))