Statistics
| Branch: | Tag: | Revision:

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()