root / test / py / ganeti.confd.client_unittest.py @ d01e51a5
History | View | Annotate | Download (7.1 kB)
1 | 74554d66 | Guido Trotter | #!/usr/bin/python
|
---|---|---|---|
2 | 74554d66 | Guido Trotter | #
|
3 | 74554d66 | Guido Trotter | |
4 | 74554d66 | Guido Trotter | # Copyright (C) 2009 Google Inc.
|
5 | 74554d66 | Guido Trotter | #
|
6 | 74554d66 | Guido Trotter | # This program is free software; you can redistribute it and/or modify
|
7 | 74554d66 | Guido Trotter | # it under the terms of the GNU General Public License as published by
|
8 | 74554d66 | Guido Trotter | # the Free Software Foundation; either version 2 of the License, or
|
9 | 74554d66 | Guido Trotter | # (at your option) any later version.
|
10 | 74554d66 | Guido Trotter | #
|
11 | 74554d66 | Guido Trotter | # This program is distributed in the hope that it will be useful, but
|
12 | 74554d66 | Guido Trotter | # WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | 74554d66 | Guido Trotter | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | 74554d66 | Guido Trotter | # General Public License for more details.
|
15 | 74554d66 | Guido Trotter | #
|
16 | 74554d66 | Guido Trotter | # You should have received a copy of the GNU General Public License
|
17 | 74554d66 | Guido Trotter | # along with this program; if not, write to the Free Software
|
18 | 74554d66 | Guido Trotter | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
19 | fd7b69c0 | Michael Hanselmann | # 02110-1301, USA.
|
20 | 74554d66 | Guido Trotter | |
21 | 74554d66 | Guido Trotter | |
22 | 74554d66 | Guido Trotter | """Script for unittesting the confd client module"""
|
23 | 74554d66 | Guido Trotter | |
24 | 74554d66 | Guido Trotter | |
25 | d8bcfe21 | Manuel Franceschini | import socket |
26 | 74554d66 | Guido Trotter | import unittest |
27 | 74554d66 | Guido Trotter | |
28 | 74554d66 | Guido Trotter | from ganeti import confd |
29 | 74554d66 | Guido Trotter | from ganeti import constants |
30 | 74554d66 | Guido Trotter | from ganeti import errors |
31 | 74554d66 | Guido Trotter | |
32 | 74554d66 | Guido Trotter | import ganeti.confd.client |
33 | 74554d66 | Guido Trotter | |
34 | 25231ec5 | Michael Hanselmann | import testutils |
35 | 25231ec5 | Michael Hanselmann | |
36 | 74554d66 | Guido Trotter | |
37 | 74554d66 | Guido Trotter | class ResettableMock(object): |
38 | 74554d66 | Guido Trotter | def __init__(self, *args, **kwargs): |
39 | 74554d66 | Guido Trotter | self.Reset()
|
40 | 74554d66 | Guido Trotter | |
41 | 74554d66 | Guido Trotter | def Reset(self): |
42 | 74554d66 | Guido Trotter | pass
|
43 | 74554d66 | Guido Trotter | |
44 | 74554d66 | Guido Trotter | |
45 | 74554d66 | Guido Trotter | class MockLogger(ResettableMock): |
46 | 74554d66 | Guido Trotter | def Reset(self): |
47 | 74554d66 | Guido Trotter | self.debug_count = 0 |
48 | 74554d66 | Guido Trotter | self.warn_count = 0 |
49 | 74554d66 | Guido Trotter | self.error_count = 0 |
50 | 74554d66 | Guido Trotter | |
51 | 74554d66 | Guido Trotter | def debug(string): |
52 | 74554d66 | Guido Trotter | self.debug_count += 1 |
53 | 74554d66 | Guido Trotter | |
54 | 74554d66 | Guido Trotter | def warning(string): |
55 | 74554d66 | Guido Trotter | self.warn_count += 1 |
56 | 74554d66 | Guido Trotter | |
57 | 74554d66 | Guido Trotter | def error(string): |
58 | 74554d66 | Guido Trotter | self.error_count += 1 |
59 | 74554d66 | Guido Trotter | |
60 | 74554d66 | Guido Trotter | class MockConfdAsyncUDPClient(ResettableMock): |
61 | 74554d66 | Guido Trotter | def Reset(self): |
62 | 74554d66 | Guido Trotter | self.send_count = 0 |
63 | 74554d66 | Guido Trotter | self.last_address = '' |
64 | 74554d66 | Guido Trotter | self.last_port = -1 |
65 | 74554d66 | Guido Trotter | self.last_sent = '' |
66 | 74554d66 | Guido Trotter | |
67 | 74554d66 | Guido Trotter | def enqueue_send(self, address, port, payload): |
68 | 74554d66 | Guido Trotter | self.send_count += 1 |
69 | 74554d66 | Guido Trotter | self.last_payload = payload
|
70 | 74554d66 | Guido Trotter | self.last_port = port
|
71 | 74554d66 | Guido Trotter | self.last_address = address
|
72 | 74554d66 | Guido Trotter | |
73 | 74554d66 | Guido Trotter | class MockCallback(ResettableMock): |
74 | 74554d66 | Guido Trotter | def Reset(self): |
75 | 74554d66 | Guido Trotter | self.call_count = 0 |
76 | 74554d66 | Guido Trotter | self.last_up = None |
77 | 74554d66 | Guido Trotter | |
78 | 74554d66 | Guido Trotter | def __call__(self, up): |
79 | 74554d66 | Guido Trotter | """Callback
|
80 | 74554d66 | Guido Trotter |
|
81 | 74554d66 | Guido Trotter | @type up: L{ConfdUpcallPayload}
|
82 | 74554d66 | Guido Trotter | @param up: upper callback
|
83 | 74554d66 | Guido Trotter |
|
84 | 74554d66 | Guido Trotter | """
|
85 | 74554d66 | Guido Trotter | self.call_count += 1 |
86 | 74554d66 | Guido Trotter | self.last_up = up
|
87 | 74554d66 | Guido Trotter | |
88 | 74554d66 | Guido Trotter | |
89 | 74554d66 | Guido Trotter | class MockTime(ResettableMock): |
90 | 74554d66 | Guido Trotter | def Reset(self): |
91 | 74554d66 | Guido Trotter | self.mytime = 1254213006.5175071 |
92 | 74554d66 | Guido Trotter | |
93 | 74554d66 | Guido Trotter | def time(self): |
94 | 74554d66 | Guido Trotter | return self.mytime |
95 | 74554d66 | Guido Trotter | |
96 | 74554d66 | Guido Trotter | def increase(self, delta): |
97 | 74554d66 | Guido Trotter | self.mytime += delta
|
98 | 74554d66 | Guido Trotter | |
99 | 74554d66 | Guido Trotter | |
100 | d8bcfe21 | Manuel Franceschini | class _BaseClientTest: |
101 | d8bcfe21 | Manuel Franceschini | """Base class for client tests"""
|
102 | d8bcfe21 | Manuel Franceschini | mc_list = None
|
103 | d8bcfe21 | Manuel Franceschini | new_peers = None
|
104 | d8bcfe21 | Manuel Franceschini | family = None
|
105 | 74554d66 | Guido Trotter | |
106 | 74554d66 | Guido Trotter | def setUp(self): |
107 | 74554d66 | Guido Trotter | self.mock_time = MockTime()
|
108 | 74554d66 | Guido Trotter | confd.client.time = self.mock_time
|
109 | 74554d66 | Guido Trotter | confd.client.ConfdAsyncUDPClient = MockConfdAsyncUDPClient |
110 | 74554d66 | Guido Trotter | self.logger = MockLogger()
|
111 | 74554d66 | Guido Trotter | hmac_key = "mykeydata"
|
112 | 74554d66 | Guido Trotter | self.callback = MockCallback()
|
113 | 74554d66 | Guido Trotter | self.client = confd.client.ConfdClient(hmac_key, self.mc_list, |
114 | 74554d66 | Guido Trotter | self.callback, logger=self.logger) |
115 | 74554d66 | Guido Trotter | |
116 | 74554d66 | Guido Trotter | def testRequest(self): |
117 | 74554d66 | Guido Trotter | req1 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
118 | 74554d66 | Guido Trotter | req2 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
119 | 74554d66 | Guido Trotter | self.assertNotEqual(req1.rsalt, req2.rsalt)
|
120 | 74554d66 | Guido Trotter | self.assertEqual(req1.protocol, constants.CONFD_PROTOCOL_VERSION)
|
121 | 74554d66 | Guido Trotter | self.assertEqual(req2.protocol, constants.CONFD_PROTOCOL_VERSION)
|
122 | 74554d66 | Guido Trotter | self.assertRaises(errors.ConfdClientError, confd.client.ConfdClientRequest,
|
123 | 74554d66 | Guido Trotter | type=-33)
|
124 | 74554d66 | Guido Trotter | |
125 | 74554d66 | Guido Trotter | def testClientSend(self): |
126 | 74554d66 | Guido Trotter | req = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
127 | 74554d66 | Guido Trotter | self.client.SendRequest(req)
|
128 | 74554d66 | Guido Trotter | # Cannot send the same request twice
|
129 | 74554d66 | Guido Trotter | self.assertRaises(errors.ConfdClientError, self.client.SendRequest, req) |
130 | 74554d66 | Guido Trotter | req2 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
131 | 74554d66 | Guido Trotter | # Coverage is too big
|
132 | 74554d66 | Guido Trotter | self.assertRaises(errors.ConfdClientError, self.client.SendRequest, |
133 | 74554d66 | Guido Trotter | req2, coverage=15)
|
134 | 74554d66 | Guido Trotter | self.assertEquals(self.client._socket.send_count, |
135 | 74554d66 | Guido Trotter | constants.CONFD_DEFAULT_REQ_COVERAGE) |
136 | cc6484c4 | Iustin Pop | # Send with max coverage
|
137 | cc6484c4 | Iustin Pop | self.client.SendRequest(req2, coverage=-1) |
138 | cc6484c4 | Iustin Pop | self.assertEquals(self.client._socket.send_count, |
139 | cc6484c4 | Iustin Pop | constants.CONFD_DEFAULT_REQ_COVERAGE + len(self.mc_list)) |
140 | 74554d66 | Guido Trotter | self.assert_(self.client._socket.last_address in self.mc_list) |
141 | 74554d66 | Guido Trotter | |
142 | 74554d66 | Guido Trotter | |
143 | 74554d66 | Guido Trotter | def testClientExpire(self): |
144 | 74554d66 | Guido Trotter | req = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
145 | 74554d66 | Guido Trotter | self.client.SendRequest(req)
|
146 | 74554d66 | Guido Trotter | # Make a couple of seconds pass ;)
|
147 | 74554d66 | Guido Trotter | self.mock_time.increase(2) |
148 | 74554d66 | Guido Trotter | # Now sending the second request
|
149 | 74554d66 | Guido Trotter | req2 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
150 | 74554d66 | Guido Trotter | self.client.SendRequest(req2)
|
151 | 74554d66 | Guido Trotter | self.mock_time.increase(constants.CONFD_CLIENT_EXPIRE_TIMEOUT - 1) |
152 | 74554d66 | Guido Trotter | # First request should be expired, second one should not
|
153 | 74554d66 | Guido Trotter | self.client.ExpireRequests()
|
154 | 74554d66 | Guido Trotter | self.assertEquals(self.callback.call_count, 1) |
155 | 74554d66 | Guido Trotter | self.assertEquals(self.callback.last_up.type, confd.client.UPCALL_EXPIRE) |
156 | 74554d66 | Guido Trotter | self.assertEquals(self.callback.last_up.salt, req.rsalt) |
157 | 74554d66 | Guido Trotter | self.assertEquals(self.callback.last_up.orig_request, req) |
158 | 74554d66 | Guido Trotter | self.mock_time.increase(3) |
159 | 74554d66 | Guido Trotter | self.assertEquals(self.callback.call_count, 1) |
160 | 74554d66 | Guido Trotter | self.client.ExpireRequests()
|
161 | 74554d66 | Guido Trotter | self.assertEquals(self.callback.call_count, 2) |
162 | 74554d66 | Guido Trotter | self.assertEquals(self.callback.last_up.type, confd.client.UPCALL_EXPIRE) |
163 | 74554d66 | Guido Trotter | self.assertEquals(self.callback.last_up.salt, req2.rsalt) |
164 | 74554d66 | Guido Trotter | self.assertEquals(self.callback.last_up.orig_request, req2) |
165 | 74554d66 | Guido Trotter | |
166 | 74554d66 | Guido Trotter | def testClientCascadeExpire(self): |
167 | 74554d66 | Guido Trotter | req = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
168 | 74554d66 | Guido Trotter | self.client.SendRequest(req)
|
169 | 74554d66 | Guido Trotter | self.mock_time.increase(constants.CONFD_CLIENT_EXPIRE_TIMEOUT +1) |
170 | 74554d66 | Guido Trotter | req2 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
171 | 74554d66 | Guido Trotter | self.client.SendRequest(req2)
|
172 | 74554d66 | Guido Trotter | self.assertEquals(self.callback.call_count, 1) |
173 | 74554d66 | Guido Trotter | |
174 | 74554d66 | Guido Trotter | def testUpdatePeerList(self): |
175 | d8bcfe21 | Manuel Franceschini | self.client.UpdatePeerList(self.new_peers) |
176 | d8bcfe21 | Manuel Franceschini | self.assertEquals(self.client._peers, self.new_peers) |
177 | 74554d66 | Guido Trotter | req = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING) |
178 | 74554d66 | Guido Trotter | self.client.SendRequest(req)
|
179 | d8bcfe21 | Manuel Franceschini | self.assertEquals(self.client._socket.send_count, len(self.new_peers)) |
180 | d8bcfe21 | Manuel Franceschini | self.assert_(self.client._socket.last_address in self.new_peers) |
181 | d8bcfe21 | Manuel Franceschini | |
182 | d8bcfe21 | Manuel Franceschini | def testSetPeersFamily(self): |
183 | d8bcfe21 | Manuel Franceschini | self.client._SetPeersAddressFamily()
|
184 | d8bcfe21 | Manuel Franceschini | self.assertEquals(self.client._family, self.family) |
185 | 926feaf1 | Manuel Franceschini | mixed_peers = ["192.0.2.99", "2001:db8:beef::13"] |
186 | d8bcfe21 | Manuel Franceschini | self.client.UpdatePeerList(mixed_peers)
|
187 | d8bcfe21 | Manuel Franceschini | self.assertRaises(errors.ConfdClientError,
|
188 | d8bcfe21 | Manuel Franceschini | self.client._SetPeersAddressFamily)
|
189 | d8bcfe21 | Manuel Franceschini | |
190 | d8bcfe21 | Manuel Franceschini | |
191 | d8bcfe21 | Manuel Franceschini | class TestIP4Client(unittest.TestCase, _BaseClientTest): |
192 | d8bcfe21 | Manuel Franceschini | """Client tests"""
|
193 | 926feaf1 | Manuel Franceschini | mc_list = ["192.0.2.1",
|
194 | 926feaf1 | Manuel Franceschini | "192.0.2.2",
|
195 | 926feaf1 | Manuel Franceschini | "192.0.2.3",
|
196 | 926feaf1 | Manuel Franceschini | "192.0.2.4",
|
197 | 926feaf1 | Manuel Franceschini | "192.0.2.5",
|
198 | 926feaf1 | Manuel Franceschini | "192.0.2.6",
|
199 | 926feaf1 | Manuel Franceschini | "192.0.2.7",
|
200 | 926feaf1 | Manuel Franceschini | "192.0.2.8",
|
201 | 926feaf1 | Manuel Franceschini | "192.0.2.9",
|
202 | d8bcfe21 | Manuel Franceschini | ] |
203 | 926feaf1 | Manuel Franceschini | new_peers = ["198.51.100.1", "198.51.100.2"] |
204 | d8bcfe21 | Manuel Franceschini | family = socket.AF_INET |
205 | d8bcfe21 | Manuel Franceschini | |
206 | d8bcfe21 | Manuel Franceschini | def setUp(self): |
207 | d8bcfe21 | Manuel Franceschini | unittest.TestCase.setUp(self)
|
208 | d8bcfe21 | Manuel Franceschini | _BaseClientTest.setUp(self)
|
209 | d8bcfe21 | Manuel Franceschini | |
210 | d8bcfe21 | Manuel Franceschini | |
211 | d8bcfe21 | Manuel Franceschini | class TestIP6Client(unittest.TestCase, _BaseClientTest): |
212 | d8bcfe21 | Manuel Franceschini | """Client tests"""
|
213 | d8bcfe21 | Manuel Franceschini | mc_list = ["2001:db8::1",
|
214 | d8bcfe21 | Manuel Franceschini | "2001:db8::2",
|
215 | d8bcfe21 | Manuel Franceschini | "2001:db8::3",
|
216 | d8bcfe21 | Manuel Franceschini | "2001:db8::4",
|
217 | d8bcfe21 | Manuel Franceschini | "2001:db8::5",
|
218 | d8bcfe21 | Manuel Franceschini | "2001:db8::6",
|
219 | d8bcfe21 | Manuel Franceschini | "2001:db8::7",
|
220 | d8bcfe21 | Manuel Franceschini | "2001:db8::8",
|
221 | d8bcfe21 | Manuel Franceschini | "2001:db8::9",
|
222 | d8bcfe21 | Manuel Franceschini | ] |
223 | d8bcfe21 | Manuel Franceschini | new_peers = ["2001:db8:beef::11", "2001:db8:beef::12"] |
224 | d8bcfe21 | Manuel Franceschini | family = socket.AF_INET6 |
225 | d8bcfe21 | Manuel Franceschini | |
226 | d8bcfe21 | Manuel Franceschini | def setUp(self): |
227 | d8bcfe21 | Manuel Franceschini | unittest.TestCase.setUp(self)
|
228 | d8bcfe21 | Manuel Franceschini | _BaseClientTest.setUp(self)
|
229 | 74554d66 | Guido Trotter | |
230 | 74554d66 | Guido Trotter | |
231 | 2f96c43c | Michael Hanselmann | if __name__ == "__main__": |
232 | 25231ec5 | Michael Hanselmann | testutils.GanetiTestProgram() |