Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.confd_client_unittest.py @ 25231ec5

History | View | Annotate | Download (5.9 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
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
    self.assert_(self.client._socket.last_address in self.mc_list)
143

    
144

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

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

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

    
185

    
186
if __name__ == '__main__':
187
  testutils.GanetiTestProgram()