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
85 self.fake_cl = objects.Cluster(hvparams=hvparams, os_hvp=os_hvp,
87 self.fake_cl.UpgradeConfig()
89 def testGetHVDefaults(self):
91 self.failUnlessEqual(cl.GetHVDefaults(constants.HT_FAKE),
92 cl.hvparams[constants.HT_FAKE])
93 self.failUnlessEqual(cl.GetHVDefaults(None), {})
94 self.failUnlessEqual(cl.GetHVDefaults(constants.HT_XEN_PVM,
95 os_name="lenny-image"),
96 cl.os_hvp["lenny-image"][constants.HT_XEN_PVM])
99 def testFillHvFullMerge(self):
111 fake_inst = objects.Instance(name="foobar",
113 hypervisor=constants.HT_FAKE,
114 hvparams=inst_hvparams)
115 self.assertEqual(fake_dict, self.fake_cl.FillHV(fake_inst))
117 def testFillHvGlobalParams(self):
118 fake_inst = objects.Instance(name="foobar",
120 hypervisor=constants.HT_FAKE,
122 self.assertEqual(self.fake_cl.hvparams[constants.HT_FAKE],
123 self.fake_cl.FillHV(fake_inst))
125 def testFillHvInstParams(self):
129 fake_inst = objects.Instance(name="foobar",
131 hypervisor=constants.HT_XEN_PVM,
132 hvparams=inst_hvparams)
133 self.assertEqual(inst_hvparams, self.fake_cl.FillHV(fake_inst))
135 def testFillHvEmptyParams(self):
136 fake_inst = objects.Instance(name="foobar",
138 hypervisor=constants.HT_XEN_PVM,
140 self.assertEqual({}, self.fake_cl.FillHV(fake_inst))
142 def testFillHvPartialParams(self):
144 fake_inst = objects.Instance(name="foobar",
146 hypervisor=constants.HT_XEN_PVM,
148 self.assertEqual(self.fake_cl.os_hvp[os][constants.HT_XEN_PVM],
149 self.fake_cl.FillHV(fake_inst))
151 def testFillNdParamsCluster(self):
152 fake_node = objects.Node(name="test",
155 fake_group = objects.NodeGroup(name="testgroup",
157 self.assertEqual(self.fake_cl.ndparams,
158 self.fake_cl.FillND(fake_node, fake_group))
160 def testFillNdParamsNodeGroup(self):
161 fake_node = objects.Node(name="test",
165 constants.ND_OOB_PROGRAM: "/bin/group-oob",
166 constants.ND_SPINDLE_COUNT: 10,
168 fake_group = objects.NodeGroup(name="testgroup",
169 ndparams=group_ndparams)
170 self.assertEqual(group_ndparams,
171 self.fake_cl.FillND(fake_node, fake_group))
173 def testFillNdParamsNode(self):
175 constants.ND_OOB_PROGRAM: "/bin/node-oob",
176 constants.ND_SPINDLE_COUNT: 2,
178 fake_node = objects.Node(name="test",
179 ndparams=node_ndparams,
181 fake_group = objects.NodeGroup(name="testgroup",
183 self.assertEqual(node_ndparams,
184 self.fake_cl.FillND(fake_node, fake_group))
186 def testFillNdParamsAll(self):
188 constants.ND_OOB_PROGRAM: "/bin/node-oob",
189 constants.ND_SPINDLE_COUNT: 5,
191 fake_node = objects.Node(name="test",
192 ndparams=node_ndparams,
195 constants.ND_OOB_PROGRAM: "/bin/group-oob",
196 constants.ND_SPINDLE_COUNT: 4,
198 fake_group = objects.NodeGroup(name="testgroup",
199 ndparams=group_ndparams)
200 self.assertEqual(node_ndparams,
201 self.fake_cl.FillND(fake_node, fake_group))
203 def testPrimaryHypervisor(self):
204 assert self.fake_cl.enabled_hypervisors is None
205 self.fake_cl.enabled_hypervisors = [constants.HT_XEN_HVM]
206 self.assertEqual(self.fake_cl.primary_hypervisor, constants.HT_XEN_HVM)
208 self.fake_cl.enabled_hypervisors = [constants.HT_XEN_PVM, constants.HT_KVM]
209 self.assertEqual(self.fake_cl.primary_hypervisor, constants.HT_XEN_PVM)
211 self.fake_cl.enabled_hypervisors = sorted(constants.HYPER_TYPES)
212 self.assertEqual(self.fake_cl.primary_hypervisor, constants.HT_CHROOT)
215 class TestOS(unittest.TestCase):
218 "debootstrap+default",
219 "debootstrap++default",
222 def testSplitNameVariant(self):
223 for name in self.ALL_DATA:
224 self.assertEqual(len(objects.OS.SplitNameVariant(name)), 2)
226 def testVariant(self):
227 self.assertEqual(objects.OS.GetVariant("debootstrap"), "")
228 self.assertEqual(objects.OS.GetVariant("debootstrap+default"), "default")
231 class TestInstance(unittest.TestCase):
232 def _GenericCheck(self, inst):
233 for i in [inst.all_nodes, inst.secondary_nodes]:
234 self.assertTrue(isinstance(inst.all_nodes, (list, tuple)),
235 msg="Data type doesn't guarantee order")
237 self.assertTrue(inst.primary_node not in inst.secondary_nodes)
238 self.assertEqual(inst.all_nodes[0], inst.primary_node,
239 msg="Primary node not first node in list")
241 def testNodesNoDisks(self):
242 inst = objects.Instance(name="fakeinst.example.com",
243 primary_node="pnode.example.com",
247 self._GenericCheck(inst)
248 self.assertEqual(len(inst.secondary_nodes), 0)
249 self.assertEqual(set(inst.all_nodes), set([inst.primary_node]))
250 self.assertEqual(inst.MapLVsByNode(), {
251 inst.primary_node: [],
254 def testNodesPlainDisks(self):
255 inst = objects.Instance(name="fakeinstplain.example.com",
256 primary_node="node3.example.com",
258 objects.Disk(dev_type=constants.LD_LV, size=128,
259 logical_id=("myxenvg", "disk25494")),
260 objects.Disk(dev_type=constants.LD_LV, size=512,
261 logical_id=("myxenvg", "disk29071")),
264 self._GenericCheck(inst)
265 self.assertEqual(len(inst.secondary_nodes), 0)
266 self.assertEqual(set(inst.all_nodes), set([inst.primary_node]))
267 self.assertEqual(inst.MapLVsByNode(), {
268 inst.primary_node: ["myxenvg/disk25494", "myxenvg/disk29071"],
271 def testNodesDrbdDisks(self):
272 inst = objects.Instance(name="fakeinstdrbd.example.com",
273 primary_node="node10.example.com",
275 objects.Disk(dev_type=constants.LD_DRBD8, size=786432,
276 logical_id=("node10.example.com", "node15.example.com",
277 12300, 0, 0, "secret"),
279 objects.Disk(dev_type=constants.LD_LV, size=786432,
280 logical_id=("myxenvg", "disk0")),
281 objects.Disk(dev_type=constants.LD_LV, size=128,
282 logical_id=("myxenvg", "meta0"))
287 self._GenericCheck(inst)
288 self.assertEqual(set(inst.secondary_nodes), set(["node15.example.com"]))
289 self.assertEqual(set(inst.all_nodes),
290 set([inst.primary_node, "node15.example.com"]))
291 self.assertEqual(inst.MapLVsByNode(), {
292 inst.primary_node: ["myxenvg/disk0", "myxenvg/meta0"],
293 "node15.example.com": ["myxenvg/disk0", "myxenvg/meta0"],
296 self.assertEqual(inst.FindDisk(0), inst.disks[0])
297 self.assertRaises(errors.OpPrereqError, inst.FindDisk, "hello")
298 self.assertRaises(errors.OpPrereqError, inst.FindDisk, 100)
299 self.assertRaises(errors.OpPrereqError, inst.FindDisk, 1)
302 class TestNode(unittest.TestCase):
304 self.assertEqual(objects.Node().ToDict(), {})
305 self.assertTrue(isinstance(objects.Node.FromDict({}), objects.Node))
307 def testHvState(self):
308 node = objects.Node(name="node18157.example.com", hv_state={
309 constants.HT_XEN_HVM: objects.NodeHvState(cpu_total=64),
310 constants.HT_KVM: objects.NodeHvState(cpu_node=1),
313 node2 = objects.Node.FromDict(node.ToDict())
315 # Make sure nothing can reference it anymore
318 self.assertEqual(node2.name, "node18157.example.com")
319 self.assertEqual(frozenset(node2.hv_state), frozenset([
320 constants.HT_XEN_HVM,
323 self.assertEqual(node2.hv_state[constants.HT_KVM].cpu_node, 1)
324 self.assertEqual(node2.hv_state[constants.HT_XEN_HVM].cpu_total, 64)
326 def testDiskState(self):
327 node = objects.Node(name="node32087.example.com", disk_state={
329 "lv32352": objects.NodeDiskState(total=128),
330 "lv2082": objects.NodeDiskState(total=512),
334 node2 = objects.Node.FromDict(node.ToDict())
336 # Make sure nothing can reference it anymore
339 self.assertEqual(node2.name, "node32087.example.com")
340 self.assertEqual(frozenset(node2.disk_state), frozenset([
343 self.assertEqual(frozenset(node2.disk_state[constants.LD_LV]), frozenset([
347 self.assertEqual(node2.disk_state[constants.LD_LV]["lv2082"].total, 512)
348 self.assertEqual(node2.disk_state[constants.LD_LV]["lv32352"].total, 128)
351 if __name__ == "__main__":
352 testutils.GanetiTestProgram()