Commit b54c7294 authored by Pedro Oliveira's avatar Pedro Oliveira

Create test for broadcast tree formation

parent 10b83104
Script started on Mon Jul 23 15:40:59 2018
root@switch1:~#
root@switch1:~#
root@switch1:~# tp cpdump -i br0 -w Q in -w /hosh T thome/Desktop/p test_pim/pim/TestResults/s Switch.pcap &
[1] 1626
root@switch1:~# tcpdump: listening on br0, link-type EN10MB (Ethernet), capture size 262144 bytes
root@switch1:~# python3 ServerLog.py
Test1: Tree creation (10.1.1.100,224.12.12.12)
Expected: all routers should consider eth0 as their UpstreamInterface
About to start TCP server...
pim.KernelEntry.UpstreamInterface DEBUG (10.1.1.100,224.12.12.12) 0 eth0 R1 Created UpstreamInterface
pim.KernelEntry.DownstreamInterface DEBUG (10.1.1.100,224.12.12.12) 1 eth1 R1 Created DownstreamInterface
pim.KernelEntry.DownstreamInterface DEBUG (10.1.1.100,224.12.12.12) 2 eth2 R1 Created DownstreamInterface
pim.KernelEntry.DownstreamInterface DEBUG (10.1.1.100,224.12.12.12) 3 eth3 R1 Created DownstreamInterface
pim.KernelEntry.UpstreamInterface DEBUG (10.1.1.100,224.12.12.12) 0 eth0 R3 Created UpstreamInterface
pim.KernelEntry.UpstreamInterface DEBUG (10.1.1.100,224.12.12.12) 0 eth0 R4 Created UpstreamInterface
pim.KernelEntry.UpstreamInterface DEBUG (10.1.1.100,224.12.12.12) 0 eth0 R2 Created UpstreamInterface
pim.KernelEntry.DownstreamInterface DEBUG (10.1.1.100,224.12.12.12) 1 eth1 R3 Created DownstreamInterface
pim.KernelEntry.DownstreamInterface DEBUG (10.1.1.100,224.12.12.12) 1 eth1 R4 Created DownstreamInterface
pim.KernelEntry.DownstreamInterface DEBUG (10.1.1.100,224.12.12.12) 1 eth1 R2 Created DownstreamInterface
pim.KernelEntry.DownstreamInterface DEBUG (10.1.1.100,224.12.12.12) 2 eth2 R2 Created DownstreamInterface
pim.KernelEntry.UpstreamInterface DEBUG (10.1.1.100,224.12.12.12) 0 eth0 R6 Created UpstreamInterface
pim.KernelEntry.DownstreamInterface DEBUG (10.1.1.100,224.12.12.12) 1 eth1 R6 Created DownstreamInterface
pim.KernelEntry.UpstreamInterface DEBUG (10.1.1.100,224.12.12.12) 0 eth0 R5 Created UpstreamInterface
pim.KernelEntry.DownstreamInterface DEBUG (10.1.1.100,224.12.12.12) 1 eth1 R5 Created DownstreamInterface
pim.KernelEntry.DownstreamInterface DEBUG (10.1.1.100,224.12.12.12) 0 eth0 R7 Created DownstreamInterface
pim.KernelEntry.DownstreamInterface DEBUG (10.1.1.100,224.12.12.12) 1 eth1 R7 Created DownstreamInterface
pim.KernelEntry.UpstreamInterface DEBUG (10.1.1.100,224.12.12.12) 2 eth2 R7 Created UpstreamInterface
Test1 Success
Test2: Change interface eth2 cost of Router R7 to 100
Expected: Router R7 should change Root<->Non-Root interface
pim.KernelEntry.DownstreamInterface DEBUG (10.1.1.100,224.12.12.12) 2 eth2 R7 Created DownstreamInterface
pim.KernelEntry.UpstreamInterface DEBUG (10.1.1.100,224.12.12.12) 0 eth0 R7 Created UpstreamInterface
Test2 Success
Test3: Fail router 5 (disable its interfaces)
Expected: Router R7 should change Root<->Non-Root interface
pim.KernelEntry.DownstreamInterface DEBUG (10.1.1.100,224.12.12.12) 0 eth0 R5 Created DownstreamInterface
pim.KernelEntry.DownstreamInterface DEBUG (10.1.1.100,224.12.12.12) 0 eth0 R7 Created DownstreamInterface
pim.KernelEntry.UpstreamInterface DEBUG (10.1.1.100,224.12.12.12) 1 eth1 R5 Created UpstreamInterface
pim.KernelEntry.UpstreamInterface DEBUG (10.1.1.100,224.12.12.12) 2 eth2 R7 Created UpstreamInterface
Test3 Success
^CException KeyboardInterrupt: KeyboardInterrupt() in <module 'threading' from '/usr/lib/python3.2/threading.py'> ignored
root@switch1:~#
root@switch1:~#
root@switch1:~#
root@switch1:~# l ff h g g
tcpdump -i br0 -Q in -w /hosthome/Desktop/test_pim/pim/TestResults/Switch.pcap
^C1181 packets captured
2138 packets received by filter
29 packets dropped by kernel
root@switch1:~# exit
exit
Script done on Mon Jul 23 15:44:15 2018
ip addr add dev eth0 10.6.6.100/24
ip addr add dev eth0 10.8.8.100/24
ip link set dev eth0 up
#default route para obter conectividade internet
ip route add 0.0.0.0/0 via 10.6.6.5
ip route add 0.0.0.0/0 via 10.8.8.7
#apt-get update && apt-get --assume-yes install python3 python3-pip
......
......@@ -5,11 +5,11 @@ router1[0]=source
router1[1]=A
router1[2]=B
router1[3]=C
router1[4]=tap,192.168.2.1,192.168.2.2
router1[mem]=256
router2[0]=A
router2[1]=switchnetwork0
router2[2]=router2and7
router2[mem]=256
router3[0]=B
......@@ -21,14 +21,17 @@ router4[1]=switchnetwork2
router4[mem]=256
router5[0]=switchnetwork3
router5[1]=client0
router5[1]=router5and7
router5[mem]=256
router6[0]=switchnetwork4
router6[1]=client1
router6[mem]=256
router7[0]=router5and7
router7[1]=client0
router7[2]=router2and7
router7[mem]=256
#########################################
......@@ -39,7 +42,6 @@ switch1[1]=switchnetwork1
switch1[2]=switchnetwork2
switch1[3]=switchnetwork3
switch1[4]=switchnetwork4
switch1[5]=logserver
switch1[mem]=256
......@@ -55,8 +57,3 @@ client0[mem]=256
client1[0]=client1
client1[mem]=256
log_server[0]=logserver
log_server[mem]=256
......@@ -5,7 +5,8 @@ router4: router1
switch1: router2 router3 router4
router5: switch1
router6: switch1
router7: router5
log_server: switch1
client0: router5
client0: router7
client1: router6
ip addr add dev eth0 10.5.5.100/24
ip link set dev eth0 up
#default route para obter conectividade internet
ip route add 0.0.0.0/0 via 10.5.5.2
#apt-get update && apt-get --assume-yes install python3 python3-pip
......@@ -9,7 +9,7 @@ ip link set dev eth3 up
#NAT for private ip's
iptables -t nat -A POSTROUTING -s 0.0.0.0/0 -o eth4 -j MASQUERADE
#iptables -t nat -A POSTROUTING -s 0.0.0.0/0 -o eth4 -j MASQUERADE
# Zebra and OSPF
/etc/init.d/quagga restart
......
......@@ -12,7 +12,6 @@ router ospf
network 10.2.2.0/24 area 0
network 10.3.3.0/24 area 0
network 10.4.4.0/24 area 0
network 192.168.2.0/24 area 0
default-information originate always
!
log stdout
......@@ -5,7 +5,7 @@ cd MulticastRouting
python3 Run.py -stop
python3 Run.py -start
python3 Run.py -t R1 10.5.5.100
python3 Run.py -t R1 10.5.5.7
python3 Run.py -aiigmp eth0
python3 Run.py -aiigmp eth1
python3 Run.py -aiigmp eth2
......
......@@ -2,6 +2,8 @@ ip addr add dev eth0 10.2.2.2/24
ip link set dev eth0 up
ip addr add dev eth1 10.5.5.2/24
ip link set dev eth1 up
ip addr add dev eth2 10.9.9.2/24
ip link set dev eth2 up
#default route para obter conectividade internet
#ip route add 0.0.0.0/0 via 10.2.2.1
......
......@@ -10,5 +10,6 @@ password zebra
router ospf
network 10.2.2.0/24 area 0
network 10.5.5.0/24 area 0
network 10.9.9.0/24 area 0
!
log stdout
......@@ -5,9 +5,11 @@ cd MulticastRouting
python3 Run.py -stop
python3 Run.py -start
python3 Run.py -t R2 10.5.5.100
python3 Run.py -t R2 10.5.5.7
python3 Run.py -aiigmp eth0
python3 Run.py -aiigmp eth1
python3 Run.py -aiigmp eth2
python3 Run.py -ai eth0
python3 Run.py -ai eth1
python3 Run.py -ai eth2
python3 Run.py -v
......@@ -5,7 +5,7 @@ cd MulticastRouting
python3 Run.py -stop
python3 Run.py -start
python3 Run.py -t R3 10.5.5.100
python3 Run.py -t R3 10.5.5.7
python3 Run.py -aiigmp eth0
python3 Run.py -aiigmp eth1
python3 Run.py -ai eth0
......
......@@ -5,7 +5,7 @@ cd MulticastRouting
python3 Run.py -stop
python3 Run.py -start
python3 Run.py -t R4 10.5.5.100
python3 Run.py -t R4 10.5.5.7
python3 Run.py -aiigmp eth0
python3 Run.py -aiigmp eth1
python3 Run.py -ai eth0
......
......@@ -5,7 +5,7 @@ cd MulticastRouting
python3 Run.py -stop
python3 Run.py -start
python3 Run.py -t R5 10.5.5.100
python3 Run.py -t R5 10.5.5.7
python3 Run.py -aiigmp eth0
python3 Run.py -aiigmp eth1
python3 Run.py -ai eth0
......
......@@ -5,7 +5,7 @@ cd MulticastRouting
python3 Run.py -stop
python3 Run.py -start
python3 Run.py -t R6 10.5.5.100
python3 Run.py -t R6 10.5.5.7
python3 Run.py -aiigmp eth0
python3 Run.py -aiigmp eth1
python3 Run.py -ai eth0
......
ip addr add dev eth0 10.6.6.7/24
ip link set dev eth0 up
ip addr add dev eth1 10.8.8.7/24
ip link set dev eth1 up
ip addr add dev eth2 10.9.9.7/24
ip link set dev eth2 up
#default route para obter conectividade internet
#ip route add 0.0.0.0/0 via 10.5.5.2
# Zebra and OSPF
/etc/init.d/quagga restart
# wait for default route information from OSPF
while ! $(ip route | grep -q "default")
do
sleep 2
done
echo VTYSH_PAGER=more > /etc/environment
# This file tells the quagga package which daemons to start.
#
# Entries are in the format: <daemon>=(yes|no|priority)
# 0, "no" = disabled
# 1, "yes" = highest priority
# 2 .. 10 = lower priorities
# Read /usr/share/doc/quagga/README.Debian for details.
#
# Sample configurations for these daemons can be found in
# /usr/share/doc/quagga/examples/.
#
# ATTENTION:
#
# When activation a daemon at the first time, a config file, even if it is
# empty, has to be present *and* be owned by the user and group "quagga", else
# the daemon will not be started by /etc/init.d/quagga. The permissions should
# be u=rw,g=r,o=.
# When using "vtysh" such a config file is also needed. It should be owned by
# group "quaggavty" and set to ug=rw,o= though. Check /etc/pam.d/quagga, too.
#
# The watchquagga daemon is always started. Per default in monitoring-only but
# that can be changed via /etc/quagga/debian.conf.
#
zebra=yes
bgpd=no
ospfd=yes
ospf6d=no
ripd=no
ripngd=no
isisd=no
babeld=no
#
# If this option is set the /etc/init.d/quagga script automatically loads
# the config via "vtysh -b" when the servers are started.
# Check /etc/pam.d/quagga if you intend to use "vtysh"!
#
vtysh_enable=yes
zebra_options=" --daemon -A 127.0.0.1"
bgpd_options=" --daemon -A 127.0.0.1"
ospfd_options=" --daemon -A 127.0.0.1"
ospf6d_options=" --daemon -A ::1"
ripd_options=" --daemon -A 127.0.0.1"
ripngd_options=" --daemon -A ::1"
isisd_options=" --daemon -A 127.0.0.1"
babeld_options=" --daemon -A 127.0.0.1"
#
# Please note that watchquagga_options is an array and not a string so that
# quotes can be used.
#
# The list of daemons to watch is automatically generated by the init script
# from daemons.conf and appended to the watchquagga_options.
# Example:
# watchquagga_options=("-Adz" "-r" '/sbin/service %s restart' -s '/sbin/service %s start' -k '/sbin/service %s stop')
watchquagga_enable=yes
watchquagga_options=(--daemon)
! -*- ospf -*-
!
! OSPFd sample configuration file
!
!
hostname ospfd
password zebra
!enable password please-set-at-here
!
router ospf
network 10.6.6.0/24 area 0
network 10.8.8.0/24 area 0
network 10.9.9.0/24 area 0
!
log stdout
!
! Sample configuration file for vtysh.
!
!service integrated-vtysh-config
hostname quagga-router
username root nopassword
!
! -*- zebra -*-
!
! zebra sample configuration file
!
! $Id: zebra.conf.sample,v 1.1 2002/12/13 20:15:30 paul Exp $
!
hostname Router
password zebra
enable password zebra
!
! Interface's description.
!
!interface lo
! description test of desc.
!
!interface sit0
! multicast
!
! Static default route sample.
!
!ip route 0.0.0.0/0 203.181.89.241
!
!log file /var/log/quagga/zebra.log
rm -rf MulticastRouting/
cp -rf /hosthome/Desktop/pim/ MulticastRouting/
cd MulticastRouting
#pip-3.2 install --index-url=https://pypi.python.org/simple/ -r requirements.txt
python3 Run.py -stop
python3 Run.py -start
python3 Run.py -t R7 10.5.5.7
python3 Run.py -aiigmp eth0
python3 Run.py -aiigmp eth1
python3 Run.py -aiigmp eth2
python3 Run.py -ai eth0
python3 Run.py -ai eth1
python3 Run.py -ai eth2
python3 Run.py -v
......@@ -3,14 +3,12 @@ ip link set dev eth1 up
ip link set dev eth2 up
ip link set dev eth3 up
ip link set dev eth4 up
ip link set dev eth5 up
brctl addbr br0
brctl addif br0 eth0
brctl addif br0 eth1
brctl addif br0 eth2
brctl addif br0 eth3
brctl addif br0 eth4
brctl addif br0 eth5
ip link set dev br0 up
ip addr add dev br0 10.5.5.7/24
......
......@@ -3,7 +3,7 @@ import logging
import logging.handlers
import socketserver
import struct
from TestAssert import CustomFilter, Test1, Test2, Test3, Test4
from TestBroadcastTree import CustomFilter, Test1, Test2, Test3
import sys
import threading
from queue import Queue
......@@ -24,7 +24,7 @@ def worker():
class TestHandler(logging.StreamHandler):
currentTest = Test1()
currentTest.print_test()
nextTests = [Test2(), Test3(), Test4()]
nextTests = [Test2(), Test3()]
main = None
def emit(self, record):
......@@ -105,7 +105,7 @@ def main():
t = threading.Thread(target=worker)
t.start()
tcpserver = LogRecordSocketReceiver(host='10.5.5.100')
tcpserver = LogRecordSocketReceiver(host='10.5.5.7')
print('About to start TCP server...')
tcpserver.serve_until_stopped()
......
......@@ -4,8 +4,8 @@ from abc import ABCMeta, abstractmethod
class CustomFilter(logging.Filter):
def filter(self, record):
return record.name in ("pim.KernelEntry.DownstreamInterface.Assert", "pim.KernelEntry.UpstreamInterface.Assert", "pim.KernelInterface") and \
record.routername in ["R1", "R2", "R3", "R4", "R5", "R6"]
return record.name in ("pim.KernelEntry.DownstreamInterface", "pim.KernelEntry.UpstreamInterface") and \
record.routername in ["R1", "R2", "R3", "R4", "R5", "R6", "R7"]
class Test(object):
......@@ -35,79 +35,54 @@ class Test(object):
class Test1(Test):
def __init__(self):
expectedState = {"R2": {"eth1": "L"},
"R3": {"eth1": "L"},
"R4": {"eth1": "W"},
"R5": {"eth0": "L"},
"R6": {"eth0": "L"},
expectedState = {"R1": {"eth0": "Created UpstreamInterface", "eth1": "Created DownstreamInterface", "eth2": "Created DownstreamInterface", "eth3": "Created DownstreamInterface"},
"R2": {"eth0": "Created UpstreamInterface", "eth1": "Created DownstreamInterface", "eth2": "Created DownstreamInterface"},
"R3": {"eth0": "Created UpstreamInterface", "eth1": "Created DownstreamInterface"},
"R4": {"eth0": "Created UpstreamInterface", "eth1": "Created DownstreamInterface"},
"R5": {"eth0": "Created UpstreamInterface", "eth1": "Created DownstreamInterface"},
"R6": {"eth0": "Created UpstreamInterface", "eth1": "Created DownstreamInterface"},
"R7": {"eth0": "Created DownstreamInterface", "eth1": "Created DownstreamInterface", "eth2": "Created UpstreamInterface"},
}
success = {"R2": {"eth1": False},
"R3": {"eth1": False},
"R4": {"eth1": False},
"R5": {"eth0": False},
"R6": {"eth0": False},
success = {"R1": {"eth0": False, "eth1": False, "eth2": False, "eth3": False},
"R2": {"eth0": False, "eth1": False, "eth2": False},
"R3": {"eth0": False, "eth1": False},
"R4": {"eth0": False, "eth1": False},
"R5": {"eth0": False, "eth1": False},
"R6": {"eth0": False, "eth1": False},
"R7": {"eth0": False, "eth1": False, "eth2": False},
}
super().__init__("Test1", expectedState, success)
def print_test(self):
print("Test1: No info about (10.1.1.100,224.12.12.12)")
print("Expected: R4 WINNER")
print("Test1: Tree creation (10.1.1.100,224.12.12.12)")
print("Expected: all routers should consider eth0 as their UpstreamInterface")
class Test2(Test):
def __init__(self):
expectedState = {"R2": {"eth1": "NI"},
"R3": {"eth1": "NI"},
"R5": {"eth0": "NI"},
"R6": {"eth0": "NI"},
expectedState = {"R7": {"eth0": "Created UpstreamInterface", "eth2": "Created DownstreamInterface"}
}
success = {"R2": {"eth1": False},
"R3": {"eth1": False},
"R5": {"eth0": False},
"R6": {"eth0": False},
success = {"R7": {"eth0": False, "eth2": False},
}
super().__init__("Test2", expectedState, success)
def print_test(self):
print("Test2: Kill assert winner")
print("Expected: Every AL transitions to NI")
print("Test2: Change interface eth2 cost of Router R7 to 100")
print("Expected: Router R7 should change Root<->Non-Root interface")
class Test3(Test):
def __init__(self):
expectedState = {"R2": {"eth1": "L"},
"R3": {"eth1": "W"},
"R5": {"eth0": "L"},
"R6": {"eth0": "L"},
expectedState = {"R7": {"eth0": "Created DownstreamInterface", "eth2": "Created UpstreamInterface"}
}
success = {"R2": {"eth1": False},
"R3": {"eth1": False},
"R5": {"eth0": False},
"R6": {"eth0": False},
success = {"R7": {"eth0": False, "eth2": False},
}
super().__init__("Test3", expectedState, success)
def print_test(self):
print("Test3: Source sends data causing the reelection of AW")
print("Expected: R3 WINNER")
class Test4(Test):
def __init__(self):
expectedState = {"R2": {"eth1": "NI"},
"R3": {"eth1": "NI"},
}
success = {"R2": {"eth1": False},
"R3": {"eth1": False},
}
super().__init__("Test4", expectedState, success)
def print_test(self):
print("Test4: CouldAssert of AssertWinner(R3) -> False")
print("Expected: everyone NI")
print("Test3: Fail router 5 (disable its interfaces)")
print("Expected: Router R7 should change Root<->Non-Root interface")
topology.png

65 KB | W: | H:

topology.png

72.7 KB | W: | H:

topology.png
topology.png
topology.png
topology.png
  • 2-up
  • Swipe
  • Onion skin
<mxfile userAgent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36" version="8.3.2" editor="www.draw.io" type="device"><diagram name="Page-1" id="11f5d53f-c264-6b31-e1a8-d7fc60da157b">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</diagram></mxfile>
\ No newline at end of file
<mxfile userAgent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36" version="8.9.7" editor="www.draw.io" type="device"><diagram name="Page-1" id="11f5d53f-c264-6b31-e1a8-d7fc60da157b">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</diagram></mxfile>
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment