Use query client when neccessary for group queries
[ganeti-github.git] / test / py / ganeti.client.gnt_cluster_unittest.py
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(qcl=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, [], qcl=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, [], qcl=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, [], qcl=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()