def __init__(self, port=9000, log_level=255, encoder: ExtendedNdnTlvEncoder = None, interfaces: List[BaseInterface] = None): # debug level logger = Logger("ICNForwarder", log_level) # packet encoder if encoder is None: self.encoder = () else: encoder.set_log_level(log_level) self.encoder = encoder # setup data structures synced_data_struct_factory = PiCNSyncDataStructFactory() synced_data_struct_factory.register("cs", ContentStoreMemoryExact) synced_data_struct_factory.register( "fib", ForwardingInformationBaseMemoryPrefix) synced_data_struct_factory.register("pit", PendingInterstTableMemoryExact) synced_data_struct_factory.register("face_id_table", FaceIDDict) synced_data_struct_factory.create_manager() cs = synced_data_struct_factory.manager.cs() fib = synced_data_struct_factory.manager.fib() pit = synced_data_struct_factory.manager.pit(pit_timeout=60) face_id_table = synced_data_struct_factory.manager.face_id_table() # default interface if interfaces is not None: self.interfaces = interfaces mgmt_port = port else: interfaces = [UDP4Interface(port)] mgmt_port = interfaces[0].get_port() # initialize layers self.link_layer = BasicLinkLayer(interfaces, face_id_table, log_level=log_level) self.packet_encoding_layer = HeartbeatPacketEncodingLayer( self.encoder, log_level=log_level) self.icn_layer = HeartbeatNetworkLayer(log_level=log_level) self.lstack: LayerStack = LayerStack( [self.icn_layer, self.packet_encoding_layer, self.link_layer]) self.icn_layer.cs = cs self.icn_layer.fib = fib self.icn_layer.pit = pit # routing self.routing = BasicRouting( self.icn_layer.pit, None, log_level=log_level) # TODO NOT IMPLEMENTED YET # mgmt self.mgmt = Mgmt(cs, fib, pit, self.link_layer, mgmt_port, self.stop_forwarder, log_level=log_level)
class test_BasicLinkLayer(unittest.TestCase): """Test the Basic Link Layer""" def setUp(self): self.udp4interface1 = UDP4Interface(0) synced_data_struct_factory1 = PiCNSyncDataStructFactory() synced_data_struct_factory1.register("faceidtable", FaceIDDict) synced_data_struct_factory1.create_manager() self.faceidtable1 = synced_data_struct_factory1.manager.faceidtable() self.linklayer1 = BasicLinkLayer([self.udp4interface1], self.faceidtable1) self.linklayer1.queue_to_higher = multiprocessing.Queue() self.linklayer1.queue_from_higher = multiprocessing.Queue() self.udp4interface2 = UDP4Interface(0) synced_data_struct_factory2 = PiCNSyncDataStructFactory() synced_data_struct_factory2.register("faceidtable", FaceIDDict) synced_data_struct_factory2.create_manager() self.faceidtable2 = synced_data_struct_factory2.manager.faceidtable() self.linklayer2 = BasicLinkLayer([self.udp4interface2], self.faceidtable2) self.linklayer2.queue_to_higher = multiprocessing.Queue() self.linklayer2.queue_from_higher = multiprocessing.Queue() self.udp4interface3 = UDP4Interface(0) synced_data_struct_factory3 = PiCNSyncDataStructFactory() synced_data_struct_factory3.register("faceidtable", FaceIDDict) synced_data_struct_factory3.create_manager() self.faceidtable3 = synced_data_struct_factory3.manager.faceidtable() self.linklayer3 = BasicLinkLayer([self.udp4interface3], self.faceidtable3) self.linklayer3.queue_to_higher = multiprocessing.Queue() self.linklayer3.queue_from_higher = multiprocessing.Queue() self.testSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.testSock.bind(("0.0.0.0", 0)) self.test_port = self.testSock.getsockname()[1] def tearDown(self): self.udp4interface1.close() self.udp4interface2.close() self.linklayer1.stop_process() self.linklayer2.stop_process() def test_receiving_a_packet(self): """Test if a packet is received correctly""" self.linklayer1.start_process() self.testSock.sendto("HelloWorld".encode(), ("127.0.0.1", self.udp4interface1.get_port())) data = self.linklayer1.queue_to_higher.get(timeout=2.0) faceid = data[0] content = data[1].decode() self.assertEqual("HelloWorld", content) self.assertEqual(self.linklayer1.faceidtable.get_num_entries(), 1) self.assertEqual(self.linklayer1.faceidtable.get_address_info(0).address[1], self.test_port) self.assertEqual(self.linklayer1.faceidtable.get_address_info(0).interface_id, 0) def test_sending_a_packet(self): """Test if a packet is sent correctly""" self.linklayer1.start_process() fid = self.linklayer1.faceidtable.get_or_create_faceid(AddressInfo(("127.0.0.1", self.test_port), self.linklayer1.interfaces.index( self.udp4interface1))) self.linklayer1.queue_from_higher.put([fid, "HelloWorld".encode()]) data, addr = self.testSock.recvfrom(8192) self.assertEqual(data.decode(), "HelloWorld") def test_sending_and_receiving_a_packet(self): """Test sending/receiving in a single case""" self.linklayer1.start_process() self.linklayer2.start_process() fid = self.linklayer1.faceidtable.get_or_create_faceid(AddressInfo(("127.0.0.1", self.udp4interface2.get_port()), self.linklayer1.interfaces.index( self.udp4interface1))) self.linklayer1.queue_from_higher.put([fid, "HelloWorld".encode()]) data = self.linklayer2.queue_to_higher.get(timeout=2.0) faceid = data[0] packet = data[1] self.assertEqual(faceid, 0) self.assertEqual(packet.decode(), "HelloWorld") def test_sending_and_receiving_packets(self): """Test sending/receiving many packets in a single case""" self.linklayer1.start_process() self.linklayer2.start_process() fid1 = self.linklayer1.faceidtable.get_or_create_faceid(AddressInfo(("127.0.0.1", self.udp4interface2.get_port()), self.linklayer1.interfaces.index( self.udp4interface1))) self.linklayer1.start_process() self.linklayer2.start_process() fid2 = self.linklayer2.faceidtable.get_or_create_faceid(AddressInfo(("127.0.0.1", self.udp4interface1.get_port()), self.linklayer2.interfaces.index( self.udp4interface2))) for i in range(1,int(1e3)): str1 = "HelloWorld" + str(i) str2 = "GoodBye" + str(i) self.linklayer1.queue_from_higher.put([fid1, str1.encode()]) self.linklayer2.queue_from_higher.put([fid2, str2.encode()]) d2 = self.linklayer2.queue_to_higher.get(timeout=2.0) d1 = self.linklayer1.queue_to_higher.get(timeout=2.0) packet2 = d1[1].decode() packet1 = d2[1].decode() self.assertEqual(packet1, str1) self.assertEqual(packet2, str2) for i in range(1, int(1e3)): str1 = "HelloWorld" + str(i) str2 = "GoodBye" + str(i) self.linklayer1.queue_from_higher.put([fid1, str1.encode()]) self.linklayer2.queue_from_higher.put([fid2, str2.encode()]) d1 = self.linklayer1.queue_to_higher.get(timeout=2.0) d2 = self.linklayer2.queue_to_higher.get(timeout=2.0) packet2 = d1[1].decode() packet1 = d2[1].decode() self.assertEqual(packet1, str1) self.assertEqual(packet2, str2) def test_sending_and_receiving_pacets_three_nodes(self): """Testing sending/receiving packets with three nodes""" self.linklayer1.start_process() self.linklayer2.start_process() self.linklayer3.start_process() fid1_2 = self.linklayer1.faceidtable.get_or_create_faceid(AddressInfo(("127.0.0.1", self.udp4interface2.get_port()), self.linklayer1.interfaces.index(self.udp4interface1))) fid1_3 = self.linklayer1.faceidtable.get_or_create_faceid(AddressInfo(("127.0.0.1", self.udp4interface3.get_port()), self.linklayer1.interfaces.index(self.udp4interface1))) fid2_1 = self.linklayer2.faceidtable.get_or_create_faceid(AddressInfo(("127.0.0.1", self.udp4interface1.get_port()), self.linklayer2.interfaces.index(self.udp4interface2))) fid3_1 = self.linklayer3.faceidtable.get_or_create_faceid(AddressInfo(("127.0.0.1", self.udp4interface1.get_port()), self.linklayer3.interfaces.index(self.udp4interface3))) fid3_2 = self.linklayer3.faceidtable.get_or_create_faceid(AddressInfo(("127.0.0.1", self.udp4interface2.get_port()), self.linklayer3.interfaces.index(self.udp4interface3))) for i in range(1, 100): str1 = "Node1" + str(i) str2 = "Node2" + str(i) str3 = "Node3" + str(i) # Node 1 ---> Node 2 self.linklayer1.queue_from_higher.put([fid1_2, str1.encode()]) try: data1_2 = self.linklayer2.queue_to_higher.get(timeout=2.0) except: self.fail() # Node 1 ---> Node 3 self.linklayer1.queue_from_higher.put([fid1_3, str1.encode()]) try: data1_3 = self.linklayer3.queue_to_higher.get(timeout=2.0) except: self.fail() # Node 2 ---> Node 1 self.linklayer2.queue_from_higher.put([fid2_1, str2.encode()]) try: data2_1 = self.linklayer1.queue_to_higher.get(timeout=2.0) except: self.fail() # Node 3 ---> Node 1 self.linklayer3.queue_from_higher.put([fid3_1, str3.encode()]) try: data3_1 = self.linklayer1.queue_to_higher.get(timeout=2.0) except: self.fail() # Node 3 ---> Node 2 self.linklayer3.queue_from_higher.put([fid3_2, str3.encode()]) try: data3_2 = self.linklayer2.queue_to_higher.get(timeout=2.0) except: self.fail() self.assertEqual(data1_2[1].decode(), str1) self.assertEqual(data1_3[1].decode(), str1) self.assertEqual(data2_1[1].decode(), str2) self.assertEqual(data3_1[1].decode(), str3) self.assertEqual(data3_2[1].decode(), str3)
def __init__(self, foldername: Optional[str], prefix: Name, port=9000, log_level=255, encoder: BasicEncoder = None, autoconfig: bool = False, autoconfig_routed: bool = False, interfaces: List[BaseInterface] = None, use_thunks=False): """ :param foldername: If None, use an in-memory repository. Else, use a file system repository. """ logger = Logger("ICNRepo", log_level) logger.info("Start PiCN Data Repository") # packet encoder if encoder is None: self.encoder = SimpleStringEncoder(log_level=log_level) else: encoder.set_log_level(log_level) self.encoder = encoder # chunkifyer self.chunkifyer = SimpleContentChunkifyer() # repo manager = multiprocessing.Manager() if foldername is None: self.repo: BaseRepository = SimpleMemoryRepository( prefix, manager, logger) else: self.repo: BaseRepository = SimpleFileSystemRepository( foldername, prefix, manager, logger) # initialize layers synced_data_struct_factory = PiCNSyncDataStructFactory() synced_data_struct_factory.register("faceidtable", FaceIDDict) if use_thunks: synced_data_struct_factory.register("thunktable", ThunkList) synced_data_struct_factory.register("plantable", PlanTable) synced_data_struct_factory.create_manager() faceidtable = synced_data_struct_factory.manager.faceidtable() if use_thunks: self.parser = DefaultNFNParser() thunktable = synced_data_struct_factory.manager.thunktable() plantable = synced_data_struct_factory.manager.plantable( self.parser) if interfaces is not None: self.interfaces = interfaces mgmt_port = port else: interfaces = [UDP4Interface(port)] mgmt_port = interfaces[0].get_port() self.linklayer = BasicLinkLayer(interfaces, faceidtable, log_level=log_level) self.packetencodinglayer = BasicPacketEncodingLayer( self.encoder, log_level=log_level) self.chunklayer = BasicChunkLayer(self.chunkifyer, log_level=log_level) self.repolayer = BasicRepositoryLayer(self.repo, log_level=log_level) if use_thunks: self.thunklayer = BasicThunkLayer(None, None, None, faceidtable, thunktable, plantable, self.parser, self.repo, log_level=log_level) logger.info("Using Thunks") if use_thunks: self.lstack: LayerStack = LayerStack([ self.repolayer, self.chunklayer, self.thunklayer, self.packetencodinglayer, self.linklayer ]) else: self.lstack: LayerStack = LayerStack([ self.repolayer, self.chunklayer, self.packetencodinglayer, self.linklayer ]) if autoconfig: self.autoconfiglayer = AutoconfigRepoLayer( name=prefix.string_components[-1], addr='127.0.0.1', linklayer=self.linklayer, repo=self.repo, register_global=autoconfig_routed, log_level=log_level) self.lstack.insert(self.autoconfiglayer, below_of=self.chunklayer) # mgmt self.mgmt = Mgmt(None, None, None, self.linklayer, mgmt_port, self.start_repo, repo_path=foldername, repo_prfx=prefix, log_level=log_level)
class test_Mgmt(unittest.TestCase): def setUp(self): synced_data_struct_factory = PiCNSyncDataStructFactory() synced_data_struct_factory.register("cs", ContentStoreMemoryExact) synced_data_struct_factory.register( "fib", ForwardingInformationBaseMemoryPrefix) synced_data_struct_factory.register("pit", PendingInterstTableMemoryExact) synced_data_struct_factory.register("faceidtable", FaceIDDict) synced_data_struct_factory.create_manager() cs = synced_data_struct_factory.manager.cs() fib = synced_data_struct_factory.manager.fib() pit = synced_data_struct_factory.manager.pit() faceidtable = synced_data_struct_factory.manager.faceidtable() interface = UDP4Interface(0) self.linklayer = BasicLinkLayer([interface], faceidtable) self.linklayerport = self.linklayer.interfaces[0].get_port() self.q1 = multiprocessing.Queue() self.linklayer.queue_from_higher = self.q1 self.mgmt = Mgmt(cs, fib, pit, self.linklayer, self.linklayerport) self.testMgmtSock1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.testMgmtSock2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.testMgmtSock3 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.mgmt_client = MgmtClient(self.linklayerport) def tearDown(self): self.linklayer.stop_process() self.mgmt.stop_process() self.testMgmtSock1.close() self.testMgmtSock2.close() self.testMgmtSock3.close() def test_mgmt_new_face(self): """Test the mgmt interace to create a new face""" self.linklayer.start_process() self.mgmt.start_process() self.testMgmtSock1.connect(("127.0.0.1", self.linklayerport)) self.testMgmtSock1.send( "GET /linklayer/newface/127.0.0.1:9000:0 HTTP/1.1\r\n\r\n".encode( )) data = self.testMgmtSock1.recv(1024) self.testMgmtSock1.close() self.assertEqual( data.decode(), "HTTP/1.1 200 OK \r\n Content-Type: text/html \r\n\r\n newface OK:0\r\n" ) self.assertEqual(self.linklayer.faceidtable.get_num_entries(), 1) self.assertEqual( self.linklayer.faceidtable.get_face_id( AddressInfo(("127.0.0.1", 9000), 0)), 0) self.assertEqual(self.linklayer.faceidtable.get_address_info(0), AddressInfo(("127.0.0.1", 9000), 0)) def test_mgmt_multiple_new_face(self): """Test the mgmt interace to create multiple new faces with deduplication""" self.linklayer.start_process() self.mgmt.start_process() self.testMgmtSock1.connect(("127.0.0.1", self.linklayerport)) self.testMgmtSock1.send( "GET /linklayer/newface/127.0.0.1:9000:0 HTTP/1.1\r\n\r\n".encode( )) data = self.testMgmtSock1.recv(1024) self.testMgmtSock1.close() self.assertEqual( data.decode(), "HTTP/1.1 200 OK \r\n Content-Type: text/html \r\n\r\n newface OK:0\r\n" ) self.testMgmtSock2.connect(("127.0.0.1", self.linklayerport)) self.testMgmtSock2.send( "GET /linklayer/newface/127.0.0.1:8000:0 HTTP/1.1\r\n\r\n".encode( )) data = self.testMgmtSock2.recv(1024) self.testMgmtSock2.close() self.assertEqual( data.decode(), "HTTP/1.1 200 OK \r\n Content-Type: text/html \r\n\r\n newface OK:1\r\n" ) self.testMgmtSock3.connect(("127.0.0.1", self.linklayerport)) self.testMgmtSock3.send( "GET /linklayer/newface/127.0.0.1:9000:0 HTTP/1.1\r\n\r\n".encode( )) data = self.testMgmtSock3.recv(1024) self.testMgmtSock3.close() self.assertEqual( data.decode(), "HTTP/1.1 200 OK \r\n Content-Type: text/html \r\n\r\n newface OK:0\r\n" ) self.assertEqual(self.linklayer.faceidtable.get_num_entries(), 2) self.assertEqual( self.linklayer.faceidtable.get_face_id( AddressInfo(("127.0.0.1", 9000), 0)), 0) self.assertEqual( self.linklayer.faceidtable.get_face_id( AddressInfo(("127.0.0.1", 8000), 0)), 1) def test_mgmt_add_forwaring_rule(self): """Test adding Forwarding rules""" self.linklayer.start_process() self.mgmt.start_process() self.testMgmtSock1.connect(("127.0.0.1", self.linklayerport)) self.testMgmtSock1.send( "GET /icnlayer/newforwardingrule/%2Ftest%2Fdata:2 HTTP/1.1\r\n\r\n" .encode()) data = self.testMgmtSock1.recv(1024) self.testMgmtSock1.close() self.assertEqual( data.decode(), "HTTP/1.1 200 OK \r\n Content-Type: text/html \r\n\r\n newforwardingrule OK:2\r\n" ) time.sleep(1) self.testMgmtSock2.connect(("127.0.0.1", self.linklayerport)) self.testMgmtSock2.send( "GET /icnlayer/newforwardingrule/%2Fdata%2Ftest:3 HTTP/1.1\r\n\r\n" .encode()) data = self.testMgmtSock2.recv(1024) self.testMgmtSock2.close() self.assertEqual( data.decode(), "HTTP/1.1 200 OK \r\n Content-Type: text/html \r\n\r\n newforwardingrule OK:3\r\n" ) self.assertEqual( self.mgmt.fib.find_fib_entry(Name("/test/data")).faceid, 2) self.assertEqual( self.mgmt.fib.find_fib_entry(Name("/data/test")).faceid, 3) def test_mgmt_add_content(self): """Test adding content""" self.linklayer.start_process() self.mgmt.start_process() self.testMgmtSock1.connect(("127.0.0.1", self.linklayerport)) self.testMgmtSock1.send( "GET /icnlayer/newcontent/%2Ftest%2Fdata:HelloWorld HTTP/1.1\r\n\r\n" .encode()) data = self.testMgmtSock1.recv(1024) self.testMgmtSock1.close() self.assertEqual( data.decode(), "HTTP/1.1 200 OK \r\n Content-Type: text/html \r\n\r\n newcontent OK\r\n" ) time.sleep(1) self.testMgmtSock2.connect(("127.0.0.1", self.linklayerport)) self.testMgmtSock2.send( "GET /icnlayer/newcontent/%2Fdata%2Ftest:GoodBye HTTP/1.1\r\n\r\n". encode()) data = self.testMgmtSock2.recv(1024) self.testMgmtSock2.close() self.assertEqual( data.decode(), "HTTP/1.1 200 OK \r\n Content-Type: text/html \r\n\r\n newcontent OK\r\n" ) self.assertEqual( self.mgmt.cs.find_content_object( Name("/test/data")).content.content, "HelloWorld") self.assertEqual( self.mgmt.cs.find_content_object( Name("/data/test")).content.content, "GoodBye") def test_add_face_mgmt_client(self): """Test adding a face using the mgmtclient""" self.linklayer.start_process() self.mgmt.start_process() data = self.mgmt_client.add_face("127.0.0.1", 9000, 0) self.assertEqual( data, "HTTP/1.1 200 OK \r\n Content-Type: text/html \r\n\r\n newface OK:0\r\n" ) self.assertEqual(self.linklayer.faceidtable.get_num_entries(), 1) self.assertEqual(self.linklayer.faceidtable.get_address_info(0), AddressInfo(("127.0.0.1", 9000), 0)) self.assertEqual( self.linklayer.faceidtable.get_face_id( AddressInfo(("127.0.0.1", 9000), 0)), 0) def test_add_forwarding_rule_mgmt_client(self): """Test adding forwarding rule using MgmtClient""" self.linklayer.start_process() self.mgmt.start_process() data = self.mgmt_client.add_forwarding_rule(Name("/test/data"), 2) self.assertEqual( "HTTP/1.1 200 OK \r\n Content-Type: text/html \r\n\r\n newforwardingrule OK:2\r\n", data) time.sleep(1) data = self.mgmt_client.add_forwarding_rule(Name("/data/test"), 3) self.assertEqual( data, "HTTP/1.1 200 OK \r\n Content-Type: text/html \r\n\r\n newforwardingrule OK:3\r\n" ) self.assertEqual( self.mgmt.fib.find_fib_entry(Name("/test/data")).faceid, 2) self.assertEqual( self.mgmt.fib.find_fib_entry(Name("/data/test")).faceid, 3) def test_mgmt_add_content_mgmt_client(self): """Test adding content using MgmtClient""" self.linklayer.start_process() self.mgmt.start_process() data = self.mgmt_client.add_new_content(Name("/test/data"), "HelloWorld") self.assertEqual( data, "HTTP/1.1 200 OK \r\n Content-Type: text/html \r\n\r\n newcontent OK\r\n" ) time.sleep(1) data = self.mgmt_client.add_new_content(Name("/data/test"), "GoodBye") self.assertEqual( data, "HTTP/1.1 200 OK \r\n Content-Type: text/html \r\n\r\n newcontent OK\r\n" ) self.assertEqual( self.mgmt.cs.find_content_object( Name("/test/data")).content.content, "HelloWorld") self.assertEqual( self.mgmt.cs.find_content_object( Name("/data/test")).content.content, "GoodBye") def test_mgmt_shutdown_mgmt_client(self): """Test adding content""" self.linklayer.start_process() self.mgmt.start_process() data = self.mgmt_client.shutdown() self.assertEqual( data, "HTTP/1.1 200 OK \r\n Content-Type: text/html \r\n\r\n shutdown\r\n" )