2025-02-05 10:03:58 +01:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#
|
|
|
|
# test_nhrp_redundancy.py
|
|
|
|
#
|
|
|
|
# Copyright 2024, LabN Consulting, L.L.C.
|
|
|
|
# Dave LeRoy
|
|
|
|
#
|
|
|
|
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import json
|
|
|
|
from functools import partial
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
# pylint: disable=C0413
|
|
|
|
# Import topogen and topotest helpers
|
|
|
|
from lib import topotest
|
|
|
|
from lib.topogen import Topogen, TopoRouter, get_topogen
|
|
|
|
from lib.topolog import logger
|
|
|
|
from lib.common_config import (
|
|
|
|
required_linux_kernel_version,
|
|
|
|
shutdown_bringup_interface,
|
|
|
|
retry,
|
|
|
|
)
|
|
|
|
|
|
|
|
"""
|
|
|
|
test_nhrp_redundancy.py: Test NHS redundancy for NHRP
|
|
|
|
"""
|
|
|
|
|
|
|
|
TOPOLOGY = """
|
2025-02-05 10:17:20 +01:00
|
|
|
+------------+ +------------+ +------------+
|
|
|
|
| | | | | |
|
|
|
|
| | | | | |
|
|
|
|
| NHS 1 | | NHS 2 | | NHS 3 |
|
|
|
|
| | | | | |
|
|
|
|
+-----+------+ +-----+------+ +-----+------+
|
|
|
|
|.1 |.2 |.3
|
|
|
|
| | |
|
|
|
|
| | 192.168.1.0/24 |
|
|
|
|
------+-------------------------------+------------------+-------------+------
|
|
|
|
|
|
|
|
|
|.6
|
|
|
|
GRE P2MP between all NHS and NHC +-----+------+
|
|
|
|
172.16.1.x/32 | |
|
|
|
|
| |
|
|
|
|
| Router |
|
|
|
|
| |
|
|
|
|
+-----+------+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---------+----------------+-------------+------
|
|
|
|
| 192.168.2.0/24 |
|
|
|
|
| |
|
|
|
|
| |.4 |.5
|
|
|
|
+------------+ | +-------+----+ +------+-----+ |
|
|
|
|
| | | | | | | |
|
|
|
|
| | +--------+ | | | |
|
2025-02-05 10:03:58 +01:00
|
|
|
| Host |.7 | | NHC 1 | | NHC 2 +-----+10.5.5.0/24
|
2025-02-05 10:17:20 +01:00
|
|
|
| +---------+ | | | | |
|
|
|
|
+------------+ | +------------+ +------------+ |
|
|
|
|
| |
|
|
|
|
10.4.4.0/24
|
2025-02-05 10:03:58 +01:00
|
|
|
"""
|
|
|
|
|
|
|
|
# Save the Current Working Directory to find configuration files.
|
|
|
|
CWD = os.path.dirname(os.path.realpath(__file__))
|
|
|
|
sys.path.append(os.path.join(CWD, "../"))
|
|
|
|
|
|
|
|
# Required to instantiate the topology builder class.
|
|
|
|
|
|
|
|
pytestmark = [pytest.mark.nhrpd]
|
|
|
|
|
|
|
|
|
|
|
|
def build_topo(tgen):
|
|
|
|
"Build function"
|
|
|
|
|
|
|
|
# Create 7 routers
|
|
|
|
for rname in ["nhs1", "nhs2", "nhs3", "nhc1", "nhc2", "router", "host"]:
|
|
|
|
tgen.add_router(rname)
|
|
|
|
|
|
|
|
switch = tgen.add_switch("s1")
|
|
|
|
switch.add_link(tgen.gears["nhs1"])
|
|
|
|
switch.add_link(tgen.gears["nhs2"])
|
|
|
|
switch.add_link(tgen.gears["nhs3"])
|
|
|
|
switch.add_link(tgen.gears["router"])
|
|
|
|
|
|
|
|
switch = tgen.add_switch("s2")
|
|
|
|
switch.add_link(tgen.gears["nhc1"])
|
|
|
|
switch.add_link(tgen.gears["nhc2"])
|
|
|
|
switch.add_link(tgen.gears["router"])
|
|
|
|
|
|
|
|
switch = tgen.add_switch("s3")
|
|
|
|
switch.add_link(tgen.gears["nhc1"])
|
|
|
|
switch.add_link(tgen.gears["host"])
|
|
|
|
|
|
|
|
switch = tgen.add_switch("s4")
|
|
|
|
switch.add_link(tgen.gears["nhc2"])
|
|
|
|
|
|
|
|
|
|
|
|
def _populate_iface():
|
|
|
|
tgen = get_topogen()
|
|
|
|
cmds_tot_hub = [
|
|
|
|
"ip tunnel add {0}-gre0 mode gre ttl 64 key 42 dev {0}-eth0 local 192.168.1.{1} remote 0.0.0.0",
|
|
|
|
"ip link set dev {0}-gre0 up",
|
|
|
|
"echo 0 > /proc/sys/net/ipv4/ip_forward_use_pmtu",
|
|
|
|
"echo 1 > /proc/sys/net/ipv6/conf/{0}-eth0/disable_ipv6",
|
|
|
|
"echo 1 > /proc/sys/net/ipv6/conf/{0}-gre0/disable_ipv6",
|
|
|
|
"iptables -A FORWARD -i {0}-gre0 -o {0}-gre0 -m hashlimit --hashlimit-upto 4/minute --hashlimit-burst 1 --hashlimit-mode srcip,dstip --hashlimit-srcmask 24 --hashlimit-dstmask 24 --hashlimit-name loglimit-0 -j NFLOG --nflog-group 1 --nflog-size 128",
|
|
|
|
]
|
|
|
|
|
|
|
|
cmds_tot = [
|
|
|
|
"ip tunnel add {0}-gre0 mode gre ttl 64 key 42 dev {0}-eth0 local 192.168.2.{1} remote 0.0.0.0",
|
|
|
|
"ip link set dev {0}-gre0 up",
|
|
|
|
"echo 0 > /proc/sys/net/ipv4/ip_forward_use_pmtu",
|
|
|
|
"echo 1 > /proc/sys/net/ipv6/conf/{0}-eth0/disable_ipv6",
|
|
|
|
"echo 1 > /proc/sys/net/ipv6/conf/{0}-gre0/disable_ipv6",
|
|
|
|
]
|
|
|
|
|
|
|
|
for cmd in cmds_tot_hub:
|
|
|
|
input = cmd.format("nhs1", "1")
|
|
|
|
logger.info("input: " + input)
|
|
|
|
output = tgen.net["nhs1"].cmd(input)
|
|
|
|
logger.info("output: " + output)
|
|
|
|
|
|
|
|
input = cmd.format("nhs2", "2")
|
|
|
|
logger.info("input: " + input)
|
|
|
|
output = tgen.net["nhs2"].cmd(input)
|
|
|
|
logger.info("output: " + output)
|
|
|
|
|
|
|
|
input = cmd.format("nhs3", "3")
|
|
|
|
logger.info("input: " + input)
|
|
|
|
output = tgen.net["nhs3"].cmd(input)
|
|
|
|
logger.info("output: " + output)
|
|
|
|
|
|
|
|
for cmd in cmds_tot:
|
|
|
|
input = cmd.format("nhc1", "4")
|
|
|
|
logger.info("input: " + input)
|
|
|
|
output = tgen.net["nhc1"].cmd(input)
|
|
|
|
logger.info("output: " + output)
|
|
|
|
|
|
|
|
input = cmd.format("nhc2", "5")
|
|
|
|
logger.info("input: " + input)
|
|
|
|
output = tgen.net["nhc2"].cmd(input)
|
|
|
|
logger.info("output: " + output)
|
|
|
|
|
|
|
|
|
|
|
|
def _verify_iptables():
|
|
|
|
tgen = get_topogen()
|
|
|
|
# Verify iptables is installed. Required for shortcuts
|
2025-02-05 10:17:20 +01:00
|
|
|
rc, _, _ = tgen.net["nhs1"].cmd_status("iptables -V")
|
|
|
|
return True if rc == 0 else False
|
2025-02-05 10:03:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
def setup_module(mod):
|
|
|
|
logger.info("NHRP Redundant NHS:\n {}".format(TOPOLOGY))
|
|
|
|
|
|
|
|
result = required_linux_kernel_version("5.0")
|
|
|
|
if result is not True:
|
|
|
|
pytest.skip("Kernel requirements are not met")
|
|
|
|
|
|
|
|
tgen = Topogen(build_topo, mod.__name__)
|
|
|
|
tgen.start_topology()
|
|
|
|
|
|
|
|
# Starting Routers
|
|
|
|
router_list = tgen.routers()
|
|
|
|
_populate_iface()
|
|
|
|
|
|
|
|
for rname, router in router_list.items():
|
2025-02-05 10:17:20 +01:00
|
|
|
logger.info("Loading router %s" % rname)
|
|
|
|
router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname)))
|
2025-02-05 10:03:58 +01:00
|
|
|
|
|
|
|
# Initialize all routers.
|
|
|
|
tgen.start_router()
|
|
|
|
|
|
|
|
|
|
|
|
def teardown_module(_mod):
|
|
|
|
"Teardown the pytest environment"
|
|
|
|
tgen = get_topogen()
|
|
|
|
tgen.stop_topology()
|
|
|
|
|
|
|
|
|
|
|
|
def test_protocols_convergence():
|
|
|
|
"""
|
|
|
|
Assert that all protocols have converged before checking for the NHRP
|
|
|
|
statuses as they depend on it.
|
|
|
|
"""
|
|
|
|
tgen = get_topogen()
|
|
|
|
if tgen.routers_have_failure():
|
|
|
|
pytest.skip(tgen.errors)
|
|
|
|
|
|
|
|
logger.info("Checking NHRP cache for convergence")
|
|
|
|
router_list = tgen.routers()
|
|
|
|
|
|
|
|
# Check NHRP cache on servers and clients
|
|
|
|
for rname, router in router_list.items():
|
|
|
|
if "nh" not in rname:
|
|
|
|
continue
|
|
|
|
|
|
|
|
json_file = "{}/{}/nhrp_cache.json".format(CWD, router.name)
|
|
|
|
expected = json.loads(open(json_file).read())
|
|
|
|
test_func = partial(
|
|
|
|
topotest.router_json_cmp, router, "show ip nhrp cache json", expected
|
|
|
|
)
|
|
|
|
_, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5)
|
|
|
|
|
|
|
|
output = router.vtysh_cmd("show ip nhrp cache")
|
|
|
|
logger.info(output)
|
|
|
|
|
|
|
|
assertmsg = '"{}" JSON output mismatches'.format(router.name)
|
|
|
|
assert result is None, assertmsg
|
|
|
|
|
|
|
|
# Check NHRP IPV4 routes on servers and clients
|
|
|
|
logger.info("Checking IPv4 routes for convergence")
|
|
|
|
for rname, router in router_list.items():
|
|
|
|
if "nh" not in rname:
|
|
|
|
continue
|
|
|
|
|
|
|
|
json_file = "{}/{}/nhrp_route.json".format(CWD, router.name)
|
|
|
|
expected = json.loads(open(json_file).read())
|
|
|
|
test_func = partial(
|
|
|
|
topotest.router_json_cmp, router, "show ip route nhrp json", expected
|
|
|
|
)
|
|
|
|
_, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5)
|
|
|
|
|
|
|
|
output = router.vtysh_cmd("show ip route nhrp")
|
|
|
|
logger.info(output)
|
|
|
|
|
|
|
|
assertmsg = '"{}" JSON output mismatches'.format(router.name)
|
|
|
|
assert result is None, assertmsg
|
|
|
|
|
|
|
|
# Test connectivity from 1 NHRP server to all clients
|
|
|
|
nhs1 = tgen.gears["nhs1"]
|
|
|
|
logger.info("Check Ping IPv4 from nhs1 to nhc1 = 172.16.1.4)")
|
|
|
|
output = nhs1.run("ping 172.16.1.4 -f -c 1000")
|
|
|
|
logger.info(output)
|
|
|
|
if "1000 packets transmitted, 1000 received" not in output:
|
|
|
|
assertmsg = "expected ping IPv4 from nhs1 to nhc1 should be ok"
|
|
|
|
assert 0, assertmsg
|
|
|
|
else:
|
|
|
|
logger.info("Check Ping IPv4 from nhs1 to nhc1 OK")
|
|
|
|
|
|
|
|
logger.info("Check Ping IPv4 from nhs1 to nhc2 = 172.16.1.5)")
|
|
|
|
output = nhs1.run("ping 172.16.1.5 -f -c 1000")
|
|
|
|
logger.info(output)
|
|
|
|
if "1000 packets transmitted, 1000 received" not in output:
|
|
|
|
assertmsg = "expected ping IPv4 from nhs1 to nhc2 should be ok"
|
|
|
|
assert 0, assertmsg
|
|
|
|
else:
|
|
|
|
logger.info("Check Ping IPv4 from nhs1 to nhc2 OK")
|
|
|
|
|
|
|
|
# Test connectivity from 1 NHRP client to all servers
|
|
|
|
nhc1 = tgen.gears["nhc1"]
|
|
|
|
logger.info("Check Ping IPv4 from nhc1 to nhs1 = 172.16.1.1)")
|
|
|
|
output = nhc1.run("ping 172.16.1.1 -f -c 1000")
|
|
|
|
logger.info(output)
|
|
|
|
if "1000 packets transmitted, 1000 received" not in output:
|
|
|
|
assertmsg = "expected ping IPv4 from nhc1 to nhs1 should be ok"
|
|
|
|
assert 0, assertmsg
|
|
|
|
else:
|
|
|
|
logger.info("Check Ping IPv4 from nhc1 to nhs1 OK")
|
|
|
|
|
|
|
|
logger.info("Check Ping IPv4 from nhc1 to nhs2 = 172.16.1.2)")
|
|
|
|
output = nhc1.run("ping 172.16.1.2 -f -c 1000")
|
|
|
|
logger.info(output)
|
|
|
|
if "1000 packets transmitted, 1000 received" not in output:
|
|
|
|
assertmsg = "expected ping IPv4 from nhc1 to nhs2 should be ok"
|
|
|
|
assert 0, assertmsg
|
|
|
|
else:
|
|
|
|
logger.info("Check Ping IPv4 from nhc1 to nhs2 OK")
|
|
|
|
|
|
|
|
logger.info("Check Ping IPv4 from nhc1 to nhs3 = 172.16.1.3)")
|
|
|
|
output = nhc1.run("ping 172.16.1.3 -f -c 1000")
|
|
|
|
logger.info(output)
|
|
|
|
if "1000 packets transmitted, 1000 received" not in output:
|
|
|
|
assertmsg = "expected ping IPv4 from nhc1 to nhs3 should be ok"
|
|
|
|
assert 0, assertmsg
|
|
|
|
else:
|
|
|
|
logger.info("Check Ping IPv4 from nhc1 to nhs3 OK")
|
|
|
|
|
|
|
|
|
|
|
|
@retry(retry_timeout=30, initial_wait=5)
|
|
|
|
def verify_shortcut_path():
|
|
|
|
"""
|
|
|
|
Verifying that traffic flows through shortcut path
|
|
|
|
"""
|
|
|
|
tgen = get_topogen()
|
|
|
|
host = tgen.gears["host"]
|
|
|
|
logger.info("Check Ping IPv4 from host to nhc2 = 10.5.5.5")
|
|
|
|
|
|
|
|
output = host.run("ping 10.5.5.5 -f -c 1000")
|
|
|
|
logger.info(output)
|
|
|
|
if "1000 packets transmitted, 1000 received" not in output:
|
|
|
|
assertmsg = "expected ping IPv4 from host to nhc2 should be ok"
|
|
|
|
assert 0, assertmsg
|
|
|
|
else:
|
|
|
|
logger.info("Check Ping IPv4 from host to nhc2 OK")
|
|
|
|
|
|
|
|
|
|
|
|
def test_redundancy_shortcut():
|
|
|
|
"""
|
|
|
|
Assert that if shortcut created and then NHS goes down, there is no traffic disruption
|
|
|
|
"""
|
|
|
|
tgen = get_topogen()
|
|
|
|
if tgen.routers_have_failure():
|
|
|
|
pytest.skip(tgen.errors)
|
|
|
|
|
|
|
|
if not _verify_iptables():
|
|
|
|
pytest.skip("iptables not installed")
|
|
|
|
|
|
|
|
logger.info("Testing NHRP shortcuts with redundant servers")
|
|
|
|
|
|
|
|
# Verify nhc1 nhrp routes before shortcut creation
|
|
|
|
nhc1 = tgen.gears["nhc1"]
|
|
|
|
json_file = "{}/{}/nhrp_route.json".format(CWD, nhc1.name)
|
|
|
|
assertmsg = "No nhrp_route file found"
|
|
|
|
assert os.path.isfile(json_file), assertmsg
|
|
|
|
|
|
|
|
expected = json.loads(open(json_file).read())
|
|
|
|
test_func = partial(
|
|
|
|
topotest.router_json_cmp, nhc1, "show ip route nhrp json", expected
|
|
|
|
)
|
|
|
|
_, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5)
|
|
|
|
|
|
|
|
output = nhc1.vtysh_cmd("show ip route nhrp")
|
|
|
|
logger.info(output)
|
|
|
|
|
|
|
|
assertmsg = '"{}" JSON output mismatches'.format(nhc1.name)
|
|
|
|
assert result is None, assertmsg
|
|
|
|
|
|
|
|
# Initiate shortcut by pinging between clients
|
|
|
|
host = tgen.gears["host"]
|
|
|
|
logger.info("Check Ping IPv4 from host to nhc2 via shortcut = 10.5.5.5")
|
|
|
|
|
|
|
|
output = host.run("ping 10.5.5.5 -f -c 1000")
|
|
|
|
logger.info(output)
|
|
|
|
if "1000 packets transmitted, 1000 received" not in output:
|
|
|
|
assertmsg = "expected ping IPv4 from host to nhc2 via shortcut should be ok"
|
|
|
|
assert 0, assertmsg
|
|
|
|
else:
|
|
|
|
logger.info("Check Ping IPv4 from host to nhc2 via shortcut OK")
|
|
|
|
|
|
|
|
# Now check that NHRP shortcut route installed
|
|
|
|
json_file = "{}/{}/nhrp_route_shortcut.json".format(CWD, nhc1.name)
|
|
|
|
assertmsg = "No nhrp_route file found"
|
|
|
|
assert os.path.isfile(json_file), assertmsg
|
|
|
|
|
|
|
|
expected = json.loads(open(json_file).read())
|
|
|
|
test_func = partial(
|
|
|
|
topotest.router_json_cmp, nhc1, "show ip route nhrp json", expected
|
|
|
|
)
|
|
|
|
_, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5)
|
|
|
|
|
|
|
|
output = nhc1.vtysh_cmd("show ip route nhrp")
|
|
|
|
logger.info(output)
|
|
|
|
|
|
|
|
assertmsg = '"{}" JSON output mismatches'.format(nhc1.name)
|
|
|
|
assert result is None, assertmsg
|
|
|
|
|
|
|
|
json_file = "{}/{}/nhrp_shortcut_present.json".format(CWD, nhc1.name)
|
|
|
|
expected = json.loads(open(json_file).read())
|
|
|
|
test_func = partial(
|
|
|
|
topotest.router_json_cmp, nhc1, "show ip nhrp shortcut json", expected
|
|
|
|
)
|
|
|
|
_, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5)
|
|
|
|
|
|
|
|
output = nhc1.vtysh_cmd("show ip nhrp shortcut")
|
|
|
|
logger.info(output)
|
|
|
|
|
|
|
|
assertmsg = '"{}" JSON output mismatches'.format(nhc1.name)
|
|
|
|
assert result is None, assertmsg
|
|
|
|
|
|
|
|
# check the shortcut disappears because of no traffic
|
|
|
|
json_file = "{}/{}/nhrp_shortcut_absent.json".format(CWD, nhc1.name)
|
|
|
|
expected = json.loads(open(json_file).read())
|
|
|
|
test_func = partial(
|
|
|
|
topotest.router_json_cmp, nhc1, "show ip nhrp shortcut json", expected
|
|
|
|
)
|
|
|
|
_, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5)
|
|
|
|
|
|
|
|
output = nhc1.vtysh_cmd("show ip nhrp shortcut")
|
|
|
|
logger.info(output)
|
|
|
|
|
|
|
|
assertmsg = '"{}" JSON output mismatches'.format(nhc1.name)
|
|
|
|
assert result is None, assertmsg
|
|
|
|
|
|
|
|
|
|
|
|
def test_redundancy_shortcut_backup():
|
|
|
|
"""
|
|
|
|
Stop traffic and verify next time traffic started, shortcut is initiated by backup NHS
|
|
|
|
"""
|
|
|
|
tgen = get_topogen()
|
|
|
|
if tgen.routers_have_failure():
|
|
|
|
pytest.skip(tgen.errors)
|
|
|
|
|
|
|
|
if not _verify_iptables():
|
|
|
|
pytest.skip("iptables not installed")
|
|
|
|
|
|
|
|
nhc1 = tgen.gears["nhc1"]
|
|
|
|
router_list = tgen.routers()
|
|
|
|
|
|
|
|
# Bring down primary GRE interface and verify shortcut is not disturbed
|
|
|
|
logger.info("Bringing down nhs1, primary NHRP server.")
|
|
|
|
shutdown_bringup_interface(tgen, "nhs1", "nhs1-gre0", False)
|
|
|
|
|
|
|
|
# Check NHRP cache on servers and clients
|
|
|
|
for rname, router in router_list.items():
|
|
|
|
if "nh" not in rname:
|
|
|
|
continue
|
|
|
|
if "nhs1" in rname:
|
|
|
|
continue
|
|
|
|
|
|
|
|
json_file = "{}/{}/nhrp_cache_nhs1_down.json".format(CWD, router.name)
|
|
|
|
expected = json.loads(open(json_file).read())
|
|
|
|
test_func = partial(
|
|
|
|
topotest.router_json_cmp, router, "show ip nhrp cache json", expected
|
|
|
|
)
|
|
|
|
_, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5)
|
|
|
|
|
|
|
|
output = router.vtysh_cmd("show ip nhrp cache")
|
|
|
|
logger.info(output)
|
|
|
|
|
|
|
|
assertmsg = '"{}" JSON output mismatches'.format(router.name)
|
|
|
|
assert result is None, assertmsg
|
|
|
|
|
|
|
|
# Check NHRP IPV4 routes on servers and clients
|
|
|
|
logger.info("Checking IPv4 routes for convergence")
|
|
|
|
for rname, router in router_list.items():
|
|
|
|
if "nh" not in rname:
|
|
|
|
continue
|
|
|
|
if "nhs1" in rname:
|
|
|
|
continue
|
|
|
|
|
|
|
|
json_file = "{}/{}/nhrp_route_nhs1_down.json".format(CWD, router.name)
|
|
|
|
expected = json.loads(open(json_file).read())
|
|
|
|
test_func = partial(
|
|
|
|
topotest.router_json_cmp, router, "show ip route nhrp json", expected
|
|
|
|
)
|
|
|
|
_, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5)
|
|
|
|
|
|
|
|
output = router.vtysh_cmd("show ip route nhrp")
|
|
|
|
logger.info(output)
|
|
|
|
|
|
|
|
assertmsg = '"{}" JSON output mismatches'.format(router.name)
|
|
|
|
assert result is None, assertmsg
|
|
|
|
|
|
|
|
# Verify shortcut is still active
|
|
|
|
host = tgen.gears["host"]
|
|
|
|
logger.info("Check Ping IPv4 from host to nhc2 via shortcut = 10.5.5.5")
|
|
|
|
|
|
|
|
output = host.run("ping 10.5.5.5 -f -c 1000")
|
|
|
|
logger.info(output)
|
|
|
|
if "1000 packets transmitted, 1000 received" not in output:
|
|
|
|
assertmsg = "expected ping IPv4 from host to nhc2 via shortcut should be ok"
|
|
|
|
assert 0, assertmsg
|
|
|
|
else:
|
|
|
|
logger.info("Check Ping IPv4 from host to nhc2 via shortcut OK")
|
|
|
|
|
|
|
|
# Verify shortcut is present in routing table
|
|
|
|
json_file = "{}/{}/nhrp_route_shortcut_nhs1_down.json".format(CWD, nhc1.name)
|
|
|
|
assertmsg = "No nhrp_route file found"
|
|
|
|
assert os.path.isfile(json_file), assertmsg
|
|
|
|
|
|
|
|
expected = json.loads(open(json_file).read())
|
|
|
|
test_func = partial(
|
|
|
|
topotest.router_json_cmp, nhc1, "show ip route nhrp json", expected
|
|
|
|
)
|
|
|
|
_, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5)
|
|
|
|
|
|
|
|
output = nhc1.vtysh_cmd("show ip route nhrp")
|
|
|
|
logger.info(output)
|
|
|
|
|
|
|
|
json_file = "{}/{}/nhrp_shortcut_present.json".format(CWD, nhc1.name)
|
|
|
|
expected = json.loads(open(json_file).read())
|
|
|
|
test_func = partial(
|
|
|
|
topotest.router_json_cmp, nhc1, "show ip nhrp shortcut json", expected
|
|
|
|
)
|
|
|
|
_, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5)
|
|
|
|
|
|
|
|
output = nhc1.vtysh_cmd("show ip nhrp shortcut")
|
|
|
|
logger.info(output)
|
|
|
|
|
|
|
|
assertmsg = '"{}" JSON output mismatches'.format(nhc1.name)
|
|
|
|
assert result is None, assertmsg
|
|
|
|
|
|
|
|
# Now verify shortcut is purged with lack of traffic
|
|
|
|
json_file = "{}/{}/nhrp_route_nhs1_down.json".format(CWD, nhc1.name)
|
|
|
|
assertmsg = "No nhrp_route file found"
|
|
|
|
assert os.path.isfile(json_file), assertmsg
|
|
|
|
|
|
|
|
expected = json.loads(open(json_file).read())
|
|
|
|
test_func = partial(
|
|
|
|
topotest.router_json_cmp, nhc1, "show ip route nhrp json", expected
|
|
|
|
)
|
|
|
|
_, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5)
|
|
|
|
|
|
|
|
output = nhc1.vtysh_cmd("show ip route nhrp")
|
|
|
|
logger.info(output)
|
|
|
|
|
|
|
|
assertmsg = '"{}" JSON output mismatches'.format(nhc1.name)
|
|
|
|
assert result is None, assertmsg
|
|
|
|
|
|
|
|
json_file = "{}/{}/nhrp_shortcut_absent.json".format(CWD, nhc1.name)
|
|
|
|
expected = json.loads(open(json_file).read())
|
|
|
|
test_func = partial(
|
|
|
|
topotest.router_json_cmp, nhc1, "show ip nhrp shortcut json", expected
|
|
|
|
)
|
|
|
|
_, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5)
|
|
|
|
|
|
|
|
output = nhc1.vtysh_cmd("show ip nhrp shortcut")
|
|
|
|
logger.info(output)
|
|
|
|
|
|
|
|
assertmsg = '"{}" JSON output mismatches'.format(nhc1.name)
|
|
|
|
assert result is None, assertmsg
|
|
|
|
|
|
|
|
|
|
|
|
def test_memory_leak():
|
|
|
|
"Run the memory leak test and report results."
|
|
|
|
tgen = get_topogen()
|
|
|
|
if not tgen.is_memleak_enabled():
|
|
|
|
pytest.skip("Memory leak test/report is disabled")
|
|
|
|
|
|
|
|
tgen.report_memory_leaks()
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
args = ["-s"] + sys.argv[1:]
|
|
|
|
sys.exit(pytest.main(args))
|