Commit 7494e2c8 authored by Pedro Oliveira's avatar Pedro Oliveira

Test originator transitions

parent 6a618729
...@@ -39,7 +39,7 @@ switch1[1]=switchnetwork1 ...@@ -39,7 +39,7 @@ switch1[1]=switchnetwork1
switch1[2]=switchnetwork2 switch1[2]=switchnetwork2
switch1[3]=switchnetwork3 switch1[3]=switchnetwork3
switch1[4]=switchnetwork4 switch1[4]=switchnetwork4
switch1[5]=log_server switch1[5]=logserver
switch1[mem]=256 switch1[mem]=256
...@@ -55,7 +55,7 @@ client0[mem]=256 ...@@ -55,7 +55,7 @@ client0[mem]=256
client1[0]=client1 client1[0]=client1
client1[mem]=256 client1[mem]=256
log_server[0]=log_server log_server[0]=logserver
log_server[mem]=256 log_server[mem]=256
......
...@@ -3,8 +3,10 @@ import logging ...@@ -3,8 +3,10 @@ import logging
import logging.handlers import logging.handlers
import socketserver import socketserver
import struct import struct
from TestJoinPrune import CustomFilter, Test1, Test2, Test3, Test4, Test5 from TestStateRefresh import CustomFilter, Test1, Test2, Test3
from queue import Queue from queue import Queue
import sys
import threading
q = Queue() q = Queue()
...@@ -22,7 +24,7 @@ def worker(): ...@@ -22,7 +24,7 @@ def worker():
class TestHandler(logging.StreamHandler): class TestHandler(logging.StreamHandler):
currentTest = Test1() currentTest = Test1()
currentTest.print_test() currentTest.print_test()
nextTests = [Test2(), Test3(), Test4(), Test5()] nextTests = [Test2(), Test3()]
main = None main = None
def emit(self, record): def emit(self, record):
...@@ -93,14 +95,12 @@ class LogRecordSocketReceiver(socketserver.ThreadingTCPServer): ...@@ -93,14 +95,12 @@ class LogRecordSocketReceiver(socketserver.ThreadingTCPServer):
def main(): def main():
import sys
handler = TestHandler(sys.stdout) handler = TestHandler(sys.stdout)
formatter = logging.Formatter('%(name)-50s %(levelname)-8s %(tree)-35s %(vif)-2s %(interfacename)-5s %(routername)-2s %(message)s') formatter = logging.Formatter('%(name)-50s %(levelname)-8s %(tree)-35s %(vif)-2s %(interfacename)-5s %(routername)-2s %(message)s')
handler.setFormatter(formatter) handler.setFormatter(formatter)
logging.getLogger('my_logger').addHandler(handler) logging.getLogger('my_logger').addHandler(handler)
logging.getLogger('my_logger').addFilter(CustomFilter()) logging.getLogger('my_logger').addFilter(CustomFilter())
import threading
t = threading.Thread(target=worker) t = threading.Thread(target=worker)
t.start() t.start()
......
...@@ -3,7 +3,7 @@ from abc import ABCMeta ...@@ -3,7 +3,7 @@ from abc import ABCMeta
class CustomFilter(logging.Filter): class CustomFilter(logging.Filter):
def filter(self, record): def filter(self, record):
return record.name in ("pim.KernelEntry.DownstreamInterface.JoinPrune", "pim.KernelEntry.UpstreamInterface.JoinPrune", "pim.KernelInterface") and \ return record.name in ("pim.KernelEntry.UpstreamInterface.Originator", "pim.KernelEntry.DownstreamInterface.JoinPrune", "pim.KernelEntry.UpstreamInterface.JoinPrune", "pim.KernelInterface") and \
record.routername in ["R1", "R2","R3","R4","R5","R6"] record.routername in ["R1", "R2","R3","R4","R5","R6"]
...@@ -30,25 +30,20 @@ class Test(): ...@@ -30,25 +30,20 @@ class Test():
return True return True
class Test1(Test): class Test1(Test):
def __init__(self): def __init__(self):
expectedState = {"R1": {"eth0": "F", "eth1": "P", "eth2": "P", "eth3": "NI"}, # Only downstream interface connected to AssertWinner \ expectedState = {"R1": {"eth0": "O"},
# in NI state and upstream interface connected to source\ "R2": {"eth0": "NO"},
# in Forward state "R3": {"eth0": "NO"},
"R2": {"eth0": "P"}, # Assert Loser upstream interface in pruned state "R4": {"eth0": "NO"},
"R3": {"eth0": "P"}, # Assert Loser upstream interface in pruned state "R5": {"eth0": "NO"},
"R4": {"eth0": "F", "eth1": "NI"}, # Assert Winner upstream interface in forward state "R6": {"eth0": "NO"},
"R5": {"eth0": "F"}, # Downstream router interested (client0)
"R6": {"eth0": "F"}, # Downstream router interested (client0)
} }
success = {"R1": {"eth0": False, "eth1": False, "eth2": False, "eth3": False}, success = {"R1": {"eth0": False},
"R2": {"eth0": False}, "R2": {"eth0": False},
"R3": {"eth0": False}, "R3": {"eth0": False},
"R4": {"eth0": False, "eth1": False}, "R4": {"eth0": False},
"R5": {"eth0": False}, "R5": {"eth0": False},
"R6": {"eth0": False}, "R6": {"eth0": False},
} }
...@@ -56,80 +51,32 @@ class Test1(Test): ...@@ -56,80 +51,32 @@ class Test1(Test):
super().__init__("Test1", expectedState, success) super().__init__("Test1", expectedState, success)
def print_test(self): def print_test(self):
print("Test1: Formation of (S,G) Broadcast Tree") print("Test1: Originator")
print("Having Client0 and Client1 interested") print("Having Client0 and Client1 interested")
class Test2(Test): class Test2(Test):
def __init__(self): def __init__(self):
expectedState = {"R4": {"eth1": "PP"}, # Assert Winner upstream interface in PP because of Prune msg expectedState = {"R1": {"eth0": "NO"}
"R6": {"eth0": "P"}, # Downstream router not interested
} }
success = {"R4": {"eth1": False}, success = {"R1": {"eth0": False},
"R6": {"eth0": False},
} }
super().__init__("Test2", expectedState, success) super().__init__("Test2", expectedState, success)
def print_test(self): def print_test(self):
print("Test2: Client1 not interested in receiving traffic destined to group G") print("Test2: After some time without source sending data... router originator should transition to NO")
print("R6 sends a Prune and R5 overrides the prune")
class Test3(Test): class Test3(Test):
def __init__(self): def __init__(self):
expectedState = {"R4": {"eth1": "NI"}, # Assert Winner upstream interface in PP because of Join msg expectedState = {"R1": {"eth0": "O"}
} }
success = {"R4": {"eth1": False}, success = {"R1": {"eth0": False},
} }
super().__init__("Test3", expectedState, success) super().__init__("Test3", expectedState, success)
def print_test(self): def print_test(self):
print("Test3: R5 overrides prune via Join") print("Test3: Source sends data")
print("R4 should transition to Forward state") print("Expected: R1 transitions to Originator")
class Test4(Test):
def __init__(self):
expectedState = {"R1": {"eth3": "P"}, # Only interface eth3 changes to Pruned state... eth1 is directly connected so it should stay in a Forward state
#"R2": {"eth0": "P"}, #R2 already in a Pruned state
#"R3": {"eth0": "P"}, #R3 already in a Pruned state
"R4": {"eth0": "P", "eth1": "P"}, # Assert Winner upstream interface in forward state
"R5": {"eth0": "P"}, # Downstream router interested (client0)
#"R6": {"eth0": "P"}, # R6 already in a Pruned state
}
success = {"R1": {"eth3": False},
"R4": {"eth0": False, "eth1": False},
"R5": {"eth0": False},
}
super().__init__("Test4", expectedState, success)
def print_test(self):
print("Test4: No client interested")
print("Prune tree")
class Test5(Test):
def __init__(self):
expectedState = {"R1": {"eth3": "NI"}, # R4 grafted this interface
"R4": {"eth0": "F", "eth1": "NI"}, # R5 grafted this interface
"R5": {"eth0": "F"}, # client0 interested
}
success = {"R1": {"eth3": False},
"R4": {"eth0": False, "eth1": False},
"R5": {"eth0": False},
}
super().__init__("Test5", expectedState, success)
def print_test(self):
print("Test5: client0 interested in receiving traffic")
print("Graft tree")
pip-3.2 install --index-url=https://pypi.python.org/simple/ netifaces
cp /hosthome/PycharmProjects/Test/ServerLog.py .
cp /hosthome/PycharmProjects/Test/TestAssert.py .
python3 ServerLog.py
...@@ -10,8 +10,8 @@ python3 Run.py -aiigmp eth0 ...@@ -10,8 +10,8 @@ python3 Run.py -aiigmp eth0
python3 Run.py -aiigmp eth1 python3 Run.py -aiigmp eth1
python3 Run.py -aiigmp eth2 python3 Run.py -aiigmp eth2
python3 Run.py -aiigmp eth3 python3 Run.py -aiigmp eth3
python3 Run.py -ai eth0 python3 Run.py -aisr eth0
python3 Run.py -ai eth1 python3 Run.py -aisr eth1
python3 Run.py -ai eth2 python3 Run.py -aisr eth2
python3 Run.py -ai eth3 python3 Run.py -aisr eth3
python3 Run.py -v python3 Run.py -v
...@@ -8,6 +8,6 @@ python3 Run.py -start ...@@ -8,6 +8,6 @@ python3 Run.py -start
python3 Run.py -t R2 10.5.5.100 python3 Run.py -t R2 10.5.5.100
python3 Run.py -aiigmp eth0 python3 Run.py -aiigmp eth0
python3 Run.py -aiigmp eth1 python3 Run.py -aiigmp eth1
python3 Run.py -ai eth0 python3 Run.py -aisr eth0
python3 Run.py -ai eth1 python3 Run.py -aisr eth1
python3 Run.py -v python3 Run.py -v
...@@ -8,7 +8,7 @@ python3 Run.py -start ...@@ -8,7 +8,7 @@ python3 Run.py -start
python3 Run.py -t R3 10.5.5.100 python3 Run.py -t R3 10.5.5.100
python3 Run.py -aiigmp eth0 python3 Run.py -aiigmp eth0
python3 Run.py -aiigmp eth1 python3 Run.py -aiigmp eth1
python3 Run.py -ai eth0 python3 Run.py -aisr eth0
python3 Run.py -ai eth1 python3 Run.py -aisr eth1
python3 Run.py -v python3 Run.py -v
...@@ -8,6 +8,6 @@ python3 Run.py -start ...@@ -8,6 +8,6 @@ python3 Run.py -start
python3 Run.py -t R4 10.5.5.100 python3 Run.py -t R4 10.5.5.100
python3 Run.py -aiigmp eth0 python3 Run.py -aiigmp eth0
python3 Run.py -aiigmp eth1 python3 Run.py -aiigmp eth1
python3 Run.py -ai eth0 python3 Run.py -aisr eth0
python3 Run.py -ai eth1 python3 Run.py -aisr eth1
python3 Run.py -v python3 Run.py -v
...@@ -8,6 +8,6 @@ python3 Run.py -start ...@@ -8,6 +8,6 @@ python3 Run.py -start
python3 Run.py -t R5 10.5.5.100 python3 Run.py -t R5 10.5.5.100
python3 Run.py -aiigmp eth0 python3 Run.py -aiigmp eth0
python3 Run.py -aiigmp eth1 python3 Run.py -aiigmp eth1
python3 Run.py -ai eth0 python3 Run.py -aisr eth0
python3 Run.py -ai eth1 python3 Run.py -aisr eth1
python3 Run.py -v python3 Run.py -v
...@@ -8,6 +8,6 @@ python3 Run.py -start ...@@ -8,6 +8,6 @@ python3 Run.py -start
python3 Run.py -t R6 10.5.5.100 python3 Run.py -t R6 10.5.5.100
python3 Run.py -aiigmp eth0 python3 Run.py -aiigmp eth0
python3 Run.py -aiigmp eth1 python3 Run.py -aiigmp eth1
python3 Run.py -ai eth0 python3 Run.py -aisr eth0
python3 Run.py -ai eth1 python3 Run.py -aisr eth1
python3 Run.py -v python3 Run.py -v
tcpdump -i br0 -Q in -w /hosthome/Desktop/assert_capture.pcap rm /hosthome/Desktop/state_refresh_capture.pcap
tcpdump -i br0 -Q in -w /hosthome/Desktop/state_refresh_capture.pcap
topology.png

65.6 KB | W: | H:

topology.png

65 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.140 Safari/537.36" version="8.0.6" editor="www.draw.io" type="device"><diagram name="Page-1" id="11f5d53f-c264-6b31-e1a8-d7fc60da157b">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</diagram></mxfile> <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 \ 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