Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.client.gnt_cluster_unittest.py @ 14933c17

History | View | Annotate | Download (12.1 kB)

1
#!/usr/bin/python
2
#
3

    
4
# Copyright (C) 2011 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
# 02110-1301, USA.
20

    
21

    
22
"""Script for testing ganeti.client.gnt_cluster"""
23

    
24
import unittest
25
import optparse
26

    
27
from ganeti import errors
28
from ganeti.client import gnt_cluster
29
from ganeti import utils
30
from ganeti import compat
31
from ganeti import constants
32

    
33
import mock
34
import testutils
35

    
36

    
37
class TestEpoUtilities(unittest.TestCase):
38
  def setUp(self):
39
    self.nodes2ip = dict(("node%s" % i, "192.0.2.%s" % i) for i in range(1, 10))
40
    self.nodes = set(self.nodes2ip.keys())
41
    self.ips2node = dict((v, k) for (k, v) in self.nodes2ip.items())
42

    
43
  def _FakeAction(*args):
44
    return True
45

    
46
  def _FakePing(ip, port, live_port_needed=False):
47
    self.assert_(live_port_needed)
48
    self.assertEqual(port, 0)
49
    return True
50

    
51
  def _FakeSleep(secs):
52
    self.assert_(secs >= 0 and secs <= 5)
53
    return
54

    
55
  def _NoopFeedback(self, text):
56
    return
57

    
58
  def testPingFnRemoveHostsUp(self):
59
    seen = set()
60
    def _FakeSeenPing(ip, *args, **kwargs):
61
      node = self.ips2node[ip]
62
      self.assertFalse(node in seen)
63
      seen.add(node)
64
      return True
65

    
66
    helper = gnt_cluster._RunWhenNodesReachableHelper(self.nodes,
67
                                                      self._FakeAction,
68
                                                      self.nodes2ip, 0,
69
                                                      self._NoopFeedback,
70
                                                      _ping_fn=_FakeSeenPing,
71
                                                      _sleep_fn=self._FakeSleep)
72

    
73
    nodes_len = len(self.nodes)
74
    for (num, _) in enumerate(self.nodes):
75
      helper.Wait(5)
76
      if num < nodes_len - 1:
77
        self.assertRaises(utils.RetryAgain, helper)
78
      else:
79
        helper()
80

    
81
    self.assertEqual(seen, self.nodes)
82
    self.assertFalse(helper.down)
83
    self.assertEqual(helper.up, self.nodes)
84

    
85
  def testActionReturnFalseSetsHelperFalse(self):
86
    called = False
87
    def _FalseAction(*args):
88
      return called
89

    
90
    helper = gnt_cluster._RunWhenNodesReachableHelper(self.nodes, _FalseAction,
91
                                                      self.nodes2ip, 0,
92
                                                      self._NoopFeedback,
93
                                                      _ping_fn=self._FakePing,
94
                                                      _sleep_fn=self._FakeSleep)
95
    for _ in self.nodes:
96
      try:
97
        helper()
98
      except utils.RetryAgain:
99
        called = True
100

    
101
    self.assertFalse(helper.success)
102

    
103
  def testMaybeInstanceStartup(self):
104
    instances_arg = []
105
    def _FakeInstanceStart(opts, instances, start):
106
      instances_arg.append(set(instances))
107
      return None
108

    
109
    inst_map = {
110
      "inst1": set(["node1", "node2"]),
111
      "inst2": set(["node1", "node3"]),
112
      "inst3": set(["node2", "node1"]),
113
      "inst4": set(["node2", "node1", "node3"]),
114
      "inst5": set(["node4"]),
115
      }
116

    
117
    fn = _FakeInstanceStart
118
    self.assert_(gnt_cluster._MaybeInstanceStartup(None, inst_map, set(),
119
                                                   _instance_start_fn=fn))
120
    self.assertFalse(instances_arg)
121
    result = gnt_cluster._MaybeInstanceStartup(None, inst_map, set(["node1"]),
122
                                               _instance_start_fn=fn)
123
    self.assert_(result)
124
    self.assertFalse(instances_arg)
125
    result = gnt_cluster._MaybeInstanceStartup(None, inst_map,
126
                                               set(["node1", "node3"]),
127
                                               _instance_start_fn=fn)
128
    self.assert_(result is None)
129
    self.assertEqual(instances_arg.pop(0), set(["inst2"]))
130
    self.assertFalse("inst2" in inst_map)
131
    result = gnt_cluster._MaybeInstanceStartup(None, inst_map,
132
                                               set(["node1", "node3"]),
133
                                               _instance_start_fn=fn)
134
    self.assert_(result)
135
    self.assertFalse(instances_arg)
136
    result = gnt_cluster._MaybeInstanceStartup(None, inst_map,
137
                                               set(["node1", "node3", "node2"]),
138
                                               _instance_start_fn=fn)
139
    self.assertEqual(instances_arg.pop(0), set(["inst1", "inst3", "inst4"]))
140
    self.assert_(result is None)
141
    result = gnt_cluster._MaybeInstanceStartup(None, inst_map,
142
                                               set(["node1", "node3", "node2",
143
                                                    "node4"]),
144
                                               _instance_start_fn=fn)
145
    self.assert_(result is None)
146
    self.assertEqual(instances_arg.pop(0), set(["inst5"]))
147
    self.assertFalse(inst_map)
148

    
149

    
150
class _ClientForEpo:
151
  def __init__(self, groups, nodes):
152
    self._groups = groups
153
    self._nodes = nodes
154

    
155
  def QueryGroups(self, names, fields, use_locking):
156
    assert not use_locking
157
    assert fields == ["node_list"]
158
    return self._groups
159

    
160
  def QueryNodes(self, names, fields, use_locking):
161
    assert not use_locking
162
    assert fields == ["name", "master", "pinst_list", "sinst_list", "powered",
163
                      "offline"]
164
    return self._nodes
165

    
166

    
167
class TestEpo(unittest.TestCase):
168
  _ON_EXITCODE = 253
169
  _OFF_EXITCODE = 254
170

    
171
  def _ConfirmForce(self, *args):
172
    self.fail("Shouldn't need confirmation")
173

    
174
  def _Confirm(self, exp_names, result, names, ltype, text):
175
    self.assertEqual(names, exp_names)
176
    self.assertFalse(result is NotImplemented)
177
    return result
178

    
179
  def _Off(self, exp_node_list, opts, node_list, inst_map):
180
    self.assertEqual(node_list, exp_node_list)
181
    self.assertFalse(inst_map)
182
    return self._OFF_EXITCODE
183

    
184
  def _Test(self, *args, **kwargs):
185
    defaults = dict(cl=NotImplemented, _on_fn=NotImplemented,
186
                    _off_fn=NotImplemented,
187
                    _stdout_fn=lambda *args: None,
188
                    _stderr_fn=lambda *args: None)
189
    defaults.update(kwargs)
190
    return gnt_cluster.Epo(*args, **defaults)
191

    
192
  def testShowAllWithGroups(self):
193
    opts = optparse.Values(dict(groups=True, show_all=True))
194
    result = self._Test(opts, NotImplemented)
195
    self.assertEqual(result, constants.EXIT_FAILURE)
196

    
197
  def testShowAllWithArgs(self):
198
    opts = optparse.Values(dict(groups=False, show_all=True))
199
    result = self._Test(opts, ["a", "b", "c"])
200
    self.assertEqual(result, constants.EXIT_FAILURE)
201

    
202
  def testNoArgumentsNoParameters(self):
203
    for (force, confirm_result) in [(True, NotImplemented), (False, False),
204
                                    (False, True)]:
205
      opts = optparse.Values(dict(groups=False, show_all=False, force=force,
206
                                  on=False))
207
      client = _ClientForEpo(NotImplemented, [
208
        ("node1.example.com", False, [], [], True, False),
209
        ])
210

    
211
      if force:
212
        confirm_fn = self._ConfirmForce
213
      else:
214
        confirm_fn = compat.partial(self._Confirm, ["node1.example.com"],
215
                                    confirm_result)
216

    
217
      off_fn = compat.partial(self._Off, ["node1.example.com"])
218

    
219
      result = self._Test(opts, [], cl=client, _off_fn=off_fn,
220
                          _confirm_fn=confirm_fn)
221
      if force or confirm_result:
222
        self.assertEqual(result, self._OFF_EXITCODE)
223
      else:
224
        self.assertEqual(result, constants.EXIT_FAILURE)
225

    
226
  def testPowerOn(self):
227
    for master in [False, True]:
228
      opts = optparse.Values(dict(groups=False, show_all=True,
229
                                  force=True, on=True))
230
      client = _ClientForEpo(NotImplemented, [
231
        ("node1.example.com", False, [], [], True, False),
232
        ("node2.example.com", False, [], [], False, False),
233
        ("node3.example.com", False, [], [], True, True),
234
        ("node4.example.com", False, [], [], None, True),
235
        ("node5.example.com", master, [], [], False, False),
236
        ])
237

    
238
      def _On(_, all_nodes, node_list, inst_map):
239
        self.assertEqual(all_nodes,
240
                         ["node%s.example.com" % i for i in range(1, 6)])
241
        if master:
242
          self.assertEqual(node_list, ["node2.example.com"])
243
        else:
244
          self.assertEqual(node_list, ["node2.example.com",
245
                                       "node5.example.com"])
246
        self.assertFalse(inst_map)
247
        return self._ON_EXITCODE
248

    
249
      result = self._Test(opts, [], cl=client, _on_fn=_On,
250
                          _confirm_fn=self._ConfirmForce)
251
      self.assertEqual(result, self._ON_EXITCODE)
252

    
253
  def testMasterWithoutShowAll(self):
254
    opts = optparse.Values(dict(groups=False, show_all=False,
255
                                force=True, on=False))
256
    client = _ClientForEpo(NotImplemented, [
257
      ("node1.example.com", True, [], [], True, False),
258
      ])
259
    result = self._Test(opts, [], cl=client, _confirm_fn=self._ConfirmForce)
260
    self.assertEqual(result, constants.EXIT_FAILURE)
261

    
262

    
263
class DrbdHelperTestCase(unittest.TestCase):
264

    
265
  def setUp(self):
266
    unittest.TestCase.setUp(self)
267
    self.enabled_disk_templates = []
268

    
269
  def enableDrbd(self):
270
    self.enabled_disk_templates = [constants.DT_DRBD8]
271

    
272
  def disableDrbd(self):
273
    self.enabled_disk_templates = [constants.DT_DISKLESS]
274

    
275

    
276
class InitDrbdHelper(DrbdHelperTestCase):
277

    
278
  def testNoDrbdNoHelper(self):
279
    opts = mock.Mock()
280
    opts.drbd_helper = None
281
    self.disableDrbd()
282
    helper = gnt_cluster._InitDrbdHelper(opts, self.enabled_disk_templates)
283
    self.assertEquals(None, helper)
284

    
285
  def testNoDrbdHelper(self):
286
    opts = mock.Mock()
287
    self.disableDrbd()
288
    opts.drbd_helper = "/bin/true"
289
    helper = gnt_cluster._InitDrbdHelper(opts, self.enabled_disk_templates)
290
    self.assertEquals(opts.drbd_helper, helper)
291

    
292
  def testDrbdHelperNone(self):
293
    opts = mock.Mock()
294
    self.enableDrbd()
295
    opts.drbd_helper = None
296
    helper = gnt_cluster._InitDrbdHelper(opts, self.enabled_disk_templates)
297
    self.assertEquals(constants.DEFAULT_DRBD_HELPER, helper)
298

    
299
  def testDrbdHelperEmpty(self):
300
    opts = mock.Mock()
301
    self.enableDrbd()
302
    opts.drbd_helper = ''
303
    self.assertRaises(errors.OpPrereqError, gnt_cluster._InitDrbdHelper, opts,
304
        self.enabled_disk_templates)
305

    
306
  def testDrbdHelper(self):
307
    opts = mock.Mock()
308
    self.enableDrbd()
309
    opts.drbd_helper = "/bin/true"
310
    helper = gnt_cluster._InitDrbdHelper(opts, self.enabled_disk_templates)
311
    self.assertEquals(opts.drbd_helper, helper)
312

    
313

    
314
class GetDrbdHelper(DrbdHelperTestCase):
315

    
316
  def testNoDrbdNoHelper(self):
317
    opts = mock.Mock()
318
    self.disableDrbd()
319
    opts.drbd_helper = None
320
    helper = gnt_cluster._GetDrbdHelper(opts, self.enabled_disk_templates)
321
    self.assertEquals(None, helper)
322

    
323
  def testNoTemplateInfoNoHelper(self):
324
    opts = mock.Mock()
325
    opts.drbd_helper = None
326
    helper = gnt_cluster._GetDrbdHelper(opts, None)
327
    self.assertEquals(None, helper)
328

    
329
  def testNoTemplateInfoHelper(self):
330
    opts = mock.Mock()
331
    opts.drbd_helper = "/bin/true"
332
    helper = gnt_cluster._GetDrbdHelper(opts, None)
333
    self.assertEquals(opts.drbd_helper, helper)
334

    
335
  def testNoDrbdHelper(self):
336
    opts = mock.Mock()
337
    self.disableDrbd()
338
    opts.drbd_helper = "/bin/true"
339
    helper = gnt_cluster._GetDrbdHelper(opts, None)
340
    self.assertEquals(opts.drbd_helper, helper)
341

    
342
  def testDrbdNoHelper(self):
343
    opts = mock.Mock()
344
    self.enableDrbd()
345
    opts.drbd_helper = None
346
    helper = gnt_cluster._GetDrbdHelper(opts, self.enabled_disk_templates)
347
    self.assertEquals(None, helper)
348

    
349
  def testDrbdHelper(self):
350
    opts = mock.Mock()
351
    self.enableDrbd()
352
    opts.drbd_helper = "/bin/true"
353
    helper = gnt_cluster._GetDrbdHelper(opts, self.enabled_disk_templates)
354
    self.assertEquals(opts.drbd_helper, helper)
355

    
356

    
357
if __name__ == "__main__":
358
  testutils.GanetiTestProgram()