zonemgr_test.py 24.9 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Copyright (C) 2010  Internet Systems Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

16
'''Tests for the ZonemgrRefresh and Zonemgr classes '''
17
18
19
20
21
22
23


import unittest
import os
import tempfile
from zonemgr import *

24
25
26
27
28
ZONE_NAME_CLASS1_IN = ("sd.cn.", "IN")
ZONE_NAME_CLASS2_CH = ("tw.cn", "CH")
ZONE_NAME_CLASS3_IN = ("example.com", "IN")
ZONE_NAME_CLASS1_CH = ("sd.cn.", "CH")
ZONE_NAME_CLASS2_IN = ("tw.cn", "IN")
29

30
31
32
33
34
MAX_TRANSFER_TIMEOUT = 14400
LOWERBOUND_REFRESH = 10
LOWERBOUND_RETRY = 5 
JITTER_SCOPE = 0.10

35
36
37
38
39
40
41
42
43
44
45
class ZonemgrTestException(Exception):
    pass

class MySession():
    def __init__(self):
        pass

    def group_sendmsg(self, msg, module_name):
        if module_name not in ("Auth", "Xfrin"):
            raise ZonemgrTestException("module name not exist")

46
class MyZonemgrRefresh(ZonemgrRefresh):
47
48
49
    def __init__(self):
        self._cc = MySession()
        self._db_file = "initdb.file"
50
        current_time = time.time()
51
52
53
54
        self._max_transfer_timeout = MAX_TRANSFER_TIMEOUT
        self._lowerbound_refresh = LOWERBOUND_REFRESH
        self._lowerbound_retry = LOWERBOUND_RETRY
        self._jitter_scope = JITTER_SCOPE
Jerry's avatar
Jerry committed
55
56
        self._zonemgr_refresh_info = { 
         ('sd.cn.', 'IN'): {
57
58
         'last_refresh_time': current_time,
         'next_refresh_time': current_time + 6500, 
59
60
         'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600', 
         'zone_state': 0},
61
         ('tw.cn', 'CH'): {
62
63
         'last_refresh_time': current_time, 
         'next_refresh_time': current_time + 6900, 
64
65
         'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073112 7200 3600 2419200 21600', 
         'zone_state': 0}
Jerry's avatar
Jerry committed
66
        } 
67

68
class TestZonemgrRefresh(unittest.TestCase):
69
70
    def setUp(self):
        self.stdout_backup = sys.stdout
Jerry's avatar
Jerry committed
71
        sys.stdout = open(os.devnull, 'w')
72
        self.zone_refresh = MyZonemgrRefresh()
73
74
75
76

    def test_random_jitter(self):
        max = 100025.120
        jitter = 0
77
        self.assertEqual(max, self.zone_refresh._random_jitter(max, jitter))
78
        jitter = max / 4
79
80
81
82
        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) 
            i += 1;
83
84
85
86

    def test_get_current_time(self):
        pass

87
    def test_set_zone_timer(self):
88
89
90
        max = 3600
        jitter = 900
        time1 = time.time()
91
        self.zone_refresh._set_zone_timer(ZONE_NAME_CLASS1_IN, 3600, 900)
92
        time2 = time.time()
93
        zone_timeout = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"]
94
95
96
        self.assertTrue((3600 - 900) <= (zone_timeout - time1))
        self.assertTrue((zone_timeout - time2) <= 3600)

97
    def test_set_zone_refresh_timer(self):
98
        time1 = time.time()
99
100
        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"]
101
102
103
104
        time2 = time.time()
        self.assertTrue((time1 + 7200 * 3 / 4) <= zone_timeout)
        self.assertTrue(zone_timeout <= time2 + 7200)
        
105
    def test_set_zone_retry_timer(self):
106
        time1 = time.time()
107
108
        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"]
109
110
111
112
        time2 = time.time()
        self.assertTrue((time1 + 3600 * 3 / 4) <= zone_timeout)
        self.assertTrue(zone_timeout <= time2 + 3600)

Jerry's avatar
Jerry committed
113
    def test_zone_not_exist(self):
114
115
116
117
118
        self.assertFalse(self.zone_refresh._zone_not_exist(ZONE_NAME_CLASS1_IN))
        self.assertTrue(self.zone_refresh._zone_not_exist(ZONE_NAME_CLASS1_CH))
        self.assertFalse(self.zone_refresh._zone_not_exist(ZONE_NAME_CLASS2_CH))
        self.assertTrue(self.zone_refresh._zone_not_exist(ZONE_NAME_CLASS2_IN))
        self.assertTrue(self.zone_refresh._zone_not_exist(ZONE_NAME_CLASS3_IN))
Jerry's avatar
Jerry committed
119

120
    def test_set_zone_notify_timer(self):
121
        time1 = time.time()
122
123
        self.zone_refresh._set_zone_notify_timer(ZONE_NAME_CLASS1_IN)
        zone_timeout = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"]
124
125
126
127
128
129
130
        time2 = time.time()
        self.assertTrue(time1 <= zone_timeout)
        self.assertTrue(zone_timeout <= time2)

    def test_zone_is_expired(self):
        current_time = time.time()
        zone_expired_time = 2419200
131
        self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["last_refresh_time"] = \
Jerry's avatar
Jerry committed
132
                                                  current_time - zone_expired_time - 1
133
134
        self.assertTrue(self.zone_refresh._zone_is_expired(ZONE_NAME_CLASS1_IN))
        self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["last_refresh_time"] = \
Jerry's avatar
Jerry committed
135
                                                  current_time - zone_expired_time + 1
136
137
138
        self.assertFalse(self.zone_refresh._zone_is_expired(ZONE_NAME_CLASS1_IN))
        self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"] = ZONE_EXPIRED
        self.assertTrue(self.zone_refresh._zone_is_expired(ZONE_NAME_CLASS1_IN))
139
140
141
142

    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' 
143
144
145
146
        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)
147
148
149
150
151
152
153
154
         
    def test_zonemgr_reload_zone(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, 
                    'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600')
        sqlite3_ds.get_zone_soa = get_zone_soa

155
156
        self.zone_refresh.zonemgr_reload_zone(ZONE_NAME_CLASS1_IN)
        self.assertEqual(soa_rdata, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_soa_rdata"])
157
158

    def test_get_zone_notifier_master(self):
Jerry's avatar
Jerry committed
159
        notify_master = "192.168.1.1"
160
161
162
        self.assertEqual(None, self.zone_refresh._get_zone_notifier_master(ZONE_NAME_CLASS1_IN))
        self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["notify_master"] = notify_master
        self.assertEqual(notify_master, self.zone_refresh._get_zone_notifier_master(ZONE_NAME_CLASS1_IN))
163
164

    def test_set_zone_notifier_master(self):
Jerry's avatar
Jerry committed
165
        notify_master = "192.168.1.1"
166
167
        self.zone_refresh._set_zone_notifier_master(ZONE_NAME_CLASS1_IN, notify_master)
        self.assertEqual(self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]\
Jerry's avatar
Jerry committed
168
                                                                ["notify_master"], notify_master)
169
170

    def test_clear_zone_notifier_master(self):
Jerry's avatar
Jerry committed
171
        notify_master = "192.168.1.1"
172
173
174
175
176
        self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["notify_master"] = notify_master
        self.zone_refresh._clear_zone_notifier_master(ZONE_NAME_CLASS1_IN)
        self.assertFalse("notify_master" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
        self.zone_refresh._clear_zone_notifier_master(ZONE_NAME_CLASS2_CH)
        self.assertFalse("notify_master" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS2_CH].keys())
177
178

    def test_get_zone_state(self):
179
180
        self.assertEqual(ZONE_OK, self.zone_refresh._get_zone_state(ZONE_NAME_CLASS1_IN))
        self.assertEqual(ZONE_OK, self.zone_refresh._get_zone_state(ZONE_NAME_CLASS2_CH))
181
182

    def test_set_zone_state(self):
183
184
        self.zone_refresh._set_zone_state(ZONE_NAME_CLASS1_IN, ZONE_REFRESHING)
        self.zone_refresh._set_zone_state(ZONE_NAME_CLASS2_CH, ZONE_EXPIRED)
Jerry's avatar
Jerry committed
185
        self.assertEqual(ZONE_REFRESHING, \
186
                self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"])
Jerry's avatar
Jerry committed
187
        self.assertEqual(ZONE_EXPIRED, \
188
                self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS2_CH]["zone_state"])
189
190
191

    def test_get_zone_refresh_timeout(self):
        current_time = time.time()
192
193
194
        self.assertFalse("refresh_timeout" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
        self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["refresh_timeout"] = current_time
        self.assertEqual(current_time, self.zone_refresh._get_zone_refresh_timeout(ZONE_NAME_CLASS1_IN))
195
196
197

    def test_set_zone_refresh_timeout(self):
        current_time = time.time()
198
199
        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"]
Jerry's avatar
Jerry committed
200
        self.assertEqual(current_time, refresh_time) 
201

202
    def test_get_zone_next_refresh_time(self):
203
        current_time = time.time()
204
205
        self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"] = current_time
        self.assertEqual(current_time, self.zone_refresh._get_zone_next_refresh_time(ZONE_NAME_CLASS1_IN))
206

207
    def test_set_zone_next_refresh_time(self):
208
        current_time = time.time()
209
210
        self.zone_refresh._set_zone_next_refresh_time(ZONE_NAME_CLASS1_IN, current_time)
        next_refresh_time = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"]
Jerry's avatar
Jerry committed
211
        self.assertEqual(current_time, next_refresh_time)
212
213
214

    def test_get_zone_last_refresh_time(self):
        current_time = time.time()
215
216
        self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["last_refresh_time"] = current_time
        self.assertEqual(current_time, self.zone_refresh._get_zone_last_refresh_time(ZONE_NAME_CLASS1_IN))
217
218
219

    def test_set_zone_last_refresh_time(self):
        current_time = time.time()
220
221
        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"]
Jerry's avatar
Jerry committed
222
        self.assertEqual(current_time, last_refresh_time) 
223
224

    def test_send_command(self):
225
        self.assertRaises(ZonemgrTestException, self.zone_refresh._send_command, "Unknown", "Notify", None)
226
227

    def test_zone_mgr_is_empty(self):
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
        self.assertFalse(self.zone_refresh._zone_mgr_is_empty())
        self.zone_refresh._zonemgr_refresh_info = {} 
        self.assertTrue(self.zone_refresh._zone_mgr_is_empty())

    def test_zonemgr_add_zone(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, 
                    'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600')

        sqlite3_ds.get_zone_soa = get_zone_soa

        self.zone_refresh._zonemgr_refresh_info = {}
        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(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())

        def get_zone_soa2(zone_name, db_file):
            return None
        sqlite3_ds.get_zone_soa = get_zone_soa2
        self.assertRaises(ZonemgrException, self.zone_refresh.zonemgr_add_zone, \
                                          ZONE_NAME_CLASS1_IN)
255
256
257
258

    def test_build_zonemgr_refresh_info(self):
        soa_rdata = 'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600'

Jerry's avatar
Jerry committed
259
        def get_zones_info(db_file):
Jerry's avatar
Jerry committed
260
            return [("sd.cn.", "IN")] 
261
262
263
264
265

        def get_zone_soa(zone_name, db_file):
            return (1, 2, 'sd.cn.', 'cn.sd.', 21600, 'SOA', None, 
                    'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600')

Jerry's avatar
Jerry committed
266
        sqlite3_ds.get_zones_info = get_zones_info
267
268
        sqlite3_ds.get_zone_soa = get_zone_soa

269
270
271
272
        self.zone_refresh._zonemgr_refresh_info = {}
        self.zone_refresh._build_zonemgr_refresh_info()
        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"]
Jerry's avatar
Jerry committed
273
        self.assertEqual(soa_rdata, zone_soa_rdata) 
274
275
276
        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())
277
278

    def test_zone_handle_notify(self):
279
280
        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"]
Jerry's avatar
Jerry committed
281
        self.assertEqual("127.0.0.1", notify_master) 
282
        zone_timeout = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"]
283
284
        current_time = time.time()
        self.assertTrue(zone_timeout <= current_time)
285
286
287
288
        self.assertRaises(ZonemgrException, self.zone_refresh.zone_handle_notify,\
                          ("org.cn.", "IN"), "127.0.0.1")
        self.assertRaises(ZonemgrException, self.zone_refresh.zone_handle_notify,\
                          ZONE_NAME_CLASS3_IN, "127.0.0.1")
289
290
291
292
293
294
295
296

    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, 
                    'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600')
        sqlite3_ds.get_zone_soa = get_zone_soa
        time1 = time.time()
297
298
        self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"] = ZONE_REFRESHING
        self.zone_refresh.zone_refresh_success(ZONE_NAME_CLASS1_IN)
299
        time2 = time.time()
300
        zone_soa_rdata = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_soa_rdata"]
Jerry's avatar
Jerry committed
301
        self.assertEqual(soa_rdata, zone_soa_rdata) 
302
        next_refresh_time = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"]
Jerry's avatar
Jerry committed
303
304
        self.assertTrue((time1 + 3 * 1800 / 4) <= next_refresh_time) 
        self.assertTrue(next_refresh_time <= time2 + 1800)
305
306
        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"]
Jerry's avatar
Jerry committed
307
308
        self.assertTrue(time1 <= last_refresh_time)
        self.assertTrue(last_refresh_time <= time2)
309
310
        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) 
311
312
313
314

    def test_zone_refresh_fail(self):
        soa_rdata = 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600' 
        time1 = time.time()
315
316
        self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"] = ZONE_REFRESHING
        self.zone_refresh.zone_refresh_fail(ZONE_NAME_CLASS1_IN)
317
        time2 = time.time()
318
        zone_soa_rdata = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_soa_rdata"]
Jerry's avatar
Jerry committed
319
        self.assertEqual(soa_rdata, zone_soa_rdata)
320
        next_refresh_time = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["next_refresh_time"]
Jerry's avatar
Jerry committed
321
322
        self.assertTrue((time1 + 3 * 3600 / 4) <= next_refresh_time)
        self.assertTrue(next_refresh_time <= time2 + 3600)
323
        self.assertEqual(ZONE_OK, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"])
324
325
326
327
328

        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"])

329
330
        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) 
331

332
    def test_find_need_do_refresh_zone(self):
333
        time1 = time.time()
334
        self.zone_refresh._zonemgr_refresh_info = { 
Jerry's avatar
Jerry committed
335
336
337
338
339
                ("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', 
                    'zone_state': ZONE_OK},
340
                ("tw.cn","CH"):{
Jerry's avatar
Jerry committed
341
342
343
344
345
346
                    '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}
                }
347
348
        zone_need_refresh = self.zone_refresh._find_need_do_refresh_zone()
        self.assertEqual(ZONE_NAME_CLASS1_IN, zone_need_refresh)
Jerry's avatar
Jerry committed
349

350
351
352
        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)
353
354
355

    def test_do_refresh(self):
        time1 = time.time()
356
        self.zone_refresh._zonemgr_refresh_info = {
Jerry's avatar
Jerry committed
357
358
359
360
361
362
                ("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', 
                    'zone_state': ZONE_OK}
                }
363
        self.zone_refresh._do_refresh(ZONE_NAME_CLASS1_IN)
364
        time2 = time.time()
365
        zone_state = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"]
Jerry's avatar
Jerry committed
366
        self.assertEqual(ZONE_REFRESHING, zone_state)
367
        refresh_timeout = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["refresh_timeout"] 
Jerry's avatar
Jerry committed
368
369
370
        self.assertTrue(time1 + MAX_TRANSFER_TIMEOUT <= refresh_timeout)
        self.assertTrue(time2 + MAX_TRANSFER_TIMEOUT >= refresh_timeout) 

371
372
        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)
373
        time2 = time.time()
374
        zone_state = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"]
Jerry's avatar
Jerry committed
375
        self.assertEqual(ZONE_REFRESHING, zone_state) 
376
        refresh_timeout = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["refresh_timeout"] 
Jerry's avatar
Jerry committed
377
378
        self.assertTrue(time1 + MAX_TRANSFER_TIMEOUT <= refresh_timeout)
        self.assertTrue(time2 + MAX_TRANSFER_TIMEOUT >= refresh_timeout)
379
        self.assertFalse("notify_master" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
380

Jerry's avatar
Jerry committed
381
    def test_run_timer(self):
382
383
384
385
        """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". 
        Then closing the socket ,the timer will stop, and throw a ZonemgrException."""
Jerry's avatar
Jerry committed
386
        time1 = time.time()
387
        self.zone_refresh._zonemgr_refresh_info = {
Jerry's avatar
Jerry committed
388
389
390
391
392
393
394
                ("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', 
                    'zone_state': ZONE_OK}
                }
        master_socket, slave_socket = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM)
395
396
397
398
        self.zone_refresh._socket = master_socket 
        master_socket.close()
        self.assertRaises(ZonemgrException, self.zone_refresh.run_timer)

399
400
        self.zone_refresh._socket = slave_socket
        listener = threading.Thread(target = self.zone_refresh.run_timer, args = ())
Jerry's avatar
Jerry committed
401
402
        listener.setDaemon(True)
        listener.start()
403
404
        time.sleep(1)

405
406
        zone_state = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"]
        self.assertTrue("refresh_timeout" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
Jerry's avatar
Jerry committed
407
408
        self.assertTrue(zone_state == ZONE_REFRESHING)

409
410
411
412
413
414
415
416
417
418
419
420
421
    def test_update_config_data(self):
        config_data = {
                    "lowerbound_refresh" : 60,
                    "lowerbound_retry" : 30,
                    "max_transfer_timeout" : 19800,
                    "jitter_scope" : 0.25
                }
        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)

422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441

    def tearDown(self):
        sys.stdout = self.stdout_backup


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
        else:
            return "unknown", False


class MyZonemgr(Zonemgr):

    def __init__(self):
        self._db_file = "initdb.file"
442
        self._zone_refresh = None
443
444
445
        self._shutdown_event = threading.Event()
        self._cc = MySession()
        self._module_cc = MyCCSession()
446
447
448
449
450
451
        self._config_data = {
                    "lowerbound_refresh" : 10, 
                    "lowerbound_retry" : 5, 
                    "max_transfer_timeout" : 14400,
                    "jitter_scope" : 0.1
                    }
452
453
454
455
456
457
458
459
460
461

    def _start_zone_refresh_timer(self):
        pass

class TestZonemgr(unittest.TestCase):

    def setUp(self):
        self.zonemgr = MyZonemgr()

    def test_config_handler(self):
462
463
464
465
466
467
        config_data1 = {
                    "lowerbound_refresh" : 60, 
                    "lowerbound_retry" : 30, 
                    "max_transfer_timeout" : 14400,
                    "jitter_scope" : 0.1
                    }
468
469
470
471
472
        self.zonemgr.config_handler(config_data1)
        self.assertEqual(config_data1, self.zonemgr._config_data)
        config_data2 = {"zone_name" : "sd.cn.", "port" : "53", "master" : "192.168.1.1"}
        self.zonemgr.config_handler(config_data2)
        self.assertEqual(config_data1, self.zonemgr._config_data)
473
474
475
476
        # jitter should not be bigger than half of the original value
        config_data3 = {"jitter_scope" : 0.7}
        self.zonemgr.config_handler(config_data3)
        self.assertEqual(0.5, self.zonemgr._config_data.get("jitter_scope"))
477
478
479
480
481

    def test_get_db_file(self):
        self.assertEqual("initdb.file", self.zonemgr.get_db_file())
    
    def test_parse_cmd_params(self):
482
483
        params1 = {"zone_name" : "org.cn", "zone_class" : "CH", "master" : "127.0.0.1"}
        answer1 = (("org.cn", "CH"), "127.0.0.1")
Jerry's avatar
Jerry committed
484
        self.assertEqual(answer1, self.zonemgr._parse_cmd_params(params1, ZONE_NOTIFY_COMMAND))
485
486
        params2 = {"zone_name" : "org.cn", "zone_class" : "CH"}
        answer2 = ("org.cn", "CH")
Jerry's avatar
Jerry committed
487
488
        self.assertEqual(answer2, self.zonemgr._parse_cmd_params(params2, ZONE_XFRIN_SUCCESS_COMMAND))
        self.assertRaises(ZonemgrException, self.zonemgr._parse_cmd_params, params2, ZONE_NOTIFY_COMMAND)
489
        params1 = {"zone_class" : "CH"}
490
        self.assertRaises(ZonemgrException, self.zonemgr._parse_cmd_params, params2, ZONE_NOTIFY_COMMAND)
491

Jerry's avatar
Jerry committed
492
493
494
495
496
497
498
499
500
    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}
        self.zonemgr._config_data_check(config_data2)
        self.assertEqual(0.2, config_data2.get("jitter_scope"))
        self.zonemgr._config_data_check(config_data3)
        self.assertEqual(0.5, config_data3.get("jitter_scope"))

501
502
503
504
505
    def tearDown(self):
        pass

if __name__== "__main__":
    unittest.main()