From: Rafael Zalamena Date: Mon, 19 Jun 2017 19:18:25 +0000 (-0300) Subject: ospf: added convergence test for IPv4 X-Git-Tag: frr-7.1-dev~151^2~266 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=6024e0b5dee842f6d34af12b7ca1a171b947cf60;p=matthieu%2Ffrr.git ospf: added convergence test for IPv4 Added a convergence test for OSPF (IPv4) using the new topology builder Topogen. --- diff --git a/tests/topotests/ospf-topo1/__init__.py b/tests/topotests/ospf-topo1/__init__.py new file mode 100755 index 0000000000..e69de29bb2 diff --git a/tests/topotests/ospf-topo1/r1/ospfd.conf b/tests/topotests/ospf-topo1/r1/ospfd.conf new file mode 100644 index 0000000000..f1b43b8214 --- /dev/null +++ b/tests/topotests/ospf-topo1/r1/ospfd.conf @@ -0,0 +1,10 @@ +log file /tmp/r1-ospfd.log +! +router ospf + ospf router-id 10.0.255.1 + redistribute kernel + redistribute connected + redistribute static + network 10.0.1.0/24 area 0 + network 10.0.3.0/24 area 0 +! diff --git a/tests/topotests/ospf-topo1/r1/ospfroute.txt b/tests/topotests/ospf-topo1/r1/ospfroute.txt new file mode 100644 index 0000000000..db648722f5 --- /dev/null +++ b/tests/topotests/ospf-topo1/r1/ospfroute.txt @@ -0,0 +1,23 @@ +============ OSPF network routing table ============ +N 10.0.1.0/24 [10] area: 0.0.0.0 + directly attached to r1-eth0 +N 10.0.2.0/24 [20] area: 0.0.0.0 + via 10.0.3.3, r1-eth1 +N 10.0.3.0/24 [10] area: 0.0.0.0 + directly attached to r1-eth1 +N 10.0.10.0/24 [20] area: 0.0.0.0 + via 10.0.3.1, r1-eth1 +N IA 172.16.0.0/24 [20] area: 0.0.0.0 + via 10.0.3.1, r1-eth1 +N IA 172.16.1.0/24 [30] area: 0.0.0.0 + via 10.0.3.1, r1-eth1 + +============ OSPF router routing table ============= +R 10.0.255.2 [10] area: 0.0.0.0, ASBR + via 10.0.3.3, r1-eth1 +R 10.0.255.3 [10] area: 0.0.0.0, ABR, ASBR + via 10.0.3.1, r1-eth1 +R 10.0.255.4 IA [20] area: 0.0.0.0, ASBR + via 10.0.3.1, r1-eth1 + +============ OSPF external routing table =========== diff --git a/tests/topotests/ospf-topo1/r1/zebra.conf b/tests/topotests/ospf-topo1/r1/zebra.conf new file mode 100644 index 0000000000..152d3c0a90 --- /dev/null +++ b/tests/topotests/ospf-topo1/r1/zebra.conf @@ -0,0 +1,14 @@ +! +hostname r1 +log file /tmp/r1-zebra.log +! +interface r1-eth0 + ip address 10.0.1.1/24 +! +interface r1-eth1 + ip address 10.0.3.2/24 +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/ospf-topo1/r2/ospfd.conf b/tests/topotests/ospf-topo1/r2/ospfd.conf new file mode 100644 index 0000000000..11c416d574 --- /dev/null +++ b/tests/topotests/ospf-topo1/r2/ospfd.conf @@ -0,0 +1,10 @@ +log file /tmp/r1-ospfd.log +! +router ospf + ospf router-id 10.0.255.2 + redistribute kernel + redistribute connected + redistribute static + network 10.0.2.0/24 area 0 + network 10.0.3.0/24 area 0 +! diff --git a/tests/topotests/ospf-topo1/r2/ospfroute.txt b/tests/topotests/ospf-topo1/r2/ospfroute.txt new file mode 100644 index 0000000000..79b389baab --- /dev/null +++ b/tests/topotests/ospf-topo1/r2/ospfroute.txt @@ -0,0 +1,23 @@ +============ OSPF network routing table ============ +N 10.0.1.0/24 [20] area: 0.0.0.0 + via 10.0.3.2, r2-eth1 +N 10.0.2.0/24 [10] area: 0.0.0.0 + directly attached to r2-eth0 +N 10.0.3.0/24 [10] area: 0.0.0.0 + directly attached to r2-eth1 +N 10.0.10.0/24 [20] area: 0.0.0.0 + via 10.0.3.1, r2-eth1 +N IA 172.16.0.0/24 [20] area: 0.0.0.0 + via 10.0.3.1, r2-eth1 +N IA 172.16.1.0/24 [30] area: 0.0.0.0 + via 10.0.3.1, r2-eth1 + +============ OSPF router routing table ============= +R 10.0.255.1 [10] area: 0.0.0.0, ASBR + via 10.0.3.2, r2-eth1 +R 10.0.255.3 [10] area: 0.0.0.0, ABR, ASBR + via 10.0.3.1, r2-eth1 +R 10.0.255.4 IA [20] area: 0.0.0.0, ASBR + via 10.0.3.1, r2-eth1 + +============ OSPF external routing table =========== diff --git a/tests/topotests/ospf-topo1/r2/zebra.conf b/tests/topotests/ospf-topo1/r2/zebra.conf new file mode 100644 index 0000000000..35d9c96b54 --- /dev/null +++ b/tests/topotests/ospf-topo1/r2/zebra.conf @@ -0,0 +1,14 @@ +! +hostname r2 +log file /tmp/r2-zebra.log +! +interface r2-eth0 + ip address 10.0.2.1/24 +! +interface r2-eth1 + ip address 10.0.3.3/24 +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/ospf-topo1/r3/ospfd.conf b/tests/topotests/ospf-topo1/r3/ospfd.conf new file mode 100644 index 0000000000..00023e2ba9 --- /dev/null +++ b/tests/topotests/ospf-topo1/r3/ospfd.conf @@ -0,0 +1,11 @@ +log file /tmp/r3-ospfd.log +! +router ospf + ospf router-id 10.0.255.3 + redistribute kernel + redistribute connected + redistribute static + network 10.0.3.0/24 area 0 + network 10.0.10.0/24 area 0 + network 172.16.0.0/24 area 1 +! diff --git a/tests/topotests/ospf-topo1/r3/ospfroute.txt b/tests/topotests/ospf-topo1/r3/ospfroute.txt new file mode 100644 index 0000000000..c7799065d9 --- /dev/null +++ b/tests/topotests/ospf-topo1/r3/ospfroute.txt @@ -0,0 +1,23 @@ +============ OSPF network routing table ============ +N 10.0.1.0/24 [20] area: 0.0.0.0 + via 10.0.3.2, r3-eth0 +N 10.0.2.0/24 [20] area: 0.0.0.0 + via 10.0.3.3, r3-eth0 +N 10.0.3.0/24 [10] area: 0.0.0.0 + directly attached to r3-eth0 +N 10.0.10.0/24 [10] area: 0.0.0.0 + directly attached to r3-eth1 +N 172.16.0.0/24 [10] area: 0.0.0.1 + directly attached to r3-eth2 +N 172.16.1.0/24 [20] area: 0.0.0.1 + via 172.16.0.1, r3-eth2 + +============ OSPF router routing table ============= +R 10.0.255.1 [10] area: 0.0.0.0, ASBR + via 10.0.3.2, r3-eth0 +R 10.0.255.2 [10] area: 0.0.0.0, ASBR + via 10.0.3.3, r3-eth0 +R 10.0.255.4 [10] area: 0.0.0.1, ASBR + via 172.16.0.1, r3-eth2 + +============ OSPF external routing table =========== diff --git a/tests/topotests/ospf-topo1/r3/zebra.conf b/tests/topotests/ospf-topo1/r3/zebra.conf new file mode 100644 index 0000000000..7521a9b95b --- /dev/null +++ b/tests/topotests/ospf-topo1/r3/zebra.conf @@ -0,0 +1,17 @@ +! +hostname r3 +log file /tmp/r3-zebra.log +! +interface r3-eth0 + ip address 10.0.3.1/24 +! +interface r3-eth1 + ip address 10.0.10.1/24 +! +interface r3-eth2 + ip address 172.16.0.2/24 +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/ospf-topo1/r4/ospfd.conf b/tests/topotests/ospf-topo1/r4/ospfd.conf new file mode 100644 index 0000000000..6826808c52 --- /dev/null +++ b/tests/topotests/ospf-topo1/r4/ospfd.conf @@ -0,0 +1,10 @@ +log file /tmp/r4-ospfd.log +! +router ospf + ospf router-id 10.0.255.4 + redistribute kernel + redistribute connected + redistribute static + network 172.16.0.0/24 area 1 + network 172.16.1.0/24 area 1 +! diff --git a/tests/topotests/ospf-topo1/r4/ospfroute.txt b/tests/topotests/ospf-topo1/r4/ospfroute.txt new file mode 100644 index 0000000000..b582ef043b --- /dev/null +++ b/tests/topotests/ospf-topo1/r4/ospfroute.txt @@ -0,0 +1,23 @@ +============ OSPF network routing table ============ +N IA 10.0.1.0/24 [30] area: 0.0.0.1 + via 172.16.0.2, r4-eth0 +N IA 10.0.2.0/24 [30] area: 0.0.0.1 + via 172.16.0.2, r4-eth0 +N IA 10.0.3.0/24 [20] area: 0.0.0.1 + via 172.16.0.2, r4-eth0 +N IA 10.0.10.0/24 [20] area: 0.0.0.1 + via 172.16.0.2, r4-eth0 +N 172.16.0.0/24 [10] area: 0.0.0.1 + directly attached to r4-eth0 +N 172.16.1.0/24 [10] area: 0.0.0.1 + directly attached to r4-eth1 + +============ OSPF router routing table ============= +R 10.0.255.1 IA [20] area: 0.0.0.1, ASBR + via 172.16.0.2, r4-eth0 +R 10.0.255.2 IA [20] area: 0.0.0.1, ASBR + via 172.16.0.2, r4-eth0 +R 10.0.255.3 [10] area: 0.0.0.1, ABR, ASBR + via 172.16.0.2, r4-eth0 + +============ OSPF external routing table =========== diff --git a/tests/topotests/ospf-topo1/r4/zebra.conf b/tests/topotests/ospf-topo1/r4/zebra.conf new file mode 100644 index 0000000000..d90bdc6cf4 --- /dev/null +++ b/tests/topotests/ospf-topo1/r4/zebra.conf @@ -0,0 +1,14 @@ +! +hostname r4 +log file /tmp/r4-zebra.log +! +interface r4-eth0 + ip address 172.16.0.1/24 +! +interface r4-eth1 + ip address 172.16.1.100/24 +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/ospf-topo1/test_ospf_topo1.dot b/tests/topotests/ospf-topo1/test_ospf_topo1.dot new file mode 100644 index 0000000000..25ee214b1c --- /dev/null +++ b/tests/topotests/ospf-topo1/test_ospf_topo1.dot @@ -0,0 +1,95 @@ +## 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 ospf_topo1 { + label="ospf topo1"; + + # Routers + r1 [ + label="r1\nrtr-id 10.0.255.1/32", + shape=doubleoctagon, + fillcolor="#f08080", + style=filled, + ]; + r2 [ + label="r2\nrtr-id 10.0.255.2/32", + shape=doubleoctagon, + fillcolor="#f08080", + style=filled, + ]; + r3 [ + label="r3\nrtr-id 10.0.255.3/32", + shape=doubleoctagon, + fillcolor="#f08080", + style=filled, + ]; + r4 [ + label="r4\nrtr-id 10.0.255.4/32", + shape=doubleoctagon, + fillcolor="#f08080", + style=filled, + ]; + + # Switches + s1 [ + label="s1\n10.0.1.0/24", + shape=oval, + fillcolor="#d0e0d0", + style=filled, + ]; + s2 [ + label="s2\n10.0.2.0/24", + shape=oval, + fillcolor="#d0e0d0", + style=filled, + ]; + s3 [ + label="s3\n10.0.3.0/24", + shape=oval, + fillcolor="#d0e0d0", + style=filled, + ]; + s4 [ + label="s4\n10.0.10.0/24", + shape=oval, + fillcolor="#d0e0d0", + style=filled, + ]; + s5 [ + label="s5\n172.16.0.0/24", + shape=oval, + fillcolor="#d0e0d0", + style=filled, + ]; + s6 [ + label="s6\n172.16.1.0/24", + shape=oval, + fillcolor="#d0e0d0", + style=filled, + ]; + + # Connections + r1 -- s1 [label="eth0\n.1"]; + r1 -- s3 [label="eth1\n.2"]; + + r2 -- s2 [label="eth0\n.1"]; + r2 -- s3 [label="eth1\n.3"]; + + r3 -- s3 [label="eth0\n.1"]; + r3 -- s4 [label="eth1\n.1"]; + r3 -- s5 [label="eth2\n.2"]; + + r4 -- s5 [label="eth0\n.1"]; + r4 -- s6 [label="eth1\n.100"]; +} diff --git a/tests/topotests/ospf-topo1/test_ospf_topo1.jpg b/tests/topotests/ospf-topo1/test_ospf_topo1.jpg new file mode 100644 index 0000000000..b01f46278a Binary files /dev/null and b/tests/topotests/ospf-topo1/test_ospf_topo1.jpg differ diff --git a/tests/topotests/ospf-topo1/test_ospf_topo1.py b/tests/topotests/ospf-topo1/test_ospf_topo1.py new file mode 100755 index 0000000000..4cb569da8e --- /dev/null +++ b/tests/topotests/ospf-topo1/test_ospf_topo1.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python + +# +# test_ospf_topo1.py +# Part of NetDEF Topology Tests +# +# Copyright (c) 2017 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_ospf_topo1.py: Test the FRR/Quagga OSPF routing daemon. +""" + +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. +from mininet.topo import Topo + +class OSPFTopo(Topo): + "Test topology builder" + def build(self, *_args, **_opts): + "Build function" + tgen = get_topogen(self) + + # Create 4 routers + for routern in range(1, 5): + tgen.add_router('r{}'.format(routern)) + + # Create a empty network for router 1 + switch = tgen.add_switch('s1') + switch.add_link(tgen.gears['r1']) + + # Create a empty network for router 2 + switch = tgen.add_switch('s2') + switch.add_link(tgen.gears['r2']) + + # Interconect router 1, 2 and 3 + switch = tgen.add_switch('s3') + switch.add_link(tgen.gears['r1']) + switch.add_link(tgen.gears['r2']) + switch.add_link(tgen.gears['r3']) + + # Create empty netowrk for router3 + switch = tgen.add_switch('s4') + switch.add_link(tgen.gears['r3']) + + # Interconect router 3 and 4 + switch = tgen.add_switch('s5') + switch.add_link(tgen.gears['r3']) + switch.add_link(tgen.gears['r4']) + + # Create a empty network for router 4 + switch = tgen.add_switch('s6') + switch.add_link(tgen.gears['r4']) + +def setup_module(mod): + "Sets up the pytest environment" + tgen = Topogen(OSPFTopo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + for rname, router in router_list.iteritems(): + router.load_config( + TopoRouter.RD_ZEBRA, + os.path.join(CWD, '{}/zebra.conf'.format(rname)) + ) + router.load_config( + TopoRouter.RD_OSPF, + os.path.join(CWD, '{}/ospfd.conf'.format(rname)) + ) + + # Initialize all routers. + tgen.start_router() + +def teardown_module(mod): + "Teardown the pytest environment" + tgen = get_topogen() + tgen.stop_topology() + +def test_ospf_convergence(): + "Test OSPF daemon convergence" + tgen = get_topogen() + + # Define test function + def compare_show_ip_ospf(rname, expected): + """ + Calls 'show ip ospf route' for router `rname` and compare the obtained + result with the expected output. + """ + current = tgen.gears[rname].vtysh_cmd('show ip ospf route') + return topotest.difflines(current, expected, + title1="Current output", + title2="Expected output") + + # Run the file comparison for all routers + for rnum in range(1, 5): + router = 'r{}'.format(rnum) + + # Load expected results from the command + reffile = os.path.join(CWD, '{}/ospfroute.txt'.format(router)) + expected = open(reffile).read() + + # Run test function until we get an result. Wait at most 60 seconds. + test_func = partial(compare_show_ip_ospf, router, expected) + result, diff = topotest.run_and_expect(test_func, '', + count=20, wait=3) + assert result, 'OSPF did not converge on {}:\n{}'.format(router, diff) + +if __name__ == '__main__': + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args))