root / test / py / cmdlib / group_unittest.py @ a6c43c02
History | View | Annotate | Download (14 kB)
1 | 8129eac1 | Thomas Thrainer | #!/usr/bin/python
|
---|---|---|---|
2 | 8129eac1 | Thomas Thrainer | #
|
3 | 8129eac1 | Thomas Thrainer | |
4 | 8129eac1 | Thomas Thrainer | # Copyright (C) 2008, 2011, 2012, 2013 Google Inc.
|
5 | 8129eac1 | Thomas Thrainer | #
|
6 | 8129eac1 | Thomas Thrainer | # This program is free software; you can redistribute it and/or modify
|
7 | 8129eac1 | Thomas Thrainer | # it under the terms of the GNU General Public License as published by
|
8 | 8129eac1 | Thomas Thrainer | # the Free Software Foundation; either version 2 of the License, or
|
9 | 8129eac1 | Thomas Thrainer | # (at your option) any later version.
|
10 | 8129eac1 | Thomas Thrainer | #
|
11 | 8129eac1 | Thomas Thrainer | # This program is distributed in the hope that it will be useful, but
|
12 | 8129eac1 | Thomas Thrainer | # WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | 8129eac1 | Thomas Thrainer | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | 8129eac1 | Thomas Thrainer | # General Public License for more details.
|
15 | 8129eac1 | Thomas Thrainer | #
|
16 | 8129eac1 | Thomas Thrainer | # You should have received a copy of the GNU General Public License
|
17 | 8129eac1 | Thomas Thrainer | # along with this program; if not, write to the Free Software
|
18 | 8129eac1 | Thomas Thrainer | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
19 | 8129eac1 | Thomas Thrainer | # 02110-1301, USA.
|
20 | 8129eac1 | Thomas Thrainer | |
21 | 8129eac1 | Thomas Thrainer | |
22 | 8129eac1 | Thomas Thrainer | """Tests for LUGroup*
|
23 | 8129eac1 | Thomas Thrainer |
|
24 | 8129eac1 | Thomas Thrainer | """
|
25 | 8129eac1 | Thomas Thrainer | |
26 | 3c768f88 | Thomas Thrainer | import itertools |
27 | 3c768f88 | Thomas Thrainer | |
28 | 8129eac1 | Thomas Thrainer | from ganeti import constants |
29 | 8129eac1 | Thomas Thrainer | from ganeti import opcodes |
30 | ae904a6b | Thomas Thrainer | from ganeti import query |
31 | 8129eac1 | Thomas Thrainer | |
32 | 8129eac1 | Thomas Thrainer | from testsupport import * |
33 | 8129eac1 | Thomas Thrainer | |
34 | 8129eac1 | Thomas Thrainer | import testutils |
35 | 8129eac1 | Thomas Thrainer | |
36 | 8129eac1 | Thomas Thrainer | |
37 | 9051a390 | Thomas Thrainer | class TestLUGroupAdd(CmdlibTestCase): |
38 | 9051a390 | Thomas Thrainer | def testAddExistingGroup(self): |
39 | 9051a390 | Thomas Thrainer | self.cfg.AddNewNodeGroup(name="existing_group") |
40 | 9051a390 | Thomas Thrainer | |
41 | 9051a390 | Thomas Thrainer | op = opcodes.OpGroupAdd(group_name="existing_group")
|
42 | 9051a390 | Thomas Thrainer | self.ExecOpCodeExpectOpPrereqError(
|
43 | 9051a390 | Thomas Thrainer | op, "Desired group name 'existing_group' already exists")
|
44 | 9051a390 | Thomas Thrainer | |
45 | 9051a390 | Thomas Thrainer | def testAddNewGroup(self): |
46 | 9051a390 | Thomas Thrainer | op = opcodes.OpGroupAdd(group_name="new_group")
|
47 | 9051a390 | Thomas Thrainer | |
48 | 9051a390 | Thomas Thrainer | self.ExecOpCode(op)
|
49 | 9051a390 | Thomas Thrainer | |
50 | 9051a390 | Thomas Thrainer | self.mcpu.assertLogIsEmpty()
|
51 | 9051a390 | Thomas Thrainer | |
52 | 9051a390 | Thomas Thrainer | def testAddNewGroupParams(self): |
53 | 9051a390 | Thomas Thrainer | ndparams = {constants.ND_EXCLUSIVE_STORAGE: True}
|
54 | 9051a390 | Thomas Thrainer | hv_state = {constants.HT_FAKE: {constants.HVST_CPU_TOTAL: 8}}
|
55 | 9051a390 | Thomas Thrainer | disk_state = { |
56 | 0c5f1b13 | Thomas Thrainer | constants.DT_PLAIN: { |
57 | 9051a390 | Thomas Thrainer | "mock_vg": {constants.DS_DISK_TOTAL: 10} |
58 | 9051a390 | Thomas Thrainer | } |
59 | 9051a390 | Thomas Thrainer | } |
60 | 9051a390 | Thomas Thrainer | diskparams = {constants.DT_RBD: {constants.RBD_POOL: "mock_pool"}}
|
61 | 9051a390 | Thomas Thrainer | ipolicy = constants.IPOLICY_DEFAULTS |
62 | 9051a390 | Thomas Thrainer | op = opcodes.OpGroupAdd(group_name="new_group",
|
63 | 9051a390 | Thomas Thrainer | ndparams=ndparams, |
64 | 9051a390 | Thomas Thrainer | hv_state=hv_state, |
65 | 9051a390 | Thomas Thrainer | disk_state=disk_state, |
66 | 9051a390 | Thomas Thrainer | diskparams=diskparams, |
67 | 9051a390 | Thomas Thrainer | ipolicy=ipolicy) |
68 | 9051a390 | Thomas Thrainer | |
69 | 9051a390 | Thomas Thrainer | self.ExecOpCode(op)
|
70 | 9051a390 | Thomas Thrainer | |
71 | 9051a390 | Thomas Thrainer | self.mcpu.assertLogIsEmpty()
|
72 | 9051a390 | Thomas Thrainer | |
73 | 9051a390 | Thomas Thrainer | def testAddNewGroupInvalidDiskparams(self): |
74 | 9051a390 | Thomas Thrainer | diskparams = {constants.DT_RBD: {constants.LV_STRIPES: 1}}
|
75 | 9051a390 | Thomas Thrainer | op = opcodes.OpGroupAdd(group_name="new_group",
|
76 | 9051a390 | Thomas Thrainer | diskparams=diskparams) |
77 | 9051a390 | Thomas Thrainer | |
78 | 9051a390 | Thomas Thrainer | self.ExecOpCodeExpectOpPrereqError(
|
79 | 9051a390 | Thomas Thrainer | op, "Provided option keys not supported")
|
80 | 9051a390 | Thomas Thrainer | |
81 | 9051a390 | Thomas Thrainer | def testAddNewGroupInvalidIPolic(self): |
82 | 9051a390 | Thomas Thrainer | ipolicy = {"invalid_key": "value"} |
83 | 9051a390 | Thomas Thrainer | op = opcodes.OpGroupAdd(group_name="new_group",
|
84 | 9051a390 | Thomas Thrainer | ipolicy=ipolicy) |
85 | 9051a390 | Thomas Thrainer | |
86 | 9051a390 | Thomas Thrainer | self.ExecOpCodeExpectOpPrereqError(op, "Invalid keys in ipolicy") |
87 | 9051a390 | Thomas Thrainer | |
88 | 9051a390 | Thomas Thrainer | |
89 | 8129eac1 | Thomas Thrainer | class TestLUGroupAssignNodes(CmdlibTestCase): |
90 | 8129eac1 | Thomas Thrainer | def __init__(self, methodName='runTest'): |
91 | 8129eac1 | Thomas Thrainer | super(TestLUGroupAssignNodes, self).__init__(methodName) |
92 | 8129eac1 | Thomas Thrainer | |
93 | 8129eac1 | Thomas Thrainer | self.op = opcodes.OpGroupAssignNodes(group_name="default", |
94 | 8129eac1 | Thomas Thrainer | nodes=[]) |
95 | 8129eac1 | Thomas Thrainer | |
96 | d189f139 | Thomas Thrainer | def testAssignSingleNode(self): |
97 | d189f139 | Thomas Thrainer | node = self.cfg.AddNewNode()
|
98 | d189f139 | Thomas Thrainer | op = self.CopyOpCode(self.op, nodes=[node.name]) |
99 | d189f139 | Thomas Thrainer | |
100 | d189f139 | Thomas Thrainer | self.ExecOpCode(op)
|
101 | d189f139 | Thomas Thrainer | |
102 | d189f139 | Thomas Thrainer | self.mcpu.assertLogIsEmpty()
|
103 | d189f139 | Thomas Thrainer | |
104 | d189f139 | Thomas Thrainer | def _BuildSplitInstanceSituation(self): |
105 | d189f139 | Thomas Thrainer | node = self.cfg.AddNewNode()
|
106 | d189f139 | Thomas Thrainer | self.cfg.AddNewInstance(disk_template=constants.DT_DRBD8,
|
107 | d189f139 | Thomas Thrainer | primary_node=self.master,
|
108 | d189f139 | Thomas Thrainer | secondary_node=node) |
109 | d189f139 | Thomas Thrainer | group = self.cfg.AddNewNodeGroup()
|
110 | d189f139 | Thomas Thrainer | |
111 | d189f139 | Thomas Thrainer | return (node, group)
|
112 | d189f139 | Thomas Thrainer | |
113 | d189f139 | Thomas Thrainer | def testSplitInstanceNoForce(self): |
114 | d189f139 | Thomas Thrainer | (node, group) = self._BuildSplitInstanceSituation()
|
115 | d189f139 | Thomas Thrainer | op = opcodes.OpGroupAssignNodes(group_name=group.name, |
116 | d189f139 | Thomas Thrainer | nodes=[node.name]) |
117 | d189f139 | Thomas Thrainer | |
118 | d189f139 | Thomas Thrainer | self.ExecOpCodeExpectOpExecError(
|
119 | d189f139 | Thomas Thrainer | op, "instances get split by this change and --force was not given")
|
120 | d189f139 | Thomas Thrainer | |
121 | d189f139 | Thomas Thrainer | def testSplitInstanceForce(self): |
122 | d189f139 | Thomas Thrainer | (node, group) = self._BuildSplitInstanceSituation()
|
123 | d189f139 | Thomas Thrainer | |
124 | d189f139 | Thomas Thrainer | node2 = self.cfg.AddNewNode(group=group)
|
125 | d189f139 | Thomas Thrainer | self.cfg.AddNewInstance(disk_template=constants.DT_DRBD8,
|
126 | d189f139 | Thomas Thrainer | primary_node=self.master,
|
127 | d189f139 | Thomas Thrainer | secondary_node=node2) |
128 | d189f139 | Thomas Thrainer | |
129 | d189f139 | Thomas Thrainer | op = opcodes.OpGroupAssignNodes(group_name=group.name, |
130 | d189f139 | Thomas Thrainer | nodes=[node.name], |
131 | d189f139 | Thomas Thrainer | force=True)
|
132 | d189f139 | Thomas Thrainer | |
133 | d189f139 | Thomas Thrainer | self.ExecOpCode(op)
|
134 | d189f139 | Thomas Thrainer | |
135 | d189f139 | Thomas Thrainer | self.mcpu.assertLogContainsRegex("will split the following instances") |
136 | d189f139 | Thomas Thrainer | self.mcpu.assertLogContainsRegex(
|
137 | d189f139 | Thomas Thrainer | "instances continue to be split across groups")
|
138 | d189f139 | Thomas Thrainer | |
139 | d189f139 | Thomas Thrainer | |
140 | 8129eac1 | Thomas Thrainer | @withLockedLU
|
141 | 8129eac1 | Thomas Thrainer | def testCheckAssignmentForSplitInstances(self, lu): |
142 | 8129eac1 | Thomas Thrainer | g1 = self.cfg.AddNewNodeGroup()
|
143 | 8129eac1 | Thomas Thrainer | g2 = self.cfg.AddNewNodeGroup()
|
144 | 8129eac1 | Thomas Thrainer | g3 = self.cfg.AddNewNodeGroup()
|
145 | 8129eac1 | Thomas Thrainer | |
146 | 8129eac1 | Thomas Thrainer | for (n, g) in [("n1a", g1), ("n1b", g1), ("n2a", g2), ("n2b", g2), |
147 | 8129eac1 | Thomas Thrainer | ("n3a", g3), ("n3b", g3), ("n3c", g3)]: |
148 | 8129eac1 | Thomas Thrainer | self.cfg.AddNewNode(uuid=n, group=g.uuid)
|
149 | 8129eac1 | Thomas Thrainer | |
150 | 8129eac1 | Thomas Thrainer | for uuid, pnode, snode in [("inst1a", "n1a", "n1b"), |
151 | 8129eac1 | Thomas Thrainer | ("inst1b", "n1b", "n1a"), |
152 | 8129eac1 | Thomas Thrainer | ("inst2a", "n2a", "n2b"), |
153 | 8129eac1 | Thomas Thrainer | ("inst3a", "n3a", None), |
154 | 8129eac1 | Thomas Thrainer | ("inst3b", "n3b", "n1b"), |
155 | 8129eac1 | Thomas Thrainer | ("inst3c", "n3b", "n2b")]: |
156 | 8129eac1 | Thomas Thrainer | dt = constants.DT_DISKLESS if snode is None else constants.DT_DRBD8 |
157 | 8129eac1 | Thomas Thrainer | self.cfg.AddNewInstance(uuid=uuid,
|
158 | 8129eac1 | Thomas Thrainer | disk_template=dt, |
159 | 8129eac1 | Thomas Thrainer | primary_node=pnode, |
160 | 8129eac1 | Thomas Thrainer | secondary_node=snode) |
161 | 8129eac1 | Thomas Thrainer | |
162 | 8129eac1 | Thomas Thrainer | # Test first with the existing state.
|
163 | 8129eac1 | Thomas Thrainer | (new, prev) = lu.CheckAssignmentForSplitInstances( |
164 | 8129eac1 | Thomas Thrainer | [], self.cfg.GetAllNodesInfo(), self.cfg.GetAllInstancesInfo()) |
165 | 8129eac1 | Thomas Thrainer | |
166 | 8129eac1 | Thomas Thrainer | self.assertEqual([], new)
|
167 | 8129eac1 | Thomas Thrainer | self.assertEqual(set(["inst3b", "inst3c"]), set(prev)) |
168 | 8129eac1 | Thomas Thrainer | |
169 | 8129eac1 | Thomas Thrainer | # And now some changes.
|
170 | 8129eac1 | Thomas Thrainer | (new, prev) = lu.CheckAssignmentForSplitInstances( |
171 | 9051a390 | Thomas Thrainer | [("n1b", g3.uuid)],
|
172 | 9051a390 | Thomas Thrainer | self.cfg.GetAllNodesInfo(),
|
173 | 9051a390 | Thomas Thrainer | self.cfg.GetAllInstancesInfo())
|
174 | 8129eac1 | Thomas Thrainer | |
175 | 8129eac1 | Thomas Thrainer | self.assertEqual(set(["inst1a", "inst1b"]), set(new)) |
176 | 8129eac1 | Thomas Thrainer | self.assertEqual(set(["inst3c"]), set(prev)) |
177 | 8129eac1 | Thomas Thrainer | |
178 | 8129eac1 | Thomas Thrainer | |
179 | 67d2f602 | Thomas Thrainer | class TestLUGroupSetParams(CmdlibTestCase): |
180 | 67d2f602 | Thomas Thrainer | def testNoModifications(self): |
181 | 67d2f602 | Thomas Thrainer | op = opcodes.OpGroupSetParams(group_name=self.group.name)
|
182 | 67d2f602 | Thomas Thrainer | |
183 | 67d2f602 | Thomas Thrainer | self.ExecOpCodeExpectOpPrereqError(op,
|
184 | 67d2f602 | Thomas Thrainer | "Please pass at least one modification")
|
185 | 67d2f602 | Thomas Thrainer | |
186 | 67d2f602 | Thomas Thrainer | def testModifyingAll(self): |
187 | 67d2f602 | Thomas Thrainer | ndparams = {constants.ND_EXCLUSIVE_STORAGE: True}
|
188 | 67d2f602 | Thomas Thrainer | hv_state = {constants.HT_FAKE: {constants.HVST_CPU_TOTAL: 8}}
|
189 | 67d2f602 | Thomas Thrainer | disk_state = { |
190 | 0c5f1b13 | Thomas Thrainer | constants.DT_PLAIN: { |
191 | 67d2f602 | Thomas Thrainer | "mock_vg": {constants.DS_DISK_TOTAL: 10} |
192 | 67d2f602 | Thomas Thrainer | } |
193 | 67d2f602 | Thomas Thrainer | } |
194 | 67d2f602 | Thomas Thrainer | diskparams = {constants.DT_RBD: {constants.RBD_POOL: "mock_pool"}}
|
195 | 67d2f602 | Thomas Thrainer | ipolicy = {constants.IPOLICY_DTS: [constants.DT_DRBD8]} |
196 | 67d2f602 | Thomas Thrainer | op = opcodes.OpGroupSetParams(group_name=self.group.name,
|
197 | 67d2f602 | Thomas Thrainer | ndparams=ndparams, |
198 | 67d2f602 | Thomas Thrainer | hv_state=hv_state, |
199 | 67d2f602 | Thomas Thrainer | disk_state=disk_state, |
200 | 67d2f602 | Thomas Thrainer | diskparams=diskparams, |
201 | 67d2f602 | Thomas Thrainer | ipolicy=ipolicy) |
202 | 67d2f602 | Thomas Thrainer | |
203 | 67d2f602 | Thomas Thrainer | self.ExecOpCode(op)
|
204 | 67d2f602 | Thomas Thrainer | |
205 | 67d2f602 | Thomas Thrainer | self.mcpu.assertLogIsEmpty()
|
206 | 67d2f602 | Thomas Thrainer | |
207 | 67d2f602 | Thomas Thrainer | def testInvalidDiskparams(self): |
208 | 67d2f602 | Thomas Thrainer | diskparams = {constants.DT_RBD: {constants.LV_STRIPES: 1}}
|
209 | 67d2f602 | Thomas Thrainer | op = opcodes.OpGroupSetParams(group_name=self.group.name,
|
210 | 67d2f602 | Thomas Thrainer | diskparams=diskparams) |
211 | 67d2f602 | Thomas Thrainer | |
212 | 67d2f602 | Thomas Thrainer | self.ExecOpCodeExpectOpPrereqError(
|
213 | 67d2f602 | Thomas Thrainer | op, "Provided option keys not supported")
|
214 | 67d2f602 | Thomas Thrainer | |
215 | 67d2f602 | Thomas Thrainer | def testIPolicyNewViolations(self): |
216 | 67d2f602 | Thomas Thrainer | self.cfg.AddNewInstance(beparams={constants.BE_VCPUS: 8}) |
217 | 67d2f602 | Thomas Thrainer | |
218 | 67d2f602 | Thomas Thrainer | min_max = dict(constants.ISPECS_MINMAX_DEFAULTS)
|
219 | 67d2f602 | Thomas Thrainer | min_max[constants.ISPECS_MAX].update({constants.ISPEC_CPU_COUNT: 2})
|
220 | 67d2f602 | Thomas Thrainer | ipolicy = {constants.ISPECS_MINMAX: [min_max]} |
221 | 67d2f602 | Thomas Thrainer | op = opcodes.OpGroupSetParams(group_name=self.group.name,
|
222 | 67d2f602 | Thomas Thrainer | ipolicy=ipolicy) |
223 | 67d2f602 | Thomas Thrainer | |
224 | 67d2f602 | Thomas Thrainer | self.ExecOpCode(op)
|
225 | 67d2f602 | Thomas Thrainer | |
226 | 67d2f602 | Thomas Thrainer | self.assertLogContainsRegex(
|
227 | 67d2f602 | Thomas Thrainer | "After the ipolicy change the following instances violate them")
|
228 | 67d2f602 | Thomas Thrainer | |
229 | 67d2f602 | Thomas Thrainer | |
230 | 8ef0c3eb | Thomas Thrainer | class TestLUGroupRemove(CmdlibTestCase): |
231 | 8ef0c3eb | Thomas Thrainer | def testNonEmptyGroup(self): |
232 | 8ef0c3eb | Thomas Thrainer | group = self.cfg.AddNewNodeGroup()
|
233 | 8ef0c3eb | Thomas Thrainer | self.cfg.AddNewNode(group=group)
|
234 | 8ef0c3eb | Thomas Thrainer | op = opcodes.OpGroupRemove(group_name=group.name) |
235 | 8ef0c3eb | Thomas Thrainer | |
236 | 8ef0c3eb | Thomas Thrainer | self.ExecOpCodeExpectOpPrereqError(op, "Group .* not empty") |
237 | 8ef0c3eb | Thomas Thrainer | |
238 | 8ef0c3eb | Thomas Thrainer | def testRemoveLastGroup(self): |
239 | 8ef0c3eb | Thomas Thrainer | self.master.group = "invalid_group" |
240 | 8ef0c3eb | Thomas Thrainer | op = opcodes.OpGroupRemove(group_name=self.group.name)
|
241 | 8ef0c3eb | Thomas Thrainer | |
242 | 8ef0c3eb | Thomas Thrainer | self.ExecOpCodeExpectOpPrereqError(
|
243 | 8ef0c3eb | Thomas Thrainer | op, "Group .* is the only group, cannot be removed")
|
244 | 8ef0c3eb | Thomas Thrainer | |
245 | 8ef0c3eb | Thomas Thrainer | def testRemoveGroup(self): |
246 | 8ef0c3eb | Thomas Thrainer | group = self.cfg.AddNewNodeGroup()
|
247 | 8ef0c3eb | Thomas Thrainer | op = opcodes.OpGroupRemove(group_name=group.name) |
248 | 8ef0c3eb | Thomas Thrainer | |
249 | 8ef0c3eb | Thomas Thrainer | self.ExecOpCode(op)
|
250 | 8ef0c3eb | Thomas Thrainer | |
251 | 8ef0c3eb | Thomas Thrainer | self.mcpu.assertLogIsEmpty()
|
252 | 8ef0c3eb | Thomas Thrainer | |
253 | 8ef0c3eb | Thomas Thrainer | |
254 | 7ac3f7b0 | Thomas Thrainer | class TestLUGroupRename(CmdlibTestCase): |
255 | 7ac3f7b0 | Thomas Thrainer | def testRenameToExistingName(self): |
256 | 7ac3f7b0 | Thomas Thrainer | group = self.cfg.AddNewNodeGroup()
|
257 | 7ac3f7b0 | Thomas Thrainer | op = opcodes.OpGroupRename(group_name=group.name, |
258 | 7ac3f7b0 | Thomas Thrainer | new_name=self.group.name)
|
259 | 7ac3f7b0 | Thomas Thrainer | |
260 | 7ac3f7b0 | Thomas Thrainer | self.ExecOpCodeExpectOpPrereqError(
|
261 | 7ac3f7b0 | Thomas Thrainer | op, "Desired new name .* clashes with existing node group")
|
262 | 7ac3f7b0 | Thomas Thrainer | |
263 | 7ac3f7b0 | Thomas Thrainer | def testRename(self): |
264 | 7ac3f7b0 | Thomas Thrainer | group = self.cfg.AddNewNodeGroup()
|
265 | 7ac3f7b0 | Thomas Thrainer | op = opcodes.OpGroupRename(group_name=group.name, |
266 | 7ac3f7b0 | Thomas Thrainer | new_name="new_group_name")
|
267 | 7ac3f7b0 | Thomas Thrainer | |
268 | 7ac3f7b0 | Thomas Thrainer | self.ExecOpCode(op)
|
269 | 7ac3f7b0 | Thomas Thrainer | |
270 | 7ac3f7b0 | Thomas Thrainer | self.mcpu.assertLogIsEmpty()
|
271 | 7ac3f7b0 | Thomas Thrainer | |
272 | 4b8f9420 | Thomas Thrainer | |
273 | 4b8f9420 | Thomas Thrainer | class TestLUGroupEvacuate(CmdlibTestCase): |
274 | 4b8f9420 | Thomas Thrainer | def testEvacuateEmptyGroup(self): |
275 | 4b8f9420 | Thomas Thrainer | group = self.cfg.AddNewNodeGroup()
|
276 | 4b8f9420 | Thomas Thrainer | op = opcodes.OpGroupEvacuate(group_name=group.name) |
277 | 4b8f9420 | Thomas Thrainer | |
278 | 4b8f9420 | Thomas Thrainer | self.iallocator_cls.return_value.result = ([], [], [])
|
279 | 4b8f9420 | Thomas Thrainer | |
280 | 4b8f9420 | Thomas Thrainer | self.ExecOpCode(op)
|
281 | 4b8f9420 | Thomas Thrainer | |
282 | 4b8f9420 | Thomas Thrainer | def testEvacuateOnlyGroup(self): |
283 | 4b8f9420 | Thomas Thrainer | op = opcodes.OpGroupEvacuate(group_name=self.group.name)
|
284 | 4b8f9420 | Thomas Thrainer | |
285 | 4b8f9420 | Thomas Thrainer | self.ExecOpCodeExpectOpPrereqError(
|
286 | 4b8f9420 | Thomas Thrainer | op, "There are no possible target groups")
|
287 | 4b8f9420 | Thomas Thrainer | |
288 | 4b8f9420 | Thomas Thrainer | def testEvacuateWithTargetGroups(self): |
289 | 4b8f9420 | Thomas Thrainer | group = self.cfg.AddNewNodeGroup()
|
290 | 4b8f9420 | Thomas Thrainer | self.cfg.AddNewNode(group=group)
|
291 | 4b8f9420 | Thomas Thrainer | self.cfg.AddNewNode(group=group)
|
292 | 4b8f9420 | Thomas Thrainer | |
293 | 4b8f9420 | Thomas Thrainer | target_group1 = self.cfg.AddNewNodeGroup()
|
294 | 4b8f9420 | Thomas Thrainer | target_group2 = self.cfg.AddNewNodeGroup()
|
295 | 4b8f9420 | Thomas Thrainer | op = opcodes.OpGroupEvacuate(group_name=group.name, |
296 | 4b8f9420 | Thomas Thrainer | target_groups=[target_group1.name, |
297 | 4b8f9420 | Thomas Thrainer | target_group2.name]) |
298 | 4b8f9420 | Thomas Thrainer | |
299 | 4b8f9420 | Thomas Thrainer | self.iallocator_cls.return_value.result = ([], [], [])
|
300 | 4b8f9420 | Thomas Thrainer | |
301 | 4b8f9420 | Thomas Thrainer | self.ExecOpCode(op)
|
302 | 4b8f9420 | Thomas Thrainer | |
303 | 4b8f9420 | Thomas Thrainer | def testFailingIAllocator(self): |
304 | 4b8f9420 | Thomas Thrainer | group = self.cfg.AddNewNodeGroup()
|
305 | 4b8f9420 | Thomas Thrainer | op = opcodes.OpGroupEvacuate(group_name=group.name) |
306 | 4b8f9420 | Thomas Thrainer | |
307 | 4b8f9420 | Thomas Thrainer | self.iallocator_cls.return_value.success = False |
308 | 4b8f9420 | Thomas Thrainer | |
309 | 4b8f9420 | Thomas Thrainer | self.ExecOpCodeExpectOpPrereqError(
|
310 | 4b8f9420 | Thomas Thrainer | op, "Can't compute group evacuation using iallocator")
|
311 | 4b8f9420 | Thomas Thrainer | |
312 | 4b8f9420 | Thomas Thrainer | |
313 | 3c768f88 | Thomas Thrainer | class TestLUGroupVerifyDisks(CmdlibTestCase): |
314 | 3c768f88 | Thomas Thrainer | def testNoInstances(self): |
315 | 3c768f88 | Thomas Thrainer | op = opcodes.OpGroupVerifyDisks(group_name=self.group.name)
|
316 | 3c768f88 | Thomas Thrainer | |
317 | 3c768f88 | Thomas Thrainer | self.ExecOpCode(op)
|
318 | 3c768f88 | Thomas Thrainer | |
319 | 3c768f88 | Thomas Thrainer | self.mcpu.assertLogIsEmpty()
|
320 | 3c768f88 | Thomas Thrainer | |
321 | 3c768f88 | Thomas Thrainer | def testOfflineAndFailingNode(self): |
322 | 3c768f88 | Thomas Thrainer | node = self.cfg.AddNewNode(offline=True) |
323 | 3c768f88 | Thomas Thrainer | self.cfg.AddNewInstance(primary_node=node,
|
324 | 3c768f88 | Thomas Thrainer | admin_state=constants.ADMINST_UP) |
325 | 3c768f88 | Thomas Thrainer | self.cfg.AddNewInstance(admin_state=constants.ADMINST_UP)
|
326 | 3c768f88 | Thomas Thrainer | self.rpc.call_lv_list.return_value = \
|
327 | 3c768f88 | Thomas Thrainer | self.RpcResultsBuilder() \
|
328 | 3c768f88 | Thomas Thrainer | .AddFailedNode(self.master) \
|
329 | 3c768f88 | Thomas Thrainer | .AddOfflineNode(node) \ |
330 | 3c768f88 | Thomas Thrainer | .Build() |
331 | 3c768f88 | Thomas Thrainer | |
332 | 3c768f88 | Thomas Thrainer | op = opcodes.OpGroupVerifyDisks(group_name=self.group.name)
|
333 | 3c768f88 | Thomas Thrainer | |
334 | 3c768f88 | Thomas Thrainer | (nerrors, offline, missing) = self.ExecOpCode(op)
|
335 | 3c768f88 | Thomas Thrainer | |
336 | 3c768f88 | Thomas Thrainer | self.assertEqual(1, len(nerrors)) |
337 | 3c768f88 | Thomas Thrainer | self.assertEqual(0, len(offline)) |
338 | 3c768f88 | Thomas Thrainer | self.assertEqual(2, len(missing)) |
339 | 3c768f88 | Thomas Thrainer | |
340 | 3c768f88 | Thomas Thrainer | def testValidNodeResult(self): |
341 | 3c768f88 | Thomas Thrainer | self.cfg.AddNewInstance(
|
342 | 0c5f1b13 | Thomas Thrainer | disks=[self.cfg.CreateDisk(dev_type=constants.DT_PLAIN),
|
343 | 0c5f1b13 | Thomas Thrainer | self.cfg.CreateDisk(dev_type=constants.DT_PLAIN)
|
344 | 3c768f88 | Thomas Thrainer | ], |
345 | 3c768f88 | Thomas Thrainer | admin_state=constants.ADMINST_UP) |
346 | 3c768f88 | Thomas Thrainer | self.rpc.call_lv_list.return_value = \
|
347 | 3c768f88 | Thomas Thrainer | self.RpcResultsBuilder() \
|
348 | 3c768f88 | Thomas Thrainer | .AddSuccessfulNode(self.master, {
|
349 | 3c768f88 | Thomas Thrainer | "mockvg/mock_disk_1": (None, None, True), |
350 | 3c768f88 | Thomas Thrainer | "mockvg/mock_disk_2": (None, None, False) |
351 | 3c768f88 | Thomas Thrainer | }) \ |
352 | 3c768f88 | Thomas Thrainer | .Build() |
353 | 3c768f88 | Thomas Thrainer | |
354 | 3c768f88 | Thomas Thrainer | op = opcodes.OpGroupVerifyDisks(group_name=self.group.name)
|
355 | 3c768f88 | Thomas Thrainer | |
356 | 3c768f88 | Thomas Thrainer | (nerrors, offline, missing) = self.ExecOpCode(op)
|
357 | 3c768f88 | Thomas Thrainer | |
358 | 3c768f88 | Thomas Thrainer | self.assertEqual(0, len(nerrors)) |
359 | 3c768f88 | Thomas Thrainer | self.assertEqual(1, len(offline)) |
360 | 3c768f88 | Thomas Thrainer | self.assertEqual(0, len(missing)) |
361 | 3c768f88 | Thomas Thrainer | |
362 | 3c768f88 | Thomas Thrainer | def testDrbdDisk(self): |
363 | 3c768f88 | Thomas Thrainer | node1 = self.cfg.AddNewNode()
|
364 | 3c768f88 | Thomas Thrainer | node2 = self.cfg.AddNewNode()
|
365 | 3c768f88 | Thomas Thrainer | node3 = self.cfg.AddNewNode()
|
366 | 3c768f88 | Thomas Thrainer | node4 = self.cfg.AddNewNode()
|
367 | 3c768f88 | Thomas Thrainer | |
368 | 0c5f1b13 | Thomas Thrainer | valid_disk = self.cfg.CreateDisk(dev_type=constants.DT_DRBD8,
|
369 | 3c768f88 | Thomas Thrainer | primary_node=node1, |
370 | 3c768f88 | Thomas Thrainer | secondary_node=node2) |
371 | 0c5f1b13 | Thomas Thrainer | broken_disk = self.cfg.CreateDisk(dev_type=constants.DT_DRBD8,
|
372 | 3c768f88 | Thomas Thrainer | primary_node=node1, |
373 | 3c768f88 | Thomas Thrainer | secondary_node=node2) |
374 | 0c5f1b13 | Thomas Thrainer | failing_node_disk = self.cfg.CreateDisk(dev_type=constants.DT_DRBD8,
|
375 | 3c768f88 | Thomas Thrainer | primary_node=node3, |
376 | 3c768f88 | Thomas Thrainer | secondary_node=node4) |
377 | 3c768f88 | Thomas Thrainer | |
378 | 3c768f88 | Thomas Thrainer | self.cfg.AddNewInstance(disks=[valid_disk, broken_disk],
|
379 | 3c768f88 | Thomas Thrainer | primary_node=node1, |
380 | 3c768f88 | Thomas Thrainer | admin_state=constants.ADMINST_UP) |
381 | 3c768f88 | Thomas Thrainer | self.cfg.AddNewInstance(disks=[failing_node_disk],
|
382 | 3c768f88 | Thomas Thrainer | primary_node=node3, |
383 | 3c768f88 | Thomas Thrainer | admin_state=constants.ADMINST_UP) |
384 | 3c768f88 | Thomas Thrainer | |
385 | 3c768f88 | Thomas Thrainer | lv_list_result = dict(("/".join(disk.logical_id), (None, None, True)) |
386 | 3c768f88 | Thomas Thrainer | for disk in itertools.chain(valid_disk.children, |
387 | 3c768f88 | Thomas Thrainer | broken_disk.children)) |
388 | 3c768f88 | Thomas Thrainer | self.rpc.call_lv_list.return_value = \
|
389 | 3c768f88 | Thomas Thrainer | self.RpcResultsBuilder() \
|
390 | 3c768f88 | Thomas Thrainer | .AddSuccessfulNode(node1, lv_list_result) \ |
391 | 3c768f88 | Thomas Thrainer | .AddSuccessfulNode(node2, lv_list_result) \ |
392 | 3c768f88 | Thomas Thrainer | .AddFailedNode(node3) \ |
393 | 3c768f88 | Thomas Thrainer | .AddFailedNode(node4) \ |
394 | 3c768f88 | Thomas Thrainer | .Build() |
395 | 3c768f88 | Thomas Thrainer | |
396 | 3c768f88 | Thomas Thrainer | def GetDrbdNeedsActivationResult(node_uuid, *_): |
397 | 3c768f88 | Thomas Thrainer | if node_uuid == node1.uuid:
|
398 | 3c768f88 | Thomas Thrainer | return self.RpcResultsBuilder() \ |
399 | 3c768f88 | Thomas Thrainer | .CreateSuccessfulNodeResult(node1, []) |
400 | 3c768f88 | Thomas Thrainer | elif node_uuid == node2.uuid:
|
401 | 3c768f88 | Thomas Thrainer | return self.RpcResultsBuilder() \ |
402 | 3c768f88 | Thomas Thrainer | .CreateSuccessfulNodeResult(node2, [broken_disk.uuid]) |
403 | 3c768f88 | Thomas Thrainer | elif node_uuid == node3.uuid or node_uuid == node4.uuid: |
404 | 3c768f88 | Thomas Thrainer | return self.RpcResultsBuilder() \ |
405 | 3c768f88 | Thomas Thrainer | .CreateFailedNodeResult(node_uuid) |
406 | 3c768f88 | Thomas Thrainer | |
407 | 3c768f88 | Thomas Thrainer | self.rpc.call_drbd_needs_activation.side_effect = \
|
408 | 3c768f88 | Thomas Thrainer | GetDrbdNeedsActivationResult |
409 | 3c768f88 | Thomas Thrainer | |
410 | 3c768f88 | Thomas Thrainer | op = opcodes.OpGroupVerifyDisks(group_name=self.group.name)
|
411 | 3c768f88 | Thomas Thrainer | |
412 | 3c768f88 | Thomas Thrainer | (nerrors, offline, missing) = self.ExecOpCode(op)
|
413 | 3c768f88 | Thomas Thrainer | |
414 | 3c768f88 | Thomas Thrainer | self.assertEqual(2, len(nerrors)) |
415 | 3c768f88 | Thomas Thrainer | self.assertEqual(1, len(offline)) |
416 | 3c768f88 | Thomas Thrainer | self.assertEqual(1, len(missing)) |
417 | 3c768f88 | Thomas Thrainer | |
418 | 3c768f88 | Thomas Thrainer | |
419 | 8129eac1 | Thomas Thrainer | if __name__ == "__main__": |
420 | 8129eac1 | Thomas Thrainer | testutils.GanetiTestProgram() |