self.__clients_map = {}
self.__map_lock = threading.Lock()
+ # The generation ID of the configuration corresponding to
+ # current __clinets_map. Until we support the concept of generations
+ # in the configuration framework, we tentatively maintain it within
+ # this class.
+ self.__gen_id = 0
+
def get_clients_map(self):
- """Returns a dict from RR class to ConfigurableClientList.
+ """Returns a dict from RR class to ConfigurableClientList with gen ID.
It corresponds to the generation of data source configuration at the
time of the call. It can be safely called while reconfigure() is
"""
with self.__map_lock:
- return self.__clients_map
+ return (self.__gen_id, self.__clients_map)
def get_client_list(self, rrclass):
"""Return the configured ConfigurableClientList for the RR class.
new_map[rrclass] = new_client_list
with self.__map_lock:
self.__clients_map = new_map
+
+ # NOTE: when we support the concept of generations this should
+ # be retrieved from the configuration
+ self.__gen_id += 1
except Exception as ex:
# Catch all types of exceptions as a whole: there won't be much
# granularity for exceptions raised from the C++ module anyway.
def test_get_clients_map(self):
# This is basically a trivial getter, so it should be sufficient
# to check we can call it as we expect.
+
+ # Initially map iss empty, the generation ID is 0.
+ self.assertEqual((0, {}), self.__mgr.get_clients_map())
+
self.__mgr.reconfigure(DEFAULT_CONFIG)
- clients_map = self.__mgr.get_clients_map()
+ genid, clients_map = self.__mgr.get_clients_map()
+ self.assertEqual(1, genid)
self.assertEqual(2, len(clients_map)) # should contain 'IN' and 'CH'
# Check the retrieved map is usable even after further reconfig().
self.__mgr.reconfigure({"classes": {"IN": []}})
self.check_client_list_content(clients_map[RRClass.CH])
+ # generation ID should be incremented again
+ self.assertEqual(2, self.__mgr.get_clients_map()[0])
+
if __name__ == "__main__":
isc.log.init("bind10")
isc.log.resetUnitTestRootLogger()