4 # Copyright (C) 2008, 2011, 2012, 2013 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
26 from ganeti import constants
27 from ganeti import opcodes
28 from ganeti import query
30 from testsupport import *
35 class TestLUGroupAdd(CmdlibTestCase):
36 def testAddExistingGroup(self):
37 self.cfg.AddNewNodeGroup(name="existing_group")
39 op = opcodes.OpGroupAdd(group_name="existing_group")
40 self.ExecOpCodeExpectOpPrereqError(
41 op, "Desired group name 'existing_group' already exists")
43 def testAddNewGroup(self):
44 op = opcodes.OpGroupAdd(group_name="new_group")
48 self.mcpu.assertLogIsEmpty()
50 def testAddNewGroupParams(self):
51 ndparams = {constants.ND_EXCLUSIVE_STORAGE: True}
52 hv_state = {constants.HT_FAKE: {constants.HVST_CPU_TOTAL: 8}}
55 "mock_vg": {constants.DS_DISK_TOTAL: 10}
58 diskparams = {constants.DT_RBD: {constants.RBD_POOL: "mock_pool"}}
59 ipolicy = constants.IPOLICY_DEFAULTS
60 op = opcodes.OpGroupAdd(group_name="new_group",
63 disk_state=disk_state,
64 diskparams=diskparams,
69 self.mcpu.assertLogIsEmpty()
71 def testAddNewGroupInvalidDiskparams(self):
72 diskparams = {constants.DT_RBD: {constants.LV_STRIPES: 1}}
73 op = opcodes.OpGroupAdd(group_name="new_group",
74 diskparams=diskparams)
76 self.ExecOpCodeExpectOpPrereqError(
77 op, "Provided option keys not supported")
79 def testAddNewGroupInvalidIPolic(self):
80 ipolicy = {"invalid_key": "value"}
81 op = opcodes.OpGroupAdd(group_name="new_group",
84 self.ExecOpCodeExpectOpPrereqError(op, "Invalid keys in ipolicy")
87 class TestLUGroupAssignNodes(CmdlibTestCase):
88 def __init__(self, methodName='runTest'):
89 super(TestLUGroupAssignNodes, self).__init__(methodName)
91 self.op = opcodes.OpGroupAssignNodes(group_name="default",
94 def testAssignSingleNode(self):
95 node = self.cfg.AddNewNode()
96 op = self.CopyOpCode(self.op, nodes=[node.name])
100 self.mcpu.assertLogIsEmpty()
102 def _BuildSplitInstanceSituation(self):
103 node = self.cfg.AddNewNode()
104 self.cfg.AddNewInstance(disk_template=constants.DT_DRBD8,
105 primary_node=self.master,
107 group = self.cfg.AddNewNodeGroup()
111 def testSplitInstanceNoForce(self):
112 (node, group) = self._BuildSplitInstanceSituation()
113 op = opcodes.OpGroupAssignNodes(group_name=group.name,
116 self.ExecOpCodeExpectOpExecError(
117 op, "instances get split by this change and --force was not given")
119 def testSplitInstanceForce(self):
120 (node, group) = self._BuildSplitInstanceSituation()
122 node2 = self.cfg.AddNewNode(group=group)
123 self.cfg.AddNewInstance(disk_template=constants.DT_DRBD8,
124 primary_node=self.master,
125 secondary_node=node2)
127 op = opcodes.OpGroupAssignNodes(group_name=group.name,
133 self.mcpu.assertLogContainsRegex("will split the following instances")
134 self.mcpu.assertLogContainsRegex(
135 "instances continue to be split across groups")
139 def testCheckAssignmentForSplitInstances(self, lu):
140 g1 = self.cfg.AddNewNodeGroup()
141 g2 = self.cfg.AddNewNodeGroup()
142 g3 = self.cfg.AddNewNodeGroup()
144 for (n, g) in [("n1a", g1), ("n1b", g1), ("n2a", g2), ("n2b", g2),
145 ("n3a", g3), ("n3b", g3), ("n3c", g3)]:
146 self.cfg.AddNewNode(uuid=n, group=g.uuid)
148 for uuid, pnode, snode in [("inst1a", "n1a", "n1b"),
149 ("inst1b", "n1b", "n1a"),
150 ("inst2a", "n2a", "n2b"),
151 ("inst3a", "n3a", None),
152 ("inst3b", "n3b", "n1b"),
153 ("inst3c", "n3b", "n2b")]:
154 dt = constants.DT_DISKLESS if snode is None else constants.DT_DRBD8
155 self.cfg.AddNewInstance(uuid=uuid,
158 secondary_node=snode)
160 # Test first with the existing state.
161 (new, prev) = lu.CheckAssignmentForSplitInstances(
162 [], self.cfg.GetAllNodesInfo(), self.cfg.GetAllInstancesInfo())
164 self.assertEqual([], new)
165 self.assertEqual(set(["inst3b", "inst3c"]), set(prev))
167 # And now some changes.
168 (new, prev) = lu.CheckAssignmentForSplitInstances(
170 self.cfg.GetAllNodesInfo(),
171 self.cfg.GetAllInstancesInfo())
173 self.assertEqual(set(["inst1a", "inst1b"]), set(new))
174 self.assertEqual(set(["inst3c"]), set(prev))
177 class TestLUGroupQuery(CmdlibTestCase):
179 super(TestLUGroupQuery, self).setUp()
180 self.fields = query._BuildGroupFields().keys()
182 def testInvalidGroupName(self):
183 op = opcodes.OpGroupQuery(names=["does_not_exist"],
184 output_fields=self.fields)
186 self.ExecOpCodeExpectOpPrereqError(op, "Some groups do not exist")
188 def testQueryAllGroups(self):
189 op = opcodes.OpGroupQuery(output_fields=self.fields)
193 self.mcpu.assertLogIsEmpty()
195 def testQueryGroupsByNameAndUuid(self):
196 group1 = self.cfg.AddNewNodeGroup()
197 group2 = self.cfg.AddNewNodeGroup()
199 node1 = self.cfg.AddNewNode(group=group1)
200 node2 = self.cfg.AddNewNode(group=group1)
201 self.cfg.AddNewInstance(disk_template=constants.DT_DRBD8,
203 secondary_node=node2)
204 self.cfg.AddNewInstance(primary_node=node2)
206 op = opcodes.OpGroupQuery(names=[group1.name, group2.uuid],
207 output_fields=self.fields)
211 self.mcpu.assertLogIsEmpty()
214 if __name__ == "__main__":
215 testutils.GanetiTestProgram()