From d6df723b103f222c6c967b571d20aa062e7cdd93 Mon Sep 17 00:00:00 2001 From: Martin Winter Date: Fri, 7 Apr 2017 17:22:03 -0700 Subject: [PATCH] rip_topo1: Adding new test for RIPv2 Topology Signed-off-by: Martin Winter --- tests/topotests/rip-topo1/r1/rip_status.ref | 16 + tests/topotests/rip-topo1/r1/ripd.conf | 9 + tests/topotests/rip-topo1/r1/show_ip_rip.ref | 10 + .../topotests/rip-topo1/r1/show_ip_route.ref | 3 + tests/topotests/rip-topo1/r1/zebra.conf | 19 + tests/topotests/rip-topo1/r2/rip_status.ref | 18 + tests/topotests/rip-topo1/r2/ripd.conf | 11 + tests/topotests/rip-topo1/r2/show_ip_rip.ref | 10 + .../topotests/rip-topo1/r2/show_ip_route.ref | 2 + tests/topotests/rip-topo1/r2/zebra.conf | 21 ++ tests/topotests/rip-topo1/r3/rip_status.ref | 16 + tests/topotests/rip-topo1/r3/ripd.conf | 12 + tests/topotests/rip-topo1/r3/show_ip_rip.ref | 10 + .../topotests/rip-topo1/r3/show_ip_route.ref | 1 + tests/topotests/rip-topo1/r3/zebra.conf | 22 ++ tests/topotests/rip-topo1/test_rip_topo1.dot | 61 +++ tests/topotests/rip-topo1/test_rip_topo1.pdf | Bin 0 -> 18433 bytes tests/topotests/rip-topo1/test_rip_topo1.py | 352 ++++++++++++++++++ 18 files changed, 593 insertions(+) create mode 100644 tests/topotests/rip-topo1/r1/rip_status.ref create mode 100644 tests/topotests/rip-topo1/r1/ripd.conf create mode 100644 tests/topotests/rip-topo1/r1/show_ip_rip.ref create mode 100644 tests/topotests/rip-topo1/r1/show_ip_route.ref create mode 100644 tests/topotests/rip-topo1/r1/zebra.conf create mode 100644 tests/topotests/rip-topo1/r2/rip_status.ref create mode 100644 tests/topotests/rip-topo1/r2/ripd.conf create mode 100644 tests/topotests/rip-topo1/r2/show_ip_rip.ref create mode 100644 tests/topotests/rip-topo1/r2/show_ip_route.ref create mode 100644 tests/topotests/rip-topo1/r2/zebra.conf create mode 100644 tests/topotests/rip-topo1/r3/rip_status.ref create mode 100644 tests/topotests/rip-topo1/r3/ripd.conf create mode 100644 tests/topotests/rip-topo1/r3/show_ip_rip.ref create mode 100644 tests/topotests/rip-topo1/r3/show_ip_route.ref create mode 100644 tests/topotests/rip-topo1/r3/zebra.conf create mode 100644 tests/topotests/rip-topo1/test_rip_topo1.dot create mode 100644 tests/topotests/rip-topo1/test_rip_topo1.pdf create mode 100755 tests/topotests/rip-topo1/test_rip_topo1.py diff --git a/tests/topotests/rip-topo1/r1/rip_status.ref b/tests/topotests/rip-topo1/r1/rip_status.ref new file mode 100644 index 0000000000..30c840e508 --- /dev/null +++ b/tests/topotests/rip-topo1/r1/rip_status.ref @@ -0,0 +1,16 @@ +Routing Protocol is "rip" + Sending updates every 30 seconds with +/-50%, next due in XX seconds + Timeout after 180 seconds, garbage collect after 120 seconds + Outgoing update filter list for all interface is not set + Incoming update filter list for all interface is not set + Default redistribution metric is 1 + Redistributing: + Default version control: send version 2, receive version 2 + Interface Send Recv Key-chain + r1-eth1 2 2 + Routing for Networks: + 193.1.1.0/26 + Routing Information Sources: + Gateway BadPackets BadRoutes Distance Last Update + 193.1.1.2 0 0 120 XX:XX:XX + Distance: (default is 120) diff --git a/tests/topotests/rip-topo1/r1/ripd.conf b/tests/topotests/rip-topo1/r1/ripd.conf new file mode 100644 index 0000000000..7448f58634 --- /dev/null +++ b/tests/topotests/rip-topo1/r1/ripd.conf @@ -0,0 +1,9 @@ +log file /tmp/r1-ripd.log +! +router rip + version 2 + network 193.1.1.0/26 +! +line vty +! + diff --git a/tests/topotests/rip-topo1/r1/show_ip_rip.ref b/tests/topotests/rip-topo1/r1/show_ip_rip.ref new file mode 100644 index 0000000000..561560f230 --- /dev/null +++ b/tests/topotests/rip-topo1/r1/show_ip_rip.ref @@ -0,0 +1,10 @@ +Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP +Sub-codes: + (n) - normal, (s) - static, (d) - default, (r) - redistribute, + (i) - interface + + Network Next Hop Metric From Tag Time +R(n) 192.168.2.0/24 193.1.1.2 3 193.1.1.2 0 XX:XX +R(n) 192.168.3.0/24 193.1.1.2 3 193.1.1.2 0 XX:XX +C(i) 193.1.1.0/26 0.0.0.0 1 self 0 +R(n) 193.1.2.0/24 193.1.1.2 2 193.1.1.2 0 XX:XX diff --git a/tests/topotests/rip-topo1/r1/show_ip_route.ref b/tests/topotests/rip-topo1/r1/show_ip_route.ref new file mode 100644 index 0000000000..62d71f0ab6 --- /dev/null +++ b/tests/topotests/rip-topo1/r1/show_ip_route.ref @@ -0,0 +1,3 @@ +R>* 192.168.2.0/24 [120/3] via 193.1.1.2, r1-eth1 +R>* 192.168.3.0/24 [120/3] via 193.1.1.2, r1-eth1 +R>* 193.1.2.0/24 [120/2] via 193.1.1.2, r1-eth1 diff --git a/tests/topotests/rip-topo1/r1/zebra.conf b/tests/topotests/rip-topo1/r1/zebra.conf new file mode 100644 index 0000000000..4dc46c2c8b --- /dev/null +++ b/tests/topotests/rip-topo1/r1/zebra.conf @@ -0,0 +1,19 @@ +log file /tmp/r1-zebra.log +! +hostname r1 +! +interface r1-eth0 + ip address 192.168.1.1/24 +! +interface r1-eth1 + description to sw2 - RIPv2 interface + ip address 193.1.1.1/26 + no link-detect +! +ip forwarding +ipv6 forwarding +! +! +line vty +! + diff --git a/tests/topotests/rip-topo1/r2/rip_status.ref b/tests/topotests/rip-topo1/r2/rip_status.ref new file mode 100644 index 0000000000..b539d321d5 --- /dev/null +++ b/tests/topotests/rip-topo1/r2/rip_status.ref @@ -0,0 +1,18 @@ +Routing Protocol is "rip" + Sending updates every 30 seconds with +/-50%, next due in XX seconds + Timeout after 180 seconds, garbage collect after 120 seconds + Outgoing update filter list for all interface is not set + Incoming update filter list for all interface is not set + Default redistribution metric is 1 + Redistributing: + Default version control: send version 2, receive version 2 + Interface Send Recv Key-chain + r2-eth0 2 2 + r2-eth1 2 2 + Routing for Networks: + 193.1.1.0/26 + 193.1.2.0/24 + Routing Information Sources: + Gateway BadPackets BadRoutes Distance Last Update + 193.1.2.2 0 0 120 XX:XX:XX + Distance: (default is 120) diff --git a/tests/topotests/rip-topo1/r2/ripd.conf b/tests/topotests/rip-topo1/r2/ripd.conf new file mode 100644 index 0000000000..d4e3065cfe --- /dev/null +++ b/tests/topotests/rip-topo1/r2/ripd.conf @@ -0,0 +1,11 @@ +log file /tmp/r2-ripd.log +! +! +router rip + version 2 + network 193.1.1.0/26 + network 193.1.2.0/24 +! +line vty +! + diff --git a/tests/topotests/rip-topo1/r2/show_ip_rip.ref b/tests/topotests/rip-topo1/r2/show_ip_rip.ref new file mode 100644 index 0000000000..58ab052160 --- /dev/null +++ b/tests/topotests/rip-topo1/r2/show_ip_rip.ref @@ -0,0 +1,10 @@ +Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP +Sub-codes: + (n) - normal, (s) - static, (d) - default, (r) - redistribute, + (i) - interface + + Network Next Hop Metric From Tag Time +R(n) 192.168.2.0/24 193.1.2.2 2 193.1.2.2 0 XX:XX +R(n) 192.168.3.0/24 193.1.2.2 2 193.1.2.2 0 XX:XX +C(i) 193.1.1.0/26 0.0.0.0 1 self 0 +C(i) 193.1.2.0/24 0.0.0.0 1 self 0 diff --git a/tests/topotests/rip-topo1/r2/show_ip_route.ref b/tests/topotests/rip-topo1/r2/show_ip_route.ref new file mode 100644 index 0000000000..4b34939aa5 --- /dev/null +++ b/tests/topotests/rip-topo1/r2/show_ip_route.ref @@ -0,0 +1,2 @@ +R>* 192.168.2.0/24 [120/2] via 193.1.2.2, r2-eth1 +R>* 192.168.3.0/24 [120/2] via 193.1.2.2, r2-eth1 diff --git a/tests/topotests/rip-topo1/r2/zebra.conf b/tests/topotests/rip-topo1/r2/zebra.conf new file mode 100644 index 0000000000..74f7bfec06 --- /dev/null +++ b/tests/topotests/rip-topo1/r2/zebra.conf @@ -0,0 +1,21 @@ +log file /tmp/r2-zebra.log +! +hostname r2 +! +interface r2-eth0 + description to sw2 - RIPv2 interface + ip address 193.1.1.2/26 + no link-detect +! +interface r2-eth1 + description to sw3 - RIPv1 interface + ip address 193.1.2.1/24 + no link-detect +! +ip forwarding +ipv6 forwarding +! +! +line vty +! + diff --git a/tests/topotests/rip-topo1/r3/rip_status.ref b/tests/topotests/rip-topo1/r3/rip_status.ref new file mode 100644 index 0000000000..0e3a4be944 --- /dev/null +++ b/tests/topotests/rip-topo1/r3/rip_status.ref @@ -0,0 +1,16 @@ +Routing Protocol is "rip" + Sending updates every 30 seconds with +/-50%, next due in XX seconds + Timeout after 180 seconds, garbage collect after 120 seconds + Outgoing update filter list for all interface is not set + Incoming update filter list for all interface is not set + Default redistribution metric is 1 + Redistributing: connected static + Default version control: send version 2, receive version 2 + Interface Send Recv Key-chain + r3-eth1 2 2 + Routing for Networks: + 193.1.2.0/24 + Routing Information Sources: + Gateway BadPackets BadRoutes Distance Last Update + 193.1.2.1 0 0 120 XX:XX:XX + Distance: (default is 120) diff --git a/tests/topotests/rip-topo1/r3/ripd.conf b/tests/topotests/rip-topo1/r3/ripd.conf new file mode 100644 index 0000000000..e9918c975f --- /dev/null +++ b/tests/topotests/rip-topo1/r3/ripd.conf @@ -0,0 +1,12 @@ +log file /tmp/r3-ripd.log +! +! +router rip + version 2 + redistribute connected + redistribute static + network 193.1.2.0/24 +! +line vty +! + diff --git a/tests/topotests/rip-topo1/r3/show_ip_rip.ref b/tests/topotests/rip-topo1/r3/show_ip_rip.ref new file mode 100644 index 0000000000..cf672712a8 --- /dev/null +++ b/tests/topotests/rip-topo1/r3/show_ip_rip.ref @@ -0,0 +1,10 @@ +Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP +Sub-codes: + (n) - normal, (s) - static, (d) - default, (r) - redistribute, + (i) - interface + + Network Next Hop Metric From Tag Time +S(r) 192.168.2.0/24 192.168.3.10 1 self 0 +C(r) 192.168.3.0/24 0.0.0.0 1 self 0 +R(n) 193.1.1.0/26 193.1.2.1 2 193.1.2.1 0 XX:XX +C(i) 193.1.2.0/24 0.0.0.0 1 self 0 diff --git a/tests/topotests/rip-topo1/r3/show_ip_route.ref b/tests/topotests/rip-topo1/r3/show_ip_route.ref new file mode 100644 index 0000000000..835e1229c8 --- /dev/null +++ b/tests/topotests/rip-topo1/r3/show_ip_route.ref @@ -0,0 +1 @@ +R>* 193.1.1.0/26 [120/2] via 193.1.2.1, r3-eth1 diff --git a/tests/topotests/rip-topo1/r3/zebra.conf b/tests/topotests/rip-topo1/r3/zebra.conf new file mode 100644 index 0000000000..1c79b36b3e --- /dev/null +++ b/tests/topotests/rip-topo1/r3/zebra.conf @@ -0,0 +1,22 @@ +log file /tmp/r3-zebra.log +! +hostname r3 +! +interface r3-eth0 + description to sw4 - Stub interface + ip address 192.168.3.1/24 + no link-detect +! +interface r3-eth1 + description to sw3 - RIPv2 interface + ip address 193.1.2.2/24 + no link-detect +! +ip route 192.168.2.0/24 192.168.3.10 +! +ip forwarding +ipv6 forwarding +! +! +line vty +! diff --git a/tests/topotests/rip-topo1/test_rip_topo1.dot b/tests/topotests/rip-topo1/test_rip_topo1.dot new file mode 100644 index 0000000000..f052b697ea --- /dev/null +++ b/tests/topotests/rip-topo1/test_rip_topo1.dot @@ -0,0 +1,61 @@ +## GraphViz file for test_rip_topo1 +## +## 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 test_rip_topo1 { + overlap=false; + constraint=false; + + // title + labelloc="t"; + label="Test Topologoy RIP Topo1"; + + ###################### + # Routers + ###################### + + # Main FRR Router with all protocols + R1 [shape=doubleoctagon, label="R1 FRR\nMain Router", fillcolor="#f08080", style=filled]; + + # RIP Routers + R2 [shape=doubleoctagon, label="R2 FRR\nRIP Router", fillcolor="#19e3d9", style=filled]; + R3 [shape=doubleoctagon, label="R3 FRR\nRIP Router", fillcolor="#19e3d9", style=filled]; + + ###################### + # Network Lists + ###################### + + SW1_R1_stub [label="SW1\n192.168.1.0/24", fillcolor="#d0e0d0", style=filled]; + + # RIP Networks + SW2_R1_R2 [label="SW2\nRIPv2\n193.1.1.0/26", fillcolor="#d0e0d0", style=filled]; + SW3_R2_R3 [label="SW3\nRIPv1\n193.1.2.0/24", fillcolor="#d0e0d0", style=filled]; + SW4_R3 [label="SW4\n192.168.3.0/24", fillcolor="#d0e0d0", style=filled]; + Net_R3_remote [label="Static Net\n192.168.2.0/24"]; + + ###################### + # Network Connections + ###################### + R1 -- SW1_R1_stub [label = "eth0\n.1\n::1"]; + + # RIP Network + R1 -- SW2_R1_R2 [label = "eth1\n.1"]; + SW2_R1_R2 -- R2 [label = "eth0\n.2"]; + R2 -- SW3_R2_R3 [label = "eth1\n.1"]; + SW3_R2_R3 -- R3 [label = "eth1\n.2"]; + R3 -- SW4_R3 [label = "eth0\n.1"]; + SW4_R3 -- Net_R3_remote [label = ".10"]; + +} diff --git a/tests/topotests/rip-topo1/test_rip_topo1.pdf b/tests/topotests/rip-topo1/test_rip_topo1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c201ac1f0796c880e9a46f403b207388a5314b3f GIT binary patch literal 18433 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 literal 0 HcmV?d00001 diff --git a/tests/topotests/rip-topo1/test_rip_topo1.py b/tests/topotests/rip-topo1/test_rip_topo1.py new file mode 100755 index 0000000000..7f39dffca1 --- /dev/null +++ b/tests/topotests/rip-topo1/test_rip_topo1.py @@ -0,0 +1,352 @@ +#!/usr/bin/env python + +# +# test_rip_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_rip_topo1.py: Testing RIPv2 + +""" + +import os +import re +import sys +import difflib +import pytest +from time import sleep + +from mininet.topo import Topo +from mininet.net import Mininet +from mininet.node import Node, OVSSwitch, Host +from mininet.log import setLogLevel, info +from mininet.cli import CLI +from mininet.link import Intf + +from functools import partial + +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +from lib import topotest + +fatal_error = "" + + +##################################################### +## +## Network Topology Definition +## +##################################################### + +class NetworkTopo(Topo): + "RIP Topology 1" + + def build(self, **_opts): + + # Setup Routers + router = {} + # + # Setup Main Router + router[1] = topotest.addRouter(self, 'r1') + # + # Setup RIP Routers + for i in range(2, 4): + router[i] = topotest.addRouter(self, 'r%s' % i) + # + # Setup Switches + switch = {} + # + # On main router + # First switch is for a dummy interface (for local network) + switch[1] = self.addSwitch('sw1', cls=topotest.LegacySwitch) + self.addLink(switch[1], router[1], intfName2='r1-eth0') + # + # Switches for RIP + # switch 2 switch is for connection to RIP router + switch[2] = self.addSwitch('sw2', cls=topotest.LegacySwitch) + self.addLink(switch[2], router[1], intfName2='r1-eth1') + self.addLink(switch[2], router[2], intfName2='r2-eth0') + # switch 3 is between RIP routers + switch[3] = self.addSwitch('sw3', cls=topotest.LegacySwitch) + self.addLink(switch[3], router[2], intfName2='r2-eth1') + self.addLink(switch[3], router[3], intfName2='r3-eth1') + # switch 4 is stub on remote RIP router + switch[4] = self.addSwitch('sw4', cls=topotest.LegacySwitch) + self.addLink(switch[4], router[3], intfName2='r3-eth0') + + + +##################################################### +## +## Tests starting +## +##################################################### + +def setup_module(module): + global topo, net + + print("\n\n** %s: Setup Topology" % module.__name__) + print("******************************************\n") + + print("Cleanup old Mininet runs") + os.system('sudo mn -c > /dev/null 2>&1') + + thisDir = os.path.dirname(os.path.realpath(__file__)) + topo = NetworkTopo() + + net = Mininet(controller=None, topo=topo) + net.start() + + # Starting Routers + # + for i in range(1, 4): + net['r%s' % i].loadConf('zebra', '%s/r%s/zebra.conf' % (thisDir, i)) + net['r%s' % i].loadConf('ripd', '%s/r%s/ripd.conf' % (thisDir, i)) + net['r%s' % i].startRouter() + + # For debugging after starting Quagga/FRR daemons, uncomment the next line + # CLI(net) + + +def teardown_module(module): + global net + + print("\n\n** %s: Shutdown Topology" % module.__name__) + print("******************************************\n") + + # End - Shutdown network + net.stop() + + +def test_router_running(): + global fatal_error + global net + + # Skip if previous fatal error condition is raised + if (fatal_error != ""): + pytest.skip(fatal_error) + + print("\n\n** Check if FRR/Quagga is running on each Router node") + print("******************************************\n") + sleep(5) + + # Starting Routers + for i in range(1, 4): + fatal_error = net['r%s' % i].checkRouterRunning() + assert fatal_error == "", fatal_error + + # For debugging after starting FRR/Quagga daemons, uncomment the next line + # CLI(net) + + +def test_converge_protocols(): + global fatal_error + global net + + # Skip if previous fatal error condition is raised + if (fatal_error != ""): + pytest.skip(fatal_error) + + thisDir = os.path.dirname(os.path.realpath(__file__)) + + print("\n\n** Waiting for protocols convergence") + print("******************************************\n") + + # Not really implemented yet - just sleep 60 secs for now + sleep(60) + + # For debugging after starting FRR/Quagga daemons, uncomment the next line + # CLI(net) + + +def test_rip_status(): + global fatal_error + global net + + # Skip if previous fatal error condition is raised + if (fatal_error != ""): + pytest.skip(fatal_error) + + thisDir = os.path.dirname(os.path.realpath(__file__)) + + # Verify RIP Status + print("\n\n** Verifing RIP status") + print("******************************************\n") + failures = 0 + for i in range(1, 4): + refTableFile = '%s/r%s/rip_status.ref' % (thisDir, i) + if os.path.isfile(refTableFile): + # Read expected result from file + expected = open(refTableFile).read().rstrip() + # Fix newlines (make them all the same) + expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1) + + # Actual output from router + actual = net['r%s' % i].cmd('vtysh -c "show ip rip status" 2> /dev/null').rstrip() + # Drop time in next due + actual = re.sub(r"in [0-9]+ seconds", "in XX seconds", actual) + # Drop time in last update + actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual) + # Fix newlines (make them all the same) + actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1) + + # Generate Diff + diff = ''.join(difflib.context_diff(actual, expected, + fromfile="actual IP RIP status", + tofile="expected IP RIP status")) + + # Empty string if it matches, otherwise diff contains unified diff + if diff: + sys.stderr.write('r%s failed IP RIP status check:\n%s\n' % (i, diff)) + failures += 1 + else: + print("r%s ok" % i) + + assert failures == 0, "IP RIP status failed for router r%s:\n%s" % (i, diff) + + # For debugging after starting FRR/Quagga daemons, uncomment the next line + # CLI(net) + + +def test_rip_routes(): + global fatal_error + global net + + # Skip if previous fatal error condition is raised + if (fatal_error != ""): + pytest.skip(fatal_error) + + thisDir = os.path.dirname(os.path.realpath(__file__)) + + # Verify RIP Status + print("\n\n** Verifing RIP routes") + print("******************************************\n") + failures = 0 + for i in range(1, 4): + refTableFile = '%s/r%s/show_ip_rip.ref' % (thisDir, i) + if os.path.isfile(refTableFile): + # Read expected result from file + expected = open(refTableFile).read().rstrip() + # Fix newlines (make them all the same) + expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1) + + # Actual output from router + actual = net['r%s' % i].cmd('vtysh -c "show ip rip" 2> /dev/null').rstrip() + # Drop Time + actual = re.sub(r"[0-9][0-9]:[0-5][0-9]", "XX:XX", actual) + # Fix newlines (make them all the same) + actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1) + + # Generate Diff + diff = ''.join(difflib.context_diff(actual, expected, + fromfile="actual SHOW IP RIP", + tofile="expected SHOW IP RIP")) + + # Empty string if it matches, otherwise diff contains unified diff + if diff: + sys.stderr.write('r%s failed SHOW IP RIP check:\n%s\n' % (i, diff)) + failures += 1 + else: + print("r%s ok" % i) + + assert failures == 0, "SHOW IP RIP failed for router r%s:\n%s" % (i, diff) + + # For debugging after starting FRR/Quagga daemons, uncomment the next line + # CLI(net) + + +def test_zebra_ipv4_routingTable(): + global fatal_error + global net + + # Skip if previous fatal error condition is raised + if (fatal_error != ""): + pytest.skip(fatal_error) + + thisDir = os.path.dirname(os.path.realpath(__file__)) + + # Verify OSPFv3 Routing Table + print("\n\n** Verifing Zebra IPv4 Routing Table") + print("******************************************\n") + failures = 0 + for i in range(1, 4): + refTableFile = '%s/r%s/show_ip_route.ref' % (thisDir, i) + if os.path.isfile(refTableFile): + # Read expected result from file + expected = open(refTableFile).read().rstrip() + # Fix newlines (make them all the same) + expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1) + + # Actual output from router + actual = net['r%s' % i].cmd('vtysh -c "show ip route" 2> /dev/null | grep "^R"').rstrip() + # Drop timers on end of line (older Quagga Versions) + actual = re.sub(r", [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", "", actual) + # Fix newlines (make them all the same) + actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1) + + # Generate Diff + diff = ''.join(difflib.context_diff(actual, expected, + fromfile="actual Zebra IPv4 routing table", + tofile="expected Zebra IPv4 routing table")) + + # Empty string if it matches, otherwise diff contains unified diff + if diff: + sys.stderr.write('r%s failed Zebra IPv4 Routing Table Check:\n%s\n' % (i, diff)) + failures += 1 + else: + print("r%s ok" % i) + + assert failures == 0, "Zebra IPv4 Routing Table verification failed for router r%s:\n%s" % (i, diff) + + # For debugging after starting FRR/Quagga daemons, uncomment the next line + # CLI(net) + + +def test_shutdown_check_stderr(): + global fatal_error + global net + + # Skip if previous fatal error condition is raised + if (fatal_error != ""): + pytest.skip(fatal_error) + + if os.environ.get('TOPOTESTS_CHECK_STDERR') is None: + pytest.skip('Skipping test for Stderr output and memory leaks') + + thisDir = os.path.dirname(os.path.realpath(__file__)) + + print("\n\n** Verifing unexpected STDERR output from daemons") + print("******************************************\n") + + net['r1'].stopRouter() + + log = net['r1'].getStdErr('ripd') + print("\nRIPd StdErr Log:\n" + log) + log = net['r1'].getStdErr('zebra') + print("\nZebra StdErr Log:\n" + log) + + +if __name__ == '__main__': + + setLogLevel('info') + # To suppress tracebacks, either use the following pytest call or add "--tb=no" to cli + # retval = pytest.main(["-s", "--tb=no"]) + retval = pytest.main(["-s"]) + sys.exit(retval) -- 2.39.5