def setUp(self): synced_data_struct_factory = PiCNSyncDataStructFactory() synced_data_struct_factory.register('faceidtable', FaceIDDict) synced_data_struct_factory.create_manager() self.mock_interface = MockInterface(port=1337) self.faceidtable: FaceIDDict = synced_data_struct_factory.manager.faceidtable() self.linklayer = BasicLinkLayer([self.mock_interface], self.faceidtable) self.repo = MockRepository(Name('/unconfigured')) self.autoconflayer = AutoconfigRepoLayer(name='testrepo', linklayer=self.linklayer, repo=self.repo, addr='127.0.1.1', bcport=4242) self.autoconflayer.queue_to_higher = self.queue_to_higher = multiprocessing.Queue() self.autoconflayer.queue_from_higher = self.queue_from_higher = multiprocessing.Queue() self.autoconflayer.queue_to_lower = self.queue_to_lower = multiprocessing.Queue() self.autoconflayer.queue_from_lower = self.queue_from_lower = multiprocessing.Queue()
def setUp(self): synced_data_struct_factory = PiCNSyncDataStructFactory() synced_data_struct_factory.register('cs', ContentStoreMemoryExact) synced_data_struct_factory.register('pit', PendingInterstTableMemoryExact) synced_data_struct_factory.register( 'fib', ForwardingInformationBaseMemoryPrefix) synced_data_struct_factory.register('faceidtable', FaceIDDict) synced_data_struct_factory.create_manager() # Set up forwarder cs = synced_data_struct_factory.manager.cs() pit = synced_data_struct_factory.manager.pit() fib = synced_data_struct_factory.manager.fib() prefixes = [(Name('/test/prefix/repos'), True)] # Auto-assign port forwarder_interface = UDP4Interface(0) forwarder_fidtable = synced_data_struct_factory.manager.faceidtable() forwarder_linklayer = BasicLinkLayer([forwarder_interface], forwarder_fidtable) forwarder_port = forwarder_interface.get_port() forwarder_encoder = NdnTlvEncoder() icnlayer = BasicICNLayer() icnlayer.cs = cs icnlayer.pit = pit icnlayer.fib = fib forwarder_autoconfiglayer = AutoconfigServerLayer( forwarder_linklayer, registration_prefixes=prefixes) forwarder_autoconfiglayer.fib = fib self.forwarder = LayerStack([ icnlayer, forwarder_autoconfiglayer, BasicPacketEncodingLayer(forwarder_encoder), forwarder_linklayer ]) # Set up repo repository = MockRepository(Name('/thisshouldbechanged')) repo_chunkifyer = SimpleContentChunkifyer() repo_chunklayer = BasicChunkLayer(repo_chunkifyer) repo_encoder = NdnTlvEncoder() # Auto-assign port repo_interface = UDP4Interface(0) repo_fidtable = synced_data_struct_factory.manager.faceidtable() repo_linklayer = BasicLinkLayer([repo_interface], repo_fidtable) repo_port = repo_interface.get_port() self.repo = LayerStack([ BasicRepositoryLayer(repository), repo_chunklayer, AutoconfigRepoLayer('testrepo', repo_linklayer, repository, '127.0.0.1', forwarder_port), BasicPacketEncodingLayer(repo_encoder), repo_linklayer ]) # Set up fetch client client_chunkifyer = SimpleContentChunkifyer() client_chunklayer = BasicChunkLayer(client_chunkifyer) client_encoder = NdnTlvEncoder() client_interface = UDP4Interface(0) client_fidtable = synced_data_struct_factory.manager.faceidtable() client_linklayer = BasicLinkLayer([client_interface], client_fidtable) self.client = LayerStack([ client_chunklayer, AutoconfigClientLayer(client_linklayer, bcport=forwarder_port), BasicPacketEncodingLayer(client_encoder), client_linklayer ])
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("ICNRepoSession", log_level) logger.info("Start PiCN Data Repository with Sessions") # 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 = SessionRepositoryLayer(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_AutoconfigRepoLayer(unittest.TestCase): def setUp(self): synced_data_struct_factory = PiCNSyncDataStructFactory() synced_data_struct_factory.register('faceidtable', FaceIDDict) synced_data_struct_factory.create_manager() self.mock_interface = MockInterface(port=1337) self.faceidtable: FaceIDDict = synced_data_struct_factory.manager.faceidtable() self.linklayer = BasicLinkLayer([self.mock_interface], self.faceidtable) self.repo = MockRepository(Name('/unconfigured')) self.autoconflayer = AutoconfigRepoLayer(name='testrepo', linklayer=self.linklayer, repo=self.repo, addr='127.0.1.1', bcport=4242) self.autoconflayer.queue_to_higher = self.queue_to_higher = multiprocessing.Queue() self.autoconflayer.queue_from_higher = self.queue_from_higher = multiprocessing.Queue() self.autoconflayer.queue_to_lower = self.queue_to_lower = multiprocessing.Queue() self.autoconflayer.queue_from_lower = self.queue_from_lower = multiprocessing.Queue() def tearDown(self): self.autoconflayer.stop_process() self.queue_to_higher.close() self.queue_from_higher.close() self.queue_to_lower.close() self.queue_from_lower.close() def test_broadcast_enabled(self): """Test that broadcasting was enabled on the UDP socket""" self.autoconflayer.start_process() self.mock_interface.sock.setsockopt.assert_called_once_with(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) def test_initial_forwarder_solicitation(self): """Test that the autoconfig layer sends an initial forwarder solicitation when starting""" self.autoconflayer.start_process() # Receive forwarder solicitation data = self.queue_to_lower.get() self.assertEqual(2, len(data)) self.assertIsInstance(data[0], int) self.assertIsInstance(data[1], Interest) self.assertEqual(Name('/autoconfig/forwarders'), data[1].name) def test_pass_through(self): """Test that autoconfig-unrelated content is passed through unchanged""" self.faceidtable.add(42, AddressInfo(('127.13.37.42', 4567), 0)) self.autoconflayer.start_process() # Receive forwarder solicitation _ = self.queue_to_lower.get() # Pass an interest object from below interest = Interest(Name('/foo/bar')) self.queue_from_lower.put([42, interest]) data = self.queue_to_higher.get() self.assertEqual(2, len(data)) self.assertEqual(42, data[0]) self.assertEqual(interest, data[1]) # Pass a content object from above content = Content(Name('/foo/bar'), 'foo bar') self.queue_from_higher.put([1337, content]) data = self.queue_to_lower.get() self.assertEqual(2, len(data)) self.assertEqual(1337, data[0]) self.assertEqual(content, data[1]) def test_service_registration(self): """Test that a service registration interest is sent""" self.faceidtable.add(42, AddressInfo(('127.42.42.42', 9000), 0)) self.autoconflayer.start_process() # Receive forwarder solicitation bface, _ = self.queue_to_lower.get() # Send forwarder advertisement forwarders = Content(Name('/autoconfig/forwarders'), 'udp4://127.42.42.42:9000\nr:/global\npl:/test\n') self.queue_from_lower.put([42, forwarders]) # Receive service registration fid, data = self.queue_to_lower.get() self.assertEqual(42, fid) self.assertIsInstance(data, Interest) registration_name = Name('/autoconfig/service') registration_name += 'udp4://127.0.1.1:1337' registration_name += 'test' registration_name += 'testrepo' self.assertEqual(registration_name, data.name) def test_service_registration_prefix_changed(self): """Test that a service registration interest is sent""" self.faceidtable.add(42, AddressInfo(('127.42.42.42', 9000), 0)) self.autoconflayer.start_process() # Receive forwarder solicitation bface, _ = self.queue_to_lower.get() # Send forwarder advertisement forwarders = Content(Name('/autoconfig/forwarders'), 'udp4://127.42.42.42:9000\nr:/global\npl:/test\n') self.queue_from_lower.put([42, forwarders]) # Receive service registration fid, data = self.queue_to_lower.get() registration_name = Name('/autoconfig/service') registration_name += 'udp4://127.0.1.1:1337' registration_name += 'test' registration_name += 'testrepo' self.assertEqual(registration_name, data.name) # Send service registration ACK content = Content(registration_name, '3600\n') self.queue_from_lower.put([42, content]) time.sleep(1) # Make sure the repo prefix was changed self.assertEqual(Name('/test/testrepo'), self.repo.prefix.value) def test_service_registration_nack_prefix_not_changed(self): """Test that a service registration interest is sent""" self.faceidtable.add(42, AddressInfo(('127.42.42.42', 9000), 0)) self.autoconflayer.start_process() # Receive forwarder solicitation bface, _ = self.queue_to_lower.get() # Send forwarder advertisement forwarders = Content(Name('/autoconfig/forwarders'), 'udp4://127.42.42.42:9000\nr:/global\npl:/test\n') self.queue_from_lower.put([42, forwarders]) # Receive service registration fid, data = self.queue_to_lower.get() registration_name = Name('/autoconfig/service') registration_name += 'udp4://127.0.1.1:1337' registration_name += 'test' registration_name += 'testrepo' self.assertEqual(registration_name, data.name) # Send service registration NACK nack = Nack(registration_name, NackReason.NO_ROUTE, data) self.queue_from_lower.put([42, nack]) time.sleep(1) # Make sure the repo prefix was NOT changed self.assertEqual(Name('/unconfigured'), self.repo.prefix.value) def test_service_registration_timeout_renewal(self): """Test that the service registration is renewed before the timeout""" self.faceidtable.add(42, AddressInfo(('127.42.42.42', 9000), 0)) waittime = 5 self.autoconflayer.start_process() # Receive forwarder solicitation bface, _ = self.queue_to_lower.get() # Send forwarder advertisement forwarders = Content(Name('/autoconfig/forwarders'), 'udp4://127.42.42.42:9000\nr:/global\npl:/test\n') self.queue_from_lower.put([42, forwarders]) # Receive service registration fid, data = self.queue_to_lower.get() registration_name = Name('/autoconfig/service') registration_name += 'udp4://127.0.1.1:1337' registration_name += 'test' registration_name += 'testrepo' self.assertEqual(registration_name, data.name) # Send service registration ACK with a ridiculously short timeout content = Content(registration_name, f'{waittime}\n') self.queue_from_lower.put([42, content]) # Catch all data the autoconfig layer sends downwards for 5 seconds data = [] timeout = datetime.utcnow() + timedelta(seconds=waittime) while datetime.utcnow() < timeout: try: data.append(self.queue_to_lower.get(timeout=waittime/10)) except queue.Empty: pass registration_interest = Interest(registration_name) self.assertIn([42, registration_interest], data) def test_service_registration_global_ignored(self): self.faceidtable.add(42, AddressInfo(('127.42.42.42', 9000), 0)) waittime = 5 self.autoconflayer.start_process() # Receive forwarder solicitation bface, _ = self.queue_to_lower.get() # Send forwarder advertisement forwarders = Content(Name('/autoconfig/forwarders'), 'udp4://127.42.42.42:9000\nr:/global\npl:/test\npg:/routed\n') self.queue_from_lower.put([42, forwarders]) # Receive service registration # Catch all data the autoconfig layer sends downwards for 5 seconds data = [] timeout = datetime.utcnow() + timedelta(seconds=waittime) while datetime.utcnow() < timeout: try: data.append(self.queue_to_lower.get(timeout=waittime/10)) except queue.Empty: pass self.assertEqual(1, len(data)) fid, data = data[0] self.assertEqual(42, fid) self.assertIsInstance(data, Interest) registration_name = Name('/autoconfig/service') registration_name += 'udp4://127.0.1.1:1337' registration_name += 'test' registration_name += 'testrepo' self.assertEqual(registration_name, data.name) def test_service_registration_global_only(self): self.faceidtable.add(42, AddressInfo(('127.42.42.42', 9000), 0)) waittime = 5 self.autoconflayer._register_local = False self.autoconflayer._register_global = True self.autoconflayer.start_process() # Receive forwarder solicitation bface, _ = self.queue_to_lower.get() # Send forwarder advertisement forwarders = Content(Name('/autoconfig/forwarders'), 'udp4://127.42.42.42:9000\nr:/global\npl:/test\npg:/routed\n') self.queue_from_lower.put([42, forwarders]) # Receive service registration # Catch all data the autoconfig layer sends downwards for 5 seconds data = [] timeout = datetime.utcnow() + timedelta(seconds=waittime) while datetime.utcnow() < timeout: try: data.append(self.queue_to_lower.get(timeout=waittime/10)) except queue.Empty: pass self.assertEqual(1, len(data)) fid, data = data[0] self.assertEqual(42, fid) self.assertIsInstance(data, Interest) registration_name = Name('/autoconfig/service') registration_name += 'udp4://127.0.1.1:1337' registration_name += 'routed' registration_name += 'testrepo' self.assertEqual(registration_name, data.name)