Commit 39f0760e authored by Pedro Oliveira's avatar Pedro Oliveira

Test assert using loggers

parent 6b99c6d1
import rpyc
import time
from subprocess import Popen
def test_neighbor_table(router_id_str, router_rpc, expected_neighbors):
print("\ttesting " + router_id_str)
success = False
while not success:
(table, dict) = router_rpc.root.get_neighbors()
if "eth0" in dict:
neighbors_of_eth = dict["eth0"]
elif len(expected_neighbors) != 0:
print("\t\x1b[1;31;20m[NOT OK]\x1b[0m " + router_id_str + " table empty")
time.sleep(5)
continue
else:
print("\t\x1b[1;32;40m[OK]\x1b[0m " + router_id_str + " neighbor table is empty")
break
if len(expected_neighbors) != len(neighbors_of_eth):
print("\t\x1b[1;31;20m[NOT OK]\x1b[0m " + router_id_str + " different number of neighbors")
time.sleep(5)
continue
success = True
for n in expected_neighbors:
if (n not in neighbors_of_eth):
print("\t\x1b[1;31;20m[NOT OK]\x1b[0m " + router_id_str + " doesn't know about " + n)
print("\t ... trying again ...")
success = False
time.sleep(2)
break
print("\t\x1b[1;32;20m[OK]\x1b[0m " + router_id_str + " success")
print(table + "\n\n\n")
return dict
print("START TCPDUMP CAPTURE")
p = Popen(['tcpdump', '-i', 'br0', '-w', './capture.pcap'])
ips = ["10.0.0.1", "10.0.0.2", "10.0.0.3", "10.0.0.4"]
expected_neighbors = [["10.0.0.2", "10.0.0.3", "10.0.0.4"], ["10.0.0.1", "10.0.0.3", "10.0.0.4"], ["10.0.0.1", "10.0.0.2", "10.0.0.4"], ["10.0.0.2", "10.0.0.3", "10.0.0.1"]]
r1 = rpyc.connect("10.0.0.1", 10000)
r2 = rpyc.connect("10.0.0.2", 10000)
r3 = rpyc.connect("10.0.0.3", 10000)
r4 = rpyc.connect("10.0.0.4", 10000)
print("Test1: Start PIM process and check if neighbor tables are empty")
test_neighbor_table("R1", r1, [])
test_neighbor_table("R2", r2, [])
test_neighbor_table("R3", r3, [])
test_neighbor_table("R4", r4, [])
print("\x1b[1;32;20m[OK]\x1b[0m Test1 success")
print("============================\n\n\n")
print("Enabling R1's interface eth0...")
r1.root.add_interface("eth0")
print("Enabling R2's interface eth0...")
r2.root.add_interface("eth0")
print("Enabling R3's interface eth0...")
r3.root.add_interface("eth0")
print("Enabling R4's interface eth0...")
r4.root.add_interface("eth0")
print("Test2: Check if routers establish neighborship relations")
dict = test_neighbor_table("R1", r1, expected_neighbors[0])
test_neighbor_table("R2", r2, expected_neighbors[1])
test_neighbor_table("R3", r3, expected_neighbors[2])
test_neighbor_table("R4", r4, expected_neighbors[3])
print("\x1b[1;32;20m[OK]\x1b[0m Test2 Success")
print("============================\n\n\n")
print("Test3: Disable Router3 and check if others router react to R3 HelloHoldTime=0")
print("Disabling R3's interface eth0...")
r3.root.remove_interface("eth0")
expected_neighbors = [["10.0.0.2", "10.0.0.4"], ["10.0.0.1", "10.0.0.4"], [], ["10.0.0.2", "10.0.0.1"]]
test_neighbor_table("R1", r1, expected_neighbors[0])
test_neighbor_table("R2", r2, expected_neighbors[1])
test_neighbor_table("R4", r4, expected_neighbors[3])
print("\x1b[1;32;20m[OK]\x1b[0m Test3 success")
print("============================\n\n\n")
print("Test4: KILL router (doesn't send Hello with HelloHoldTime set to 0) and check if others remove that router after timeout")
print("Route4 has HelloHoldTime set to: " + str(dict["eth0"]["10.0.0.4"][0]))
print("Killing router4...")
r4.root.kill()
print("Waiting for " + str(str(dict["eth0"]["10.0.0.4"][0])) + " seconds...")
time.sleep(int(dict["eth0"]["10.0.0.4"][0]))
expected_neighbors = [["10.0.0.2"], ["10.0.0.1"], [], []]
test_neighbor_table("R1", r1, expected_neighbors[0])
test_neighbor_table("R2", r2, expected_neighbors[1])
print("\x1b[1;32;20m[OK]\x1b[0m Test4 success")
print("============================\n\n\n")
print("Test5: ReEnable router R3 and check if Generation ID is different")
print("R3 had old GenerationID set to: " + str(dict["eth0"]["10.0.0.3"][1]))
print("Enabling router3...")
r3.root.add_interface("eth0")
print("Enabled router3...")
expected_neighbors = [["10.0.0.2", "10.0.0.3"], ["10.0.0.1", "10.0.0.3"], ["10.0.0.1", "10.0.0.2"], []]
new_dict_r1 = test_neighbor_table("R1", r1, expected_neighbors[0])
new_dict_r2 = test_neighbor_table("R2", r2, expected_neighbors[1])
new_dict_r3 = test_neighbor_table("R3", r3, expected_neighbors[2])
print("R1 has in its neighbor table, R3 with GenerationID set to: " + new_dict_r1["eth0"]["10.0.0.3"][1])
print("R2 has in its neighbor table, R3 with GenerationID set to: " + new_dict_r2["eth0"]["10.0.0.3"][1])
if new_dict_r1["eth0"]["10.0.0.3"][1] == new_dict_r2["eth0"]["10.0.0.3"][1]:
print("\x1b[1;32;20m[OK]\x1b[0m R1 and R2 have same R3's GenerationID")
else:
print("\x1b[1;31;20m[NOT OK]\x1b[0m R1 and R2 have different R3's GenerationID")
exit()
if dict["eth0"]["10.0.0.3"][1] != new_dict_r2["eth0"]["10.0.0.3"][1]:
print("\x1b[1;32;20m[OK]\x1b[0m old and new GenerationID are differents (" + dict["eth0"]["10.0.0.3"][1] + " != " + new_dict_r1["eth0"]["10.0.0.3"][1] + ")")
else:
print("\x1b[1;31;20m[NOT OK]\x1b[0m old and new GenerationID are equal (" + dict["eth0"]["10.0.0.3"][1] + " == " + new_dict_r1["eth0"]["10.0.0.3"][1] + ")")
exit()
print("FINISH TCPDUMP CAPTURE")
p.terminate()
\ No newline at end of file
import rpyc
import socket
import _pickle as pickle
from argparse import Namespace
import os
class MyService(rpyc.Service):
daemon = None
def client_socket(self, data_to_send):
# Create a UDS socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
# Connect the socket to the port where the server is listening
server_address = './uds_socket'
# print('connecting to %s' % server_address)
try:
sock.connect(server_address)
sock.sendall(pickle.dumps(data_to_send))
data_rcv = sock.recv(1024 * 256)
if data_rcv:
return pickle.loads(data_rcv)
except socket.error as error:
print(error)
pass
finally:
# print('closing socket')
sock.close()
def on_connect(self):
# code that runs when a connection is created
# (to init the serivce, if needed)
os.system("python3 Run.py -restart")
pass
def on_disconnect(self):
# code that runs when the connection has already closed
# (to finalize the service, if needed)
pass
def exposed_kill(self):
import signal
with open("/tmp/Daemon-pim.pid", 'r') as pf:
pid = int(pf.read().strip())
os.kill(pid, signal.SIGTERM)
def exposed_add_interface(self, interface_name):
self.client_socket(Namespace(add_interface_igmp=[interface_name]))
self.client_socket(Namespace(add_interface=[interface_name]))
def exposed_remove_interface(self, interface_name):
self.client_socket(Namespace(remove_interface_igmp=[interface_name]))
self.client_socket(Namespace(remove_interface=[interface_name]))
def exposed_get_neighbors(self): # this is an exposed method
import re
table_list_neighbors = self.client_socket(Namespace(list_neighbors=True))
#x = table_list_neighbors.replace("-", "").replace("+", "").replace("\n", "").replace(" ", "").split("|")
x = re.sub(r"[\s\-\+]+", "", table_list_neighbors).split("|")
x = list(filter(lambda a: a != '', x))
dict = {}
for i in range(5, len(x), 5):
print(x[i+1])
if x[i] not in dict:
dict[x[i]] = {x[i+1]: [x[i+2], x[i+3], x[i+4]]}
else:
dict[x[i]][x[i+1]] = [x[i+2], x[i+3], x[i+4]]
return (table_list_neighbors, dict)
def exposed_list_igm_state(self): # this is an exposed method
x = self.client_socket(Namespace(list_state=True))
x = x.split("Multicast Routing State:")[0]
x = x.replace(" - ", "No")
x = x.replace("-", "").replace("+", "").replace("\n", "").replace(" ", "").split("|")
x = list(filter(lambda a: a != '', x))
for i in range(0, len(x), 4):
print(x[i+1])
def exposed_list_state(self): # this is an exposed method
x = self.client_socket(Namespace(list_state=True))
x = x.split("Multicast Routing State:")[1]
x = x.replace(" - ", "No")
x = x.replace("-", "").replace("+", "").replace("\n", "").replace(" ", "").split("|")
x = list(filter(lambda a: a != '', x))
for i in range(0, len(x), 7):
print(x[i+1])
def get_question(self): # while this method is not exposed
return "what is the airspeed velocity of an unladen swallow?"
if __name__ == "__main__":
from rpyc.utils.server import ThreadedServer
t = ThreadedServer(MyService, port = 10000)
t.start()
\ No newline at end of file
pip-3.2 install --index-url=https://pypi.python.org/simple/ netifaces
#pip-3.2 install --index-url=https://pypi.python.org/simple/ netifaces
python3 client.py
pip-3.2 install --index-url=https://pypi.python.org/simple/ netifaces
#pip-3.2 install --index-url=https://pypi.python.org/simple/ netifaces
python3 client.py
import socket
import struct
import sys
import netifaces
import signal
import sys
is_running = True
sock = None
def exit(signal, frame):
is_running = False
sock.close()
sys.exit(0)
def chooseInterface():
interfaces = netifaces.interfaces()
def printInterfaces():
print('Indique a interface de captura:')
for i in range(len(interfaces)):
print (i+1, '-', interfaces[i])
if len(interfaces) == 1: #user has just 1 interface and any
return interfaces[0]
else:
printInterfaces()
inputValue = input('Numero da interface: ')
if int(inputValue)-1 not in range(len(interfaces)):
raise Exception('numero de interface invalida')
inputValue = interfaces[int(inputValue)-1]
return inputValue
if not hasattr(socket, 'SO_BINDTODEVICE'):
socket.SO_BINDTODEVICE = 25
signal.signal(signal.SIGINT, exit)
signal.signal(signal.SIGTERM, exit)
multicast_group = '224.12.12.12'
server_address = ('', 10000)
# Create the socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Bind to the server address
sock.bind(server_address)
#interface_name = input("interface name: ")
interface_name = chooseInterface()
ip_interface = netifaces.ifaddresses(interface_name)[netifaces.AF_INET][0]['addr']
# Tell the operating system to add the socket to the multicast group
# on all interfaces.
group = socket.inet_aton(multicast_group)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP,
socket.inet_aton(multicast_group) + socket.inet_aton(ip_interface))
#sock.setsockopt(socket.SOL_SOCKET, socket.SO_BINDTODEVICE, str(interface_name + "\0").encode('utf-8'))
# Receive/respond loop
while is_running:
#print >>sys.stderr, '\nwaiting to receive message'
data, address = sock.recvfrom(10240)
print(data.decode("utf-8"))
#print >>sys.stderr, 'received %s bytes from %s' % (len(data), address)
#print >>sys.stderr, data
#print >>sys.stderr, 'sending acknowledgement to', address
#sock.sendto('ack', address)
import socket
import struct
import sys
import netifaces
import traceback
import signal
is_running = True
sock = None
def exit(signal, frame):
is_running = False
sock.close()
sys.exit(0)
def chooseInterface():
interfaces = netifaces.interfaces()
def printInterfaces():
print('Indique a interface de captura:')
for i in range(len(interfaces)):
print (i+1, '-', interfaces[i])
if len(interfaces) == 1: #user has just 1 interface and any
return interfaces[0]
else:
printInterfaces()
inputValue = input('Numero da interface: ')
if int(inputValue)-1 not in range(len(interfaces)):
raise Exception('numero de interface invalida')
inputValue = interfaces[int(inputValue)-1]
return inputValue
signal.signal(signal.SIGINT, exit)
signal.signal(signal.SIGTERM, exit)
multicast_group = ('224.12.12.12', 10000)
# Create the datagram socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Set the time-to-live for messages to 1 so they do not go past the
# local network segment.
ttl = struct.pack('b', 12)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
interface_name = chooseInterface()
ip_interface = netifaces.ifaddresses(interface_name)[netifaces.AF_INET][0]['addr']
sock.bind((ip_interface, 10000))
try:
# Look for responses from all recipients
while is_running:
input_msg = input('msg --> ')
try:
sock.sendto(input_msg.encode("utf-8"), multicast_group)
except:
traceback.print_exc()
continue
#print >>sys.stderr, 'received "%s" from %s' % (data, server)
finally:
#print >>sys.stderr, 'closing socket'
sock.close()
......@@ -39,7 +39,7 @@ switch1[1]=switchnetwork1
switch1[2]=switchnetwork2
switch1[3]=switchnetwork3
switch1[4]=switchnetwork4
switch1[5]=client2
switch1[5]=log_server
switch1[mem]=256
......@@ -55,8 +55,8 @@ client0[mem]=256
client1[0]=client1
client1[mem]=256
client2[0]=client2
client2[mem]=256
log_server[0]=log_server
log_server[mem]=256
......@@ -5,7 +5,7 @@ router4: router1
switch1: router2 router3 router4
router5: switch1
router6: switch1
client2: switch1
log_server: switch1
client0: router5
client1: router6
......@@ -3,14 +3,39 @@ import logging
import logging.handlers
import socketserver
import struct
from TestAssert import Test1, Test2, Test3
from threading import Lock
from TestAssert import CustomFilter, Test1, Test2, Test3
import sys
import threading
from queue import Queue
class CustomFilter(logging.Filter):
def filter(self, record):
return record.name in ("pim.KernelEntry.DownstreamInterface.Assert", "pim.KernelEntry.UpstreamInterface.Assert", "pim.KernelInterface")
q = Queue()
def worker():
while True:
item = q.get()
if item is None:
break
logger = logging.getLogger('my_logger')
logger.handle(item)
q.task_done()
class TestHandler(logging.StreamHandler):
currentTest = Test1()
currentTest.print_test()
nextTests = [Test2(), Test3()]
main = None
def emit(self, record):
super().emit(record)
if TestHandler.currentTest and TestHandler.currentTest.test(record):
if len(TestHandler.nextTests) > 0:
TestHandler.currentTest = TestHandler.nextTests.pop(0)
TestHandler.currentTest.print_test()
else:
TestHandler.currentTest = None
TestHandler.main.abort = True
class LogRecordStreamHandler(socketserver.StreamRequestHandler):
"""Handler for a streaming logging request.
......@@ -18,11 +43,6 @@ class LogRecordStreamHandler(socketserver.StreamRequestHandler):
This basically logs the record using whatever logging policy is
configured locally.
"""
currentTest = Test1()
currentTest.print_test()
nextTests = [Test2(), Test3()]
lock = Lock()
main = None
def handle(self):
"""
......@@ -30,7 +50,6 @@ class LogRecordStreamHandler(socketserver.StreamRequestHandler):
followed by the LogRecord in pickle format. Logs the record
according to whatever policy is configured locally.
"""
#logging.FileHandler('server.log').setLevel(logging.DEBUG)
while True:
chunk = self.connection.recv(4)
if len(chunk) < 4:
......@@ -41,37 +60,11 @@ class LogRecordStreamHandler(socketserver.StreamRequestHandler):
chunk = chunk + self.connection.recv(slen - len(chunk))
obj = self.unPickle(chunk)
record = logging.makeLogRecord(obj)
self.handleLogRecord(record)
q.put(item=record)
def unPickle(self, data):
return pickle.loads(data)
def handleLogRecord(self, record):
# if a name is specified, we use the named logger rather than the one
# implied by the record.
if self.server.logname is not None:
name = self.server.logname
else:
name = record.name
logger = logging.getLogger(name)
logger.addFilter(CustomFilter())
# N.B. EVERY record gets logged. This is because Logger.handle
# is normally called AFTER logger-level filtering. If you want
# to do filtering, do it at the client end to save wasting
# cycles and network bandwidth!
#if record.routername == "R2":
logger.handle(record)
with LogRecordStreamHandler.lock:
if LogRecordStreamHandler.currentTest and record.routername in ["R2","R3","R4","R5","R6"] and record.name in ("pim.KernelEntry.DownstreamInterface.Assert", "pim.KernelEntry.UpstreamInterface.Assert") and LogRecordStreamHandler.currentTest.test(record):
if len(LogRecordStreamHandler.nextTests) > 0:
LogRecordStreamHandler.currentTest = LogRecordStreamHandler.nextTests.pop(0)
LogRecordStreamHandler.currentTest.print_test()
else:
LogRecordStreamHandler.currentTest = None
LogRecordStreamHandler.main.abort = True
class LogRecordSocketReceiver(socketserver.ThreadingTCPServer):
"""
......@@ -102,10 +95,15 @@ class LogRecordSocketReceiver(socketserver.ThreadingTCPServer):
def main():
logging.basicConfig(
format='%(name)-50s %(levelname)-8s %(tree)-35s %(vif)-2s %(interfacename)-5s %(routername)-2s %(message)s',
)
#filename='example.log')
handler = TestHandler(sys.stdout)
formatter = logging.Formatter('%(name)-50s %(levelname)-8s %(tree)-35s %(vif)-2s %(interfacename)-5s %(routername)-2s %(message)s')
handler.setFormatter(formatter)
logging.getLogger('my_logger').addHandler(handler)
logging.getLogger('my_logger').addFilter(CustomFilter())
t = threading.Thread(target=worker)
t.start()
tcpserver = LogRecordSocketReceiver(host='10.5.5.100')
print('About to start TCP server...')
tcpserver.serve_until_stopped()
......
import logging
from abc import ABCMeta
class ContextFilter(logging.Filter):
"""
This is a filter which injects contextual information into the log.
Rather than use actual contextual information, we just use random
data in this demo.
"""
def __init__(self):
super().__init__()
class CustomFilter(logging.Filter):
def filter(self, record):
return record.routername in ["R2","R3","R4","R5","R6"]
return record.name in ("pim.KernelEntry.DownstreamInterface.Assert", "pim.KernelEntry.UpstreamInterface.Assert", "pim.KernelInterface") and \
record.routername in ["R1", "R2", "R3", "R4", "R5", "R6"]
class Test():
......
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
#pip-3.2 install --index-url=https://pypi.python.org/simple/ -r requirements.txt
python3 Run.py -stop
python3 Run.py -start
......
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
#pip-3.2 install --index-url=https://pypi.python.org/simple/ -r requirements.txt
python3 Run.py -stop
python3 Run.py -start
......
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
#pip-3.2 install --index-url=https://pypi.python.org/simple/ -r requirements.txt
python3 Run.py -stop
python3 Run.py -start
......
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
#pip-3.2 install --index-url=https://pypi.python.org/simple/ -r requirements.txt
python3 Run.py -stop
python3 Run.py -start
......
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
#pip-3.2 install --index-url=https://pypi.python.org/simple/ -r requirements.txt
python3 Run.py -stop
python3 Run.py -start
......
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
#pip-3.2 install --index-url=https://pypi.python.org/simple/ -r requirements.txt
python3 Run.py -stop
python3 Run.py -start
......
pip-3.2 install --index-url=https://pypi.python.org/simple/ netifaces
#pip-3.2 install --index-url=https://pypi.python.org/simple/ netifaces
python3 server.py
tcpdump -i any -w /hosthome/Desktop/assert_capture.pcap
tcpdump -i br0 -Q in -w /hosthome/Desktop/assert_capture.pcap
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