]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py
Merge pull request #11302 from punith-shivakumar/master
[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 # get list of daemons needs to be started for this suite.
227 daemons = topo_daemons(tgen, TOPO)
228
229 # Starting topology, create tmp files which are loaded to routers
230 # to start daemons and then start routers
231 start_topology(tgen, daemons)
232
233 # Don"t run this test if we have any failure.
234 if tgen.routers_have_failure():
235 pytest.skip(tgen.errors)
236
237 # Creating configuration from JSON
238 build_config_from_json(tgen, TOPO)
239
240 # Verify PIM neighbors
241 result = verify_pim_neighbors(tgen, TOPO)
242 assert result is True, "setup_module :Failed \n Error:" " {}".format(result)
243
244 # XXX Replace this using "with McastTesterHelper()... " in each test if possible.
245 global app_helper
246 app_helper = McastTesterHelper(tgen)
247
248 logger.info("Running setup_module() done")
249
250
251 def teardown_module():
252 """Teardown the pytest environment"""
253
254 logger.info("Running teardown_module to delete topology")
255
256 tgen = get_topogen()
257
258 app_helper.cleanup()
259
260 # Stop toplogy and Remove tmp files
261 tgen.stop_topology()
262
263 logger.info("Testsuite end time: %s", time.asctime(time.localtime(time.time())))
264 logger.info("=" * 40)
265
266
267 #####################################################
268 #
269 # Testcases
270 #
271 #####################################################
272
273
274 def verify_mroute_repopulated(uptime_before, uptime_after):
275 """
276 API to compare uptime for mroutes
277
278 Parameters
279 ----------
280 * `uptime_before` : Uptime dictionary for any particular instance
281 * `uptime_after` : Uptime dictionary for any particular instance
282 """
283
284 for group in uptime_before.keys():
285 for source in uptime_before[group].keys():
286 if set(uptime_before[group]) != set(uptime_after[group]):
287 errormsg = (
288 "mroute (%s, %s) has not come"
289 " up after mroute clear [FAILED!!]" % (source, group)
290 )
291 return errormsg
292
293 d_1 = datetime.datetime.strptime(uptime_before[group][source], "%H:%M:%S")
294 d_2 = datetime.datetime.strptime(uptime_after[group][source], "%H:%M:%S")
295 if d_2 >= d_1:
296 errormsg = "mroute (%s, %s) is not " "repopulated [FAILED!!]" % (
297 source,
298 group,
299 )
300 return errormsg
301
302 logger.info("mroute (%s, %s) is " "repopulated [PASSED!!]", source, group)
303
304 return True
305
306
307 def verify_state_incremented(state_before, state_after):
308 """
309 API to compare interface traffic state incrementing
310
311 Parameters
312 ----------
313 * `state_before` : State dictionary for any particular instance
314 * `state_after` : State dictionary for any particular instance
315 """
316
317 for router, state_data in state_before.items():
318 for state, _ in state_data.items():
319 if state_before[router][state] >= state_after[router][state]:
320 errormsg = (
321 "[DUT: %s]: state %s value has not"
322 " incremented, Initial value: %s, "
323 "Current value: %s [FAILED!!]"
324 % (
325 router,
326 state,
327 state_before[router][state],
328 state_after[router][state],
329 )
330 )
331 return errormsg
332
333 logger.info(
334 "[DUT: %s]: State %s value is "
335 "incremented, Initial value: %s, Current value: %s"
336 " [PASSED!!]",
337 router,
338 state,
339 state_before[router][state],
340 state_after[router][state],
341 )
342
343 return True
344
345
346 def test_add_delete_static_RP_p0(request):
347 """
348 TC_1_P0 : Verify upstream interfaces(IIF) and join state are updated
349 properly after adding and deleting the static RP
350 TC_2_P0 : Verify IIF and OIL in "show ip pim state" updated properly
351 after adding and deleting the static RP
352 TC_3_P0: (*, G) Mroute entry are cleared when static RP gets deleted
353 TC_4_P0: Verify (*,G) prune is send towards the RP after deleting the
354 static RP
355
356 Topology used:
357 r0------r1-----r2
358 iperf DUT RP
359 """
360
361 tgen = get_topogen()
362 tc_name = request.node.name
363 write_test_header(tc_name)
364
365 # Don"t run this test if we have any failure.
366 if tgen.routers_have_failure():
367 pytest.skip(tgen.errors)
368
369 step("pre-configuration to send IGMP join and multicast traffic")
370
371 step("Enable IGMP on r1 interface and send IGMP " "join (225.1.1.1) to r1")
372 step("Configure r2 loopback interface as RP")
373 step("Enable PIM between r1 and r3")
374
375 step("r1: Verify show ip igmp group without any IGMP join")
376 dut = "r1"
377 interface = "r1-r0-eth0"
378 result = verify_igmp_groups(tgen, dut, interface, GROUP_ADDRESS, expected=False)
379 assert result is not True, (
380 "Testcase {} : Failed \n "
381 "r1: igmp group present without any IGMP join \n Error: {}".format(
382 tc_name, result
383 )
384 )
385
386 step("r1: Verify show ip pim interface traffic without any IGMP join")
387 state_dict = {"r1": {"r1-r2-eth1": ["pruneTx"]}}
388
389 state_before = get_pim_interface_traffic(tgen, state_dict)
390 assert isinstance(
391 state_before, dict
392 ), "Testcase {} : Failed \n state_before is not dictionary\n Error: {}".format(
393 tc_name, result
394 )
395
396 step("r0 : Send IGMP join")
397 result = app_helper.run_join("r0", GROUP_ADDRESS, "r1")
398 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
399
400 step("r1: Verify IGMP groups")
401 oif = "r1-r0-eth0"
402 result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS)
403 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
404
405 step("r1: Verify RP info")
406 dut = "r1"
407 iif = "r1-r2-eth1"
408 rp_address = "1.0.2.17"
409 result = verify_pim_rp_info(
410 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE
411 )
412 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
413
414 step("r1: Verify upstream IIF interface")
415 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
416 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
417
418 step("r1: Verify upstream join state and join timer")
419 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
420 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
421 step("r1: Verify ip mroutes")
422 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
423 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
424
425 step("r1: Verify ip pim join")
426 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
427 step("r1: Delete RP configuration")
428
429 # Delete RP configuration
430 input_dict = {
431 "r1": {
432 "pim": {
433 "rp": [
434 {
435 "rp_addr": "1.0.2.17",
436 "group_addr_range": GROUP_RANGE_ALL,
437 "delete": True,
438 }
439 ]
440 }
441 }
442 }
443
444 result = create_pim_config(tgen, TOPO, input_dict)
445 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
446
447 step("r1: Verify RP info")
448 result = verify_pim_rp_info(
449 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE, expected=False
450 )
451 assert (
452 result is not True
453 ), "Testcase {} : Failed \n " "r1: RP info present \n Error: {}".format(
454 tc_name, result
455 )
456
457 step("r1: Verify upstream IIF interface")
458 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False)
459 assert result is not True, (
460 "Testcase {} : Failed \n "
461 "r1: upstream IIF interface present \n Error: {}".format(tc_name, result)
462 )
463
464 step("r1: Verify upstream join state and join timer")
465 result = verify_join_state_and_timer(
466 tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False
467 )
468 assert result is not True, (
469 "Testcase {} : Failed \n "
470 "r1: upstream join state is up and join timer is running \n Error: {}".format(
471 tc_name, result
472 )
473 )
474
475 # 20
476 step("r1: Verify PIM state")
477 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False)
478 assert result is not True, "Testcase {} :Failed \n Error: {}".format(
479 tc_name, result
480 )
481
482 step("r1: Verify ip mroutes")
483 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
484 assert (
485 result is not True
486 ), "Testcase {} : Failed \n " "r1: mroutes are still present \n Error: {}".format(
487 tc_name, result
488 )
489
490 step("r1: Verify show ip pim interface traffic without any IGMP join")
491 state_after = get_pim_interface_traffic(tgen, state_dict)
492 assert isinstance(
493 state_after, dict
494 ), "Testcase {} : Failed \n state_before is not dictionary \n Error: {}".format(
495 tc_name, result
496 )
497
498 result = verify_state_incremented(state_before, state_after)
499 assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result)
500
501 # Uncomment next line for debugging
502 # tgen.mininet_cli()
503
504 write_test_footer(tc_name)
505
506
507 def test_SPT_RPT_path_same_p1(request):
508 """
509 TC_24_P1 : Verify (*,G) and (S,G) populated correctly when SPT and RPT
510 share the same path
511
512 Topology used:
513 ________r2_____
514 | |
515 iperf | | iperf
516 r0-----r1 r3-----r5
517
518 r1 : LHR
519 r2 : RP
520 r3 : FHR
521 """
522
523 tgen = get_topogen()
524 tc_name = request.node.name
525 write_test_header(tc_name)
526
527 # Don"t run this test if we have any failure.
528 if tgen.routers_have_failure():
529 pytest.skip(tgen.errors)
530
531 step("Creating configuration from JSON")
532 reset_config_on_routers(tgen)
533 app_helper.stop_all_hosts()
534 clear_mroute(tgen)
535 clear_pim_interface_traffic(tgen, TOPO)
536
537 dut = "r1"
538 intf = "r1-r3-eth2"
539 shutdown_bringup_interface(tgen, dut, intf, False)
540 intf = "r1-r4-eth3"
541 shutdown_bringup_interface(tgen, dut, intf, False)
542
543 dut = "r3"
544 intf = "r3-r1-eth0"
545 shutdown_bringup_interface(tgen, dut, intf, False)
546 intf = "r3-r4-eth2"
547 shutdown_bringup_interface(tgen, dut, intf, False)
548
549 step("Enable IGMP on r1 interface and send IGMP join (225.1.1.1) to R1")
550 step("Configure RP on r2 (loopback interface) for the group range" " 224.0.0.0/4")
551 step("Enable the PIM on all the interfaces of r1, r2, r3 and r4 routers")
552 step("Send multicast traffic from R3")
553
554 step("r2: Verify RP info")
555 dut = "r2"
556 rp_address = "1.0.2.17"
557 iif = "lo"
558 result = verify_pim_rp_info(
559 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE
560 )
561 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
562
563 step("r0: Send IGMP join")
564 result = app_helper.run_join("r0", GROUP_ADDRESS, "r1")
565 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
566
567 step("r1: Verify IGMP groups")
568 dut = "r1"
569 oif = "r1-r0-eth0"
570 result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS)
571 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
572
573 step("r5: Send multicast traffic for group 225.1.1.1")
574 result = app_helper.run_traffic("r5", GROUP_ADDRESS, "r3")
575 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
576
577 step("r1: Verify (*, G) upstream IIF interface")
578 dut = "r1"
579 iif = "r1-r2-eth1"
580 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
581 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
582
583 step("r1: Verify (*, G) upstream join state and join timer")
584 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
585 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
586
587 step("r1: Verify (*, G) ip mroutes")
588 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
589 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
590
591 step("r1: Verify (S, G) upstream IIF interface")
592 iif = "r1-r2-eth1"
593 result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
594 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
595
596 step("r1: Verify (S, G) upstream join state and join timer")
597 result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
598 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
599
600 step("r1: Verify (S, G) ip mroutes")
601 result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif)
602 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
603
604 step("r2: Verify (*, G) upstream IIF interface")
605 dut = "r2"
606 iif = "lo"
607 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
608 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
609
610 step("r2: Verify (*, G) upstream join state and join timer")
611 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
612 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
613
614 step("r2: Verify (*, G) ip mroutes")
615 oif = "r2-r1-eth0"
616 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
617 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
618
619 step("r2: Verify (S, G) upstream IIF interface")
620 iif = "r2-r3-eth1"
621 result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
622 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
623
624 step("r2: Verify (S, G) upstream join state and join timer")
625 result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
626 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
627
628 step("r2: Verify (S, G) ip mroutes")
629 result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif)
630 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
631
632 step("r3: Verify (S, G) upstream IIF interface")
633 dut = "r3"
634 iif = "r3-r5-eth3"
635 result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
636 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
637
638 step("r3: Verify (S, G) upstream join state and join timer")
639 result = verify_join_state_and_timer(
640 tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False
641 )
642 assert result is not True, (
643 "Testcase {} : Failed \n "
644 "r3: (S, G) upstream join state is up and join timer is running\n Error: {}".format(
645 tc_name, result
646 )
647 )
648
649 step("r3: Verify (S, G) ip mroutes")
650 oif = "r3-r2-eth1"
651 result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif)
652 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
653
654 # Uncomment next line for debugging
655 # tgen.mininet_cli()
656
657 write_test_footer(tc_name)
658
659
660 def test_not_reachable_static_RP_p0(request):
661 """
662 TC_5_P0: Verify OIF entry for RP is cleared when RP becomes unreachable
663 TC_6_P0: Verify IIF and OIL in "show ip pim state" updated properly when
664 RP becomes unreachable
665 TC_7_P0 : Verify upstream interfaces(IIF) and join state are updated
666 properly after adding and deleting the static RP
667 TC_8_P0: Verify (*,G) prune is send towards the RP when RP becomes
668 unreachable
669
670 Topology used:
671 r0------r1-----r2
672 iperf DUT RP
673 """
674
675 tgen = get_topogen()
676 tc_name = request.node.name
677 write_test_header(tc_name)
678
679 # Don"t run this test if we have any failure.
680 if tgen.routers_have_failure():
681 pytest.skip(tgen.errors)
682
683 step("Creating configuration from JSON")
684 reset_config_on_routers(tgen)
685 app_helper.stop_all_hosts()
686 clear_mroute(tgen)
687 clear_pim_interface_traffic(tgen, TOPO)
688
689 dut = "r1"
690 intf = "r1-r3-eth2"
691 shutdown_bringup_interface(tgen, dut, intf, False)
692
693 dut = "r1"
694 intf = "r1-r4-eth3"
695 shutdown_bringup_interface(tgen, dut, intf, False)
696
697 step(
698 "r1: (*,G) prune is not sent towards the RP interface, verify using"
699 "show ip pim interface traffic"
700 )
701 state_dict = {"r1": {"r1-r2-eth1": ["pruneTx"]}}
702 state_before = get_pim_interface_traffic(tgen, state_dict)
703 assert isinstance(
704 state_before, dict
705 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
706 tc_name, state_before
707 )
708
709 step("Enable IGMP on r1 interface and send IGMP " "join (225.1.1.1) to r1")
710 step("Configure r2 loopback interface as RP")
711 step("Enable PIM between r1 and r2")
712
713 step("r0 : Send IGMP join")
714 result = app_helper.run_join("r0", GROUP_ADDRESS, "r1")
715 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
716
717 step("r1 : Verify rp info")
718 dut = "r1"
719 iif = "r1-r2-eth1"
720 rp_address = "1.0.2.17"
721 result = verify_pim_rp_info(
722 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE
723 )
724 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
725
726 step("r1: Verify IGMP groups")
727 oif = "r1-r0-eth0"
728 result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS)
729 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
730
731 step("r1: Verify PIM state")
732 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS)
733 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
734
735 step("r1: Verify upstream IIF interface")
736 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
737 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
738
739 step("r1: Verify upstream join state and join timer")
740 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
741 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
742
743 step("r1 :Verify ip mroutes")
744 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
745 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
746
747 step("r1: Make RP un-reachable")
748 dut = "r1"
749 input_dict = {
750 dut: {
751 "static_routes": [
752 {"network": "1.0.2.17/32", "next_hop": "10.0.1.2", "delete": True}
753 ]
754 }
755 }
756
757 result = create_static_routes(tgen, input_dict)
758 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
759
760 step("r1: Check RP detail using show ip pim rp-info OIF should be unknown")
761 result = verify_pim_rp_info(
762 tgen, TOPO, dut, GROUP_RANGE_ALL, "Unknown", rp_address, SOURCE
763 )
764 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
765
766 step(
767 "r1 : OIL should be same and IIF should be cleared on R1 verify"
768 "using show ip pim state"
769 )
770 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False)
771 assert result is not True, (
772 "Testcase {} : Failed \n "
773 "OIL is not same and IIF is not cleared on R1 \n Error: {}".format(
774 tc_name, result
775 )
776 )
777
778 step("r1: upstream IIF should be unknown , verify using show ip pim" "upstream")
779 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False)
780 assert result is not True, (
781 "Testcase {} : Failed \n "
782 "r1: upstream IIF is not unknown \n Error: {}".format(tc_name, result)
783 )
784
785 step(
786 "r1: join state should not be joined and join timer should stop,"
787 "verify using show ip pim upstream"
788 )
789 result = verify_join_state_and_timer(
790 tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False
791 )
792 assert result is not True, (
793 "Testcase {} : Failed \n "
794 "r1: join state is joined and timer is not stopped \n Error: {}".format(
795 tc_name, result
796 )
797 )
798
799 step(
800 "r1: (*,G) prune is sent towards the RP interface, verify using"
801 "show ip pim interface traffic"
802 )
803 state_after = get_pim_interface_traffic(tgen, state_dict)
804 assert isinstance(
805 state_after, dict
806 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
807 tc_name, result
808 )
809
810 result = verify_state_incremented(state_before, state_after)
811 assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result)
812
813 step("r1: (*, G) cleared from mroute table using show ip mroute")
814 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
815 assert result is not True, (
816 "Testcase {} : Failed \n "
817 "r1: (*, G) are not cleared from mroute table \n Error: {}".format(
818 tc_name, result
819 )
820 )
821 logger.info("Expected behavior: %s", result)
822
823 # Uncomment next line for debugging
824 # tgen.mininet_cli()
825
826 write_test_footer(tc_name)
827
828
829 def test_add_RP_after_join_received_p1(request):
830 """
831 TC_9_P1 : Verify RP configured after IGMP join received, PIM join towards
832 RP is sent immediately
833
834 Topology used:
835 r0------r1-----r2
836 iperf DUT RP
837 """
838
839 tgen = get_topogen()
840 tc_name = request.node.name
841 write_test_header(tc_name)
842
843 # Don"t run this test if we have any failure.
844 if tgen.routers_have_failure():
845 pytest.skip(tgen.errors)
846
847 step("Creating configuration from JSON")
848 reset_config_on_routers(tgen)
849 app_helper.stop_all_hosts()
850 clear_mroute(tgen)
851 clear_pim_interface_traffic(tgen, TOPO)
852
853 step("Enable IGMP on R1 interface")
854 step("Configure r2 loopback interface as RP")
855 step("Enable PIM between r1 and r2")
856 step("Delete RP configuration from r1")
857
858 step("r1: Delete RP configuration")
859 input_dict = {
860 "r1": {
861 "pim": {
862 "rp": [
863 {
864 "rp_addr": "1.0.2.17",
865 "group_addr_range": GROUP_RANGE_ALL,
866 "delete": True,
867 }
868 ]
869 }
870 }
871 }
872
873 result = create_pim_config(tgen, TOPO, input_dict)
874 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
875
876 step("r1: Verify rp-info")
877 dut = "r1"
878 rp_address = "1.0.2.17"
879 iif = "r1-r2-eth1"
880 result = verify_pim_rp_info(
881 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE, expected=False
882 )
883 assert (
884 result is not True
885 ), "Testcase {} : Failed \n " "r1: rp-info is present \n Error: {}".format(
886 tc_name, result
887 )
888
889 step("joinTx value before join sent")
890 state_dict = {"r1": {"r1-r2-eth1": ["joinTx"]}}
891 state_before = get_pim_interface_traffic(tgen, state_dict)
892 assert isinstance(
893 state_before, dict
894 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
895 tc_name, result
896 )
897
898 step("r0 : Send IGMP join (225.1.1.1) to r1, when rp is not configured" "in r1")
899 result = app_helper.run_join("r0", GROUP_ADDRESS, "r1")
900 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
901
902 step("r1: IGMP group is received on R1 verify using show ip igmp groups")
903 oif = "r1-r0-eth0"
904 result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS)
905 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
906
907 step("r1: Verify upstream IIF interface")
908 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False)
909 assert result is not True, (
910 "Testcase {} : Failed \n "
911 "r1: upstream IFF interface is present \n Error: {}".format(tc_name, result)
912 )
913
914 step("r1: Verify upstream join state and join timer")
915
916 result = verify_join_state_and_timer(
917 tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False
918 )
919 assert result is not True, (
920 "Testcase {} : Failed \n "
921 "r1: upstream join state is joined and timer is running \n Error: {}".format(
922 tc_name, result
923 )
924 )
925
926 step("r1: Verify PIM state")
927 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False)
928 assert (
929 result is not True
930 ), "Testcase {} : Failed \n " "r1: PIM state is up\n Error: {}".format(
931 tc_name, result
932 )
933
934 step("r1: Verify ip mroutes")
935 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
936 assert (
937 result is not True
938 ), "Testcase {} : Failed \n " "r1: mroutes are still present\n Error: {}".format(
939 tc_name, result
940 )
941
942 step("r1: Configure static RP")
943 input_dict = {
944 "r1": {
945 "pim": {
946 "rp": [
947 {
948 "rp_addr": "1.0.2.17",
949 "group_addr_range": GROUP_RANGE_ALL,
950 }
951 ]
952 }
953 }
954 }
955
956 result = create_pim_config(tgen, TOPO, input_dict)
957 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
958
959 step("r1: Verify rp-info")
960 result = verify_pim_rp_info(
961 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE
962 )
963 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
964
965 step("r1: Verify upstream IIF interface")
966 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
967 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
968
969 step("r1 : Verify upstream join state and join timer")
970 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
971 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
972
973 step("r1: Verify PIM state")
974 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS)
975 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
976
977 step("r1 : Verify ip mroutes")
978 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
979 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
980 logger.info("Expected behavior: %s", result)
981
982 state_after = get_pim_interface_traffic(tgen, state_dict)
983 assert isinstance(
984 state_after, dict
985 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
986 tc_name, result
987 )
988
989 result = verify_state_incremented(state_before, state_after)
990 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
991
992 # Uncomment next line for debugging
993 # tgen.mininet_cli()
994
995 write_test_footer(tc_name)
996
997
998 def test_reachable_static_RP_after_join_p0(request):
999 """
1000 TC_10_P0 : Verify RP becomes reachable after IGMP join received, PIM join
1001 towards RP is sent immediately
1002
1003 Topology used:
1004 r0------r1-----r3
1005 iperf DUT RP
1006 """
1007 tgen = get_topogen()
1008 tc_name = request.node.name
1009 write_test_header(tc_name)
1010
1011 # Don"t run this test if we have any failure.
1012 if tgen.routers_have_failure():
1013 pytest.skip(tgen.errors)
1014
1015 step("Creating configuration from JSON")
1016 reset_config_on_routers(tgen)
1017 app_helper.stop_all_hosts()
1018 clear_mroute(tgen)
1019 clear_pim_interface_traffic(tgen, TOPO)
1020
1021 step("Enable IGMP on r1 interface and send IGMP " "join (225.1.1.1) to r1")
1022 step("Configure r2 loopback interface as RP")
1023 step("Enable PIM between r1 and r2")
1024
1025 step("r1 : Verify pim interface traffic")
1026 state_dict = {"r1": {"r1-r2-eth1": ["joinTx"]}}
1027 state_before = get_pim_interface_traffic(tgen, state_dict)
1028 assert isinstance(
1029 state_before, dict
1030 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1031 tc_name, state_before
1032 )
1033
1034 step("r1: Make RP un-reachable")
1035 dut = "r1"
1036 intf = "r1-r2-eth1"
1037 shutdown_bringup_interface(tgen, dut, intf, False)
1038 intf = "r1-r3-eth2"
1039 shutdown_bringup_interface(tgen, dut, intf, False)
1040 intf = "r1-r4-eth3"
1041 shutdown_bringup_interface(tgen, dut, intf, False)
1042
1043 step("r1: Verify rp-info")
1044 rp_address = "1.0.2.17"
1045 result = verify_pim_rp_info(
1046 tgen, TOPO, dut, GROUP_ADDRESS, "Unknown", rp_address, SOURCE
1047 )
1048 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1049
1050 step("r1 : Send IGMP join for 225.1.1.1")
1051 result = app_helper.run_join("r0", GROUP_ADDRESS, "r1")
1052 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1053
1054 step("r1 : Verify IGMP groups")
1055 oif = "r1-r0-eth0"
1056 result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS)
1057 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1058
1059 step("r1 : Verify upstream IIF interface")
1060 iif = "r1-r2-eth1"
1061 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False)
1062 assert result is not True, (
1063 "Testcase {} : Failed \n "
1064 "r1: upstream IIF interface is present\n Error: {}".format(tc_name, result)
1065 )
1066
1067 step("r1 : Verify upstream join state and join timer")
1068 result = verify_join_state_and_timer(
1069 tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False
1070 )
1071 assert result is not True, (
1072 "Testcase {} : Failed \n "
1073 "r1: upstream join state is joined and timer is running\n Error: {}".format(
1074 tc_name, result
1075 )
1076 )
1077
1078 step("r1 : Verify PIM state")
1079 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False)
1080 assert (
1081 result is not True
1082 ), "Testcase {} : Failed \n " "r1: PIM state is up\n Error: {}".format(
1083 tc_name, result
1084 )
1085
1086 step("r1 : Verify ip mroutes")
1087 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
1088 assert (
1089 result is not True
1090 ), "Testcase {} : Failed \n " "r1: mroutes are still present\n Error: {}".format(
1091 tc_name, result
1092 )
1093
1094 step("r1: Make RP reachable")
1095 intf = "r1-r2-eth1"
1096 shutdown_bringup_interface(tgen, dut, intf, True)
1097 intf = "r1-r3-eth2"
1098 shutdown_bringup_interface(tgen, dut, intf, True)
1099 intf = "r1-r4-eth3"
1100 shutdown_bringup_interface(tgen, dut, intf, True)
1101
1102 step("r1 : Verify rp-info")
1103 result = verify_pim_rp_info(
1104 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE
1105 )
1106 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1107
1108 step("r1: Verify upstream IIF interface")
1109 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
1110 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1111
1112 step("r1 : Verify upstream join state and join timer")
1113 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
1114 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1115
1116 step("r1 : Verify PIM state")
1117 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS)
1118 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1119
1120 step("r1 : Verify ip mroutes")
1121 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
1122 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1123 logger.info("Expected behavior: %s", result)
1124
1125 step("r1 : Verify pim interface traffic")
1126 state_after = get_pim_interface_traffic(tgen, state_dict)
1127 assert isinstance(
1128 state_after, dict
1129 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1130 tc_name, result
1131 )
1132
1133 result = verify_state_incremented(state_before, state_after)
1134 assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result)
1135
1136 # Uncomment next line for debugging
1137 # tgen.mininet_cli()
1138
1139 write_test_footer(tc_name)
1140
1141
1142 def test_send_join_on_higher_preffered_rp_p1(request):
1143 """
1144 TC_11_P1 : Verify PIM join send towards the higher preferred RP
1145 TC_12_P1 : Verify PIM prune send towards the lower preferred RP
1146 TC_13_P1 : Verify RPF interface is updated in mroute (kernel) when higher
1147 preferred overlapping RP configured
1148 TC_14_P1 : Verify IIF and OIL in "show ip pim state" updated properly when
1149 higher preferred overlapping RP configured
1150 TC_15_P1 : Verify upstream interfaces(IIF) and join state are updated when
1151 higher preferred overlapping RP is configured
1152 TC_16_P1 : Verify join is send to lower preferred RP, when higher
1153 preferred RP gets deleted
1154 TC_17_P1 : Verify prune is send to higher preferred RP when higher
1155 preferred RP gets deleted
1156 TC_18_P1 : Verify RPF interface updated in mroute when higher preferred RP
1157 gets deleted
1158 TC_19_P1 : Verify IIF and OIL in "show ip pim state" updated when higher
1159 preferred overlapping RP is deleted
1160 TC_20_P1 : Verify PIM upstream IIF updated when higher preferred
1161 overlapping RP deleted
1162
1163 Topology used:
1164 _______r2
1165 |
1166 iperf |
1167 r0-----r1
1168 |
1169 |_______r4
1170 """
1171
1172 tgen = get_topogen()
1173 tc_name = request.node.name
1174 write_test_header(tc_name)
1175
1176 # Don"t run this test if we have any failure.
1177 if tgen.routers_have_failure():
1178 pytest.skip(tgen.errors)
1179
1180 step("Creating configuration from JSON")
1181 reset_config_on_routers(tgen)
1182 app_helper.stop_all_hosts()
1183 clear_mroute(tgen)
1184 clear_pim_interface_traffic(tgen, TOPO)
1185
1186 step("Enable IGMP on r1 interface")
1187 step("Configure RP on r2 (loopback interface) for the group range " "224.0.0.0/4")
1188 step("Configure RP on r4 (loopback interface) for the group range " "225.1.1.1/32")
1189
1190 step("r3 : Make all interface not reachable")
1191 dut = "r3"
1192 intf = "r3-r1-eth0"
1193 shutdown_bringup_interface(tgen, dut, intf, False)
1194 intf = "r3-r2-eth1"
1195 shutdown_bringup_interface(tgen, dut, intf, False)
1196 intf = "r3-r4-eth2"
1197 shutdown_bringup_interface(tgen, dut, intf, False)
1198
1199 dut = "r2"
1200 intf = "r2-r3-eth1"
1201 shutdown_bringup_interface(tgen, dut, intf, False)
1202
1203 dut = "r4"
1204 intf = "r4-r3-eth1"
1205 shutdown_bringup_interface(tgen, dut, intf, False)
1206
1207 dut = "r1"
1208 intf = "r1-r3-eth2"
1209 shutdown_bringup_interface(tgen, dut, intf, False)
1210
1211 step("r1 : Verify joinTx count before sending join")
1212 state_dict = {"r1": {"r1-r4-eth3": ["joinTx"], "r1-r2-eth1": ["pruneTx"]}}
1213
1214 state_before = get_pim_interface_traffic(tgen, state_dict)
1215 assert isinstance(
1216 state_before, dict
1217 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1218 tc_name, state_before
1219 )
1220
1221 step("r0 : Send IGMP join for 225.1.1.1")
1222 result = app_helper.run_join("r0", GROUP_ADDRESS, "r1")
1223 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1224
1225 step("r1 : Verify IGMP groups")
1226 dut = "r1"
1227 oif = "r1-r0-eth0"
1228 result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS)
1229 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1230
1231 step("Configure static RP for group 225.1.1.1/32")
1232 input_dict = {
1233 "r4": {
1234 "pim": {
1235 "rp": [
1236 {
1237 "rp_addr": "1.0.4.17",
1238 "group_addr_range": ["225.1.1.1/32"],
1239 }
1240 ]
1241 }
1242 }
1243 }
1244
1245 result = create_pim_config(tgen, TOPO, input_dict)
1246 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1247
1248 step("r1 : Verify RP info for group 224.0.0.0/4")
1249 rp_address_1 = "1.0.2.17"
1250 iif = "r1-r2-eth1"
1251 result = verify_pim_rp_info(
1252 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address_1, SOURCE
1253 )
1254 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1255
1256 step("r1 : Verify RP info for group 225.1.1.1")
1257 rp_address_2 = "1.0.4.17"
1258 iif = "r1-r4-eth3"
1259 result = verify_pim_rp_info(tgen, TOPO, dut, GROUP_RANGE, iif, rp_address_2, SOURCE)
1260 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1261
1262 step("r1 : Verify join is sent to higher preferred RP")
1263 step("r1 : Verify prune is sent to lower preferred RP")
1264 state_after = get_pim_interface_traffic(tgen, state_dict)
1265 assert isinstance(
1266 state_after, dict
1267 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1268 tc_name, result
1269 )
1270
1271 result = verify_state_incremented(state_before, state_after)
1272 assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result)
1273
1274 step("r1 : Verify ip mroutes")
1275 iif = "r1-r4-eth3"
1276 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
1277 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1278
1279 step("r1 : Verify PIM state")
1280 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS)
1281 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1282
1283 step("r1 : Verify upstream IIF interface")
1284 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
1285 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1286
1287 step("r1 : Verify upstream join state and join timer")
1288 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
1289 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1290
1291 clear_pim_interface_traffic(tgen, TOPO)
1292
1293 step("r1 : Verify joinTx, pruneTx count before RP gets deleted")
1294 state_dict = {"r1": {"r1-r2-eth1": ["joinTx"], "r1-r4-eth3": ["pruneTx"]}}
1295
1296 state_before = get_pim_interface_traffic(tgen, state_dict)
1297 assert isinstance(
1298 state_before, dict
1299 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1300 tc_name, result
1301 )
1302
1303 step("r1 : Delete RP configuration for 225.1.1.1")
1304 input_dict = {
1305 "r1": {
1306 "pim": {
1307 "rp": [
1308 {
1309 "rp_addr": "1.0.4.17",
1310 "group_addr_range": ["225.1.1.1/32"],
1311 "delete": True,
1312 }
1313 ]
1314 }
1315 }
1316 }
1317
1318 result = create_pim_config(tgen, TOPO, input_dict)
1319 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1320
1321 step("r1 : Verify rp-info for group 224.0.0.0/4")
1322 iif = "r1-r2-eth1"
1323 result = verify_pim_rp_info(
1324 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address_1, SOURCE
1325 )
1326 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1327
1328 step("r1 : Verify rp-info for group 225.1.1.1")
1329 iif = "r1-r4-eth3"
1330 result = verify_pim_rp_info(
1331 tgen, TOPO, dut, GROUP_RANGE, oif, rp_address_2, SOURCE, expected=False
1332 )
1333 assert result is not True, (
1334 "Testcase {} : Failed \n "
1335 "r1: rp-info is present for group 225.1.1.1 \n Error: {}".format(
1336 tc_name, result
1337 )
1338 )
1339
1340 step(
1341 "r1 : Verify RPF interface updated in mroute when higher preferred"
1342 "RP gets deleted"
1343 )
1344 iif = "r1-r2-eth1"
1345 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
1346 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1347 logger.info("Expected behavior: %s", result)
1348
1349 step(
1350 "r1 : Verify IIF and OIL in show ip pim state updated when higher"
1351 "preferred overlapping RP is deleted"
1352 )
1353 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS)
1354 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1355
1356 step(
1357 "r1 : Verify upstream IIF updated when higher preferred overlapping"
1358 "RP deleted"
1359 )
1360 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
1361 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1362
1363 step(
1364 "r1 : Verify upstream join state and join timer updated when higher"
1365 "preferred overlapping RP deleted"
1366 )
1367 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
1368 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1369
1370 step(
1371 "r1 : Verify join is sent to lower preferred RP, when higher"
1372 "preferred RP gets deleted"
1373 )
1374 step(
1375 "r1 : Verify prune is sent to higher preferred RP when higher"
1376 " preferred RP gets deleted"
1377 )
1378 state_after = get_pim_interface_traffic(tgen, state_dict)
1379 assert isinstance(
1380 state_after, dict
1381 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1382 tc_name, result
1383 )
1384
1385 result = verify_state_incremented(state_before, state_after)
1386 assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result)
1387
1388 # Uncomment next line for debugging
1389 # tgen.mininet_cli()
1390
1391 write_test_footer(tc_name)
1392
1393
1394 if __name__ == "__main__":
1395 ARGS = ["-s"] + sys.argv[1:]
1396 sys.exit(pytest.main(ARGS))