Browse Source

[trac387] Fix a bug that xfrin not checking for new copy of zone on startup.

chenzhengzhang 14 years ago
parent
commit
1241ddcffa

+ 83 - 67
src/bin/zonemgr/tests/zonemgr_test.py

@@ -29,8 +29,9 @@ ZONE_NAME_CLASS2_IN = ("tw.cn.", "IN")
 
 MAX_TRANSFER_TIMEOUT = 14400
 LOWERBOUND_REFRESH = 10
-LOWERBOUND_RETRY = 5 
-JITTER_SCOPE = 0.10
+LOWERBOUND_RETRY = 5
+REFRESH_JITTER = 0.10
+RELOAD_JITTER = 0.75
 
 class ZonemgrTestException(Exception):
     pass
@@ -60,8 +61,10 @@ class FakeConfig:
             return LOWERBOUND_RETRY
         elif name == 'max_transfer_timeout':
             return MAX_TRANSFER_TIMEOUT
-        elif name == 'jitter_scope':
-            return JITTER_SCOPE
+        elif name == 'refresh_jitter':
+            return REFRESH_JITTER
+        elif name == 'reload_jitter':
+            return RELOAD_JITTER
         elif name == 'secondary_zones':
             return self.zone_list
         else:
@@ -71,6 +74,10 @@ class MyZonemgrRefresh(ZonemgrRefresh):
     def __init__(self):
         self._master_socket, self._slave_socket = socket.socketpair()
         self._zonemgr_refresh_info = {}
+        self._lowerbound_refresh = 10
+        self._lowerbound_retry = 5
+        self._reload_jitter = 0.75
+        self._refresh_jitter = 0.25
 
         def get_zone_soa(zone_name, db_file):
             if zone_name == 'sd.cn.':
@@ -86,18 +93,18 @@ class MyZonemgrRefresh(ZonemgrRefresh):
         ZonemgrRefresh.__init__(self, MySession(), "initdb.file",
             self._slave_socket, FakeConfig())
         current_time = time.time()
-        self._zonemgr_refresh_info = { 
+        self._zonemgr_refresh_info = {
          ('sd.cn.', 'IN'): {
          'last_refresh_time': current_time,
-         'next_refresh_time': current_time + 6500, 
-         'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600', 
+         'next_refresh_time': current_time + 6500,
+         'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600',
          'zone_state': 0},
          ('tw.cn.', 'CH'): {
-         'last_refresh_time': current_time, 
-         'next_refresh_time': current_time + 6900, 
-         'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073112 7200 3600 2419200 21600', 
+         'last_refresh_time': current_time,
+         'next_refresh_time': current_time + 6900,
+         'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073112 7200 3600 2419200 21600',
          'zone_state': 0}
-        } 
+        }
 
 class TestZonemgrRefresh(unittest.TestCase):
     def setUp(self):
@@ -109,10 +116,10 @@ class TestZonemgrRefresh(unittest.TestCase):
         max = 100025.120
         jitter = 0
         self.assertEqual(max, self.zone_refresh._random_jitter(max, jitter))
-        jitter = max / 4
+        jitter = 0.3 * max
         for i in range (0, 150):
-            self.assertTrue((3 * max / 4) <= self.zone_refresh._random_jitter(max, jitter)) 
-            self.assertTrue(self.zone_refresh._random_jitter(max, jitter) <= max) 
+            self.assertTrue((max - jitter) <= self.zone_refresh._random_jitter(max, jitter))
+            self.assertTrue(self.zone_refresh._random_jitter(max, jitter) <= max)
             i += 1;
 
     def test_get_current_time(self):
@@ -133,7 +140,7 @@ class TestZonemgrRefresh(unittest.TestCase):
         self.zone_refresh._set_zone_refresh_timer(ZONE_NAME_CLASS1_IN)
         zone_timeout = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"]
         time2 = time.time()
-        self.assertTrue((time1 + 7200 * 3 / 4) <= zone_timeout)
+        self.assertTrue((time1 + 7200 * (1 - self.zone_refresh._refresh_jitter)) <= zone_timeout)
         self.assertTrue(zone_timeout <= time2 + 7200)
 
     def test_set_zone_retry_timer(self):
@@ -141,7 +148,7 @@ class TestZonemgrRefresh(unittest.TestCase):
         self.zone_refresh._set_zone_retry_timer(ZONE_NAME_CLASS1_IN)
         zone_timeout = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"]
         time2 = time.time()
-        self.assertTrue((time1 + 3600 * 3 / 4) <= zone_timeout)
+        self.assertTrue((time1 + 3600 * (1 - self.zone_refresh._refresh_jitter)) <= zone_timeout)
         self.assertTrue(zone_timeout <= time2 + 3600)
 
     def test_zone_not_exist(self):
@@ -172,19 +179,19 @@ class TestZonemgrRefresh(unittest.TestCase):
         self.assertTrue(self.zone_refresh._zone_is_expired(ZONE_NAME_CLASS1_IN))
 
     def test_get_zone_soa_rdata(self):
-        soa_rdata1  = 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600' 
-        soa_rdata2  = 'a.dns.cn. root.cnnic.cn. 2009073112 7200 3600 2419200 21600' 
+        soa_rdata1  = 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600'
+        soa_rdata2  = 'a.dns.cn. root.cnnic.cn. 2009073112 7200 3600 2419200 21600'
         self.assertEqual(soa_rdata1, self.zone_refresh._get_zone_soa_rdata(ZONE_NAME_CLASS1_IN))
         self.assertRaises(KeyError, self.zone_refresh._get_zone_soa_rdata, ZONE_NAME_CLASS1_CH)
         self.assertEqual(soa_rdata2, self.zone_refresh._get_zone_soa_rdata(ZONE_NAME_CLASS2_CH))
         self.assertRaises(KeyError, self.zone_refresh._get_zone_soa_rdata, ZONE_NAME_CLASS2_IN)
-         
+
     def test_zonemgr_reload_zone(self):
         soa_rdata = 'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600'
         # We need to restore this not to harm other tests
         old_get_zone_soa = sqlite3_ds.get_zone_soa
         def get_zone_soa(zone_name, db_file):
-            return (1, 2, 'sd.cn.', 'cn.sd.', 21600, 'SOA', None, 
+            return (1, 2, 'sd.cn.', 'cn.sd.', 21600, 'SOA', None,
                     'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600')
         sqlite3_ds.get_zone_soa = get_zone_soa
 
@@ -234,7 +241,7 @@ class TestZonemgrRefresh(unittest.TestCase):
         current_time = time.time()
         self.zone_refresh._set_zone_refresh_timeout(ZONE_NAME_CLASS1_IN, current_time)
         refresh_time = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["refresh_timeout"]
-        self.assertEqual(current_time, refresh_time) 
+        self.assertEqual(current_time, refresh_time)
 
     def test_get_zone_next_refresh_time(self):
         current_time = time.time()
@@ -256,14 +263,14 @@ class TestZonemgrRefresh(unittest.TestCase):
         current_time = time.time()
         self.zone_refresh._set_zone_last_refresh_time(ZONE_NAME_CLASS1_IN, current_time)
         last_refresh_time = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["last_refresh_time"]
-        self.assertEqual(current_time, last_refresh_time) 
+        self.assertEqual(current_time, last_refresh_time)
 
     def test_send_command(self):
         self.assertRaises(ZonemgrTestException, self.zone_refresh._send_command, "Unknown", "Notify", None)
 
     def test_zone_mgr_is_empty(self):
         self.assertFalse(self.zone_refresh._zone_mgr_is_empty())
-        self.zone_refresh._zonemgr_refresh_info = {} 
+        self.zone_refresh._zonemgr_refresh_info = {}
         self.assertTrue(self.zone_refresh._zone_mgr_is_empty())
 
     def test_zonemgr_add_zone(self):
@@ -271,9 +278,10 @@ class TestZonemgrRefresh(unittest.TestCase):
         # This needs to be restored. The following test actually failed if we left
         # this unclean
         old_get_zone_soa = sqlite3_ds.get_zone_soa
+        time1 = time.time()
 
         def get_zone_soa(zone_name, db_file):
-            return (1, 2, 'sd.cn.', 'cn.sd.', 21600, 'SOA', None, 
+            return (1, 2, 'sd.cn.', 'cn.sd.', 21600, 'SOA', None,
                     'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600')
 
         sqlite3_ds.get_zone_soa = get_zone_soa
@@ -282,10 +290,14 @@ class TestZonemgrRefresh(unittest.TestCase):
         self.zone_refresh.zonemgr_add_zone(ZONE_NAME_CLASS1_IN)
         self.assertEqual(1, len(self.zone_refresh._zonemgr_refresh_info))
         zone_soa_rdata = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_soa_rdata"]
-        self.assertEqual(soa_rdata, zone_soa_rdata) 
+        self.assertEqual(soa_rdata, zone_soa_rdata)
         self.assertEqual(ZONE_OK, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"])
         self.assertTrue("last_refresh_time" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
         self.assertTrue("next_refresh_time" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
+        time2 = time.time()
+        zone_timeout = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"]
+        self.assertTrue((time1 + 900 * (1 - self.zone_refresh._reload_jitter)) <= zone_timeout)
+        self.assertTrue(zone_timeout <= time2 + 900)
 
         def get_zone_soa2(zone_name, db_file):
             return None
@@ -297,7 +309,7 @@ class TestZonemgrRefresh(unittest.TestCase):
     def test_zone_handle_notify(self):
         self.zone_refresh.zone_handle_notify(ZONE_NAME_CLASS1_IN,"127.0.0.1")
         notify_master = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["notify_master"]
-        self.assertEqual("127.0.0.1", notify_master) 
+        self.assertEqual("127.0.0.1", notify_master)
         zone_timeout = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"]
         current_time = time.time()
         self.assertTrue(zone_timeout <= current_time)
@@ -309,7 +321,7 @@ class TestZonemgrRefresh(unittest.TestCase):
     def test_zone_refresh_success(self):
         soa_rdata = 'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600'
         def get_zone_soa(zone_name, db_file):
-            return (1, 2, 'sd.cn.', 'cn.sd.', 21600, 'SOA', None, 
+            return (1, 2, 'sd.cn.', 'cn.sd.', 21600, 'SOA', None,
                     'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600')
         sqlite3_ds.get_zone_soa = get_zone_soa
         time1 = time.time()
@@ -317,19 +329,19 @@ class TestZonemgrRefresh(unittest.TestCase):
         self.zone_refresh.zone_refresh_success(ZONE_NAME_CLASS1_IN)
         time2 = time.time()
         zone_soa_rdata = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_soa_rdata"]
-        self.assertEqual(soa_rdata, zone_soa_rdata) 
+        self.assertEqual(soa_rdata, zone_soa_rdata)
         next_refresh_time = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"]
-        self.assertTrue((time1 + 3 * 1800 / 4) <= next_refresh_time) 
+        self.assertTrue((time1 + 1800 * (1 - self.zone_refresh._refresh_jitter)) <= next_refresh_time)
         self.assertTrue(next_refresh_time <= time2 + 1800)
         self.assertEqual(ZONE_OK, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"])
         last_refresh_time = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["last_refresh_time"]
         self.assertTrue(time1 <= last_refresh_time)
         self.assertTrue(last_refresh_time <= time2)
         self.assertRaises(ZonemgrException, self.zone_refresh.zone_refresh_success, ("org.cn.", "CH"))
-        self.assertRaises(ZonemgrException, self.zone_refresh.zone_refresh_success, ZONE_NAME_CLASS3_IN) 
+        self.assertRaises(ZonemgrException, self.zone_refresh.zone_refresh_success, ZONE_NAME_CLASS3_IN)
 
     def test_zone_refresh_fail(self):
-        soa_rdata = 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600' 
+        soa_rdata = 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600'
         time1 = time.time()
         self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"] = ZONE_REFRESHING
         self.zone_refresh.zone_refresh_fail(ZONE_NAME_CLASS1_IN)
@@ -337,36 +349,36 @@ class TestZonemgrRefresh(unittest.TestCase):
         zone_soa_rdata = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_soa_rdata"]
         self.assertEqual(soa_rdata, zone_soa_rdata)
         next_refresh_time = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"]
-        self.assertTrue((time1 + 3 * 3600 / 4) <= next_refresh_time)
+        self.assertTrue(((time1 + 3600 * (1 - self.zone_refresh._refresh_jitter))) <= next_refresh_time)
         self.assertTrue(next_refresh_time <= time2 + 3600)
         self.assertEqual(ZONE_OK, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"])
 
-        self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["last_refresh_time"] = time1 - 2419200 
+        self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["last_refresh_time"] = time1 - 2419200
         self.zone_refresh.zone_refresh_fail(ZONE_NAME_CLASS1_IN)
         self.assertEqual(ZONE_EXPIRED, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"])
 
         self.assertRaises(ZonemgrException, self.zone_refresh.zone_refresh_fail, ("org.cn.", "CH"))
-        self.assertRaises(ZonemgrException, self.zone_refresh.zone_refresh_fail, ZONE_NAME_CLASS3_IN) 
+        self.assertRaises(ZonemgrException, self.zone_refresh.zone_refresh_fail, ZONE_NAME_CLASS3_IN)
 
     def test_find_need_do_refresh_zone(self):
         time1 = time.time()
-        self.zone_refresh._zonemgr_refresh_info = { 
+        self.zone_refresh._zonemgr_refresh_info = {
                 ("sd.cn.","IN"):{
                     'last_refresh_time': time1,
-                    'next_refresh_time': time1 + 7200, 
-                    'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600', 
+                    'next_refresh_time': time1 + 7200,
+                    'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600',
                     'zone_state': ZONE_OK},
                 ("tw.cn.","CH"):{
-                    'last_refresh_time': time1 - 7200, 
-                    'next_refresh_time': time1, 
-                    'refresh_timeout': time1 + MAX_TRANSFER_TIMEOUT, 
-                    'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073112 7200 3600 2419200 21600', 
+                    'last_refresh_time': time1 - 7200,
+                    'next_refresh_time': time1,
+                    'refresh_timeout': time1 + MAX_TRANSFER_TIMEOUT,
+                    'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073112 7200 3600 2419200 21600',
                     'zone_state': ZONE_REFRESHING}
                 }
         zone_need_refresh = self.zone_refresh._find_need_do_refresh_zone()
         self.assertEqual(ZONE_NAME_CLASS1_IN, zone_need_refresh)
 
-        self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS2_CH]["refresh_timeout"] = time1 
+        self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS2_CH]["refresh_timeout"] = time1
         zone_need_refresh = self.zone_refresh._find_need_do_refresh_zone()
         self.assertEqual(ZONE_NAME_CLASS2_CH, zone_need_refresh)
 
@@ -375,42 +387,42 @@ class TestZonemgrRefresh(unittest.TestCase):
         self.zone_refresh._zonemgr_refresh_info = {
                 ("sd.cn.", "IN"):{
                     'last_refresh_time': time1 - 7200,
-                    'next_refresh_time': time1 - 1, 
-                    'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600', 
+                    'next_refresh_time': time1 - 1,
+                    'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600',
                     'zone_state': ZONE_OK}
                 }
         self.zone_refresh._do_refresh(ZONE_NAME_CLASS1_IN)
         time2 = time.time()
         zone_state = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"]
         self.assertEqual(ZONE_REFRESHING, zone_state)
-        refresh_timeout = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["refresh_timeout"] 
+        refresh_timeout = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["refresh_timeout"]
         self.assertTrue(time1 + MAX_TRANSFER_TIMEOUT <= refresh_timeout)
-        self.assertTrue(time2 + MAX_TRANSFER_TIMEOUT >= refresh_timeout) 
+        self.assertTrue(time2 + MAX_TRANSFER_TIMEOUT >= refresh_timeout)
 
         self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["notify_master"] = "127.0.0.1"
         self.zone_refresh._do_refresh(ZONE_NAME_CLASS1_IN)
         time2 = time.time()
         zone_state = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"]
-        self.assertEqual(ZONE_REFRESHING, zone_state) 
-        refresh_timeout = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["refresh_timeout"] 
+        self.assertEqual(ZONE_REFRESHING, zone_state)
+        refresh_timeout = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["refresh_timeout"]
         self.assertTrue(time1 + MAX_TRANSFER_TIMEOUT <= refresh_timeout)
         self.assertTrue(time2 + MAX_TRANSFER_TIMEOUT >= refresh_timeout)
         self.assertFalse("notify_master" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
 
     def test_run_timer(self):
-        """This case will run timer in daemon thread. 
-        The zone's next_refresh_time is less than now, so zonemgr will do zone refresh 
-        immediately. The zone's state will become "refreshing". 
+        """This case will run timer in daemon thread.
+        The zone's next_refresh_time is less than now, so zonemgr will do zone refresh
+        immediately. The zone's state will become "refreshing".
         """
         time1 = time.time()
         self.zone_refresh._zonemgr_refresh_info = {
                 ("sd.cn.", "IN"):{
                     'last_refresh_time': time1 - 7200,
-                    'next_refresh_time': time1 - 1, 
-                    'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600', 
+                    'next_refresh_time': time1 - 1,
+                    'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600',
                     'zone_state': ZONE_OK}
                 }
-        self.zone_refresh._check_sock = self.zone_refresh._master_socket 
+        self.zone_refresh._check_sock = self.zone_refresh._master_socket
         listener = self.zone_refresh.run_timer(daemon=True)
         # Shut down the timer thread
         self.zone_refresh.shutdown()
@@ -424,17 +436,19 @@ class TestZonemgrRefresh(unittest.TestCase):
                     "lowerbound_refresh" : 60,
                     "lowerbound_retry" : 30,
                     "max_transfer_timeout" : 19800,
-                    "jitter_scope" : 0.25,
+                    "refresh_jitter" : 0.25,
+                    "reload_jitter" : 0.75,
                     "secondary_zones": []
                 }
         self.zone_refresh.update_config_data(config_data)
         self.assertEqual(60, self.zone_refresh._lowerbound_refresh)
         self.assertEqual(30, self.zone_refresh._lowerbound_retry)
         self.assertEqual(19800, self.zone_refresh._max_transfer_timeout)
-        self.assertEqual(0.25, self.zone_refresh._jitter_scope)
+        self.assertEqual(0.25, self.zone_refresh._refresh_jitter)
+        self.assertEqual(0.75, self.zone_refresh._reload_jitter)
 
     def test_shutdown(self):
-        self.zone_refresh._check_sock = self.zone_refresh._master_socket 
+        self.zone_refresh._check_sock = self.zone_refresh._master_socket
         listener = self.zone_refresh.run_timer()
         self.assertTrue(listener.is_alive())
         # Shut down the timer thread
@@ -473,7 +487,7 @@ class TestZonemgrRefresh(unittest.TestCase):
 class MyCCSession():
     def __init__(self):
         pass
-                    
+
     def get_remote_config_value(self, module_name, identifier):
         if module_name == "Auth" and identifier == "database_file":
             return "initdb.file", False
@@ -493,7 +507,8 @@ class MyZonemgr(Zonemgr):
                     "lowerbound_refresh" : 10,
                     "lowerbound_retry" : 5,
                     "max_transfer_timeout" : 14400,
-                    "jitter_scope" : 0.1,
+                    "refresh_jitter" : 0.1,
+                    "reload_jitter" : 0.75,
                     "secondary_zones": []
                     }
 
@@ -510,7 +525,8 @@ class TestZonemgr(unittest.TestCase):
                     "lowerbound_refresh" : 60,
                     "lowerbound_retry" : 30,
                     "max_transfer_timeout" : 14400,
-                    "jitter_scope" : 0.1,
+                    "refresh_jitter" : 0.1,
+                    "reload_jitter" : 0.75,
                     "secondary_zones": []
                     }
         self.assertEqual(self.zonemgr.config_handler(config_data1),
@@ -520,9 +536,9 @@ class TestZonemgr(unittest.TestCase):
         self.zonemgr.config_handler(config_data2)
         self.assertEqual(config_data1, self.zonemgr._config_data)
         # jitter should not be bigger than half of the original value
-        config_data3 = {"jitter_scope" : 0.7}
+        config_data3 = {"refresh_jitter" : 0.7}
         self.zonemgr.config_handler(config_data3)
-        self.assertEqual(0.5, self.zonemgr._config_data.get("jitter_scope"))
+        self.assertEqual(0.5, self.zonemgr._config_data.get("refresh_jitter"))
         # The zone doesn't exist in database, it should be rejected
         self.zonemgr._zone_refresh = ZonemgrRefresh(None, "initdb.file", None,
                                                     config_data1)
@@ -531,7 +547,7 @@ class TestZonemgr(unittest.TestCase):
         self.assertNotEqual(self.zonemgr.config_handler(config_data1),
                             {"result": [0]})
         # As it is rejected, the old value should be kept
-        self.assertEqual(0.5, self.zonemgr._config_data.get("jitter_scope"))
+        self.assertEqual(0.5, self.zonemgr._config_data.get("refresh_jitter"))
 
     def test_get_db_file(self):
         self.assertEqual("initdb.file", self.zonemgr.get_db_file())
@@ -549,12 +565,12 @@ class TestZonemgr(unittest.TestCase):
 
     def test_config_data_check(self):
         # jitter should not be bigger than half of the original value
-        config_data2 = {"jitter_scope" : 0.2}
-        config_data3 = {"jitter_scope" : 0.6}
+        config_data2 = {"refresh_jitter" : 0.2}
+        config_data3 = {"refresh_jitter" : 0.6}
         self.zonemgr._config_data_check(config_data2)
-        self.assertEqual(0.2, config_data2.get("jitter_scope"))
+        self.assertEqual(0.2, config_data2.get("refresh_jitter"))
         self.zonemgr._config_data_check(config_data3)
-        self.assertEqual(0.5, config_data3.get("jitter_scope"))
+        self.assertEqual(0.5, config_data3.get("refresh_jitter"))
 
     def tearDown(self):
         pass

+ 13 - 10
src/bin/zonemgr/zonemgr.py.in

@@ -125,19 +125,19 @@ class ZonemgrRefresh:
 
     def _set_zone_refresh_timer(self, zone_name_class):
         """Set zone next refresh time after zone refresh success.
-           now + refresh - jitter  <= next_refresh_time <= now + refresh
+           now + refresh - refresh_jitter <= next_refresh_time <= now + refresh
            """
         zone_refresh_time = float(self._get_zone_soa_rdata(zone_name_class).split(" ")[REFRESH_OFFSET])
         zone_refresh_time = max(self._lowerbound_refresh, zone_refresh_time)
-        self._set_zone_timer(zone_name_class, zone_refresh_time, self._jitter_scope * zone_refresh_time)
+        self._set_zone_timer(zone_name_class, zone_refresh_time, self._refresh_jitter * zone_refresh_time)
 
     def _set_zone_retry_timer(self, zone_name_class):
         """Set zone next refresh time after zone refresh fail.
-           now + retry - jitter <= next_refresh_time <= now + retry
+           now + retry - retry_jitter <= next_refresh_time <= now + retry
            """
         zone_retry_time = float(self._get_zone_soa_rdata(zone_name_class).split(" ")[RETRY_OFFSET])
         zone_retry_time = max(self._lowerbound_retry, zone_retry_time)
-        self._set_zone_timer(zone_name_class, zone_retry_time, self._jitter_scope * zone_retry_time)
+        self._set_zone_timer(zone_name_class, zone_retry_time, self._refresh_jitter * zone_retry_time)
 
     def _set_zone_notify_timer(self, zone_name_class):
         """Set zone next refresh time after receiving notify
@@ -194,9 +194,11 @@ class ZonemgrRefresh:
         zone_info["zone_soa_rdata"] = zone_soa[7]
         zone_info["zone_state"] = ZONE_OK
         zone_info["last_refresh_time"] = self._get_current_time()
-        zone_info["next_refresh_time"] = self._get_current_time() + \
-                                         float(zone_soa[7].split(" ")[REFRESH_OFFSET])
         self._zonemgr_refresh_info[zone_name_class] = zone_info
+        # Imposes some random jitters to avoid many zones need to do refresh at the same time.
+        zone_reload_jitter = float(zone_soa[7].split(" ")[RETRY_OFFSET])
+        zone_reload_jitter = max(self._lowerbound_retry, zone_reload_jitter)
+        self._set_zone_timer(zone_name_class, zone_reload_jitter, self._reload_jitter * zone_reload_jitter)
 
     def _zone_is_expired(self, zone_name_class):
         """Judge whether a zone is expired or not."""
@@ -431,7 +433,8 @@ class ZonemgrRefresh:
         self._lowerbound_refresh = new_config.get('lowerbound_refresh')
         self._lowerbound_retry = new_config.get('lowerbound_retry')
         self._max_transfer_timeout = new_config.get('max_transfer_timeout')
-        self._jitter_scope = new_config.get('jitter_scope')
+        self._refresh_jitter = new_config.get('refresh_jitter')
+        self._reload_jitter = new_config.get('reload_jitter')
 
 class Zonemgr:
     """Zone manager class."""
@@ -510,9 +513,9 @@ class Zonemgr:
         not. It contains only basic logic, not full check against
         database."""
         # jitter should not be bigger than half of the original value
-        if config_data.get('jitter_scope') > 0.5:
-            config_data['jitter_scope'] = 0.5
-            log_msg("[b10-zonemgr] jitter_scope is too big, its value will "
+        if config_data.get('refresh_jitter') > 0.5:
+            config_data['refresh_jitter'] = 0.5
+            log_msg("[b10-zonemgr] refresh_jitter is too big, its value will "
                       "be set to 0.5")
 
 

+ 9 - 3
src/bin/zonemgr/zonemgr.spec.pre.in

@@ -12,21 +12,27 @@
          "item_name": "lowerbound_retry",
          "item_type": "integer",
          "item_optional": false,
-         "item_default": 5 
+         "item_default": 5
        },
        {
          "item_name": "max_transfer_timeout",
          "item_type": "integer",
          "item_optional": false,
-         "item_default": 14400 
+         "item_default": 14400
        },
        {
-         "item_name": "jitter_scope",
+         "item_name": "refresh_jitter",
          "item_type": "real",
          "item_optional": false,
          "item_default": 0.25
        },
        {
+         "item_name": "reload_jitter",
+         "item_type": "real",
+         "item_optional": false,
+         "item_default": 0.75
+       },
+       {
          "item_name": "secondary_zones",
          "item_type": "list",
          "item_optional": false,