Revision edf7d66e
b/Makefile.am | ||
---|---|---|
324 | 324 |
test/ganeti.bdev_unittest.py \ |
325 | 325 |
test/ganeti.cli_unittest.py \ |
326 | 326 |
test/ganeti.cmdlib_unittest.py \ |
327 |
test/ganeti.confd_client_unittest.py \
|
|
327 |
test/ganeti.confd.client_unittest.py \
|
|
328 | 328 |
test/ganeti.config_unittest.py \ |
329 | 329 |
test/ganeti.constants_unittest.py \ |
330 | 330 |
test/ganeti.errors_unittest.py \ |
b/test/ganeti.confd.client_unittest.py | ||
---|---|---|
1 |
#!/usr/bin/python |
|
2 |
# |
|
3 |
|
|
4 |
# Copyright (C) 2009 Google Inc. |
|
5 |
# |
|
6 |
# This program is free software; you can redistribute it and/or modify |
|
7 |
# it under the terms of the GNU General Public License as published by |
|
8 |
# the Free Software Foundation; either version 2 of the License, or |
|
9 |
# (at your option) any later version. |
|
10 |
# |
|
11 |
# This program is distributed in the hope that it will be useful, but |
|
12 |
# WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 |
# General Public License for more details. |
|
15 |
# |
|
16 |
# You should have received a copy of the GNU General Public License |
|
17 |
# along with this program; if not, write to the Free Software |
|
18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
|
19 |
# 0.0510-1301, USA. |
|
20 |
|
|
21 |
|
|
22 |
"""Script for unittesting the confd client module""" |
|
23 |
|
|
24 |
|
|
25 |
import unittest |
|
26 |
|
|
27 |
from ganeti import confd |
|
28 |
from ganeti import constants |
|
29 |
from ganeti import errors |
|
30 |
|
|
31 |
import ganeti.confd.client |
|
32 |
|
|
33 |
import testutils |
|
34 |
|
|
35 |
|
|
36 |
class ResettableMock(object): |
|
37 |
def __init__(self, *args, **kwargs): |
|
38 |
self.Reset() |
|
39 |
|
|
40 |
def Reset(self): |
|
41 |
pass |
|
42 |
|
|
43 |
|
|
44 |
class MockLogger(ResettableMock): |
|
45 |
def Reset(self): |
|
46 |
self.debug_count = 0 |
|
47 |
self.warn_count = 0 |
|
48 |
self.error_count = 0 |
|
49 |
|
|
50 |
def debug(string): |
|
51 |
self.debug_count += 1 |
|
52 |
|
|
53 |
def warning(string): |
|
54 |
self.warn_count += 1 |
|
55 |
|
|
56 |
def error(string): |
|
57 |
self.error_count += 1 |
|
58 |
|
|
59 |
class MockConfdAsyncUDPClient(ResettableMock): |
|
60 |
def Reset(self): |
|
61 |
self.send_count = 0 |
|
62 |
self.last_address = '' |
|
63 |
self.last_port = -1 |
|
64 |
self.last_sent = '' |
|
65 |
|
|
66 |
def enqueue_send(self, address, port, payload): |
|
67 |
self.send_count += 1 |
|
68 |
self.last_payload = payload |
|
69 |
self.last_port = port |
|
70 |
self.last_address = address |
|
71 |
|
|
72 |
class MockCallback(ResettableMock): |
|
73 |
def Reset(self): |
|
74 |
self.call_count = 0 |
|
75 |
self.last_up = None |
|
76 |
|
|
77 |
def __call__(self, up): |
|
78 |
"""Callback |
|
79 |
|
|
80 |
@type up: L{ConfdUpcallPayload} |
|
81 |
@param up: upper callback |
|
82 |
|
|
83 |
""" |
|
84 |
self.call_count += 1 |
|
85 |
self.last_up = up |
|
86 |
|
|
87 |
|
|
88 |
class MockTime(ResettableMock): |
|
89 |
def Reset(self): |
|
90 |
self.mytime = 1254213006.5175071 |
|
91 |
|
|
92 |
def time(self): |
|
93 |
return self.mytime |
|
94 |
|
|
95 |
def increase(self, delta): |
|
96 |
self.mytime += delta |
|
97 |
|
|
98 |
|
|
99 |
class TestClient(unittest.TestCase): |
|
100 |
"""Client tests""" |
|
101 |
|
|
102 |
def setUp(self): |
|
103 |
self.mock_time = MockTime() |
|
104 |
confd.client.time = self.mock_time |
|
105 |
confd.client.ConfdAsyncUDPClient = MockConfdAsyncUDPClient |
|
106 |
self.logger = MockLogger() |
|
107 |
hmac_key = "mykeydata" |
|
108 |
self.mc_list = ['10.0.0.1', |
|
109 |
'10.0.0.2', |
|
110 |
'10.0.0.3', |
|
111 |
'10.0.0.4', |
|
112 |
'10.0.0.5', |
|
113 |
'10.0.0.6', |
|
114 |
'10.0.0.7', |
|
115 |
'10.0.0.8', |
|
116 |
'10.0.0.9', |
|
117 |
] |
|
118 |
self.callback = MockCallback() |
|
119 |
self.client = confd.client.ConfdClient(hmac_key, self.mc_list, |
|
120 |
self.callback, logger=self.logger) |
|
121 |
|
|
122 |
def testRequest(self): |
|
123 |
req1 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
|
124 |
req2 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
|
125 |
self.assertNotEqual(req1.rsalt, req2.rsalt) |
|
126 |
self.assertEqual(req1.protocol, constants.CONFD_PROTOCOL_VERSION) |
|
127 |
self.assertEqual(req2.protocol, constants.CONFD_PROTOCOL_VERSION) |
|
128 |
self.assertRaises(errors.ConfdClientError, confd.client.ConfdClientRequest, |
|
129 |
type=-33) |
|
130 |
|
|
131 |
def testClientSend(self): |
|
132 |
req = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
|
133 |
self.client.SendRequest(req) |
|
134 |
# Cannot send the same request twice |
|
135 |
self.assertRaises(errors.ConfdClientError, self.client.SendRequest, req) |
|
136 |
req2 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
|
137 |
# Coverage is too big |
|
138 |
self.assertRaises(errors.ConfdClientError, self.client.SendRequest, |
|
139 |
req2, coverage=15) |
|
140 |
self.assertEquals(self.client._socket.send_count, |
|
141 |
constants.CONFD_DEFAULT_REQ_COVERAGE) |
|
142 |
# Send with max coverage |
|
143 |
self.client.SendRequest(req2, coverage=-1) |
|
144 |
self.assertEquals(self.client._socket.send_count, |
|
145 |
constants.CONFD_DEFAULT_REQ_COVERAGE + len(self.mc_list)) |
|
146 |
self.assert_(self.client._socket.last_address in self.mc_list) |
|
147 |
|
|
148 |
|
|
149 |
def testClientExpire(self): |
|
150 |
req = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
|
151 |
self.client.SendRequest(req) |
|
152 |
# Make a couple of seconds pass ;) |
|
153 |
self.mock_time.increase(2) |
|
154 |
# Now sending the second request |
|
155 |
req2 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
|
156 |
self.client.SendRequest(req2) |
|
157 |
self.mock_time.increase(constants.CONFD_CLIENT_EXPIRE_TIMEOUT - 1) |
|
158 |
# First request should be expired, second one should not |
|
159 |
self.client.ExpireRequests() |
|
160 |
self.assertEquals(self.callback.call_count, 1) |
|
161 |
self.assertEquals(self.callback.last_up.type, confd.client.UPCALL_EXPIRE) |
|
162 |
self.assertEquals(self.callback.last_up.salt, req.rsalt) |
|
163 |
self.assertEquals(self.callback.last_up.orig_request, req) |
|
164 |
self.mock_time.increase(3) |
|
165 |
self.assertEquals(self.callback.call_count, 1) |
|
166 |
self.client.ExpireRequests() |
|
167 |
self.assertEquals(self.callback.call_count, 2) |
|
168 |
self.assertEquals(self.callback.last_up.type, confd.client.UPCALL_EXPIRE) |
|
169 |
self.assertEquals(self.callback.last_up.salt, req2.rsalt) |
|
170 |
self.assertEquals(self.callback.last_up.orig_request, req2) |
|
171 |
|
|
172 |
def testClientCascadeExpire(self): |
|
173 |
req = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
|
174 |
self.client.SendRequest(req) |
|
175 |
self.mock_time.increase(constants.CONFD_CLIENT_EXPIRE_TIMEOUT +1) |
|
176 |
req2 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
|
177 |
self.client.SendRequest(req2) |
|
178 |
self.assertEquals(self.callback.call_count, 1) |
|
179 |
|
|
180 |
def testUpdatePeerList(self): |
|
181 |
new_peers = ['1.2.3.4', '1.2.3.5'] |
|
182 |
self.client.UpdatePeerList(new_peers) |
|
183 |
self.assertEquals(self.client._peers, new_peers) |
|
184 |
req = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
|
185 |
self.client.SendRequest(req) |
|
186 |
self.assertEquals(self.client._socket.send_count, len(new_peers)) |
|
187 |
self.assert_(self.client._socket.last_address in new_peers) |
|
188 |
|
|
189 |
|
|
190 |
if __name__ == '__main__': |
|
191 |
testutils.GanetiTestProgram() |
/dev/null | ||
---|---|---|
1 |
#!/usr/bin/python |
|
2 |
# |
|
3 |
|
|
4 |
# Copyright (C) 2009 Google Inc. |
|
5 |
# |
|
6 |
# This program is free software; you can redistribute it and/or modify |
|
7 |
# it under the terms of the GNU General Public License as published by |
|
8 |
# the Free Software Foundation; either version 2 of the License, or |
|
9 |
# (at your option) any later version. |
|
10 |
# |
|
11 |
# This program is distributed in the hope that it will be useful, but |
|
12 |
# WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 |
# General Public License for more details. |
|
15 |
# |
|
16 |
# You should have received a copy of the GNU General Public License |
|
17 |
# along with this program; if not, write to the Free Software |
|
18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
|
19 |
# 0.0510-1301, USA. |
|
20 |
|
|
21 |
|
|
22 |
"""Script for unittesting the confd client module""" |
|
23 |
|
|
24 |
|
|
25 |
import unittest |
|
26 |
|
|
27 |
from ganeti import confd |
|
28 |
from ganeti import constants |
|
29 |
from ganeti import errors |
|
30 |
|
|
31 |
import ganeti.confd.client |
|
32 |
|
|
33 |
import testutils |
|
34 |
|
|
35 |
|
|
36 |
class ResettableMock(object): |
|
37 |
def __init__(self, *args, **kwargs): |
|
38 |
self.Reset() |
|
39 |
|
|
40 |
def Reset(self): |
|
41 |
pass |
|
42 |
|
|
43 |
|
|
44 |
class MockLogger(ResettableMock): |
|
45 |
def Reset(self): |
|
46 |
self.debug_count = 0 |
|
47 |
self.warn_count = 0 |
|
48 |
self.error_count = 0 |
|
49 |
|
|
50 |
def debug(string): |
|
51 |
self.debug_count += 1 |
|
52 |
|
|
53 |
def warning(string): |
|
54 |
self.warn_count += 1 |
|
55 |
|
|
56 |
def error(string): |
|
57 |
self.error_count += 1 |
|
58 |
|
|
59 |
class MockConfdAsyncUDPClient(ResettableMock): |
|
60 |
def Reset(self): |
|
61 |
self.send_count = 0 |
|
62 |
self.last_address = '' |
|
63 |
self.last_port = -1 |
|
64 |
self.last_sent = '' |
|
65 |
|
|
66 |
def enqueue_send(self, address, port, payload): |
|
67 |
self.send_count += 1 |
|
68 |
self.last_payload = payload |
|
69 |
self.last_port = port |
|
70 |
self.last_address = address |
|
71 |
|
|
72 |
class MockCallback(ResettableMock): |
|
73 |
def Reset(self): |
|
74 |
self.call_count = 0 |
|
75 |
self.last_up = None |
|
76 |
|
|
77 |
def __call__(self, up): |
|
78 |
"""Callback |
|
79 |
|
|
80 |
@type up: L{ConfdUpcallPayload} |
|
81 |
@param up: upper callback |
|
82 |
|
|
83 |
""" |
|
84 |
self.call_count += 1 |
|
85 |
self.last_up = up |
|
86 |
|
|
87 |
|
|
88 |
class MockTime(ResettableMock): |
|
89 |
def Reset(self): |
|
90 |
self.mytime = 1254213006.5175071 |
|
91 |
|
|
92 |
def time(self): |
|
93 |
return self.mytime |
|
94 |
|
|
95 |
def increase(self, delta): |
|
96 |
self.mytime += delta |
|
97 |
|
|
98 |
|
|
99 |
class TestClient(unittest.TestCase): |
|
100 |
"""Client tests""" |
|
101 |
|
|
102 |
def setUp(self): |
|
103 |
self.mock_time = MockTime() |
|
104 |
confd.client.time = self.mock_time |
|
105 |
confd.client.ConfdAsyncUDPClient = MockConfdAsyncUDPClient |
|
106 |
self.logger = MockLogger() |
|
107 |
hmac_key = "mykeydata" |
|
108 |
self.mc_list = ['10.0.0.1', |
|
109 |
'10.0.0.2', |
|
110 |
'10.0.0.3', |
|
111 |
'10.0.0.4', |
|
112 |
'10.0.0.5', |
|
113 |
'10.0.0.6', |
|
114 |
'10.0.0.7', |
|
115 |
'10.0.0.8', |
|
116 |
'10.0.0.9', |
|
117 |
] |
|
118 |
self.callback = MockCallback() |
|
119 |
self.client = confd.client.ConfdClient(hmac_key, self.mc_list, |
|
120 |
self.callback, logger=self.logger) |
|
121 |
|
|
122 |
def testRequest(self): |
|
123 |
req1 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
|
124 |
req2 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
|
125 |
self.assertNotEqual(req1.rsalt, req2.rsalt) |
|
126 |
self.assertEqual(req1.protocol, constants.CONFD_PROTOCOL_VERSION) |
|
127 |
self.assertEqual(req2.protocol, constants.CONFD_PROTOCOL_VERSION) |
|
128 |
self.assertRaises(errors.ConfdClientError, confd.client.ConfdClientRequest, |
|
129 |
type=-33) |
|
130 |
|
|
131 |
def testClientSend(self): |
|
132 |
req = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
|
133 |
self.client.SendRequest(req) |
|
134 |
# Cannot send the same request twice |
|
135 |
self.assertRaises(errors.ConfdClientError, self.client.SendRequest, req) |
|
136 |
req2 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
|
137 |
# Coverage is too big |
|
138 |
self.assertRaises(errors.ConfdClientError, self.client.SendRequest, |
|
139 |
req2, coverage=15) |
|
140 |
self.assertEquals(self.client._socket.send_count, |
|
141 |
constants.CONFD_DEFAULT_REQ_COVERAGE) |
|
142 |
# Send with max coverage |
|
143 |
self.client.SendRequest(req2, coverage=-1) |
|
144 |
self.assertEquals(self.client._socket.send_count, |
|
145 |
constants.CONFD_DEFAULT_REQ_COVERAGE + len(self.mc_list)) |
|
146 |
self.assert_(self.client._socket.last_address in self.mc_list) |
|
147 |
|
|
148 |
|
|
149 |
def testClientExpire(self): |
|
150 |
req = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
|
151 |
self.client.SendRequest(req) |
|
152 |
# Make a couple of seconds pass ;) |
|
153 |
self.mock_time.increase(2) |
|
154 |
# Now sending the second request |
|
155 |
req2 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
|
156 |
self.client.SendRequest(req2) |
|
157 |
self.mock_time.increase(constants.CONFD_CLIENT_EXPIRE_TIMEOUT - 1) |
|
158 |
# First request should be expired, second one should not |
|
159 |
self.client.ExpireRequests() |
|
160 |
self.assertEquals(self.callback.call_count, 1) |
|
161 |
self.assertEquals(self.callback.last_up.type, confd.client.UPCALL_EXPIRE) |
|
162 |
self.assertEquals(self.callback.last_up.salt, req.rsalt) |
|
163 |
self.assertEquals(self.callback.last_up.orig_request, req) |
|
164 |
self.mock_time.increase(3) |
|
165 |
self.assertEquals(self.callback.call_count, 1) |
|
166 |
self.client.ExpireRequests() |
|
167 |
self.assertEquals(self.callback.call_count, 2) |
|
168 |
self.assertEquals(self.callback.last_up.type, confd.client.UPCALL_EXPIRE) |
|
169 |
self.assertEquals(self.callback.last_up.salt, req2.rsalt) |
|
170 |
self.assertEquals(self.callback.last_up.orig_request, req2) |
|
171 |
|
|
172 |
def testClientCascadeExpire(self): |
|
173 |
req = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
|
174 |
self.client.SendRequest(req) |
|
175 |
self.mock_time.increase(constants.CONFD_CLIENT_EXPIRE_TIMEOUT +1) |
|
176 |
req2 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
|
177 |
self.client.SendRequest(req2) |
|
178 |
self.assertEquals(self.callback.call_count, 1) |
|
179 |
|
|
180 |
def testUpdatePeerList(self): |
|
181 |
new_peers = ['1.2.3.4', '1.2.3.5'] |
|
182 |
self.client.UpdatePeerList(new_peers) |
|
183 |
self.assertEquals(self.client._peers, new_peers) |
|
184 |
req = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
|
185 |
self.client.SendRequest(req) |
|
186 |
self.assertEquals(self.client._socket.send_count, len(new_peers)) |
|
187 |
self.assert_(self.client._socket.last_address in new_peers) |
|
188 |
|
|
189 |
|
|
190 |
if __name__ == '__main__': |
|
191 |
testutils.GanetiTestProgram() |
Also available in: Unified diff