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