4 # Copyright (C) 2011 Google Inc.
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions are
11 # 1. Redistributions of source code must retain the above copyright notice,
12 # this list of conditions and the following disclaimer.
14 # 2. Redistributions in binary form must reproduce the above copyright
15 # notice, this list of conditions and the following disclaimer in the
16 # documentation and/or other materials provided with the distribution.
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
19 # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 """Script for testing ganeti.client.gnt_cluster"""
36 from ganeti
import errors
37 from ganeti
.client
import gnt_cluster
38 from ganeti
import utils
39 from ganeti
import compat
40 from ganeti
import constants
46 class TestEpoUtilities(unittest
.TestCase
):
48 self
.nodes2ip
= dict(("node%s" % i
, "192.0.2.%s" % i
) for i
in range(1, 10))
49 self
.nodes
= set(self
.nodes2ip
.keys())
50 self
.ips2node
= dict((v
, k
) for (k
, v
) in self
.nodes2ip
.items())
52 def _FakeAction(*args
):
55 def _FakePing(ip
, port
, live_port_needed
=False):
56 self
.assert_(live_port_needed
)
57 self
.assertEqual(port
, 0)
61 self
.assert_(secs
>= 0 and secs
<= 5)
64 def _NoopFeedback(self
, text
):
67 def testPingFnRemoveHostsUp(self
):
69 def _FakeSeenPing(ip
, *args
, **kwargs
):
70 node
= self
.ips2node
[ip
]
71 self
.assertFalse(node
in seen
)
75 helper
= gnt_cluster
._RunWhenNodesReachableHelper(self
.nodes
,
79 _ping_fn
=_FakeSeenPing
,
80 _sleep_fn
=self
._FakeSleep
)
82 nodes_len
= len(self
.nodes
)
83 for (num
, _
) in enumerate(self
.nodes
):
85 if num
< nodes_len
- 1:
86 self
.assertRaises(utils
.RetryAgain
, helper
)
90 self
.assertEqual(seen
, self
.nodes
)
91 self
.assertFalse(helper
.down
)
92 self
.assertEqual(helper
.up
, self
.nodes
)
94 def testActionReturnFalseSetsHelperFalse(self
):
96 def _FalseAction(*args
):
99 helper
= gnt_cluster
._RunWhenNodesReachableHelper(self
.nodes
, _FalseAction
,
102 _ping_fn
=self
._FakePing
,
103 _sleep_fn
=self
._FakeSleep
)
107 except utils
.RetryAgain
:
110 self
.assertFalse(helper
.success
)
112 def testMaybeInstanceStartup(self
):
114 def _FakeInstanceStart(opts
, instances
, start
):
115 instances_arg
.append(set(instances
))
119 "inst1": set(["node1", "node2"]),
120 "inst2": set(["node1", "node3"]),
121 "inst3": set(["node2", "node1"]),
122 "inst4": set(["node2", "node1", "node3"]),
123 "inst5": set(["node4"]),
126 fn
= _FakeInstanceStart
127 self
.assert_(gnt_cluster
._MaybeInstanceStartup(None, inst_map
, set(),
128 _instance_start_fn
=fn
))
129 self
.assertFalse(instances_arg
)
130 result
= gnt_cluster
._MaybeInstanceStartup(None, inst_map
, set(["node1"]),
131 _instance_start_fn
=fn
)
133 self
.assertFalse(instances_arg
)
134 result
= gnt_cluster
._MaybeInstanceStartup(None, inst_map
,
135 set(["node1", "node3"]),
136 _instance_start_fn
=fn
)
137 self
.assert_(result
is None)
138 self
.assertEqual(instances_arg
.pop(0), set(["inst2"]))
139 self
.assertFalse("inst2" in inst_map
)
140 result
= gnt_cluster
._MaybeInstanceStartup(None, inst_map
,
141 set(["node1", "node3"]),
142 _instance_start_fn
=fn
)
144 self
.assertFalse(instances_arg
)
145 result
= gnt_cluster
._MaybeInstanceStartup(None, inst_map
,
146 set(["node1", "node3", "node2"]),
147 _instance_start_fn
=fn
)
148 self
.assertEqual(instances_arg
.pop(0), set(["inst1", "inst3", "inst4"]))
149 self
.assert_(result
is None)
150 result
= gnt_cluster
._MaybeInstanceStartup(None, inst_map
,
151 set(["node1", "node3", "node2",
153 _instance_start_fn
=fn
)
154 self
.assert_(result
is None)
155 self
.assertEqual(instances_arg
.pop(0), set(["inst5"]))
156 self
.assertFalse(inst_map
)
160 def __init__(self
, groups
, nodes
):
161 self
._groups
= groups
164 def QueryGroups(self
, names
, fields
, use_locking
):
165 assert not use_locking
166 assert fields
== ["node_list"]
169 def QueryNodes(self
, names
, fields
, use_locking
):
170 assert not use_locking
171 assert fields
== ["name", "master", "pinst_list", "sinst_list", "powered",
176 class TestEpo(unittest
.TestCase
):
180 def _ConfirmForce(self
, *args
):
181 self
.fail("Shouldn't need confirmation")
183 def _Confirm(self
, exp_names
, result
, names
, ltype
, text
):
184 self
.assertEqual(names
, exp_names
)
185 self
.assertFalse(result
is NotImplemented)
188 def _Off(self
, exp_node_list
, opts
, node_list
, inst_map
):
189 self
.assertEqual(node_list
, exp_node_list
)
190 self
.assertFalse(inst_map
)
191 return self
._OFF_EXITCODE
193 def _Test(self
, *args
, **kwargs
):
194 defaults
= dict(cl
=NotImplemented, _on_fn
=NotImplemented,
195 _off_fn
=NotImplemented,
196 _stdout_fn
=lambda *args
: None,
197 _stderr_fn
=lambda *args
: None)
198 defaults
.update(kwargs
)
199 return gnt_cluster
.Epo(*args
, **defaults
)
201 def testShowAllWithGroups(self
):
202 opts
= optparse
.Values(dict(groups
=True, show_all
=True))
203 result
= self
._Test(opts
, NotImplemented)
204 self
.assertEqual(result
, constants
.EXIT_FAILURE
)
206 def testShowAllWithArgs(self
):
207 opts
= optparse
.Values(dict(groups
=False, show_all
=True))
208 result
= self
._Test(opts
, ["a", "b", "c"])
209 self
.assertEqual(result
, constants
.EXIT_FAILURE
)
211 def testNoArgumentsNoParameters(self
):
212 for (force
, confirm_result
) in [(True, NotImplemented), (False, False),
214 opts
= optparse
.Values(dict(groups
=False, show_all
=False, force
=force
,
216 client
= _ClientForEpo(NotImplemented, [
217 ("node1.example.com", False, [], [], True, False),
221 confirm_fn
= self
._ConfirmForce
223 confirm_fn
= compat
.partial(self
._Confirm
, ["node1.example.com"],
226 off_fn
= compat
.partial(self
._Off
, ["node1.example.com"])
228 result
= self
._Test(opts
, [], cl
=client
, _off_fn
=off_fn
,
229 _confirm_fn
=confirm_fn
)
230 if force
or confirm_result
:
231 self
.assertEqual(result
, self
._OFF_EXITCODE
)
233 self
.assertEqual(result
, constants
.EXIT_FAILURE
)
235 def testPowerOn(self
):
236 for master
in [False, True]:
237 opts
= optparse
.Values(dict(groups
=False, show_all
=True,
238 force
=True, on
=True))
239 client
= _ClientForEpo(NotImplemented, [
240 ("node1.example.com", False, [], [], True, False),
241 ("node2.example.com", False, [], [], False, False),
242 ("node3.example.com", False, [], [], True, True),
243 ("node4.example.com", False, [], [], None, True),
244 ("node5.example.com", master
, [], [], False, False),
247 def _On(_
, all_nodes
, node_list
, inst_map
):
248 self
.assertEqual(all_nodes
,
249 ["node%s.example.com" % i
for i
in range(1, 6)])
251 self
.assertEqual(node_list
, ["node2.example.com"])
253 self
.assertEqual(node_list
, ["node2.example.com",
254 "node5.example.com"])
255 self
.assertFalse(inst_map
)
256 return self
._ON_EXITCODE
258 result
= self
._Test(opts
, [], cl
=client
, _on_fn
=_On
,
259 _confirm_fn
=self
._ConfirmForce
)
260 self
.assertEqual(result
, self
._ON_EXITCODE
)
262 def testMasterWithoutShowAll(self
):
263 opts
= optparse
.Values(dict(groups
=False, show_all
=False,
264 force
=True, on
=False))
265 client
= _ClientForEpo(NotImplemented, [
266 ("node1.example.com", True, [], [], True, False),
268 result
= self
._Test(opts
, [], cl
=client
, _confirm_fn
=self
._ConfirmForce
)
269 self
.assertEqual(result
, constants
.EXIT_FAILURE
)
272 class DrbdHelperTestCase(unittest
.TestCase
):
275 unittest
.TestCase
.setUp(self
)
276 self
.enabled_disk_templates
= []
278 def enableDrbd(self
):
279 self
.enabled_disk_templates
= [constants
.DT_DRBD8
]
281 def disableDrbd(self
):
282 self
.enabled_disk_templates
= [constants
.DT_DISKLESS
]
285 class InitDrbdHelper(DrbdHelperTestCase
):
287 def testNoDrbdNoHelper(self
):
289 opts
.drbd_helper
= None
291 helper
= gnt_cluster
._InitDrbdHelper(opts
, self
.enabled_disk_templates
)
292 self
.assertEquals(None, helper
)
294 def testNoDrbdHelper(self
):
297 opts
.drbd_helper
= "/bin/true"
298 helper
= gnt_cluster
._InitDrbdHelper(opts
, self
.enabled_disk_templates
)
299 self
.assertEquals(opts
.drbd_helper
, helper
)
301 def testDrbdHelperNone(self
):
304 opts
.drbd_helper
= None
305 helper
= gnt_cluster
._InitDrbdHelper(opts
, self
.enabled_disk_templates
)
306 self
.assertEquals(constants
.DEFAULT_DRBD_HELPER
, helper
)
308 def testDrbdHelperEmpty(self
):
311 opts
.drbd_helper
= ''
312 self
.assertRaises(errors
.OpPrereqError
, gnt_cluster
._InitDrbdHelper
, opts
,
313 self
.enabled_disk_templates
)
315 def testDrbdHelper(self
):
318 opts
.drbd_helper
= "/bin/true"
319 helper
= gnt_cluster
._InitDrbdHelper(opts
, self
.enabled_disk_templates
)
320 self
.assertEquals(opts
.drbd_helper
, helper
)
323 class GetDrbdHelper(DrbdHelperTestCase
):
325 def testNoDrbdNoHelper(self
):
328 opts
.drbd_helper
= None
329 helper
= gnt_cluster
._GetDrbdHelper(opts
, self
.enabled_disk_templates
)
330 self
.assertEquals(None, helper
)
332 def testNoTemplateInfoNoHelper(self
):
334 opts
.drbd_helper
= None
335 helper
= gnt_cluster
._GetDrbdHelper(opts
, None)
336 self
.assertEquals(None, helper
)
338 def testNoTemplateInfoHelper(self
):
340 opts
.drbd_helper
= "/bin/true"
341 helper
= gnt_cluster
._GetDrbdHelper(opts
, None)
342 self
.assertEquals(opts
.drbd_helper
, helper
)
344 def testNoDrbdHelper(self
):
347 opts
.drbd_helper
= "/bin/true"
348 helper
= gnt_cluster
._GetDrbdHelper(opts
, None)
349 self
.assertEquals(opts
.drbd_helper
, helper
)
351 def testDrbdNoHelper(self
):
354 opts
.drbd_helper
= None
355 helper
= gnt_cluster
._GetDrbdHelper(opts
, self
.enabled_disk_templates
)
356 self
.assertEquals(None, helper
)
358 def testDrbdHelper(self
):
361 opts
.drbd_helper
= "/bin/true"
362 helper
= gnt_cluster
._GetDrbdHelper(opts
, self
.enabled_disk_templates
)
363 self
.assertEquals(opts
.drbd_helper
, helper
)
366 if __name__
== "__main__":
367 testutils
.GanetiTestProgram()