Revision 74554d66

b/Makefile.am
264 264
	test/ganeti.bdev_unittest.py \
265 265
	test/ganeti.cli_unittest.py \
266 266
	test/ganeti.cmdlib_unittest.py \
267
	test/ganeti.confd_client_unittest.py \
267 268
	test/ganeti.config_unittest.py \
268 269
	test/ganeti.constants_unittest.py \
269 270
	test/ganeti.hooks_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

  
34
class ResettableMock(object):
35
  def __init__(self, *args, **kwargs):
36
    self.Reset()
37

  
38
  def Reset(self):
39
    pass
40

  
41

  
42
class MockLogger(ResettableMock):
43
  def Reset(self):
44
    self.debug_count = 0
45
    self.warn_count = 0
46
    self.error_count = 0
47

  
48
  def debug(string):
49
    self.debug_count += 1
50

  
51
  def warning(string):
52
    self.warn_count += 1
53

  
54
  def error(string):
55
    self.error_count += 1
56

  
57
class MockConfdAsyncUDPClient(ResettableMock):
58
  def Reset(self):
59
    self.send_count = 0
60
    self.last_address = ''
61
    self.last_port = -1
62
    self.last_sent = ''
63

  
64
  def enqueue_send(self, address, port, payload):
65
    self.send_count += 1
66
    self.last_payload = payload
67
    self.last_port = port
68
    self.last_address = address
69

  
70
class MockCallback(ResettableMock):
71
  def Reset(self):
72
    self.call_count = 0
73
    self.last_up = None
74

  
75
  def __call__(self, up):
76
    """Callback
77

  
78
    @type up: L{ConfdUpcallPayload}
79
    @param up: upper callback
80

  
81
    """
82
    self.call_count += 1
83
    self.last_up = up
84

  
85

  
86
class MockTime(ResettableMock):
87
  def Reset(self):
88
    self.mytime  = 1254213006.5175071
89

  
90
  def time(self):
91
    return self.mytime
92

  
93
  def increase(self, delta):
94
    self.mytime += delta
95

  
96

  
97
class TestClient(unittest.TestCase):
98
  """Client tests"""
99

  
100
  def setUp(self):
101
    self.mock_time = MockTime()
102
    confd.client.time = self.mock_time
103
    confd.client.ConfdAsyncUDPClient = MockConfdAsyncUDPClient
104
    self.logger = MockLogger()
105
    hmac_key = "mykeydata"
106
    self.mc_list = ['10.0.0.1',
107
                    '10.0.0.2',
108
                    '10.0.0.3',
109
                    '10.0.0.4',
110
                    '10.0.0.5',
111
                    '10.0.0.6',
112
                    '10.0.0.7',
113
                    '10.0.0.8',
114
                    '10.0.0.9',
115
                   ]
116
    self.callback = MockCallback()
117
    self.client = confd.client.ConfdClient(hmac_key, self.mc_list,
118
                                           self.callback, logger=self.logger)
119

  
120
  def testRequest(self):
121
    req1 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING)
122
    req2 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING)
123
    self.assertNotEqual(req1.rsalt, req2.rsalt)
124
    self.assertEqual(req1.protocol, constants.CONFD_PROTOCOL_VERSION)
125
    self.assertEqual(req2.protocol, constants.CONFD_PROTOCOL_VERSION)
126
    self.assertRaises(errors.ConfdClientError, confd.client.ConfdClientRequest,
127
                      type=-33)
128

  
129
  def testClientSend(self):
130
    req = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING)
131
    self.client.SendRequest(req)
132
    # Cannot send the same request twice
133
    self.assertRaises(errors.ConfdClientError, self.client.SendRequest, req)
134
    req2 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING)
135
    # Coverage is too big
136
    self.assertRaises(errors.ConfdClientError, self.client.SendRequest,
137
                      req2, coverage=15)
138
    self.assertEquals(self.client._socket.send_count,
139
                      constants.CONFD_DEFAULT_REQ_COVERAGE)
140
    self.assert_(self.client._socket.last_address in self.mc_list)
141

  
142

  
143
  def testClientExpire(self):
144
    req = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING)
145
    self.client.SendRequest(req)
146
    # Make a couple of seconds pass ;)
147
    self.mock_time.increase(2)
148
    # Now sending the second request
149
    req2 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING)
150
    self.client.SendRequest(req2)
151
    self.mock_time.increase(constants.CONFD_CLIENT_EXPIRE_TIMEOUT - 1)
152
    # First request should be expired, second one should not
153
    self.client.ExpireRequests()
154
    self.assertEquals(self.callback.call_count, 1)
155
    self.assertEquals(self.callback.last_up.type, confd.client.UPCALL_EXPIRE)
156
    self.assertEquals(self.callback.last_up.salt, req.rsalt)
157
    self.assertEquals(self.callback.last_up.orig_request, req)
158
    self.mock_time.increase(3)
159
    self.assertEquals(self.callback.call_count, 1)
160
    self.client.ExpireRequests()
161
    self.assertEquals(self.callback.call_count, 2)
162
    self.assertEquals(self.callback.last_up.type, confd.client.UPCALL_EXPIRE)
163
    self.assertEquals(self.callback.last_up.salt, req2.rsalt)
164
    self.assertEquals(self.callback.last_up.orig_request, req2)
165

  
166
  def testClientCascadeExpire(self):
167
    req = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING)
168
    self.client.SendRequest(req)
169
    self.mock_time.increase(constants.CONFD_CLIENT_EXPIRE_TIMEOUT +1)
170
    req2 = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING)
171
    self.client.SendRequest(req2)
172
    self.assertEquals(self.callback.call_count, 1)
173

  
174
  def testUpdatePeerList(self):
175
    new_peers = ['1.2.3.4', '1.2.3.5']
176
    self.client.UpdatePeerList(new_peers)
177
    self.assertEquals(self.client._peers, new_peers)
178
    req = confd.client.ConfdClientRequest(type=constants.CONFD_REQ_PING)
179
    self.client.SendRequest(req)
180
    self.assertEquals(self.client._socket.send_count, len(new_peers))
181
    self.assert_(self.client._socket.last_address in new_peers)
182

  
183

  
184
if __name__ == '__main__':
185
  unittest.main()

Also available in: Unified diff