zonemgr_test.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. # Copyright (C) 2010 Internet Systems Consortium.
  2. #
  3. # Permission to use, copy, modify, and distribute this software for any
  4. # purpose with or without fee is hereby granted, provided that the above
  5. # copyright notice and this permission notice appear in all copies.
  6. #
  7. # THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
  8. # DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
  9. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
  10. # INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
  11. # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
  12. # FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  13. # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  14. # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. '''Tests for the ZonemgrRefresh and Zonemgr classes '''
  16. import unittest
  17. import os
  18. import tempfile
  19. from zonemgr import *
  20. ZONE_NAME_CLASS1_IN = ("sd.cn.", "IN")
  21. ZONE_NAME_CLASS2_CH = ("tw.cn", "CH")
  22. ZONE_NAME_CLASS3_IN = ("example.com", "IN")
  23. ZONE_NAME_CLASS1_CH = ("sd.cn.", "CH")
  24. ZONE_NAME_CLASS2_IN = ("tw.cn", "IN")
  25. MAX_TRANSFER_TIMEOUT = 14400
  26. LOWERBOUND_REFRESH = 10
  27. LOWERBOUND_RETRY = 5
  28. JITTER_SCOPE = 0.10
  29. class ZonemgrTestException(Exception):
  30. pass
  31. class MySession():
  32. def __init__(self):
  33. pass
  34. def group_sendmsg(self, msg, module_name):
  35. if module_name not in ("Auth", "Xfrin"):
  36. raise ZonemgrTestException("module name not exist")
  37. class MyZonemgrRefresh(ZonemgrRefresh):
  38. def __init__(self):
  39. class FakeConfig:
  40. def get(self, name):
  41. if name == 'lowerbound_refresh':
  42. return LOWERBOUND_REFRESH
  43. elif name == 'lowerbound_retry':
  44. return LOWERBOUND_RETRY
  45. elif name == 'max_transfer_timeout':
  46. return MAX_TRANSFER_TIMEOUT
  47. elif name == 'jitter_scope':
  48. return JITTER_SCOPE
  49. else:
  50. raise ValueError('Uknown config option')
  51. self._master_socket, self._slave_socket = socket.socketpair()
  52. ZonemgrRefresh.__init__(self, MySession(), "initdb.file",
  53. self._slave_socket, FakeConfig())
  54. current_time = time.time()
  55. self._zonemgr_refresh_info = {
  56. ('sd.cn.', 'IN'): {
  57. 'last_refresh_time': current_time,
  58. 'next_refresh_time': current_time + 6500,
  59. 'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600',
  60. 'zone_state': 0},
  61. ('tw.cn', 'CH'): {
  62. 'last_refresh_time': current_time,
  63. 'next_refresh_time': current_time + 6900,
  64. 'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073112 7200 3600 2419200 21600',
  65. 'zone_state': 0}
  66. }
  67. class TestZonemgrRefresh(unittest.TestCase):
  68. def setUp(self):
  69. self.stderr_backup = sys.stderr
  70. sys.stderr = open(os.devnull, 'w')
  71. self.zone_refresh = MyZonemgrRefresh()
  72. def test_random_jitter(self):
  73. max = 100025.120
  74. jitter = 0
  75. self.assertEqual(max, self.zone_refresh._random_jitter(max, jitter))
  76. jitter = max / 4
  77. for i in range (0, 150):
  78. self.assertTrue((3 * max / 4) <= self.zone_refresh._random_jitter(max, jitter))
  79. self.assertTrue(self.zone_refresh._random_jitter(max, jitter) <= max)
  80. i += 1;
  81. def test_get_current_time(self):
  82. pass
  83. def test_set_zone_timer(self):
  84. max = 3600
  85. jitter = 900
  86. time1 = time.time()
  87. self.zone_refresh._set_zone_timer(ZONE_NAME_CLASS1_IN, 3600, 900)
  88. time2 = time.time()
  89. zone_timeout = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"]
  90. self.assertTrue((3600 - 900) <= (zone_timeout - time1))
  91. self.assertTrue((zone_timeout - time2) <= 3600)
  92. def test_set_zone_refresh_timer(self):
  93. time1 = time.time()
  94. self.zone_refresh._set_zone_refresh_timer(ZONE_NAME_CLASS1_IN)
  95. zone_timeout = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"]
  96. time2 = time.time()
  97. self.assertTrue((time1 + 7200 * 3 / 4) <= zone_timeout)
  98. self.assertTrue(zone_timeout <= time2 + 7200)
  99. def test_set_zone_retry_timer(self):
  100. time1 = time.time()
  101. self.zone_refresh._set_zone_retry_timer(ZONE_NAME_CLASS1_IN)
  102. zone_timeout = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"]
  103. time2 = time.time()
  104. self.assertTrue((time1 + 3600 * 3 / 4) <= zone_timeout)
  105. self.assertTrue(zone_timeout <= time2 + 3600)
  106. def test_zone_not_exist(self):
  107. self.assertFalse(self.zone_refresh._zone_not_exist(ZONE_NAME_CLASS1_IN))
  108. self.assertTrue(self.zone_refresh._zone_not_exist(ZONE_NAME_CLASS1_CH))
  109. self.assertFalse(self.zone_refresh._zone_not_exist(ZONE_NAME_CLASS2_CH))
  110. self.assertTrue(self.zone_refresh._zone_not_exist(ZONE_NAME_CLASS2_IN))
  111. self.assertTrue(self.zone_refresh._zone_not_exist(ZONE_NAME_CLASS3_IN))
  112. def test_set_zone_notify_timer(self):
  113. time1 = time.time()
  114. self.zone_refresh._set_zone_notify_timer(ZONE_NAME_CLASS1_IN)
  115. zone_timeout = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"]
  116. time2 = time.time()
  117. self.assertTrue(time1 <= zone_timeout)
  118. self.assertTrue(zone_timeout <= time2)
  119. def test_zone_is_expired(self):
  120. current_time = time.time()
  121. zone_expired_time = 2419200
  122. self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["last_refresh_time"] = \
  123. current_time - zone_expired_time - 1
  124. self.assertTrue(self.zone_refresh._zone_is_expired(ZONE_NAME_CLASS1_IN))
  125. self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["last_refresh_time"] = \
  126. current_time - zone_expired_time + 1
  127. self.assertFalse(self.zone_refresh._zone_is_expired(ZONE_NAME_CLASS1_IN))
  128. self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"] = ZONE_EXPIRED
  129. self.assertTrue(self.zone_refresh._zone_is_expired(ZONE_NAME_CLASS1_IN))
  130. def test_get_zone_soa_rdata(self):
  131. soa_rdata1 = 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600'
  132. soa_rdata2 = 'a.dns.cn. root.cnnic.cn. 2009073112 7200 3600 2419200 21600'
  133. self.assertEqual(soa_rdata1, self.zone_refresh._get_zone_soa_rdata(ZONE_NAME_CLASS1_IN))
  134. self.assertRaises(KeyError, self.zone_refresh._get_zone_soa_rdata, ZONE_NAME_CLASS1_CH)
  135. self.assertEqual(soa_rdata2, self.zone_refresh._get_zone_soa_rdata(ZONE_NAME_CLASS2_CH))
  136. self.assertRaises(KeyError, self.zone_refresh._get_zone_soa_rdata, ZONE_NAME_CLASS2_IN)
  137. def test_zonemgr_reload_zone(self):
  138. soa_rdata = 'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600'
  139. # We need to restore this not to harm other tests
  140. old_get_zone_soa = sqlite3_ds.get_zone_soa
  141. def get_zone_soa(zone_name, db_file):
  142. return (1, 2, 'sd.cn.', 'cn.sd.', 21600, 'SOA', None,
  143. 'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600')
  144. sqlite3_ds.get_zone_soa = get_zone_soa
  145. self.zone_refresh.zonemgr_reload_zone(ZONE_NAME_CLASS1_IN)
  146. self.assertEqual(soa_rdata, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_soa_rdata"])
  147. sqlite3_ds.get_zone_soa = old_get_zone_soa
  148. def test_get_zone_notifier_master(self):
  149. notify_master = "192.168.1.1"
  150. self.assertEqual(None, self.zone_refresh._get_zone_notifier_master(ZONE_NAME_CLASS1_IN))
  151. self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["notify_master"] = notify_master
  152. self.assertEqual(notify_master, self.zone_refresh._get_zone_notifier_master(ZONE_NAME_CLASS1_IN))
  153. def test_set_zone_notifier_master(self):
  154. notify_master = "192.168.1.1"
  155. self.zone_refresh._set_zone_notifier_master(ZONE_NAME_CLASS1_IN, notify_master)
  156. self.assertEqual(self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]\
  157. ["notify_master"], notify_master)
  158. def test_clear_zone_notifier_master(self):
  159. notify_master = "192.168.1.1"
  160. self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["notify_master"] = notify_master
  161. self.zone_refresh._clear_zone_notifier_master(ZONE_NAME_CLASS1_IN)
  162. self.assertFalse("notify_master" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
  163. self.zone_refresh._clear_zone_notifier_master(ZONE_NAME_CLASS2_CH)
  164. self.assertFalse("notify_master" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS2_CH].keys())
  165. def test_get_zone_state(self):
  166. self.assertEqual(ZONE_OK, self.zone_refresh._get_zone_state(ZONE_NAME_CLASS1_IN))
  167. self.assertEqual(ZONE_OK, self.zone_refresh._get_zone_state(ZONE_NAME_CLASS2_CH))
  168. def test_set_zone_state(self):
  169. self.zone_refresh._set_zone_state(ZONE_NAME_CLASS1_IN, ZONE_REFRESHING)
  170. self.zone_refresh._set_zone_state(ZONE_NAME_CLASS2_CH, ZONE_EXPIRED)
  171. self.assertEqual(ZONE_REFRESHING, \
  172. self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"])
  173. self.assertEqual(ZONE_EXPIRED, \
  174. self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS2_CH]["zone_state"])
  175. def test_get_zone_refresh_timeout(self):
  176. current_time = time.time()
  177. self.assertFalse("refresh_timeout" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
  178. self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["refresh_timeout"] = current_time
  179. self.assertEqual(current_time, self.zone_refresh._get_zone_refresh_timeout(ZONE_NAME_CLASS1_IN))
  180. def test_set_zone_refresh_timeout(self):
  181. current_time = time.time()
  182. self.zone_refresh._set_zone_refresh_timeout(ZONE_NAME_CLASS1_IN, current_time)
  183. refresh_time = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["refresh_timeout"]
  184. self.assertEqual(current_time, refresh_time)
  185. def test_get_zone_next_refresh_time(self):
  186. current_time = time.time()
  187. self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"] = current_time
  188. self.assertEqual(current_time, self.zone_refresh._get_zone_next_refresh_time(ZONE_NAME_CLASS1_IN))
  189. def test_set_zone_next_refresh_time(self):
  190. current_time = time.time()
  191. self.zone_refresh._set_zone_next_refresh_time(ZONE_NAME_CLASS1_IN, current_time)
  192. next_refresh_time = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"]
  193. self.assertEqual(current_time, next_refresh_time)
  194. def test_get_zone_last_refresh_time(self):
  195. current_time = time.time()
  196. self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["last_refresh_time"] = current_time
  197. self.assertEqual(current_time, self.zone_refresh._get_zone_last_refresh_time(ZONE_NAME_CLASS1_IN))
  198. def test_set_zone_last_refresh_time(self):
  199. current_time = time.time()
  200. self.zone_refresh._set_zone_last_refresh_time(ZONE_NAME_CLASS1_IN, current_time)
  201. last_refresh_time = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["last_refresh_time"]
  202. self.assertEqual(current_time, last_refresh_time)
  203. def test_send_command(self):
  204. self.assertRaises(ZonemgrTestException, self.zone_refresh._send_command, "Unknown", "Notify", None)
  205. def test_zone_mgr_is_empty(self):
  206. self.assertFalse(self.zone_refresh._zone_mgr_is_empty())
  207. self.zone_refresh._zonemgr_refresh_info = {}
  208. self.assertTrue(self.zone_refresh._zone_mgr_is_empty())
  209. def test_zonemgr_add_zone(self):
  210. soa_rdata = 'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600'
  211. # This needs to be restored. The following test actually failed if we left
  212. # this unclean
  213. old_get_zone_soa = sqlite3_ds.get_zone_soa
  214. def get_zone_soa(zone_name, db_file):
  215. return (1, 2, 'sd.cn.', 'cn.sd.', 21600, 'SOA', None,
  216. 'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600')
  217. sqlite3_ds.get_zone_soa = get_zone_soa
  218. self.zone_refresh._zonemgr_refresh_info = {}
  219. self.zone_refresh.zonemgr_add_zone(ZONE_NAME_CLASS1_IN)
  220. self.assertEqual(1, len(self.zone_refresh._zonemgr_refresh_info))
  221. zone_soa_rdata = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_soa_rdata"]
  222. self.assertEqual(soa_rdata, zone_soa_rdata)
  223. self.assertEqual(ZONE_OK, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"])
  224. self.assertTrue("last_refresh_time" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
  225. self.assertTrue("next_refresh_time" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
  226. def get_zone_soa2(zone_name, db_file):
  227. return None
  228. sqlite3_ds.get_zone_soa = get_zone_soa2
  229. self.assertRaises(ZonemgrException, self.zone_refresh.zonemgr_add_zone, \
  230. ZONE_NAME_CLASS1_IN)
  231. sqlite3_ds.get_zone_soa = old_get_zone_soa
  232. def test_build_zonemgr_refresh_info(self):
  233. soa_rdata = 'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600'
  234. def get_zones_info(db_file):
  235. return [("sd.cn.", "IN")]
  236. def get_zone_soa(zone_name, db_file):
  237. return (1, 2, 'sd.cn.', 'cn.sd.', 21600, 'SOA', None,
  238. 'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600')
  239. sqlite3_ds.get_zones_info = get_zones_info
  240. sqlite3_ds.get_zone_soa = get_zone_soa
  241. self.zone_refresh._zonemgr_refresh_info = {}
  242. self.zone_refresh._build_zonemgr_refresh_info()
  243. self.assertEqual(1, len(self.zone_refresh._zonemgr_refresh_info))
  244. zone_soa_rdata = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_soa_rdata"]
  245. self.assertEqual(soa_rdata, zone_soa_rdata)
  246. self.assertEqual(ZONE_OK, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"])
  247. self.assertTrue("last_refresh_time" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
  248. self.assertTrue("next_refresh_time" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
  249. def test_zone_handle_notify(self):
  250. self.zone_refresh.zone_handle_notify(ZONE_NAME_CLASS1_IN,"127.0.0.1")
  251. notify_master = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["notify_master"]
  252. self.assertEqual("127.0.0.1", notify_master)
  253. zone_timeout = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"]
  254. current_time = time.time()
  255. self.assertTrue(zone_timeout <= current_time)
  256. self.assertRaises(ZonemgrException, self.zone_refresh.zone_handle_notify,\
  257. ("org.cn.", "IN"), "127.0.0.1")
  258. self.assertRaises(ZonemgrException, self.zone_refresh.zone_handle_notify,\
  259. ZONE_NAME_CLASS3_IN, "127.0.0.1")
  260. def test_zone_refresh_success(self):
  261. soa_rdata = 'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600'
  262. def get_zone_soa(zone_name, db_file):
  263. return (1, 2, 'sd.cn.', 'cn.sd.', 21600, 'SOA', None,
  264. 'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600')
  265. sqlite3_ds.get_zone_soa = get_zone_soa
  266. time1 = time.time()
  267. self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"] = ZONE_REFRESHING
  268. self.zone_refresh.zone_refresh_success(ZONE_NAME_CLASS1_IN)
  269. time2 = time.time()
  270. zone_soa_rdata = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_soa_rdata"]
  271. self.assertEqual(soa_rdata, zone_soa_rdata)
  272. next_refresh_time = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"]
  273. self.assertTrue((time1 + 3 * 1800 / 4) <= next_refresh_time)
  274. self.assertTrue(next_refresh_time <= time2 + 1800)
  275. self.assertEqual(ZONE_OK, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"])
  276. last_refresh_time = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["last_refresh_time"]
  277. self.assertTrue(time1 <= last_refresh_time)
  278. self.assertTrue(last_refresh_time <= time2)
  279. self.assertRaises(ZonemgrException, self.zone_refresh.zone_refresh_success, ("org.cn.", "CH"))
  280. self.assertRaises(ZonemgrException, self.zone_refresh.zone_refresh_success, ZONE_NAME_CLASS3_IN)
  281. def test_zone_refresh_fail(self):
  282. soa_rdata = 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600'
  283. time1 = time.time()
  284. self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"] = ZONE_REFRESHING
  285. self.zone_refresh.zone_refresh_fail(ZONE_NAME_CLASS1_IN)
  286. time2 = time.time()
  287. zone_soa_rdata = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_soa_rdata"]
  288. self.assertEqual(soa_rdata, zone_soa_rdata)
  289. next_refresh_time = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"]
  290. self.assertTrue((time1 + 3 * 3600 / 4) <= next_refresh_time)
  291. self.assertTrue(next_refresh_time <= time2 + 3600)
  292. self.assertEqual(ZONE_OK, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"])
  293. self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["last_refresh_time"] = time1 - 2419200
  294. self.zone_refresh.zone_refresh_fail(ZONE_NAME_CLASS1_IN)
  295. self.assertEqual(ZONE_EXPIRED, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"])
  296. self.assertRaises(ZonemgrException, self.zone_refresh.zone_refresh_fail, ("org.cn.", "CH"))
  297. self.assertRaises(ZonemgrException, self.zone_refresh.zone_refresh_fail, ZONE_NAME_CLASS3_IN)
  298. def test_find_need_do_refresh_zone(self):
  299. time1 = time.time()
  300. self.zone_refresh._zonemgr_refresh_info = {
  301. ("sd.cn.","IN"):{
  302. 'last_refresh_time': time1,
  303. 'next_refresh_time': time1 + 7200,
  304. 'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600',
  305. 'zone_state': ZONE_OK},
  306. ("tw.cn","CH"):{
  307. 'last_refresh_time': time1 - 7200,
  308. 'next_refresh_time': time1,
  309. 'refresh_timeout': time1 + MAX_TRANSFER_TIMEOUT,
  310. 'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073112 7200 3600 2419200 21600',
  311. 'zone_state': ZONE_REFRESHING}
  312. }
  313. zone_need_refresh = self.zone_refresh._find_need_do_refresh_zone()
  314. self.assertEqual(ZONE_NAME_CLASS1_IN, zone_need_refresh)
  315. self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS2_CH]["refresh_timeout"] = time1
  316. zone_need_refresh = self.zone_refresh._find_need_do_refresh_zone()
  317. self.assertEqual(ZONE_NAME_CLASS2_CH, zone_need_refresh)
  318. def test_do_refresh(self):
  319. time1 = time.time()
  320. self.zone_refresh._zonemgr_refresh_info = {
  321. ("sd.cn.", "IN"):{
  322. 'last_refresh_time': time1 - 7200,
  323. 'next_refresh_time': time1 - 1,
  324. 'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600',
  325. 'zone_state': ZONE_OK}
  326. }
  327. self.zone_refresh._do_refresh(ZONE_NAME_CLASS1_IN)
  328. time2 = time.time()
  329. zone_state = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"]
  330. self.assertEqual(ZONE_REFRESHING, zone_state)
  331. refresh_timeout = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["refresh_timeout"]
  332. self.assertTrue(time1 + MAX_TRANSFER_TIMEOUT <= refresh_timeout)
  333. self.assertTrue(time2 + MAX_TRANSFER_TIMEOUT >= refresh_timeout)
  334. self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["notify_master"] = "127.0.0.1"
  335. self.zone_refresh._do_refresh(ZONE_NAME_CLASS1_IN)
  336. time2 = time.time()
  337. zone_state = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"]
  338. self.assertEqual(ZONE_REFRESHING, zone_state)
  339. refresh_timeout = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["refresh_timeout"]
  340. self.assertTrue(time1 + MAX_TRANSFER_TIMEOUT <= refresh_timeout)
  341. self.assertTrue(time2 + MAX_TRANSFER_TIMEOUT >= refresh_timeout)
  342. self.assertFalse("notify_master" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
  343. def test_run_timer(self):
  344. """This case will run timer in daemon thread.
  345. The zone's next_refresh_time is less than now, so zonemgr will do zone refresh
  346. immediately. The zone's state will become "refreshing".
  347. """
  348. time1 = time.time()
  349. self.zone_refresh._zonemgr_refresh_info = {
  350. ("sd.cn.", "IN"):{
  351. 'last_refresh_time': time1 - 7200,
  352. 'next_refresh_time': time1 - 1,
  353. 'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600',
  354. 'zone_state': ZONE_OK}
  355. }
  356. self.zone_refresh._check_sock = self.zone_refresh._master_socket
  357. listener = self.zone_refresh.run_timer(daemon=True)
  358. # Shut down the timer thread
  359. self.zone_refresh.shutdown()
  360. # After running timer, the zone's state should become "refreshing".
  361. zone_state = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"]
  362. self.assertTrue("refresh_timeout" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
  363. self.assertTrue(zone_state == ZONE_REFRESHING)
  364. def test_update_config_data(self):
  365. config_data = {
  366. "lowerbound_refresh" : 60,
  367. "lowerbound_retry" : 30,
  368. "max_transfer_timeout" : 19800,
  369. "jitter_scope" : 0.25
  370. }
  371. self.zone_refresh.update_config_data(config_data)
  372. self.assertEqual(60, self.zone_refresh._lowerbound_refresh)
  373. self.assertEqual(30, self.zone_refresh._lowerbound_retry)
  374. self.assertEqual(19800, self.zone_refresh._max_transfer_timeout)
  375. self.assertEqual(0.25, self.zone_refresh._jitter_scope)
  376. def test_shutdown(self):
  377. self.zone_refresh._check_sock = self.zone_refresh._master_socket
  378. listener = self.zone_refresh.run_timer()
  379. self.assertTrue(listener.is_alive())
  380. # Shut down the timer thread
  381. self.zone_refresh.shutdown()
  382. self.assertFalse(listener.is_alive())
  383. def tearDown(self):
  384. sys.stderr= self.stderr_backup
  385. class MyCCSession():
  386. def __init__(self):
  387. pass
  388. def get_remote_config_value(self, module_name, identifier):
  389. if module_name == "Auth" and identifier == "database_file":
  390. return "initdb.file", False
  391. else:
  392. return "unknown", False
  393. class MyZonemgr(Zonemgr):
  394. def __init__(self):
  395. self._db_file = "initdb.file"
  396. self._zone_refresh = None
  397. self._shutdown_event = threading.Event()
  398. self._cc = MySession()
  399. self._module_cc = MyCCSession()
  400. self._config_data = {
  401. "lowerbound_refresh" : 10,
  402. "lowerbound_retry" : 5,
  403. "max_transfer_timeout" : 14400,
  404. "jitter_scope" : 0.1
  405. }
  406. def _start_zone_refresh_timer(self):
  407. pass
  408. class TestZonemgr(unittest.TestCase):
  409. def setUp(self):
  410. self.zonemgr = MyZonemgr()
  411. def test_config_handler(self):
  412. config_data1 = {
  413. "lowerbound_refresh" : 60,
  414. "lowerbound_retry" : 30,
  415. "max_transfer_timeout" : 14400,
  416. "jitter_scope" : 0.1
  417. }
  418. self.zonemgr.config_handler(config_data1)
  419. self.assertEqual(config_data1, self.zonemgr._config_data)
  420. config_data2 = {"zone_name" : "sd.cn.", "port" : "53", "master" : "192.168.1.1"}
  421. self.zonemgr.config_handler(config_data2)
  422. self.assertEqual(config_data1, self.zonemgr._config_data)
  423. # jitter should not be bigger than half of the original value
  424. config_data3 = {"jitter_scope" : 0.7}
  425. self.zonemgr.config_handler(config_data3)
  426. self.assertEqual(0.5, self.zonemgr._config_data.get("jitter_scope"))
  427. def test_get_db_file(self):
  428. self.assertEqual("initdb.file", self.zonemgr.get_db_file())
  429. def test_parse_cmd_params(self):
  430. params1 = {"zone_name" : "org.cn", "zone_class" : "CH", "master" : "127.0.0.1"}
  431. answer1 = (("org.cn", "CH"), "127.0.0.1")
  432. self.assertEqual(answer1, self.zonemgr._parse_cmd_params(params1, ZONE_NOTIFY_COMMAND))
  433. params2 = {"zone_name" : "org.cn", "zone_class" : "CH"}
  434. answer2 = ("org.cn", "CH")
  435. self.assertEqual(answer2, self.zonemgr._parse_cmd_params(params2, ZONE_XFRIN_SUCCESS_COMMAND))
  436. self.assertRaises(ZonemgrException, self.zonemgr._parse_cmd_params, params2, ZONE_NOTIFY_COMMAND)
  437. params1 = {"zone_class" : "CH"}
  438. self.assertRaises(ZonemgrException, self.zonemgr._parse_cmd_params, params2, ZONE_NOTIFY_COMMAND)
  439. def test_config_data_check(self):
  440. # jitter should not be bigger than half of the original value
  441. config_data2 = {"jitter_scope" : 0.2}
  442. config_data3 = {"jitter_scope" : 0.6}
  443. self.zonemgr._config_data_check(config_data2)
  444. self.assertEqual(0.2, config_data2.get("jitter_scope"))
  445. self.zonemgr._config_data_check(config_data3)
  446. self.assertEqual(0.5, config_data3.get("jitter_scope"))
  447. def tearDown(self):
  448. pass
  449. if __name__== "__main__":
  450. unittest.main()