class cases_ICNForwarder(object): """Test the ICN Forwarder""" @abc.abstractmethod def get_encoder(self): """returns the encoder to be used """ def setUp(self): self.encoder = self.get_encoder() self.forwarder1 = ICNForwarder(0, encoder=self.get_encoder(), log_level=255) self.forwarder2 = ICNForwarder(0, encoder=self.get_encoder(), log_level=255) self.forwarder1_port = self.forwarder1.linklayer.interfaces[ 0].get_port() self.forwarder2_port = self.forwarder2.linklayer.interfaces[ 0].get_port() self.testSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.testSock.bind(("0.0.0.0", 0)) def tearDown(self): self.testSock.close() self.forwarder1.stop_forwarder() self.forwarder2.stop_forwarder() pass def test_ICNForwarder_simple_find_content_one_node(self): """Test a simple forwarding scenario, getting content from a Node""" self.forwarder1.start_forwarder() # new content testMgmtSock1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) testMgmtSock1.connect(("127.0.0.1", self.forwarder1_port)) testMgmtSock1.send( "GET /icnlayer/newcontent/%2Ftest%2Fdata%2Fobject:HelloWorld HTTP/1.1\r\n\r\n" .encode()) data = testMgmtSock1.recv(1024) testMgmtSock1.close() time.sleep(3) self.assertEqual( data.decode(), "HTTP/1.1 200 OK \r\n Content-Type: text/html \r\n\r\n newcontent OK\r\n" ) #create test content name = Name("/test/data/object") test_content = Content(name, content="HelloWorld") cs_fwd1 = self.forwarder1.icnlayer.cs self.assertEqual( cs_fwd1.find_content_object(name).content, test_content) #create interest interest = Interest("/test/data/object") encoded_interest = self.encoder.encode(interest) #send interest self.testSock.sendto(encoded_interest, ("127.0.0.1", self.forwarder1_port)) #receive content encoded_content, addr = self.testSock.recvfrom(8192) content = self.encoder.decode(encoded_content) self.assertEqual(content, test_content) def test_ICNForwarder_simple_find_content_two_nodes(self): """Test a simple forwarding scenario with one additional node forwarding the data""" self.forwarder1.start_forwarder() self.forwarder2.start_forwarder() #client <---> node1 <---> node2 #create a face testMgmtSock1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) testMgmtSock1.connect(("127.0.0.1", self.forwarder1_port)) port_to = self.forwarder2_port testMgmtSock1.send(("GET /linklayer/newface/127.0.0.1:" + str(port_to) + ":0 HTTP/1.1\r\n\r\n").encode()) data = testMgmtSock1.recv(1024) 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.forwarder1.linklayer.faceidtable.get_face_id( AddressInfo(("127.0.0.1", self.forwarder2_port), 0)), 0) #register a prefix testMgmtSock2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) testMgmtSock2.connect(("127.0.0.1", self.forwarder1_port)) testMgmtSock2.send( "GET /icnlayer/newforwardingrule/%2Ftest%2Fdata:0 HTTP/1.1\r\n\r\n" .encode()) data = testMgmtSock2.recv(1024) testMgmtSock2.close() self.assertEqual( data.decode(), "HTTP/1.1 200 OK \r\n Content-Type: text/html \r\n\r\n newforwardingrule OK:0\r\n" ) self.assertEqual( self.forwarder1.icnlayer.fib.find_fib_entry( Name("/test/data")).faceid, [0]) # new content testMgmtSock3 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) testMgmtSock3.connect(("127.0.0.1", self.forwarder2_port)) testMgmtSock3.send( "GET /icnlayer/newcontent/%2Ftest%2Fdata%2Fobject:HelloWorld HTTP/1.1\r\n\r\n" .encode()) data = testMgmtSock3.recv(1024) testMgmtSock3.close() self.assertEqual( data.decode(), "HTTP/1.1 200 OK \r\n Content-Type: text/html \r\n\r\n newcontent OK\r\n" ) #create test content name = Name("/test/data/object") test_content = Content(name, content="HelloWorld") cs_fwd2 = self.forwarder2.icnlayer.cs self.assertEqual( cs_fwd2.find_content_object(name).content, test_content) #create interest interest = Interest("/test/data/object") encoded_interest = self.encoder.encode(interest) #send interest self.testSock.sendto(encoded_interest, ("127.0.0.1", self.forwarder1_port)) #receive content encoded_content, addr = self.testSock.recvfrom(8192) content = self.encoder.decode(encoded_content) self.assertEqual(content, test_content) time.sleep(2) self.assertEqual(self.forwarder1.icnlayer.pit.get_container_size(), 0)
class TestDisconnections(unittest.TestCase): """Run the data-offloading simulation""" def setUp(self): self.encoder_type = SimpleStringEncoder() self.simulation_bus = SimulationBus(packetencoder=self.encoder_type) chunk_size = 4 self.chunkifyer = SimpleContentChunkifyer(chunk_size) self.car = ICNForwarder( 0, encoder=self.encoder_type, routing=True, interfaces=[self.simulation_bus.add_interface("car")]) self.fetch_tool_car = Fetch( "car", None, 255, self.encoder_type, interfaces=[self.simulation_bus.add_interface("ftcar")]) self.mgmt_client_car = MgmtClient( self.car.mgmt.mgmt_sock.getsockname()[1]) self.rsus = [] self.fetch_tools = [] self.mgmt_clients = [] for i in range(4): self.rsus.append( NFNForwarderData( 0, encoder=self.encoder_type, interfaces=[self.simulation_bus.add_interface(f"rsu{i}")], chunk_size=chunk_size, num_of_forwards=0)) self.fetch_tools.append( Fetch(f"rsu{i}", None, 255, self.encoder_type, interfaces=[self.simulation_bus.add_interface(f"ft{i}") ])) self.rsus[i].nfnlayer.optimizer = EdgeComputingOptimizer( self.rsus[i].icnlayer.cs, self.rsus[i].icnlayer.fib, self.rsus[i].icnlayer.pit, self.rsus[i].linklayer.faceidtable) self.mgmt_clients.append( MgmtClient(self.rsus[i].mgmt.mgmt_sock.getsockname()[1])) self.fetch_tools[i].timeoutpreventionlayer.timeout_interval = 30 def tearDown(self): self.car.stop_forwarder() self.fetch_tool_car.stop_fetch() for rsu in self.rsus: rsu.stop_forwarder() for fetch_tool in self.fetch_tools: fetch_tool.stop_fetch() self.simulation_bus.stop_process() def setup_faces_and_connections(self): self.car.start_forwarder() for rsu in self.rsus: rsu.start_forwarder() self.simulation_bus.start_process() function = "PYTHON\nf\ndef f(a):\n return a + ' World'" # Setup rsu0 self.mgmt_clients[0].add_face("car", None, 0) self.mgmt_clients[0].add_face("rsu1", None, 0) self.mgmt_clients[0].add_forwarding_rule(Name("/car"), [0]) self.mgmt_clients[0].add_forwarding_rule(Name("/nR"), [1]) self.mgmt_clients[0].add_new_content(Name("/rsu/func/f1"), function) # Setup rsu1 self.mgmt_clients[1].add_face("car", None, 0) self.mgmt_clients[1].add_face("rsu0", None, 0) self.mgmt_clients[1].add_face("rsu2", None, 0) self.mgmt_clients[1].add_forwarding_rule(Name("/car"), [0]) self.mgmt_clients[1].add_forwarding_rule(Name("/nL"), [1]) self.mgmt_clients[1].add_forwarding_rule(Name("/nR"), [2]) self.mgmt_clients[1].add_new_content(Name("/rsu/func/f1"), function) # Setup rsu2 self.mgmt_clients[2].add_face("car", None, 0) self.mgmt_clients[2].add_face("rsu1", None, 0) self.mgmt_clients[2].add_face("rsu3", None, 0) self.mgmt_clients[2].add_forwarding_rule(Name("/car"), [0]) self.mgmt_clients[2].add_forwarding_rule(Name("/nL"), [1]) self.mgmt_clients[2].add_forwarding_rule(Name("/nR"), [2]) self.mgmt_clients[2].add_new_content(Name("/rsu/func/f1"), function) # Setup rsu3 self.mgmt_clients[3].add_face("car", None, 0) self.mgmt_clients[3].add_face("rsu2", None, 0) self.mgmt_clients[3].add_forwarding_rule(Name("/car"), [0]) self.mgmt_clients[3].add_forwarding_rule(Name("/nL"), [1]) self.mgmt_clients[3].add_new_content(Name("/rsu/func/f1"), function) # Setup car self.mgmt_client_car.add_face("rsu0", None, 0) self.mgmt_client_car.add_face("rsu1", None, 0) self.mgmt_client_car.add_face("rsu2", None, 0) self.mgmt_client_car.add_forwarding_rule(Name("/rsu"), [0]) self.d = Content(Name("/car/data/test1"), "Test" * 10) self.meta_data, self.data = self.chunkifyer.chunk_data(self.d) for md in self.meta_data[:]: self.car.icnlayer.cs.add_content_object(md) # Only load first 6 chunks to car to simulate car getting out of each while uploading for d in self.data[:5]: self.mgmt_client_car.add_new_content(d.name, d.content) def test_two_disconnections(self): self.setup_faces_and_connections() name = Name("/rsu/func/f1") name += '_(/car/data/test1)' name += "NFN" print("RSU 0 FETCHING") start = time() res0 = self.fetch_tools[0].fetch_data(name, timeout=10) print(res0) sleep(1) print("\n" * 20 + "RSU 1 FETCHING") for d in self.data[5:-2]: self.mgmt_client_car.add_new_content(d.name, d.content) for d in self.data[:5]: self.car.icnlayer.cs.remove_content_object(d.name) res1 = self.fetch_tools[1].fetch_data(name, timeout=10) print(res1) sleep(1) print("\n" * 20 + "RSU 2 FETCHING") for d in self.data[-2:]: self.mgmt_client_car.add_new_content(d.name, d.content) for d in self.data[:-2]: self.car.icnlayer.cs.remove_content_object(d.name) res2 = self.fetch_tools[2].fetch_data(name, timeout=10) print(res2, time() - start) self.assertEqual(self.d.content + " World", res2) def test_skip_two_rsus(self): # Increase the number of forwards for rsu in self.rsus: rsu.chunklayer.set_number_of_forwards(2) self.setup_faces_and_connections() name = Name("/rsu/func/f1") name += '_(/car/data/test1)' name += "NFN" res0 = self.fetch_tools[0].fetch_data(name, timeout=10) print(res0) sleep(1) print("\n" * 20 + "RSU 4 STARTING") for d in self.data[5:]: self.mgmt_client_car.add_new_content(d.name, d.content) for d in self.data[:5]: self.car.icnlayer.cs.remove_content_object(d.name) res1 = self.fetch_tools[3].fetch_data(name, timeout=10) print(res1) self.assertEqual(self.d.content + " World", res1)
simple_interest = Name('/unibas/sim1/trailer.mp4') session_interest = Name('/unibas/sim1/session_connector') simple_response = fetch0.fetch_data(simple_interest, timeout=20) assert simple_response == content, f"The response should be: '{content}'. Got: '{simple_response}' instead." session_response = fetch0.fetch_data(session_interest, timeout=20) assert len( session_response ) == 11, f"The response should be of length 11. Got length {len(session_response)} instead." # Send content from fetch to repo over session. The repo will print out the content on the logger fetch0.send_content((fetch0.get_session_name(Name('/unibas/sim1')), 'Hello, please store my thesis. Thank you.')) # Send content from repo over session. The receive loop will print out the content repo0.repolayer.send_content(content='Test. Test. Test. 1-2-3') # ------------------- # Stop the simulation time.sleep( 1 ) # Be safe and wait for all messages to trickle in before shutting down everything fw0.stop_forwarder() fetch0.stop_fetch() simulation_bus.stop_process() mgmt_repo0.shutdown() mgmt_fw0.shutdown() exit(0)
class ICNSessionSimulation(unittest.TestCase): """Simulate a Scenario where timeout prevention is required""" def setUp(self): self.simulation_bus = SimulationBus( log_level=0) # Use BasicStringEncoder self.icn_repo0 = ICNDataRepository( port=0, prefix=Name('/test/t1'), foldername=None, interfaces=[self.simulation_bus.add_interface('repo0')], log_level=255) # Initialize repository 0 self.icn_repo1 = ICNDataRepositorySession( port=0, prefix=Name('/test/t2'), foldername=None, interfaces=[self.simulation_bus.add_interface('repo1')], log_level=0) # Initialize repository 1 (this one has sessions) self.icn_forwarder0 = ICNForwarder( port=0, log_level=255, interfaces=[self.simulation_bus.add_interface('fw0') ]) # Initialize forwarder 0 self.icn_forwarder1 = ICNForwarder( port=0, log_level=255, interfaces=[self.simulation_bus.add_interface('fw1') ]) # Initialize forwarder 1 self.mgmt_client0 = MgmtClient( self.icn_repo0.mgmt.mgmt_sock.getsockname() [1]) # Mgmt client for repository 0 self.mgmt_client1 = MgmtClient( self.icn_repo1.mgmt.mgmt_sock.getsockname() [1]) # Mgmt client for repository 1 self.mgmt_client2 = MgmtClient( self.icn_forwarder0.mgmt.mgmt_sock.getsockname() [1]) # Mgmt client for forwarder 0 self.mgmt_client3 = MgmtClient( self.icn_forwarder1.mgmt.mgmt_sock.getsockname() [1]) # Mgmt client for forwarder 1 # This is unintuitive. Why does the fetch tool add its own face, but the other components don't? self.fetch0 = Fetch('fw0', None, log_level=255, interfaces=[ self.simulation_bus.add_interface('fetcht0') ]) # Initialize a client (fetch tool) self.fetch1 = FetchSessions( 'fw0', None, log_level=255, interfaces=[self.simulation_bus.add_interface('fetcht1')]) self.icn_repo0.start_repo() self.icn_repo1.start_repo() self.icn_forwarder0.start_forwarder() self.icn_forwarder1.start_forwarder() self.simulation_bus.start_process() time.sleep(1) # Be safe and wait for all processes to start self.mgmt_client2.add_face( 'repo0', None, 0) # Add new interface to forwarder 0, index has to be 0. self.mgmt_client2.add_face( 'fw1', None, 0) # # Add new interface to forwarder 0, index has to be 0. self.mgmt_client2.add_forwarding_rule( Name('/test/t1'), [0]) # Add a forward-rule this prefix to interface with index 0. self.mgmt_client2.add_forwarding_rule( Name('/test/t2'), [1]) # Add a forward-rule this prefix to interface with index 1. self.mgmt_client3.add_face( 'repo1', None, 0) # Add new interface to forwarder 1, index has to be 0. self.mgmt_client3.add_forwarding_rule( Name('/test/t2'), [0]) # Add a forward-rule this prefix to interface with index 0. # Repositories do not need a forwarding rule or an interface. All done in constructor. self.test_content = 'This is just a test for repo0.' self.icn_repo0.repo.add_content( Name('/test/t1/content_object'), self.test_content ) # TODO: Create add_new_content command for DataRepository in ManagementClient print(self.icn_forwarder0.icnlayer.fib) print(self.icn_forwarder1.icnlayer.fib) def tearDown(self): time.sleep( 1 ) # Be safe and wait for all messages to trickle in before shutting down everything self.icn_forwarder0.stop_forwarder() self.icn_forwarder1.stop_forwarder() self.fetch0.stop_fetch() self.fetch1.stop_fetch() self.simulation_bus.stop_process() self.mgmt_client0.shutdown() self.mgmt_client1.shutdown() self.mgmt_client2.shutdown() self.mgmt_client3.shutdown() def test_simple_interest(self): interest = Name( '/test/t1/content_object') # Test routing, no new features. res = self.fetch0.fetch_data(interest, timeout=20) print(f"Return value: {res}") self.assertEqual(self.test_content, res, 'The content matches.') def test_simple_session_initiation(self): interest = Name( "/test/t2/session_connector" ) # Test session connection string. This should return 16bits res = self.fetch1.fetch_data(interest, timeout=20) print(f"Return value : {res}") self.assertEqual(self.icn_repo1.repolayer._pending_sessions[0], self.fetch1._session_keys[0], 'The session keys match.')
class test_RoutingLayerFullStack(unittest.TestCase): def setUp(self): self.f9000 = ICNForwarder(9000, encoder=NdnTlvEncoder(), routing=True, peers=[('127.0.0.1', 9001), ('127.0.0.1', 9002), ('127.0.0.1', 9090)]) self.f9001 = ICNForwarder(9001, encoder=NdnTlvEncoder(), routing=True, peers=[('127.0.0.1', 9000), ('127.0.0.1', 9002), ('127.0.0.1', 9003), ('127.0.0.1', 9004)]) self.f9002 = ICNForwarder(9002, encoder=NdnTlvEncoder(), routing=True, peers=[('127.0.0.1', 9000), ('127.0.0.1', 9001), ('127.0.0.1', 9004)]) self.f9003 = ICNForwarder(9003, encoder=NdnTlvEncoder(), routing=True, peers=[('127.0.0.1', 9001), ('127.0.0.1', 9004)]) self.f9004 = ICNForwarder(9004, encoder=NdnTlvEncoder(), routing=True, peers=[('127.0.0.1', 9001), ('127.0.0.1', 9002), ('127.0.0.1', 9003)]) os.makedirs('/tmp/test_repo', exist_ok=True) f = open('/tmp/test_repo/helloworld', 'w') f.write('Hello, World!\n') f.close() self.repo = ICNDataRepository('/tmp/test_repo', Name('/testrepo'), port=9090, encoder=NdnTlvEncoder()) self.fetch = Fetch('127.0.0.1', 9004, encoder=NdnTlvEncoder()) # Create RIB entry for the repository (with Python weirdness) repo_fid: int = self.f9000.linklayer.faceidtable.get_or_create_faceid(AddressInfo(('127.0.0.1', 9090), 0)) rib: BaseRoutingInformationBase = self.f9000.routinglayer.rib rib.insert(Name('/testrepo'), repo_fid, distance=1, timeout=None) def tearDown(self): self.f9000.stop_forwarder() self.f9001.stop_forwarder() self.f9002.stop_forwarder() self.f9003.stop_forwarder() self.f9004.stop_forwarder() self.repo.stop_repo() self.fetch.stop_fetch() shutil.rmtree('/tmp/test_repo') def test_network(self): """ C | F[9004] -- F[9003] / \ / / \ / / \ / F[9002] -- F[9001] \ / \ / \ / F[9000] | R """ self.f9000.start_forwarder() self.f9001.start_forwarder() self.f9002.start_forwarder() self.f9003.start_forwarder() self.f9004.start_forwarder() self.repo.start_repo() hw: str = '' until = datetime.utcnow() + timedelta(seconds=20) while hw != 'Hello, World!\n' and datetime.utcnow() < until: try: hw = self.fetch.fetch_data(Name('/testrepo/helloworld'), timeout=1.0) except queue.Empty: pass self.assertEqual('Hello, World!\n', hw) until = datetime.utcnow() + timedelta(seconds=20) hw = '' start = datetime.utcnow() end = start while hw != 'Hello, World!\n' and datetime.utcnow() < until: try: hw = self.fetch.fetch_data(Name('/testrepo/helloworld'), timeout=1.0) end = datetime.utcnow() except queue.Empty: pass self.assertEqual('Hello, World!\n', hw) self.assertLess(end-start, timedelta(seconds=4))