Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.confd_client_unittest.py @ d357f531

History | View | Annotate | Download (5.8 kB)

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()