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