4 # Copyright (C) 2006, 2007, 2008, 2010, 2012 Google Inc.
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.
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.
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
22 """Script for unittesting the objects module"""
27 from ganeti import constants
28 from ganeti import objects
29 from ganeti import errors
34 class SimpleObject(objects.ConfigObject):
35 __slots__ = ["a", "b"]
38 class TestDictState(unittest.TestCase):
39 """Simple dict tansformation tests"""
41 def testSimpleObjectToDict(self):
42 o1 = SimpleObject(a="1")
43 self.assertEquals(o1.ToDict(), {"a": "1"})
44 self.assertEquals(o1.__getstate__(), {"a": "1"})
45 self.assertEquals(o1.__getstate__(), o1.ToDict())
48 self.assertEquals(o1.ToDict(), {"a": 2, "b": 5})
49 o2 = SimpleObject.FromDict(o1.ToDict())
50 self.assertEquals(o1.ToDict(), {"a": 2, "b": 5})
53 class TestClusterObject(unittest.TestCase):
54 """Tests done on a L{objects.Cluster}"""
72 constants.HT_XEN_PVM: {
73 "root_path": "/dev/sda5",
81 constants.ND_OOB_PROGRAM: "/bin/cluster-oob",
82 constants.ND_SPINDLE_COUNT: 1,
83 constants.ND_EXCLUSIVE_STORAGE: False,
86 self.fake_cl = objects.Cluster(hvparams=hvparams, os_hvp=os_hvp,
88 self.fake_cl.UpgradeConfig()
90 def testGetHVDefaults(self):
92 self.failUnlessEqual(cl.GetHVDefaults(constants.HT_FAKE),
93 cl.hvparams[constants.HT_FAKE])
94 self.failUnlessEqual(cl.GetHVDefaults(None), {})
95 self.failUnlessEqual(cl.GetHVDefaults(constants.HT_XEN_PVM,
96 os_name="lenny-image"),
97 cl.os_hvp["lenny-image"][constants.HT_XEN_PVM])
100 def testFillHvFullMerge(self):
112 fake_inst = objects.Instance(name="foobar",
114 hypervisor=constants.HT_FAKE,
115 hvparams=inst_hvparams)
116 self.assertEqual(fake_dict, self.fake_cl.FillHV(fake_inst))
118 def testFillHvGlobalParams(self):
119 fake_inst = objects.Instance(name="foobar",
121 hypervisor=constants.HT_FAKE,
123 self.assertEqual(self.fake_cl.hvparams[constants.HT_FAKE],
124 self.fake_cl.FillHV(fake_inst))
126 def testFillHvInstParams(self):
130 fake_inst = objects.Instance(name="foobar",
132 hypervisor=constants.HT_XEN_PVM,
133 hvparams=inst_hvparams)
134 self.assertEqual(inst_hvparams, self.fake_cl.FillHV(fake_inst))
136 def testFillHvEmptyParams(self):
137 fake_inst = objects.Instance(name="foobar",
139 hypervisor=constants.HT_XEN_PVM,
141 self.assertEqual({}, self.fake_cl.FillHV(fake_inst))
143 def testFillHvPartialParams(self):
145 fake_inst = objects.Instance(name="foobar",
147 hypervisor=constants.HT_XEN_PVM,
149 self.assertEqual(self.fake_cl.os_hvp[os][constants.HT_XEN_PVM],
150 self.fake_cl.FillHV(fake_inst))
152 def testFillNdParamsCluster(self):
153 fake_node = objects.Node(name="test",
156 fake_group = objects.NodeGroup(name="testgroup",
158 self.assertEqual(self.fake_cl.ndparams,
159 self.fake_cl.FillND(fake_node, fake_group))
161 def testFillNdParamsNodeGroup(self):
162 fake_node = objects.Node(name="test",
166 constants.ND_OOB_PROGRAM: "/bin/group-oob",
167 constants.ND_SPINDLE_COUNT: 10,
168 constants.ND_EXCLUSIVE_STORAGE: True,
170 fake_group = objects.NodeGroup(name="testgroup",
171 ndparams=group_ndparams)
172 self.assertEqual(group_ndparams,
173 self.fake_cl.FillND(fake_node, fake_group))
175 def testFillNdParamsNode(self):
177 constants.ND_OOB_PROGRAM: "/bin/node-oob",
178 constants.ND_SPINDLE_COUNT: 2,
179 constants.ND_EXCLUSIVE_STORAGE: True,
181 fake_node = objects.Node(name="test",
182 ndparams=node_ndparams,
184 fake_group = objects.NodeGroup(name="testgroup",
186 self.assertEqual(node_ndparams,
187 self.fake_cl.FillND(fake_node, fake_group))
189 def testFillNdParamsAll(self):
191 constants.ND_OOB_PROGRAM: "/bin/node-oob",
192 constants.ND_SPINDLE_COUNT: 5,
193 constants.ND_EXCLUSIVE_STORAGE: True,
195 fake_node = objects.Node(name="test",
196 ndparams=node_ndparams,
199 constants.ND_OOB_PROGRAM: "/bin/group-oob",
200 constants.ND_SPINDLE_COUNT: 4,
202 fake_group = objects.NodeGroup(name="testgroup",
203 ndparams=group_ndparams)
204 self.assertEqual(node_ndparams,
205 self.fake_cl.FillND(fake_node, fake_group))
207 def testPrimaryHypervisor(self):
208 assert self.fake_cl.enabled_hypervisors is None
209 self.fake_cl.enabled_hypervisors = [constants.HT_XEN_HVM]
210 self.assertEqual(self.fake_cl.primary_hypervisor, constants.HT_XEN_HVM)
212 self.fake_cl.enabled_hypervisors = [constants.HT_XEN_PVM, constants.HT_KVM]
213 self.assertEqual(self.fake_cl.primary_hypervisor, constants.HT_XEN_PVM)
215 self.fake_cl.enabled_hypervisors = sorted(constants.HYPER_TYPES)
216 self.assertEqual(self.fake_cl.primary_hypervisor, constants.HT_CHROOT)
219 class TestOS(unittest.TestCase):
222 "debootstrap+default",
223 "debootstrap++default",
226 def testSplitNameVariant(self):
227 for name in self.ALL_DATA:
228 self.assertEqual(len(objects.OS.SplitNameVariant(name)), 2)
230 def testVariant(self):
231 self.assertEqual(objects.OS.GetVariant("debootstrap"), "")
232 self.assertEqual(objects.OS.GetVariant("debootstrap+default"), "default")
235 class TestInstance(unittest.TestCase):
236 def _GenericCheck(self, inst):
237 for i in [inst.all_nodes, inst.secondary_nodes]:
238 self.assertTrue(isinstance(inst.all_nodes, (list, tuple)),
239 msg="Data type doesn't guarantee order")
241 self.assertTrue(inst.primary_node not in inst.secondary_nodes)
242 self.assertEqual(inst.all_nodes[0], inst.primary_node,
243 msg="Primary node not first node in list")
245 def testNodesNoDisks(self):
246 inst = objects.Instance(name="fakeinst.example.com",
247 primary_node="pnode.example.com",
251 self._GenericCheck(inst)
252 self.assertEqual(len(inst.secondary_nodes), 0)
253 self.assertEqual(set(inst.all_nodes), set([inst.primary_node]))
254 self.assertEqual(inst.MapLVsByNode(), {
255 inst.primary_node: [],
258 def testNodesPlainDisks(self):
259 inst = objects.Instance(name="fakeinstplain.example.com",
260 primary_node="node3.example.com",
262 objects.Disk(dev_type=constants.LD_LV, size=128,
263 logical_id=("myxenvg", "disk25494")),
264 objects.Disk(dev_type=constants.LD_LV, size=512,
265 logical_id=("myxenvg", "disk29071")),
268 self._GenericCheck(inst)
269 self.assertEqual(len(inst.secondary_nodes), 0)
270 self.assertEqual(set(inst.all_nodes), set([inst.primary_node]))
271 self.assertEqual(inst.MapLVsByNode(), {
272 inst.primary_node: ["myxenvg/disk25494", "myxenvg/disk29071"],
275 def testNodesDrbdDisks(self):
276 inst = objects.Instance(name="fakeinstdrbd.example.com",
277 primary_node="node10.example.com",
279 objects.Disk(dev_type=constants.LD_DRBD8, size=786432,
280 logical_id=("node10.example.com", "node15.example.com",
281 12300, 0, 0, "secret"),
283 objects.Disk(dev_type=constants.LD_LV, size=786432,
284 logical_id=("myxenvg", "disk0")),
285 objects.Disk(dev_type=constants.LD_LV, size=128,
286 logical_id=("myxenvg", "meta0"))
291 self._GenericCheck(inst)
292 self.assertEqual(set(inst.secondary_nodes), set(["node15.example.com"]))
293 self.assertEqual(set(inst.all_nodes),
294 set([inst.primary_node, "node15.example.com"]))
295 self.assertEqual(inst.MapLVsByNode(), {
296 inst.primary_node: ["myxenvg/disk0", "myxenvg/meta0"],
297 "node15.example.com": ["myxenvg/disk0", "myxenvg/meta0"],
300 self.assertEqual(inst.FindDisk(0), inst.disks[0])
301 self.assertRaises(errors.OpPrereqError, inst.FindDisk, "hello")
302 self.assertRaises(errors.OpPrereqError, inst.FindDisk, 100)
303 self.assertRaises(errors.OpPrereqError, inst.FindDisk, 1)
306 class TestNode(unittest.TestCase):
308 self.assertEqual(objects.Node().ToDict(), {})
309 self.assertTrue(isinstance(objects.Node.FromDict({}), objects.Node))
311 def testHvState(self):
312 node = objects.Node(name="node18157.example.com", hv_state={
313 constants.HT_XEN_HVM: objects.NodeHvState(cpu_total=64),
314 constants.HT_KVM: objects.NodeHvState(cpu_node=1),
317 node2 = objects.Node.FromDict(node.ToDict())
319 # Make sure nothing can reference it anymore
322 self.assertEqual(node2.name, "node18157.example.com")
323 self.assertEqual(frozenset(node2.hv_state), frozenset([
324 constants.HT_XEN_HVM,
327 self.assertEqual(node2.hv_state[constants.HT_KVM].cpu_node, 1)
328 self.assertEqual(node2.hv_state[constants.HT_XEN_HVM].cpu_total, 64)
330 def testDiskState(self):
331 node = objects.Node(name="node32087.example.com", disk_state={
333 "lv32352": objects.NodeDiskState(total=128),
334 "lv2082": objects.NodeDiskState(total=512),
338 node2 = objects.Node.FromDict(node.ToDict())
340 # Make sure nothing can reference it anymore
343 self.assertEqual(node2.name, "node32087.example.com")
344 self.assertEqual(frozenset(node2.disk_state), frozenset([
347 self.assertEqual(frozenset(node2.disk_state[constants.LD_LV]), frozenset([
351 self.assertEqual(node2.disk_state[constants.LD_LV]["lv2082"].total, 512)
352 self.assertEqual(node2.disk_state[constants.LD_LV]["lv32352"].total, 128)
354 def testFilterEsNdp(self):
355 node1 = objects.Node(name="node11673.example.com", ndparams={
356 constants.ND_EXCLUSIVE_STORAGE: True,
358 node2 = objects.Node(name="node11674.example.com", ndparams={
359 constants.ND_SPINDLE_COUNT: 3,
360 constants.ND_EXCLUSIVE_STORAGE: False,
362 self.assertTrue(constants.ND_EXCLUSIVE_STORAGE in node1.ndparams)
363 node1.UpgradeConfig()
364 self.assertFalse(constants.ND_EXCLUSIVE_STORAGE in node1.ndparams)
365 self.assertTrue(constants.ND_EXCLUSIVE_STORAGE in node2.ndparams)
366 self.assertTrue(constants.ND_SPINDLE_COUNT in node2.ndparams)
367 node2.UpgradeConfig()
368 self.assertFalse(constants.ND_EXCLUSIVE_STORAGE in node2.ndparams)
369 self.assertTrue(constants.ND_SPINDLE_COUNT in node2.ndparams)
372 if __name__ == "__main__":
373 testutils.GanetiTestProgram()