diff options
Diffstat (limited to 'tests/topotests/pim_basic_topo2')
-rw-r--r-- | tests/topotests/pim_basic_topo2/__init__.py | 0 | ||||
-rw-r--r-- | tests/topotests/pim_basic_topo2/r1/bfdd.conf | 6 | ||||
-rw-r--r-- | tests/topotests/pim_basic_topo2/r1/pimd.conf | 4 | ||||
-rw-r--r-- | tests/topotests/pim_basic_topo2/r1/zebra.conf | 3 | ||||
-rw-r--r-- | tests/topotests/pim_basic_topo2/r2/bfdd.conf | 2 | ||||
-rw-r--r-- | tests/topotests/pim_basic_topo2/r2/pimd.conf | 13 | ||||
-rw-r--r-- | tests/topotests/pim_basic_topo2/r2/zebra.conf | 9 | ||||
-rw-r--r-- | tests/topotests/pim_basic_topo2/r3/bfdd.conf | 2 | ||||
-rw-r--r-- | tests/topotests/pim_basic_topo2/r3/pimd.conf | 4 | ||||
-rw-r--r-- | tests/topotests/pim_basic_topo2/r3/zebra.conf | 3 | ||||
-rw-r--r-- | tests/topotests/pim_basic_topo2/r4/bfdd.conf | 2 | ||||
-rw-r--r-- | tests/topotests/pim_basic_topo2/r4/pimd.conf | 4 | ||||
-rw-r--r-- | tests/topotests/pim_basic_topo2/r4/zebra.conf | 3 | ||||
-rw-r--r-- | tests/topotests/pim_basic_topo2/test_pim_basic_topo2.dot | 73 | ||||
-rw-r--r-- | tests/topotests/pim_basic_topo2/test_pim_basic_topo2.png | bin | 0 -> 33496 bytes | |||
-rw-r--r-- | tests/topotests/pim_basic_topo2/test_pim_basic_topo2.py | 238 |
16 files changed, 366 insertions, 0 deletions
diff --git a/tests/topotests/pim_basic_topo2/__init__.py b/tests/topotests/pim_basic_topo2/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/topotests/pim_basic_topo2/__init__.py diff --git a/tests/topotests/pim_basic_topo2/r1/bfdd.conf b/tests/topotests/pim_basic_topo2/r1/bfdd.conf new file mode 100644 index 0000000..76c6f82 --- /dev/null +++ b/tests/topotests/pim_basic_topo2/r1/bfdd.conf @@ -0,0 +1,6 @@ +bfd + profile fast-tx + receive-interval 250 + transmit-interval 250 + ! +! diff --git a/tests/topotests/pim_basic_topo2/r1/pimd.conf b/tests/topotests/pim_basic_topo2/r1/pimd.conf new file mode 100644 index 0000000..b895d7d --- /dev/null +++ b/tests/topotests/pim_basic_topo2/r1/pimd.conf @@ -0,0 +1,4 @@ +interface r1-eth0 + ip pim + ip pim bfd profile fast-tx +! diff --git a/tests/topotests/pim_basic_topo2/r1/zebra.conf b/tests/topotests/pim_basic_topo2/r1/zebra.conf new file mode 100644 index 0000000..6bf02a3 --- /dev/null +++ b/tests/topotests/pim_basic_topo2/r1/zebra.conf @@ -0,0 +1,3 @@ +interface r1-eth0 + ip address 192.168.1.1/24 +! diff --git a/tests/topotests/pim_basic_topo2/r2/bfdd.conf b/tests/topotests/pim_basic_topo2/r2/bfdd.conf new file mode 100644 index 0000000..ca61e46 --- /dev/null +++ b/tests/topotests/pim_basic_topo2/r2/bfdd.conf @@ -0,0 +1,2 @@ +bfd +! diff --git a/tests/topotests/pim_basic_topo2/r2/pimd.conf b/tests/topotests/pim_basic_topo2/r2/pimd.conf new file mode 100644 index 0000000..9f389de --- /dev/null +++ b/tests/topotests/pim_basic_topo2/r2/pimd.conf @@ -0,0 +1,13 @@ +interface r2-eth0 + ip pim + ip pim bfd +! +interface r2-eth1 + ip pim + ip pim bfd +! +interface r2-eth2 + ip pim + ip pim bfd +! +ip pim join-prune-interval 5 diff --git a/tests/topotests/pim_basic_topo2/r2/zebra.conf b/tests/topotests/pim_basic_topo2/r2/zebra.conf new file mode 100644 index 0000000..3ceb5f0 --- /dev/null +++ b/tests/topotests/pim_basic_topo2/r2/zebra.conf @@ -0,0 +1,9 @@ +interface r2-eth0 + ip address 192.168.1.2/24 +! +interface r2-eth1 + ip address 192.168.2.1/24 +! +interface r2-eth2 + ip address 192.168.3.1/24 +! diff --git a/tests/topotests/pim_basic_topo2/r3/bfdd.conf b/tests/topotests/pim_basic_topo2/r3/bfdd.conf new file mode 100644 index 0000000..ca61e46 --- /dev/null +++ b/tests/topotests/pim_basic_topo2/r3/bfdd.conf @@ -0,0 +1,2 @@ +bfd +! diff --git a/tests/topotests/pim_basic_topo2/r3/pimd.conf b/tests/topotests/pim_basic_topo2/r3/pimd.conf new file mode 100644 index 0000000..691a28e --- /dev/null +++ b/tests/topotests/pim_basic_topo2/r3/pimd.conf @@ -0,0 +1,4 @@ +interface r3-eth0 + ip pim + ip pim bfd +! diff --git a/tests/topotests/pim_basic_topo2/r3/zebra.conf b/tests/topotests/pim_basic_topo2/r3/zebra.conf new file mode 100644 index 0000000..3df218e --- /dev/null +++ b/tests/topotests/pim_basic_topo2/r3/zebra.conf @@ -0,0 +1,3 @@ +interface r3-eth0 + ip address 192.168.2.3/24 +! diff --git a/tests/topotests/pim_basic_topo2/r4/bfdd.conf b/tests/topotests/pim_basic_topo2/r4/bfdd.conf new file mode 100644 index 0000000..ca61e46 --- /dev/null +++ b/tests/topotests/pim_basic_topo2/r4/bfdd.conf @@ -0,0 +1,2 @@ +bfd +! diff --git a/tests/topotests/pim_basic_topo2/r4/pimd.conf b/tests/topotests/pim_basic_topo2/r4/pimd.conf new file mode 100644 index 0000000..2277b3e --- /dev/null +++ b/tests/topotests/pim_basic_topo2/r4/pimd.conf @@ -0,0 +1,4 @@ +interface r4-eth0 + ip pim + ip pim bfd +! diff --git a/tests/topotests/pim_basic_topo2/r4/zebra.conf b/tests/topotests/pim_basic_topo2/r4/zebra.conf new file mode 100644 index 0000000..6ac5c78 --- /dev/null +++ b/tests/topotests/pim_basic_topo2/r4/zebra.conf @@ -0,0 +1,3 @@ +interface r4-eth0 + ip address 192.168.3.4/24 +! diff --git a/tests/topotests/pim_basic_topo2/test_pim_basic_topo2.dot b/tests/topotests/pim_basic_topo2/test_pim_basic_topo2.dot new file mode 100644 index 0000000..22fce27 --- /dev/null +++ b/tests/topotests/pim_basic_topo2/test_pim_basic_topo2.dot @@ -0,0 +1,73 @@ +## Color coding: +######################### +## Main FRR: #f08080 red +## Switches: #d0e0d0 gray +## RIP: #19e3d9 Cyan +## RIPng: #fcb314 dark yellow +## OSPFv2: #32b835 Green +## OSPFv3: #19e3d9 Cyan +## ISIS IPv4 #fcb314 dark yellow +## ISIS IPv6 #9a81ec purple +## BGP IPv4 #eee3d3 beige +## BGP IPv6 #fdff00 yellow +##### Colors (see http://www.color-hex.com/) + +graph template { + label="bfd-topo3"; + + # Routers + r1 [ + shape=doubleoctagon, + label="r1", + fillcolor="#f08080", + style=filled, + ]; + r2 [ + shape=doubleoctagon + label="r2", + fillcolor="#f08080", + style=filled, + ]; + r3 [ + shape=doubleoctagon + label="r3", + fillcolor="#f08080", + style=filled, + ]; + r4 [ + shape=doubleoctagon + label="r4", + fillcolor="#f08080", + style=filled, + ]; + + # Switches + sw1 [ + shape=oval, + label="sw1\n192.168.1.0/24", + fillcolor="#d0e0d0", + style=filled, + ]; + sw2 [ + shape=oval, + label="sw2\n192.168.2.0/24", + fillcolor="#d0e0d0", + style=filled, + ]; + sw2 [ + shape=oval, + label="sw2\n192.168.3.0/24", + fillcolor="#d0e0d0", + style=filled, + ]; + + # Connections + r1 -- sw1 [label="eth0\n.1"]; + r2 -- sw1 [label="eth0\n.2"]; + + r2 -- sw2 [label="eth1\n.1"]; + r3 -- sw2 [label="eth0\n.3"]; + + r2 -- sw3 [label="eth1\n.1"]; + r4 -- sw3 [label="eth2\n.4"]; +} diff --git a/tests/topotests/pim_basic_topo2/test_pim_basic_topo2.png b/tests/topotests/pim_basic_topo2/test_pim_basic_topo2.png Binary files differnew file mode 100644 index 0000000..39139a3 --- /dev/null +++ b/tests/topotests/pim_basic_topo2/test_pim_basic_topo2.png diff --git a/tests/topotests/pim_basic_topo2/test_pim_basic_topo2.py b/tests/topotests/pim_basic_topo2/test_pim_basic_topo2.py new file mode 100644 index 0000000..9506c3c --- /dev/null +++ b/tests/topotests/pim_basic_topo2/test_pim_basic_topo2.py @@ -0,0 +1,238 @@ +#!/usr/bin/env python + +# +# test_pim_basic_topo2.py +# Part of NetDEF Topology Tests +# +# Copyright (c) 2021 by +# Network Device Education Foundation, Inc. ("NetDEF") +# +# 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 NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF 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. +# + +""" +test_pim_basic_topo2.py: Test the FRR PIM protocol convergence. +""" + +import os +import sys +from functools import partial +import pytest + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# 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 + +# Required to instantiate the topology builder class. + +pytestmark = [pytest.mark.bfdd, pytest.mark.pimd] + + +def build_topo(tgen): + "Build function" + + # Create 4 routers + for routern in range(1, 5): + tgen.add_router("r{}".format(routern)) + + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["r2"]) + switch.add_link(tgen.gears["r3"]) + + switch = tgen.add_switch("s3") + switch.add_link(tgen.gears["r2"]) + switch.add_link(tgen.gears["r4"]) + + +def setup_module(mod): + "Sets up the pytest environment" + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + for rname, router in router_list.items(): + daemon_file = "{}/{}/bfdd.conf".format(CWD, rname) + if os.path.isfile(daemon_file): + router.load_config(TopoRouter.RD_BFD, daemon_file) + + daemon_file = "{}/{}/pimd.conf".format(CWD, rname) + if os.path.isfile(daemon_file): + router.load_config(TopoRouter.RD_PIM, daemon_file) + + daemon_file = "{}/{}/zebra.conf".format(CWD, rname) + if os.path.isfile(daemon_file): + router.load_config(TopoRouter.RD_ZEBRA, daemon_file) + + # Initialize all routers. + tgen.start_router() + + +def teardown_module(_mod): + "Teardown the pytest environment" + tgen = get_topogen() + tgen.stop_topology() + + +def expect_neighbor(router, interface, peer): + "Wait until peer is present on interface." + logger.info("waiting peer {} in {}".format(peer, interface)) + tgen = get_topogen() + test_func = partial( + topotest.router_json_cmp, + tgen.gears[router], + "show ip pim neighbor json", + {interface: {peer: {}}}, + ) + _, result = topotest.run_and_expect(test_func, None, count=130, wait=1) + assertmsg = '"{}" PIM convergence failure'.format(router) + assert result is None, assertmsg + + +def test_wait_pim_convergence(): + "Wait for PIM to converge" + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("waiting for PIM to converge") + + expect_neighbor("r1", "r1-eth0", "192.168.1.2") + expect_neighbor("r2", "r2-eth0", "192.168.1.1") + + expect_neighbor("r2", "r2-eth1", "192.168.2.3") + expect_neighbor("r2", "r2-eth2", "192.168.3.4") + + expect_neighbor("r3", "r3-eth0", "192.168.2.1") + expect_neighbor("r4", "r4-eth0", "192.168.3.1") + + +def test_bfd_peers(): + "Wait for BFD peers to show up." + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("waiting for BFD to converge") + + def expect_bfd_peer(router, peer): + "Wait until peer is present on interface." + logger.info("waiting BFD peer {} in {}".format(peer, router)) + test_func = partial( + topotest.router_json_cmp, + tgen.gears[router], + "show bfd peers json", + [{"peer": peer, "status": "up"}], + ) + _, result = topotest.run_and_expect(test_func, None, count=10, wait=1) + assertmsg = '"{}" BFD convergence failure'.format(router) + assert result is None, assertmsg + + expect_bfd_peer("r1", "192.168.1.2") + expect_bfd_peer("r2", "192.168.1.1") + expect_bfd_peer("r2", "192.168.2.3") + expect_bfd_peer("r2", "192.168.3.4") + expect_bfd_peer("r3", "192.168.2.1") + expect_bfd_peer("r4", "192.168.3.1") + + +def test_pim_reconvergence(): + "Disconnect a peer and expect it to disconnect." + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("waiting for disconnect convergence") + tgen.gears["r4"].link_enable("r4-eth0", enabled=False) + + def expect_neighbor_down(router, interface, peer): + "Wait until peer is present on interface." + logger.info("waiting peer {} in {} to disappear".format(peer, interface)) + test_func = partial( + topotest.router_json_cmp, + tgen.gears[router], + "show ip pim neighbor json", + {interface: {peer: None}}, + ) + _, result = topotest.run_and_expect(test_func, None, count=4, wait=1) + assertmsg = '"{}" PIM convergence failure'.format(router) + assert result is None, assertmsg + + expect_neighbor_down("r2", "r2-eth2", "192.168.3.4") + + logger.info("waiting for reconvergence") + tgen.gears["r4"].link_enable("r4-eth0", enabled=True) + expect_neighbor("r2", "r2-eth2", "192.168.3.4") + + +def test_pim_bfd_profile(): + "Test that the BFD profile is properly applied in BFD." + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + def expect_bfd_peer_settings(router, settings): + "Expect the following BFD configuration" + logger.info("Verifying BFD peer {} in {}".format(settings["peer"], router)) + test_func = partial( + topotest.router_json_cmp, + tgen.gears[router], + "show bfd peers json", + [settings], + ) + _, result = topotest.run_and_expect(test_func, None, count=4, wait=1) + assertmsg = '"{}" BFD convergence failure'.format(router) + assert result is None, assertmsg + + expect_bfd_peer_settings( + "r1", + { + "peer": "192.168.1.2", + "receive-interval": 250, + "transmit-interval": 250, + }, + ) + + expect_bfd_peer_settings( + "r2", + { + "peer": "192.168.1.1", + "remote-receive-interval": 250, + "remote-transmit-interval": 250, + }, + ) + + +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)) |