]> git.proxmox.com Git - mirror_frr.git/blobdiff - tests/topotests/multicast_pim_sm_topo2/test_multicast_pim_sm_topo2.py
*: auto-convert to SPDX License IDs
[mirror_frr.git] / tests / topotests / multicast_pim_sm_topo2 / test_multicast_pim_sm_topo2.py
index 96886b0d9508d091d02cc9d49f7837a8d4e90e23..17f52cb86050445bc82e92eb3b6cac93cbc9f1d6 100755 (executable)
@@ -1,24 +1,11 @@
 #!/usr/bin/env python
+# SPDX-License-Identifier: ISC
 
 #
 # Copyright (c) 2020 by VMware, Inc. ("VMware")
 # Used Copyright (c) 2018 by Network Device Education Foundation,
 # Inc. ("NetDEF") in this file.
 #
-# Permission to use, copy, modify, and/or distribute this software
-# for any purpose with or without fee is hereby granted, provided
-# that the above copyright notice and this permission notice appear
-# in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
-# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
-# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
-# OF THIS SOFTWARE.
-#
 
 """
 Following tests are covered to test multicast pim sm:
@@ -47,10 +34,7 @@ Following tests are covered:
 
 import os
 import sys
-import json
 import time
-import datetime
-from time import sleep
 import pytest
 
 pytestmark = pytest.mark.pimd
@@ -65,18 +49,13 @@ sys.path.append(os.path.join(CWD, "../lib/"))
 # pylint: disable=C0413
 # Import topogen and topotest helpers
 from lib.topogen import Topogen, get_topogen
-from lib.micronet_compat import Topo
 
 from lib.common_config import (
     start_topology,
     write_test_header,
     write_test_footer,
     step,
-    iperfSendIGMPJoin,
-    addKernelRoute,
     reset_config_on_routers,
-    iperfSendTraffic,
-    kill_iperf,
     shutdown_bringup_interface,
     kill_router_daemons,
     start_router,
@@ -89,18 +68,17 @@ from lib.pim import (
     create_pim_config,
     create_igmp_config,
     verify_igmp_groups,
-    verify_ip_mroutes,
-    verify_pim_interface_traffic,
+    verify_mroutes,
+    get_pim_interface_traffic,
     verify_upstream_iif,
     verify_pim_neighbors,
     verify_pim_state,
-    verify_ip_pim_join,
-    clear_ip_mroute,
-    clear_ip_pim_interface_traffic,
-    verify_igmp_config,
+    clear_mroute,
+    clear_pim_interface_traffic,
+    McastTesterHelper,
 )
 from lib.topolog import logger
-from lib.topojson import build_topo_from_json, build_config_from_json
+from lib.topojson import build_config_from_json
 
 
 pytestmark = [pytest.mark.pimd]
@@ -166,7 +144,7 @@ def setup_module(mod):
     # Required linux kernel version for this suite to run.
     result = required_linux_kernel_version("4.19")
     if result is not True:
-        pytest.skip("Kernel requirements are not met")
+        pytest.skip("Kernel version should be >= 4.19")
 
     testsuite_run_time = time.asctime(time.localtime(time.time()))
     logger.info("Testsuite start time: {}".format(testsuite_run_time))
@@ -181,12 +159,9 @@ def setup_module(mod):
     topo = tgen.json_topo
     # ... and here it calls Mininet initialization functions.
 
-    # get list of daemons needs to be started for this suite.
-    daemons = topo_daemons(tgen, topo)
-
     # Starting topology, create tmp files which are loaded to routers
-    #  to start deamons and then start routers
-    start_topology(tgen, daemons)
+    #  to start daemons and then start routers
+    start_topology(tgen)
 
     # Don"t run this test if we have any failure.
     if tgen.routers_have_failure():
@@ -195,6 +170,10 @@ def setup_module(mod):
     # Creating configuration from JSON
     build_config_from_json(tgen, topo)
 
+    # XXX Replace this using "with McastTesterHelper()... " in each test if possible.
+    global app_helper
+    app_helper = McastTesterHelper(tgen)
+
     logger.info("Running setup_module() done")
 
 
@@ -205,8 +184,7 @@ def teardown_module():
 
     tgen = get_topogen()
 
-    # Kill any iperfs we left running.
-    kill_iperf(tgen)
+    app_helper.cleanup()
 
     # Stop toplogy and Remove tmp files
     tgen.stop_topology()
@@ -224,46 +202,6 @@ def teardown_module():
 #####################################################
 
 
-def config_to_send_igmp_join_and_traffic(
-    tgen, topo, tc_name, iperf, iperf_intf, GROUP_RANGE, join=False, traffic=False
-):
-    """
-    API to do pre-configuration to send IGMP join and multicast
-    traffic
-
-    parameters:
-    -----------
-    * `tgen`: topogen object
-    * `topo`: input json data
-    * `tc_name`: caller test case name
-    * `iperf`: router running iperf
-    * `iperf_intf`: interface name router running iperf
-    * `GROUP_RANGE`: group range
-    * `join`: IGMP join, default False
-    * `traffic`: multicast traffic, default False
-    """
-
-    if join:
-        # Add route to kernal
-        result = addKernelRoute(tgen, iperf, iperf_intf, GROUP_RANGE)
-        assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
-
-    if traffic:
-        # Add route to kernal
-        result = addKernelRoute(tgen, iperf, iperf_intf, GROUP_RANGE)
-        assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
-
-        router_list = tgen.routers()
-        for router in router_list.keys():
-            if router == iperf:
-                continue
-
-            rnode = router_list[router]
-            rnode.run("echo 2 > /proc/sys/net/ipv4/conf/all/rp_filter")
-
-    return True
-
-
 def verify_state_incremented(state_before, state_after):
     """
     API to compare interface traffic state incrementing
@@ -318,10 +256,10 @@ def test_verify_mroute_and_traffic_when_pimd_restarted_p2(request):
         pytest.skip(tgen.errors)
 
     # Creating configuration from JSON
-    kill_iperf(tgen)
-    clear_ip_mroute(tgen)
+    app_helper.stop_all_hosts()
+    clear_mroute(tgen)
     reset_config_on_routers(tgen)
-    clear_ip_pim_interface_traffic(tgen, topo)
+    clear_pim_interface_traffic(tgen, topo)
 
     step("Configure static RP for (226.1.1.1-5) in c1")
     step("Configure static RP for (232.1.1.1-5) in c2")
@@ -369,7 +307,15 @@ def test_verify_mroute_and_traffic_when_pimd_restarted_p2(request):
     )
 
     input_dict = {
-        "f1": {"igmp": {"interfaces": {"f1-i8-eth2": {"igmp": {"version": "2"}}}}}
+        "f1": {
+            "igmp": {
+                "interfaces": {
+                    "f1-i8-eth2": {
+                        "igmp": {"version": "2", "query": {"query-interval": 15}}
+                    }
+                }
+            }
+        }
     }
     result = create_igmp_config(tgen, topo, input_dict)
     assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
@@ -377,12 +323,7 @@ def test_verify_mroute_and_traffic_when_pimd_restarted_p2(request):
     input_join = {"i1": "i1-l1-eth0", "i8": "i8-f1-eth0"}
 
     for recvr, recvr_intf in input_join.items():
-        result = config_to_send_igmp_join_and_traffic(
-            tgen, topo, tc_name, recvr, recvr_intf, _GROUP_RANGE, join=True
-        )
-        assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
-
-        result = iperfSendIGMPJoin(tgen, recvr, _IGMP_JOIN_RANGE, join_interval=1)
+        result = app_helper.run_join(recvr, _IGMP_JOIN_RANGE, join_intf=recvr_intf)
         assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
 
     step(
@@ -397,12 +338,7 @@ def test_verify_mroute_and_traffic_when_pimd_restarted_p2(request):
     input_src = {"i2": "i2-f1-eth0", "i5": "i5-c2-eth0"}
 
     for src, src_intf in input_src.items():
-        result = config_to_send_igmp_join_and_traffic(
-            tgen, topo, tc_name, src, src_intf, _GROUP_RANGE, traffic=True
-        )
-        assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
-
-        result = iperfSendTraffic(tgen, src, _IGMP_JOIN_RANGE, 32, 2500)
+        result = app_helper.run_traffic(src, _IGMP_JOIN_RANGE, bind_intf=src_intf)
         assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
 
     # Verifying mroutes before PIMd restart, fetching uptime
@@ -413,7 +349,7 @@ def test_verify_mroute_and_traffic_when_pimd_restarted_p2(request):
         {"dut": "f1", "src_address": source, "iif": "f1-i2-eth1", "oil": "f1-i8-eth2"},
     ]
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -434,7 +370,7 @@ def test_verify_mroute_and_traffic_when_pimd_restarted_p2(request):
     start_router_daemons(tgen, "f1", ["pimd"])
 
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -482,7 +418,7 @@ def test_verify_mroute_and_traffic_when_pimd_restarted_p2(request):
         {"dut": "f1", "src_address": "*", "iif": "f1-c2-eth0", "oil": "f1-i8-eth2"}
     ]
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -496,7 +432,7 @@ def test_verify_mroute_and_traffic_when_pimd_restarted_p2(request):
         {"dut": "f1", "src_address": source, "iif": "f1-i2-eth1", "oil": "none"}
     ]
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -505,12 +441,11 @@ def test_verify_mroute_and_traffic_when_pimd_restarted_p2(request):
             data["oil"],
             expected=False,
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \n mroutes are still present \n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
+            "Found: {}".format(tc_name, data["dut"], result)
         )
-        logger.info("Expected Behavior: {}".format(result))
 
     write_test_footer(tc_name)
 
@@ -530,10 +465,10 @@ def test_verify_mroute_and_traffic_when_frr_restarted_p2(request):
         pytest.skip(tgen.errors)
 
     # Creating configuration from JSON
-    kill_iperf(tgen)
-    clear_ip_mroute(tgen)
+    app_helper.stop_all_hosts()
+    clear_mroute(tgen)
     reset_config_on_routers(tgen)
-    clear_ip_pim_interface_traffic(tgen, topo)
+    clear_pim_interface_traffic(tgen, topo)
 
     step("Configure static RP for (226.1.1.1-5) in c1")
     step("Configure static RP for (232.1.1.1-5) in c2")
@@ -581,7 +516,15 @@ def test_verify_mroute_and_traffic_when_frr_restarted_p2(request):
     )
 
     input_dict = {
-        "f1": {"igmp": {"interfaces": {"f1-i8-eth2": {"igmp": {"version": "2"}}}}}
+        "f1": {
+            "igmp": {
+                "interfaces": {
+                    "f1-i8-eth2": {
+                        "igmp": {"version": "2", "query": {"query-interval": 15}}
+                    }
+                }
+            }
+        }
     }
     result = create_igmp_config(tgen, topo, input_dict)
     assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
@@ -589,12 +532,7 @@ def test_verify_mroute_and_traffic_when_frr_restarted_p2(request):
     input_join = {"i1": "i1-l1-eth0", "i8": "i8-f1-eth0"}
 
     for recvr, recvr_intf in input_join.items():
-        result = config_to_send_igmp_join_and_traffic(
-            tgen, topo, tc_name, recvr, recvr_intf, _GROUP_RANGE, join=True
-        )
-        assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
-
-        result = iperfSendIGMPJoin(tgen, recvr, _IGMP_JOIN_RANGE, join_interval=1)
+        result = app_helper.run_join(recvr, _IGMP_JOIN_RANGE, join_intf=recvr_intf)
         assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
 
     step(
@@ -609,12 +547,7 @@ def test_verify_mroute_and_traffic_when_frr_restarted_p2(request):
     input_src = {"i2": "i2-f1-eth0", "i5": "i5-c2-eth0"}
 
     for src, src_intf in input_src.items():
-        result = config_to_send_igmp_join_and_traffic(
-            tgen, topo, tc_name, src, src_intf, _GROUP_RANGE, traffic=True
-        )
-        assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
-
-        result = iperfSendTraffic(tgen, src, _IGMP_JOIN_RANGE, 32, 2500)
+        result = app_helper.run_traffic(src, _IGMP_JOIN_RANGE, bind_intf=src_intf)
         assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
 
     step("Verifying mroutes before FRR restart, fetching uptime")
@@ -625,7 +558,7 @@ def test_verify_mroute_and_traffic_when_frr_restarted_p2(request):
         {"dut": "f1", "src_address": source, "iif": "f1-i2-eth1", "oil": "f1-i8-eth2"},
     ]
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -646,7 +579,7 @@ def test_verify_mroute_and_traffic_when_frr_restarted_p2(request):
     start_router(tgen, "f1")
 
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -693,7 +626,7 @@ def test_verify_mroute_and_traffic_when_frr_restarted_p2(request):
         {"dut": "f1", "src_address": "*", "iif": "f1-c2-eth0", "oil": "f1-i8-eth2"}
     ]
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -707,7 +640,7 @@ def test_verify_mroute_and_traffic_when_frr_restarted_p2(request):
         {"dut": "f1", "src_address": source, "iif": "f1-i2-eth1", "oil": "none"}
     ]
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -716,12 +649,11 @@ def test_verify_mroute_and_traffic_when_frr_restarted_p2(request):
             data["oil"],
             expected=False,
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \n mroutes are still present \n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
+            "Found: {}".format(tc_name, data["dut"], result)
         )
-        logger.info("Expected Behavior: {}".format(result))
 
     write_test_footer(tc_name)
 
@@ -741,10 +673,10 @@ def test_verify_SPT_switchover_when_RPT_and_SPT_path_is_different_p0(request):
         pytest.skip(tgen.errors)
 
     # Creating configuration from JSON
-    kill_iperf(tgen)
-    clear_ip_mroute(tgen)
+    app_helper.stop_all_hosts()
+    clear_mroute(tgen)
     reset_config_on_routers(tgen)
-    clear_ip_pim_interface_traffic(tgen, topo)
+    clear_pim_interface_traffic(tgen, topo)
 
     step("Configure static RP for (226.1.1.1-5) and " "(232.1.1.1-5) in c2")
 
@@ -774,31 +706,21 @@ def test_verify_SPT_switchover_when_RPT_and_SPT_path_is_different_p0(request):
         "(226.1.1.1-5) and (232.1.1.1-5)"
     )
 
-    result = config_to_send_igmp_join_and_traffic(
-        tgen, topo, tc_name, "i1", "i1-l1-eth0", _GROUP_RANGE, join=True
-    )
-    assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
-
-    result = iperfSendIGMPJoin(tgen, "i1", _IGMP_JOIN_RANGE, join_interval=1)
+    result = app_helper.run_join("i1", _IGMP_JOIN_RANGE, "l1")
     assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
 
     step("Send multicast traffic from FRR3 to '226.1.1.1-5'" ", '232.1.1.1-5' receiver")
 
-    result = config_to_send_igmp_join_and_traffic(
-        tgen, topo, tc_name, "i2", "i2-f1-eth0", _GROUP_RANGE, traffic=True
-    )
-    assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
-
     step("registerRx and registerStopTx value before traffic sent")
     state_dict = {"c2": {"c2-f1-eth1": ["registerRx", "registerStopTx"]}}
-    state_before = verify_pim_interface_traffic(tgen, state_dict)
+    state_before = get_pim_interface_traffic(tgen, state_dict)
     assert isinstance(
         state_before, dict
     ), "Testcase {} : Failed \n state_before is not dictionary \nError: {}".format(
         tc_name, result
     )
 
-    result = iperfSendTraffic(tgen, "i2", _IGMP_JOIN_RANGE, 32, 2500)
+    result = app_helper.run_traffic("i2", _IGMP_JOIN_RANGE, "f1")
     assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
 
     step(
@@ -806,7 +728,7 @@ def test_verify_SPT_switchover_when_RPT_and_SPT_path_is_different_p0(request):
         " 'show ip mroute' and mroute OIL is towards RP."
     )
 
-    result = verify_ip_mroutes(
+    result = verify_mroutes(
         tgen,
         "f1",
         "10.0.5.2",
@@ -816,7 +738,7 @@ def test_verify_SPT_switchover_when_RPT_and_SPT_path_is_different_p0(request):
     )
     assert result is True, "Testcase {} : " "Failed Error: {}".format(tc_name, result)
 
-    result = verify_ip_mroutes(
+    result = verify_mroutes(
         tgen, "f1", "10.0.5.2", _IGMP_JOIN_RANGE, "f1-i2-eth1", "f1-r2-eth3"
     )
     assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
@@ -833,7 +755,7 @@ def test_verify_SPT_switchover_when_RPT_and_SPT_path_is_different_p0(request):
         {"dut": "l1", "src_address": source, "iif": "l1-r2-eth4", "oil": "l1-i1-eth1"},
     ]
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -851,7 +773,7 @@ def test_verify_SPT_switchover_when_RPT_and_SPT_path_is_different_p0(request):
 
     step("Stop the traffic to all the receivers")
 
-    kill_iperf(tgen, "i2", "remove_traffic")
+    app_helper.stop_host("i2")
 
     step(
         "Null register packet being send periodically from FRR3 to RP, "
@@ -864,7 +786,7 @@ def test_verify_SPT_switchover_when_RPT_and_SPT_path_is_different_p0(request):
         {"dut": "c2", "src_address": source, "iif": "c2-f1-eth1", "oil": "none"}
     ]
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -875,7 +797,7 @@ def test_verify_SPT_switchover_when_RPT_and_SPT_path_is_different_p0(request):
         assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
 
     step("registerRx and registerStopTx value after traffic sent")
-    state_after = verify_pim_interface_traffic(tgen, state_dict)
+    state_after = get_pim_interface_traffic(tgen, state_dict)
     assert isinstance(
         state_after, dict
     ), "Testcase {} : Failed \n state_before is not dictionary \nError: {}".format(
@@ -903,10 +825,10 @@ def test_verify_mroute_after_shut_noshut_of_upstream_interface_p1(request):
         pytest.skip(tgen.errors)
 
     # Creating configuration from JSON
-    kill_iperf(tgen)
-    clear_ip_mroute(tgen)
+    app_helper.stop_all_hosts()
+    clear_mroute(tgen)
     reset_config_on_routers(tgen)
-    clear_ip_pim_interface_traffic(tgen, topo)
+    clear_pim_interface_traffic(tgen, topo)
 
     step("Configure static RP for (226.1.1.1-5) in c1")
     step("Configure static RP for (232.1.1.1-5) in c2")
@@ -954,7 +876,15 @@ def test_verify_mroute_after_shut_noshut_of_upstream_interface_p1(request):
     )
 
     input_dict = {
-        "f1": {"igmp": {"interfaces": {"f1-i8-eth2": {"igmp": {"version": "2"}}}}}
+        "f1": {
+            "igmp": {
+                "interfaces": {
+                    "f1-i8-eth2": {
+                        "igmp": {"version": "2", "query": {"query-interval": 15}}
+                    }
+                }
+            }
+        }
     }
     result = create_igmp_config(tgen, topo, input_dict)
     assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
@@ -962,12 +892,7 @@ def test_verify_mroute_after_shut_noshut_of_upstream_interface_p1(request):
     input_join = {"i1": "i1-l1-eth0", "i8": "i8-f1-eth0"}
 
     for recvr, recvr_intf in input_join.items():
-        result = config_to_send_igmp_join_and_traffic(
-            tgen, topo, tc_name, recvr, recvr_intf, _GROUP_RANGE, join=True
-        )
-        assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
-
-        result = iperfSendIGMPJoin(tgen, recvr, _IGMP_JOIN_RANGE, join_interval=1)
+        result = app_helper.run_join(recvr, _IGMP_JOIN_RANGE, join_intf=recvr_intf)
         assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
 
     step(
@@ -982,12 +907,7 @@ def test_verify_mroute_after_shut_noshut_of_upstream_interface_p1(request):
     input_src = {"i2": "i2-f1-eth0", "i5": "i5-c2-eth0"}
 
     for src, src_intf in input_src.items():
-        result = config_to_send_igmp_join_and_traffic(
-            tgen, topo, tc_name, src, src_intf, _GROUP_RANGE, traffic=True
-        )
-        assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
-
-        result = iperfSendTraffic(tgen, src, _IGMP_JOIN_RANGE, 32, 2500)
+        result = app_helper.run_traffic(src, _IGMP_JOIN_RANGE, bind_intf=src_intf)
         assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
 
     step(
@@ -1001,7 +921,7 @@ def test_verify_mroute_after_shut_noshut_of_upstream_interface_p1(request):
         {"dut": "f1", "src_address": source, "iif": "f1-i2-eth1", "oil": "f1-i8-eth2"},
     ]
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -1030,7 +950,7 @@ def test_verify_mroute_after_shut_noshut_of_upstream_interface_p1(request):
     shutdown_bringup_interface(tgen, dut, intf, True)
 
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -1053,7 +973,7 @@ def test_verify_mroute_after_shut_noshut_of_upstream_interface_p1(request):
     )
 
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -1083,8 +1003,8 @@ def test_verify_mroute_after_shut_noshut_of_upstream_interface_p1(request):
     intf = "f1-r2-eth3"
     shutdown_bringup_interface(tgen, dut, intf, True)
 
-    clear_ip_mroute(tgen, "l1")
-    clear_ip_mroute(tgen, "l1")
+    clear_mroute(tgen, "l1")
+    clear_mroute(tgen, "l1")
 
     step(
         "After no shut, verify traffic resume to all the receivers"
@@ -1092,7 +1012,7 @@ def test_verify_mroute_after_shut_noshut_of_upstream_interface_p1(request):
     )
 
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -1114,13 +1034,13 @@ def test_verify_mroute_after_shut_noshut_of_upstream_interface_p1(request):
     intf_l1_c1 = "l1-c1-eth0"
     shutdown_bringup_interface(tgen, dut, intf_l1_c1, False)
 
-
     result = verify_upstream_iif(
         tgen, "l1", "Unknown", source, IGMP_JOIN_RANGE_2, expected=False
     )
     assert result is not True, (
-        "Testcase {} : Failed Error: \n "
-        "mroutes are still present, after waiting for 10 mins".format(tc_name)
+        "Testcase {} : Failed \n "
+        "Expected: [{}]: Upstream IIF should be unknown \n "
+        "Found: {}".format(tc_name, "l1", result)
     )
 
     step("No shut the Source interface just after the upstream is expired" " from FRR1")
@@ -1128,7 +1048,7 @@ def test_verify_mroute_after_shut_noshut_of_upstream_interface_p1(request):
     shutdown_bringup_interface(tgen, dut, intf_l1_c1, True)
 
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -1139,10 +1059,10 @@ def test_verify_mroute_after_shut_noshut_of_upstream_interface_p1(request):
         assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
 
     step("Stop the traffic to all the receivers")
-    kill_iperf(tgen)
+    app_helper.stop_all_hosts()
 
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -1151,12 +1071,11 @@ def test_verify_mroute_after_shut_noshut_of_upstream_interface_p1(request):
             data["oil"],
             expected=False,
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \n mroutes are still present \n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
+            "Found: {}".format(tc_name, data["dut"], result)
         )
-        logger.info("Expected Behavior: {}".format(result))
 
     write_test_footer(tc_name)
 
@@ -1176,10 +1095,10 @@ def test_verify_mroute_when_receiver_is_outside_frr_p0(request):
         pytest.skip(tgen.errors)
 
     # Creating configuration from JSON
-    kill_iperf(tgen)
-    clear_ip_mroute(tgen)
+    app_helper.stop_all_hosts()
+    clear_mroute(tgen)
     reset_config_on_routers(tgen)
-    clear_ip_pim_interface_traffic(tgen, topo)
+    clear_pim_interface_traffic(tgen, topo)
 
     step("Configure static RP on c1 for group range " "(226.1.1.1-5) and (232.1.1.1-5)")
 
@@ -1208,24 +1127,14 @@ def test_verify_mroute_when_receiver_is_outside_frr_p0(request):
         "Enable IGMP on FRR1 interface and send IGMP join"
         " (226.1.1.1-5) and (232.1.1.1-5)"
     )
-    result = config_to_send_igmp_join_and_traffic(
-        tgen, topo, tc_name, "i1", "i1-l1-eth0", _GROUP_RANGE, join=True
-    )
-    assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
-
-    result = iperfSendIGMPJoin(tgen, "i1", _IGMP_JOIN_RANGE, join_interval=1)
+    result = app_helper.run_join("i1", _IGMP_JOIN_RANGE, "l1")
     assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
 
     step(
         "Send multicast traffic from FRR3 to all the receivers "
         "(226.1.1.1-5) and (232.1.1.1-5)"
     )
-    result = config_to_send_igmp_join_and_traffic(
-        tgen, topo, tc_name, "i2", "i2-f1-eth0", _GROUP_RANGE, traffic=True
-    )
-    assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
-
-    result = iperfSendTraffic(tgen, "i2", _IGMP_JOIN_RANGE, 32, 2500)
+    result = app_helper.run_traffic("i2", _IGMP_JOIN_RANGE, "f1")
     assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
 
     step(
@@ -1233,17 +1142,20 @@ def test_verify_mroute_when_receiver_is_outside_frr_p0(request):
         " join (226.1.1.1-5) and (232.1.1.1-5)"
     )
     input_dict = {
-        "c2": {"igmp": {"interfaces": {"c2-i5-eth2": {"igmp": {"version": "2"}}}}}
+        "c2": {
+            "igmp": {
+                "interfaces": {
+                    "c2-i5-eth2": {
+                        "igmp": {"version": "2", "query": {"query-interval": 15}}
+                    }
+                }
+            }
+        }
     }
     result = create_igmp_config(tgen, topo, input_dict)
     assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
 
-    result = config_to_send_igmp_join_and_traffic(
-        tgen, topo, tc_name, "i5", "i5-c2-eth0", _GROUP_RANGE, join=True
-    )
-    assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
-
-    result = iperfSendIGMPJoin(tgen, "i5", _IGMP_JOIN_RANGE, join_interval=1)
+    result = app_helper.run_join("i5", _IGMP_JOIN_RANGE, "c2")
     assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
 
     step("FRR1 has 10 (*.G) and 10 (S,G) verify using 'show ip mroute count'")
@@ -1264,7 +1176,7 @@ def test_verify_mroute_when_receiver_is_outside_frr_p0(request):
         {"dut": "c2", "src_address": source, "iif": "c2-f1-eth1", "oil": "c2-i5-eth2"},
     ]
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -1316,10 +1228,10 @@ def test_verify_mroute_when_FRR_is_FHR_and_LHR_p0(request):
         pytest.skip(tgen.errors)
 
     # Creating configuration from JSON
-    kill_iperf(tgen)
-    clear_ip_mroute(tgen)
+    app_helper.stop_all_hosts()
+    clear_mroute(tgen)
     reset_config_on_routers(tgen)
-    clear_ip_pim_interface_traffic(tgen, topo)
+    clear_pim_interface_traffic(tgen, topo)
 
     step("Configure static RP for group range (226.1.1.1-5) and " "(232.1.1.1-5) on c1")
     _GROUP_RANGE = GROUP_RANGE_2 + GROUP_RANGE_3
@@ -1356,22 +1268,12 @@ def test_verify_mroute_when_FRR_is_FHR_and_LHR_p0(request):
         "(226.1.1.1-5) and (232.1.1.1-5)"
     )
 
-    result = config_to_send_igmp_join_and_traffic(
-        tgen, topo, tc_name, "i1", "i1-l1-eth0", _GROUP_RANGE, join=True
-    )
-    assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
-
-    result = config_to_send_igmp_join_and_traffic(
-        tgen, topo, tc_name, "i2", "i2-f1-eth0", _GROUP_RANGE, traffic=True
-    )
-    assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
-
     step("Send IGMP join (226.1.1.1-5, 232.1.1.1-5) to LHR(l1)")
-    result = iperfSendIGMPJoin(tgen, "i1", _IGMP_JOIN_RANGE, join_interval=1)
+    result = app_helper.run_join("i1", _IGMP_JOIN_RANGE, "l1")
     assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
 
     step("Send multicast traffic from FRR3 to '226.1.1.1-5'" ", '232.1.1.1-5' receiver")
-    result = iperfSendTraffic(tgen, "i2", _IGMP_JOIN_RANGE, 32, 2500)
+    result = app_helper.run_traffic("i2", _IGMP_JOIN_RANGE, "f1")
     assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
 
     step(
@@ -1381,17 +1283,20 @@ def test_verify_mroute_when_FRR_is_FHR_and_LHR_p0(request):
 
     step("Configure one IGMP interface on f1 node and send IGMP" " join (225.1.1.1)")
     input_dict = {
-        "f1": {"igmp": {"interfaces": {"f1-i8-eth2": {"igmp": {"version": "2"}}}}}
+        "f1": {
+            "igmp": {
+                "interfaces": {
+                    "f1-i8-eth2": {
+                        "igmp": {"version": "2", "query": {"query-interval": 15}}
+                    }
+                }
+            }
+        }
     }
     result = create_igmp_config(tgen, topo, input_dict)
     assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
 
-    result = config_to_send_igmp_join_and_traffic(
-        tgen, topo, tc_name, "i8", "i8-f1-eth0", _GROUP_RANGE, join=True
-    )
-    assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
-
-    result = iperfSendIGMPJoin(tgen, "i8", _IGMP_JOIN_RANGE, join_interval=1)
+    result = app_helper.run_join("i8", _IGMP_JOIN_RANGE, "f1")
     assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
     step(
         "l1 and f1 has 10 IGMP groups (226.1.1.1-5, 232.1.1.1-5),"
@@ -1421,7 +1326,7 @@ def test_verify_mroute_when_FRR_is_FHR_and_LHR_p0(request):
         {"dut": "l1", "src_address": source, "iif": "l1-r2-eth4", "oil": "l1-i1-eth1"},
     ]
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -1446,7 +1351,7 @@ def test_verify_mroute_when_FRR_is_FHR_and_LHR_p0(request):
 
     # Stop the multicast traffic
     step("Stop the traffic to all the receivers")
-    kill_iperf(tgen)
+    app_helper.stop_all_hosts()
 
     step(
         "After traffic stopped , verify (*,G) entries are not flushed"
@@ -1458,7 +1363,7 @@ def test_verify_mroute_when_FRR_is_FHR_and_LHR_p0(request):
         {"dut": "l1", "src_address": "*", "iif": "l1-c1-eth0", "oil": "l1-i1-eth1"},
     ]
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -1466,9 +1371,9 @@ def test_verify_mroute_when_FRR_is_FHR_and_LHR_p0(request):
             data["iif"],
             data["oil"],
         )
-        assert result is True, (
-            "Testcase {} : Failed Error mroutes were flushed.".format(tc_name)
-        )
+        assert (
+            result is True
+        ), "Testcase {} : Failed Error mroutes were flushed.".format(tc_name)
 
     step(
         "After traffic stopped , verify (S,G) entries are flushed out"
@@ -1481,7 +1386,7 @@ def test_verify_mroute_when_FRR_is_FHR_and_LHR_p0(request):
     ]
 
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -1491,7 +1396,9 @@ def test_verify_mroute_when_FRR_is_FHR_and_LHR_p0(request):
             expected=False,
         )
         assert result is not True, (
-            "Testcase {} : Failed Error: \nmroutes are still present".format(tc_name)
+            "Testcase {} : Failed \n "
+            "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
+            "Found: {}".format(tc_name, data["dut"], result)
         )
 
     write_test_footer(tc_name)
@@ -1512,10 +1419,10 @@ def test_verify_mroute_when_5_different_receiver_joining_same_sources_p0(request
         pytest.skip(tgen.errors)
 
     # Creating configuration from JSON
-    kill_iperf(tgen)
-    clear_ip_mroute(tgen)
+    app_helper.stop_all_hosts()
+    clear_mroute(tgen)
     reset_config_on_routers(tgen)
-    clear_ip_pim_interface_traffic(tgen, topo)
+    clear_pim_interface_traffic(tgen, topo)
 
     step("Configure static RP for (226.1.1.1-5) in c1")
     step("Configure static RP for (232.1.1.1-5) in c2")
@@ -1570,12 +1477,24 @@ def test_verify_mroute_when_5_different_receiver_joining_same_sources_p0(request
         "f1": {
             "igmp": {
                 "interfaces": {
-                    "f1-i8-eth2": {"igmp": {"version": "2"}},
-                    "f1-i2-eth1": {"igmp": {"version": "2"}},
+                    "f1-i8-eth2": {
+                        "igmp": {"version": "2", "query": {"query-interval": 15}}
+                    },
+                    "f1-i2-eth1": {
+                        "igmp": {"version": "2", "query": {"query-interval": 15}}
+                    },
+                }
+            }
+        },
+        "l1": {
+            "igmp": {
+                "interfaces": {
+                    "l1-i6-eth2": {
+                        "igmp": {"version": "2", "query": {"query-interval": 15}}
+                    }
                 }
             }
         },
-        "l1": {"igmp": {"interfaces": {"l1-i6-eth2": {"igmp": {"version": "2"}}}}},
     }
     result = create_igmp_config(tgen, topo, input_dict)
     assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
@@ -1588,13 +1507,9 @@ def test_verify_mroute_when_5_different_receiver_joining_same_sources_p0(request
     }
 
     for recvr, recvr_intf in input_join.items():
-        result = config_to_send_igmp_join_and_traffic(
-            tgen, topo, tc_name, recvr, recvr_intf, _GROUP_RANGE, join=True
-        )
+        result = app_helper.run_join(recvr, _IGMP_JOIN_RANGE, join_intf=recvr_intf)
         assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
 
-        result = iperfSendIGMPJoin(tgen, recvr, _IGMP_JOIN_RANGE, join_interval=1)
-        assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
     step("Configure one source in FRR2 , one in c1")
     step(
         "Send multicast traffic from both the sources to all the"
@@ -1604,12 +1519,7 @@ def test_verify_mroute_when_5_different_receiver_joining_same_sources_p0(request
     input_src = {"i3": "i3-r2-eth0"}
 
     for src, src_intf in input_src.items():
-        result = config_to_send_igmp_join_and_traffic(
-            tgen, topo, tc_name, src, src_intf, _GROUP_RANGE, traffic=True
-        )
-        assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
-
-        result = iperfSendTraffic(tgen, src, _IGMP_JOIN_RANGE, 32, 2500)
+        result = app_helper.run_traffic(src, _IGMP_JOIN_RANGE, bind_intf=src_intf)
         assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
     step(
         "After all the IGMP groups received with correct port using"
@@ -1638,12 +1548,16 @@ def test_verify_mroute_when_5_different_receiver_joining_same_sources_p0(request
 
     source = topo["routers"]["i3"]["links"]["r2"]["ipv4"].split("/")[0]
     input_dict_all = [
-        {"dut": "l1", "src_address": source, "iif": ["l1-r2-eth4", "l1-c1-eth0"],
-            "oil": ["l1-i1-eth1", "l1-i6-eth2"]},
+        {
+            "dut": "l1",
+            "src_address": source,
+            "iif": ["l1-r2-eth4", "l1-c1-eth0"],
+            "oil": ["l1-i1-eth1", "l1-i6-eth2"],
+        },
         {"dut": "f1", "src_address": source, "iif": "f1-r2-eth3", "oil": "f1-i8-eth2"},
     ]
     for data in input_dict_all:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -1671,7 +1585,7 @@ def test_verify_mroute_when_5_different_receiver_joining_same_sources_p0(request
         {"dut": "l1", "src_address": source, "iif": "l1-r2-eth4", "oil": "l1-i1-eth1"}
     ]
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -1680,12 +1594,11 @@ def test_verify_mroute_when_5_different_receiver_joining_same_sources_p0(request
             data["oil"],
             expected=False,
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \n mroutes are still present \n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
+            "Found: {}".format(tc_name, data["dut"], result)
         )
-        logger.info("Expected Behavior: {}".format(result))
 
     step(
         "No traffic impact observed on other receivers verify using"
@@ -1695,7 +1608,7 @@ def test_verify_mroute_when_5_different_receiver_joining_same_sources_p0(request
         {"dut": "f1", "src_address": source, "iif": "f1-r2-eth3", "oil": "f1-i8-eth2"}
     ]
     for data in input_dict:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -1715,7 +1628,7 @@ def test_verify_mroute_when_5_different_receiver_joining_same_sources_p0(request
     )
 
     for data in input_dict_all:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -1743,10 +1656,10 @@ def test_verify_oil_iif_for_mroute_after_shut_noshut_source_interface_p1(request
         pytest.skip(tgen.errors)
 
     # Creating configuration from JSON
-    kill_iperf(tgen)
-    clear_ip_mroute(tgen)
+    app_helper.stop_all_hosts()
+    clear_mroute(tgen)
     reset_config_on_routers(tgen)
-    clear_ip_pim_interface_traffic(tgen, topo)
+    clear_pim_interface_traffic(tgen, topo)
 
     step("Configure static RP for (226.1.1.1-5) in c1")
     step("Configure static RP for (232.1.1.1-5) in c2")
@@ -1790,7 +1703,15 @@ def test_verify_oil_iif_for_mroute_after_shut_noshut_source_interface_p1(request
     )
 
     input_dict = {
-        "f1": {"igmp": {"interfaces": {"f1-i8-eth2": {"igmp": {"version": "2"}}}}}
+        "f1": {
+            "igmp": {
+                "interfaces": {
+                    "f1-i8-eth2": {
+                        "igmp": {"version": "2", "query": {"query-interval": 15}}
+                    }
+                }
+            }
+        }
     }
     result = create_igmp_config(tgen, topo, input_dict)
     assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
@@ -1798,12 +1719,7 @@ def test_verify_oil_iif_for_mroute_after_shut_noshut_source_interface_p1(request
     input_join = {"i1": "i1-l1-eth0", "i8": "i8-f1-eth0"}
 
     for recvr, recvr_intf in input_join.items():
-        result = config_to_send_igmp_join_and_traffic(
-            tgen, topo, tc_name, recvr, recvr_intf, _GROUP_RANGE, join=True
-        )
-        assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
-
-        result = iperfSendIGMPJoin(tgen, recvr, _IGMP_JOIN_RANGE, join_interval=1)
+        result = app_helper.run_join(recvr, _IGMP_JOIN_RANGE, join_intf=recvr_intf)
         assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
 
     step("Configure 1 source in FRR1 , 1 in FRR3")
@@ -1815,12 +1731,7 @@ def test_verify_oil_iif_for_mroute_after_shut_noshut_source_interface_p1(request
     input_src = {"i6": "i6-l1-eth0", "i2": "i2-f1-eth0"}
 
     for src, src_intf in input_src.items():
-        result = config_to_send_igmp_join_and_traffic(
-            tgen, topo, tc_name, src, src_intf, _GROUP_RANGE, traffic=True
-        )
-        assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
-
-        result = iperfSendTraffic(tgen, src, _IGMP_JOIN_RANGE, 32, 2500)
+        result = app_helper.run_traffic(src, _IGMP_JOIN_RANGE, bind_intf=src_intf)
         assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
 
     step(
@@ -1861,7 +1772,7 @@ def test_verify_oil_iif_for_mroute_after_shut_noshut_source_interface_p1(request
         },
     ]
     for data in input_dict_all:
-        result = verify_ip_mroutes(
+        result = verify_mroutes(
             tgen,
             data["dut"],
             data["src_address"],
@@ -1886,7 +1797,7 @@ def test_verify_oil_iif_for_mroute_after_shut_noshut_source_interface_p1(request
         " 'show ip mroute' "
     )
 
-    result = verify_ip_mroutes(
+    result = verify_mroutes(
         tgen,
         "f1",
         source_i2,
@@ -1895,12 +1806,11 @@ def test_verify_oil_iif_for_mroute_after_shut_noshut_source_interface_p1(request
         "f1-i8-eth2",
         expected=False,
     )
-    assert (
-        result is not True
-    ), "Testcase {} : Failed \n mroutes are" " still present \n Error: {}".format(
-        tc_name, result
+    assert result is not True, (
+        "Testcase {} : Failed \n "
+        "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
+        "Found: {}".format(tc_name, data["dut"], result)
     )
-    logger.info("Expected Behavior: {}".format(result))
 
     result = verify_upstream_iif(
         tgen, "f1", "Unknown", "10.0.5.2", _IGMP_JOIN_RANGE, joinState="NotJoined"