Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.cmdlib_unittest.py @ c42fbe28

History | View | Annotate | Download (62.4 kB)

1 6de7c41d Iustin Pop
#!/usr/bin/python
2 6de7c41d Iustin Pop
#
3 6de7c41d Iustin Pop
4 0c2e59ac Iustin Pop
# Copyright (C) 2008, 2011, 2012 Google Inc.
5 6de7c41d Iustin Pop
#
6 6de7c41d Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 6de7c41d Iustin Pop
# it under the terms of the GNU General Public License as published by
8 6de7c41d Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 6de7c41d Iustin Pop
# (at your option) any later version.
10 6de7c41d Iustin Pop
#
11 6de7c41d Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 6de7c41d Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 6de7c41d Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 6de7c41d Iustin Pop
# General Public License for more details.
15 6de7c41d Iustin Pop
#
16 6de7c41d Iustin Pop
# You should have received a copy of the GNU General Public License
17 6de7c41d Iustin Pop
# along with this program; if not, write to the Free Software
18 6de7c41d Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 fd7b69c0 Michael Hanselmann
# 02110-1301, USA.
20 6de7c41d Iustin Pop
21 6de7c41d Iustin Pop
22 6de7c41d Iustin Pop
"""Script for unittesting the cmdlib module"""
23 6de7c41d Iustin Pop
24 6de7c41d Iustin Pop
25 6de7c41d Iustin Pop
import os
26 6de7c41d Iustin Pop
import unittest
27 6de7c41d Iustin Pop
import time
28 b98bf262 Michael Hanselmann
import tempfile
29 b98bf262 Michael Hanselmann
import shutil
30 64c7b383 Michael Hanselmann
import operator
31 d755483c Michael Hanselmann
import itertools
32 99ccf8b9 René Nussbaumer
import copy
33 6de7c41d Iustin Pop
34 83f72637 Michael Hanselmann
from ganeti import constants
35 b8812691 Iustin Pop
from ganeti import mcpu
36 6de7c41d Iustin Pop
from ganeti import cmdlib
37 b8812691 Iustin Pop
from ganeti import opcodes
38 6de7c41d Iustin Pop
from ganeti import errors
39 b8812691 Iustin Pop
from ganeti import utils
40 e58f87a9 Michael Hanselmann
from ganeti import luxi
41 65e183af Michael Hanselmann
from ganeti import ht
42 8ec505dd Adeodato Simo
from ganeti import objects
43 170b02b7 Michael Hanselmann
from ganeti import compat
44 170b02b7 Michael Hanselmann
from ganeti import rpc
45 ef86bf28 Michael Hanselmann
from ganeti import locking
46 a56625a2 Michael Hanselmann
from ganeti import pathutils
47 0fcd0cad René Nussbaumer
from ganeti.masterd import iallocator
48 0ad1ea40 Guido Trotter
from ganeti.hypervisor import hv_xen
49 6de7c41d Iustin Pop
50 25231ec5 Michael Hanselmann
import testutils
51 bd5f214b Apollon Oikonomopoulos
import mocks
52 25231ec5 Michael Hanselmann
53 6de7c41d Iustin Pop
54 b98bf262 Michael Hanselmann
class TestCertVerification(testutils.GanetiTestCase):
55 b98bf262 Michael Hanselmann
  def setUp(self):
56 b98bf262 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
57 b98bf262 Michael Hanselmann
58 b98bf262 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
59 b98bf262 Michael Hanselmann
60 b98bf262 Michael Hanselmann
  def tearDown(self):
61 b98bf262 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
62 b98bf262 Michael Hanselmann
63 b98bf262 Michael Hanselmann
  def testVerifyCertificate(self):
64 00ef625c Michael Hanselmann
    cmdlib._VerifyCertificate(testutils.TestDataFilename("cert1.pem"))
65 b98bf262 Michael Hanselmann
66 b98bf262 Michael Hanselmann
    nonexist_filename = os.path.join(self.tmpdir, "does-not-exist")
67 b98bf262 Michael Hanselmann
68 b98bf262 Michael Hanselmann
    (errcode, msg) = cmdlib._VerifyCertificate(nonexist_filename)
69 bf93ae69 Adeodato Simo
    self.assertEqual(errcode, cmdlib.LUClusterVerifyConfig.ETYPE_ERROR)
70 b98bf262 Michael Hanselmann
71 b98bf262 Michael Hanselmann
    # Try to load non-certificate file
72 00ef625c Michael Hanselmann
    invalid_cert = testutils.TestDataFilename("bdev-net.txt")
73 b98bf262 Michael Hanselmann
    (errcode, msg) = cmdlib._VerifyCertificate(invalid_cert)
74 bf93ae69 Adeodato Simo
    self.assertEqual(errcode, cmdlib.LUClusterVerifyConfig.ETYPE_ERROR)
75 b98bf262 Michael Hanselmann
76 b98bf262 Michael Hanselmann
77 b8812691 Iustin Pop
class TestOpcodeParams(testutils.GanetiTestCase):
78 b8812691 Iustin Pop
  def testParamsStructures(self):
79 b8812691 Iustin Pop
    for op in sorted(mcpu.Processor.DISPATCH_TABLE):
80 b8812691 Iustin Pop
      lu = mcpu.Processor.DISPATCH_TABLE[op]
81 b8812691 Iustin Pop
      lu_name = lu.__name__
82 0bff0b12 Michael Hanselmann
      self.failIf(hasattr(lu, "_OP_REQP"),
83 0bff0b12 Michael Hanselmann
                  msg=("LU '%s' has old-style _OP_REQP" % lu_name))
84 0bff0b12 Michael Hanselmann
      self.failIf(hasattr(lu, "_OP_DEFS"),
85 0bff0b12 Michael Hanselmann
                  msg=("LU '%s' has old-style _OP_DEFS" % lu_name))
86 0bff0b12 Michael Hanselmann
      self.failIf(hasattr(lu, "_OP_PARAMS"),
87 0bff0b12 Michael Hanselmann
                  msg=("LU '%s' has old-style _OP_PARAMS" % lu_name))
88 b8812691 Iustin Pop
89 b8812691 Iustin Pop
90 bd5f214b Apollon Oikonomopoulos
class TestIAllocatorChecks(testutils.GanetiTestCase):
91 bd5f214b Apollon Oikonomopoulos
  def testFunction(self):
92 bd5f214b Apollon Oikonomopoulos
    class TestLU(object):
93 bd5f214b Apollon Oikonomopoulos
      def __init__(self, opcode):
94 bd5f214b Apollon Oikonomopoulos
        self.cfg = mocks.FakeConfig()
95 bd5f214b Apollon Oikonomopoulos
        self.op = opcode
96 bd5f214b Apollon Oikonomopoulos
97 ff0d18e6 Iustin Pop
    class OpTest(opcodes.OpCode):
98 ff0d18e6 Iustin Pop
       OP_PARAMS = [
99 197b323b Michael Hanselmann
        ("iallocator", None, ht.NoType, None),
100 197b323b Michael Hanselmann
        ("node", None, ht.NoType, None),
101 65e183af Michael Hanselmann
        ]
102 bd5f214b Apollon Oikonomopoulos
103 bd5f214b Apollon Oikonomopoulos
    default_iallocator = mocks.FakeConfig().GetDefaultIAllocator()
104 bd5f214b Apollon Oikonomopoulos
    other_iallocator = default_iallocator + "_not"
105 bd5f214b Apollon Oikonomopoulos
106 ff0d18e6 Iustin Pop
    op = OpTest()
107 bd5f214b Apollon Oikonomopoulos
    lu = TestLU(op)
108 bd5f214b Apollon Oikonomopoulos
109 bd5f214b Apollon Oikonomopoulos
    c_i = lambda: cmdlib._CheckIAllocatorOrNode(lu, "iallocator", "node")
110 bd5f214b Apollon Oikonomopoulos
111 bd5f214b Apollon Oikonomopoulos
    # Neither node nor iallocator given
112 43a8f36a Bernardo Dal Seno
    for n in (None, []):
113 43a8f36a Bernardo Dal Seno
      op.iallocator = None
114 43a8f36a Bernardo Dal Seno
      op.node = n
115 43a8f36a Bernardo Dal Seno
      c_i()
116 43a8f36a Bernardo Dal Seno
      self.assertEqual(lu.op.iallocator, default_iallocator)
117 43a8f36a Bernardo Dal Seno
      self.assertEqual(lu.op.node, n)
118 bd5f214b Apollon Oikonomopoulos
119 bd5f214b Apollon Oikonomopoulos
    # Both, iallocator and node given
120 43a8f36a Bernardo Dal Seno
    for a in ("test", constants.DEFAULT_IALLOCATOR_SHORTCUT):
121 43a8f36a Bernardo Dal Seno
      op.iallocator = a
122 43a8f36a Bernardo Dal Seno
      op.node = "test"
123 43a8f36a Bernardo Dal Seno
      self.assertRaises(errors.OpPrereqError, c_i)
124 bd5f214b Apollon Oikonomopoulos
125 bd5f214b Apollon Oikonomopoulos
    # Only iallocator given
126 43a8f36a Bernardo Dal Seno
    for n in (None, []):
127 43a8f36a Bernardo Dal Seno
      op.iallocator = other_iallocator
128 43a8f36a Bernardo Dal Seno
      op.node = n
129 43a8f36a Bernardo Dal Seno
      c_i()
130 43a8f36a Bernardo Dal Seno
      self.assertEqual(lu.op.iallocator, other_iallocator)
131 43a8f36a Bernardo Dal Seno
      self.assertEqual(lu.op.node, n)
132 bd5f214b Apollon Oikonomopoulos
133 bd5f214b Apollon Oikonomopoulos
    # Only node given
134 bd5f214b Apollon Oikonomopoulos
    op.iallocator = None
135 bd5f214b Apollon Oikonomopoulos
    op.node = "node"
136 bd5f214b Apollon Oikonomopoulos
    c_i()
137 bd5f214b Apollon Oikonomopoulos
    self.assertEqual(lu.op.iallocator, None)
138 bd5f214b Apollon Oikonomopoulos
    self.assertEqual(lu.op.node, "node")
139 bd5f214b Apollon Oikonomopoulos
140 43a8f36a Bernardo Dal Seno
    # Asked for default iallocator, no node given
141 43a8f36a Bernardo Dal Seno
    op.iallocator = constants.DEFAULT_IALLOCATOR_SHORTCUT
142 43a8f36a Bernardo Dal Seno
    op.node = None
143 43a8f36a Bernardo Dal Seno
    c_i()
144 43a8f36a Bernardo Dal Seno
    self.assertEqual(lu.op.iallocator, default_iallocator)
145 43a8f36a Bernardo Dal Seno
    self.assertEqual(lu.op.node, None)
146 43a8f36a Bernardo Dal Seno
147 bd5f214b Apollon Oikonomopoulos
    # No node, iallocator or default iallocator
148 bd5f214b Apollon Oikonomopoulos
    op.iallocator = None
149 bd5f214b Apollon Oikonomopoulos
    op.node = None
150 bd5f214b Apollon Oikonomopoulos
    lu.cfg.GetDefaultIAllocator = lambda: None
151 bd5f214b Apollon Oikonomopoulos
    self.assertRaises(errors.OpPrereqError, c_i)
152 bd5f214b Apollon Oikonomopoulos
153 bd5f214b Apollon Oikonomopoulos
154 b469eb4d Iustin Pop
class TestLUTestJqueue(unittest.TestCase):
155 e58f87a9 Michael Hanselmann
  def test(self):
156 b469eb4d Iustin Pop
    self.assert_(cmdlib.LUTestJqueue._CLIENT_CONNECT_TIMEOUT <
157 e58f87a9 Michael Hanselmann
                 (luxi.WFJC_TIMEOUT * 0.75),
158 e58f87a9 Michael Hanselmann
                 msg=("Client timeout too high, might not notice bugs"
159 e58f87a9 Michael Hanselmann
                      " in WaitForJobChange"))
160 e58f87a9 Michael Hanselmann
161 e58f87a9 Michael Hanselmann
162 83f72637 Michael Hanselmann
class TestLUQuery(unittest.TestCase):
163 83f72637 Michael Hanselmann
  def test(self):
164 83f72637 Michael Hanselmann
    self.assertEqual(sorted(cmdlib._QUERY_IMPL.keys()),
165 abd66bf8 Michael Hanselmann
                     sorted(constants.QR_VIA_OP))
166 83f72637 Michael Hanselmann
167 abd66bf8 Michael Hanselmann
    assert constants.QR_NODE in constants.QR_VIA_OP
168 abd66bf8 Michael Hanselmann
    assert constants.QR_INSTANCE in constants.QR_VIA_OP
169 83f72637 Michael Hanselmann
170 abd66bf8 Michael Hanselmann
    for i in constants.QR_VIA_OP:
171 83f72637 Michael Hanselmann
      self.assert_(cmdlib._GetQueryImplementation(i))
172 83f72637 Michael Hanselmann
173 83f72637 Michael Hanselmann
    self.assertRaises(errors.OpPrereqError, cmdlib._GetQueryImplementation, "")
174 83f72637 Michael Hanselmann
    self.assertRaises(errors.OpPrereqError, cmdlib._GetQueryImplementation,
175 83f72637 Michael Hanselmann
                      "xyz")
176 83f72637 Michael Hanselmann
177 83f72637 Michael Hanselmann
178 934704ae Iustin Pop
class TestLUGroupAssignNodes(unittest.TestCase):
179 8ec505dd Adeodato Simo
180 8ec505dd Adeodato Simo
  def testCheckAssignmentForSplitInstances(self):
181 8ec505dd Adeodato Simo
    node_data = dict((name, objects.Node(name=name, group=group))
182 8ec505dd Adeodato Simo
                     for (name, group) in [("n1a", "g1"), ("n1b", "g1"),
183 8ec505dd Adeodato Simo
                                           ("n2a", "g2"), ("n2b", "g2"),
184 8ec505dd Adeodato Simo
                                           ("n3a", "g3"), ("n3b", "g3"),
185 8ec505dd Adeodato Simo
                                           ("n3c", "g3"),
186 8ec505dd Adeodato Simo
                                           ])
187 8ec505dd Adeodato Simo
188 8ec505dd Adeodato Simo
    def Instance(name, pnode, snode):
189 8ec505dd Adeodato Simo
      if snode is None:
190 8ec505dd Adeodato Simo
        disks = []
191 8ec505dd Adeodato Simo
        disk_template = constants.DT_DISKLESS
192 8ec505dd Adeodato Simo
      else:
193 8ec505dd Adeodato Simo
        disks = [objects.Disk(dev_type=constants.LD_DRBD8,
194 8ec505dd Adeodato Simo
                              logical_id=[pnode, snode, 1, 17, 17])]
195 8ec505dd Adeodato Simo
        disk_template = constants.DT_DRBD8
196 8ec505dd Adeodato Simo
197 8ec505dd Adeodato Simo
      return objects.Instance(name=name, primary_node=pnode, disks=disks,
198 8ec505dd Adeodato Simo
                              disk_template=disk_template)
199 8ec505dd Adeodato Simo
200 8ec505dd Adeodato Simo
    instance_data = dict((name, Instance(name, pnode, snode))
201 8ec505dd Adeodato Simo
                         for name, pnode, snode in [("inst1a", "n1a", "n1b"),
202 8ec505dd Adeodato Simo
                                                    ("inst1b", "n1b", "n1a"),
203 8ec505dd Adeodato Simo
                                                    ("inst2a", "n2a", "n2b"),
204 8ec505dd Adeodato Simo
                                                    ("inst3a", "n3a", None),
205 8ec505dd Adeodato Simo
                                                    ("inst3b", "n3b", "n1b"),
206 8ec505dd Adeodato Simo
                                                    ("inst3c", "n3b", "n2b"),
207 8ec505dd Adeodato Simo
                                                    ])
208 8ec505dd Adeodato Simo
209 8ec505dd Adeodato Simo
    # Test first with the existing state.
210 8ec505dd Adeodato Simo
    (new, prev) = \
211 934704ae Iustin Pop
      cmdlib.LUGroupAssignNodes.CheckAssignmentForSplitInstances([],
212 8ec505dd Adeodato Simo
                                                                 node_data,
213 8ec505dd Adeodato Simo
                                                                 instance_data)
214 8ec505dd Adeodato Simo
215 8ec505dd Adeodato Simo
    self.assertEqual([], new)
216 8ec505dd Adeodato Simo
    self.assertEqual(set(["inst3b", "inst3c"]), set(prev))
217 8ec505dd Adeodato Simo
218 8ec505dd Adeodato Simo
    # And now some changes.
219 8ec505dd Adeodato Simo
    (new, prev) = \
220 934704ae Iustin Pop
      cmdlib.LUGroupAssignNodes.CheckAssignmentForSplitInstances([("n1b",
221 8ec505dd Adeodato Simo
                                                                   "g3")],
222 8ec505dd Adeodato Simo
                                                                 node_data,
223 8ec505dd Adeodato Simo
                                                                 instance_data)
224 8ec505dd Adeodato Simo
225 8ec505dd Adeodato Simo
    self.assertEqual(set(["inst1a", "inst1b"]), set(new))
226 8ec505dd Adeodato Simo
    self.assertEqual(set(["inst3c"]), set(prev))
227 8ec505dd Adeodato Simo
228 8ec505dd Adeodato Simo
229 64c7b383 Michael Hanselmann
class TestClusterVerifySsh(unittest.TestCase):
230 64c7b383 Michael Hanselmann
  def testMultipleGroups(self):
231 64c7b383 Michael Hanselmann
    fn = cmdlib.LUClusterVerifyGroup._SelectSshCheckNodes
232 64c7b383 Michael Hanselmann
    mygroupnodes = [
233 64c7b383 Michael Hanselmann
      objects.Node(name="node20", group="my", offline=False),
234 64c7b383 Michael Hanselmann
      objects.Node(name="node21", group="my", offline=False),
235 64c7b383 Michael Hanselmann
      objects.Node(name="node22", group="my", offline=False),
236 64c7b383 Michael Hanselmann
      objects.Node(name="node23", group="my", offline=False),
237 64c7b383 Michael Hanselmann
      objects.Node(name="node24", group="my", offline=False),
238 64c7b383 Michael Hanselmann
      objects.Node(name="node25", group="my", offline=False),
239 64c7b383 Michael Hanselmann
      objects.Node(name="node26", group="my", offline=True),
240 64c7b383 Michael Hanselmann
      ]
241 64c7b383 Michael Hanselmann
    nodes = [
242 64c7b383 Michael Hanselmann
      objects.Node(name="node1", group="g1", offline=True),
243 64c7b383 Michael Hanselmann
      objects.Node(name="node2", group="g1", offline=False),
244 64c7b383 Michael Hanselmann
      objects.Node(name="node3", group="g1", offline=False),
245 64c7b383 Michael Hanselmann
      objects.Node(name="node4", group="g1", offline=True),
246 64c7b383 Michael Hanselmann
      objects.Node(name="node5", group="g1", offline=False),
247 64c7b383 Michael Hanselmann
      objects.Node(name="node10", group="xyz", offline=False),
248 64c7b383 Michael Hanselmann
      objects.Node(name="node11", group="xyz", offline=False),
249 64c7b383 Michael Hanselmann
      objects.Node(name="node40", group="alloff", offline=True),
250 64c7b383 Michael Hanselmann
      objects.Node(name="node41", group="alloff", offline=True),
251 64c7b383 Michael Hanselmann
      objects.Node(name="node50", group="aaa", offline=False),
252 64c7b383 Michael Hanselmann
      ] + mygroupnodes
253 64c7b383 Michael Hanselmann
    assert not utils.FindDuplicates(map(operator.attrgetter("name"), nodes))
254 64c7b383 Michael Hanselmann
255 64c7b383 Michael Hanselmann
    (online, perhost) = fn(mygroupnodes, "my", nodes)
256 64c7b383 Michael Hanselmann
    self.assertEqual(online, ["node%s" % i for i in range(20, 26)])
257 64c7b383 Michael Hanselmann
    self.assertEqual(set(perhost.keys()), set(online))
258 64c7b383 Michael Hanselmann
259 64c7b383 Michael Hanselmann
    self.assertEqual(perhost, {
260 64c7b383 Michael Hanselmann
      "node20": ["node10", "node2", "node50"],
261 64c7b383 Michael Hanselmann
      "node21": ["node11", "node3", "node50"],
262 64c7b383 Michael Hanselmann
      "node22": ["node10", "node5", "node50"],
263 64c7b383 Michael Hanselmann
      "node23": ["node11", "node2", "node50"],
264 64c7b383 Michael Hanselmann
      "node24": ["node10", "node3", "node50"],
265 64c7b383 Michael Hanselmann
      "node25": ["node11", "node5", "node50"],
266 64c7b383 Michael Hanselmann
      })
267 64c7b383 Michael Hanselmann
268 64c7b383 Michael Hanselmann
  def testSingleGroup(self):
269 64c7b383 Michael Hanselmann
    fn = cmdlib.LUClusterVerifyGroup._SelectSshCheckNodes
270 64c7b383 Michael Hanselmann
    nodes = [
271 64c7b383 Michael Hanselmann
      objects.Node(name="node1", group="default", offline=True),
272 64c7b383 Michael Hanselmann
      objects.Node(name="node2", group="default", offline=False),
273 64c7b383 Michael Hanselmann
      objects.Node(name="node3", group="default", offline=False),
274 64c7b383 Michael Hanselmann
      objects.Node(name="node4", group="default", offline=True),
275 64c7b383 Michael Hanselmann
      ]
276 64c7b383 Michael Hanselmann
    assert not utils.FindDuplicates(map(operator.attrgetter("name"), nodes))
277 64c7b383 Michael Hanselmann
278 64c7b383 Michael Hanselmann
    (online, perhost) = fn(nodes, "default", nodes)
279 64c7b383 Michael Hanselmann
    self.assertEqual(online, ["node2", "node3"])
280 64c7b383 Michael Hanselmann
    self.assertEqual(set(perhost.keys()), set(online))
281 64c7b383 Michael Hanselmann
282 64c7b383 Michael Hanselmann
    self.assertEqual(perhost, {
283 64c7b383 Michael Hanselmann
      "node2": [],
284 64c7b383 Michael Hanselmann
      "node3": [],
285 64c7b383 Michael Hanselmann
      })
286 64c7b383 Michael Hanselmann
287 64c7b383 Michael Hanselmann
288 170b02b7 Michael Hanselmann
class TestClusterVerifyFiles(unittest.TestCase):
289 170b02b7 Michael Hanselmann
  @staticmethod
290 170b02b7 Michael Hanselmann
  def _FakeErrorIf(errors, cond, ecode, item, msg, *args, **kwargs):
291 eedf99b5 Andrea Spadaccini
    assert ((ecode == constants.CV_ENODEFILECHECK and
292 170b02b7 Michael Hanselmann
             ht.TNonEmptyString(item)) or
293 eedf99b5 Andrea Spadaccini
            (ecode == constants.CV_ECLUSTERFILECHECK and
294 170b02b7 Michael Hanselmann
             item is None))
295 170b02b7 Michael Hanselmann
296 170b02b7 Michael Hanselmann
    if args:
297 170b02b7 Michael Hanselmann
      msg = msg % args
298 170b02b7 Michael Hanselmann
299 170b02b7 Michael Hanselmann
    if cond:
300 170b02b7 Michael Hanselmann
      errors.append((item, msg))
301 170b02b7 Michael Hanselmann
302 170b02b7 Michael Hanselmann
  _VerifyFiles = cmdlib.LUClusterVerifyGroup._VerifyFiles
303 170b02b7 Michael Hanselmann
304 170b02b7 Michael Hanselmann
  def test(self):
305 170b02b7 Michael Hanselmann
    errors = []
306 170b02b7 Michael Hanselmann
    master_name = "master.example.com"
307 170b02b7 Michael Hanselmann
    nodeinfo = [
308 0ad1ea40 Guido Trotter
      objects.Node(name=master_name, offline=False, vm_capable=True),
309 0ad1ea40 Guido Trotter
      objects.Node(name="node2.example.com", offline=False, vm_capable=True),
310 0ad1ea40 Guido Trotter
      objects.Node(name="node3.example.com", master_candidate=True,
311 0ad1ea40 Guido Trotter
                   vm_capable=False),
312 0ad1ea40 Guido Trotter
      objects.Node(name="node4.example.com", offline=False, vm_capable=True),
313 0ad1ea40 Guido Trotter
      objects.Node(name="nodata.example.com", offline=False, vm_capable=True),
314 170b02b7 Michael Hanselmann
      objects.Node(name="offline.example.com", offline=True),
315 170b02b7 Michael Hanselmann
      ]
316 170b02b7 Michael Hanselmann
    cluster = objects.Cluster(modify_etc_hosts=True,
317 170b02b7 Michael Hanselmann
                              enabled_hypervisors=[constants.HT_XEN_HVM])
318 170b02b7 Michael Hanselmann
    files_all = set([
319 a56625a2 Michael Hanselmann
      pathutils.CLUSTER_DOMAIN_SECRET_FILE,
320 a56625a2 Michael Hanselmann
      pathutils.RAPI_CERT_FILE,
321 a56625a2 Michael Hanselmann
      pathutils.RAPI_USERS_FILE,
322 170b02b7 Michael Hanselmann
      ])
323 0ad1ea40 Guido Trotter
    files_opt = set([
324 a56625a2 Michael Hanselmann
      pathutils.RAPI_USERS_FILE,
325 0ad1ea40 Guido Trotter
      hv_xen.XL_CONFIG_FILE,
326 a56625a2 Michael Hanselmann
      pathutils.VNC_PASSWORD_FILE,
327 170b02b7 Michael Hanselmann
      ])
328 170b02b7 Michael Hanselmann
    files_mc = set([
329 a56625a2 Michael Hanselmann
      pathutils.CLUSTER_CONF_FILE,
330 170b02b7 Michael Hanselmann
      ])
331 0ad1ea40 Guido Trotter
    files_vm = set([
332 0ad1ea40 Guido Trotter
      hv_xen.XEND_CONFIG_FILE,
333 0ad1ea40 Guido Trotter
      hv_xen.XL_CONFIG_FILE,
334 a56625a2 Michael Hanselmann
      pathutils.VNC_PASSWORD_FILE,
335 0ad1ea40 Guido Trotter
      ])
336 170b02b7 Michael Hanselmann
    nvinfo = {
337 170b02b7 Michael Hanselmann
      master_name: rpc.RpcResult(data=(True, {
338 170b02b7 Michael Hanselmann
        constants.NV_FILELIST: {
339 a56625a2 Michael Hanselmann
          pathutils.CLUSTER_CONF_FILE: "82314f897f38b35f9dab2f7c6b1593e0",
340 a56625a2 Michael Hanselmann
          pathutils.RAPI_CERT_FILE: "babbce8f387bc082228e544a2146fee4",
341 a56625a2 Michael Hanselmann
          pathutils.CLUSTER_DOMAIN_SECRET_FILE: "cds-47b5b3f19202936bb4",
342 0ad1ea40 Guido Trotter
          hv_xen.XEND_CONFIG_FILE: "b4a8a824ab3cac3d88839a9adeadf310",
343 0ad1ea40 Guido Trotter
          hv_xen.XL_CONFIG_FILE: "77935cee92afd26d162f9e525e3d49b9"
344 170b02b7 Michael Hanselmann
        }})),
345 170b02b7 Michael Hanselmann
      "node2.example.com": rpc.RpcResult(data=(True, {
346 170b02b7 Michael Hanselmann
        constants.NV_FILELIST: {
347 a56625a2 Michael Hanselmann
          pathutils.RAPI_CERT_FILE: "97f0356500e866387f4b84233848cc4a",
348 0ad1ea40 Guido Trotter
          hv_xen.XEND_CONFIG_FILE: "b4a8a824ab3cac3d88839a9adeadf310",
349 170b02b7 Michael Hanselmann
          }
350 170b02b7 Michael Hanselmann
        })),
351 170b02b7 Michael Hanselmann
      "node3.example.com": rpc.RpcResult(data=(True, {
352 170b02b7 Michael Hanselmann
        constants.NV_FILELIST: {
353 a56625a2 Michael Hanselmann
          pathutils.RAPI_CERT_FILE: "97f0356500e866387f4b84233848cc4a",
354 a56625a2 Michael Hanselmann
          pathutils.CLUSTER_DOMAIN_SECRET_FILE: "cds-47b5b3f19202936bb4",
355 170b02b7 Michael Hanselmann
          }
356 170b02b7 Michael Hanselmann
        })),
357 170b02b7 Michael Hanselmann
      "node4.example.com": rpc.RpcResult(data=(True, {
358 170b02b7 Michael Hanselmann
        constants.NV_FILELIST: {
359 a56625a2 Michael Hanselmann
          pathutils.RAPI_CERT_FILE: "97f0356500e866387f4b84233848cc4a",
360 a56625a2 Michael Hanselmann
          pathutils.CLUSTER_CONF_FILE: "conf-a6d4b13e407867f7a7b4f0f232a8f527",
361 a56625a2 Michael Hanselmann
          pathutils.CLUSTER_DOMAIN_SECRET_FILE: "cds-47b5b3f19202936bb4",
362 a56625a2 Michael Hanselmann
          pathutils.RAPI_USERS_FILE: "rapiusers-ea3271e8d810ef3",
363 0ad1ea40 Guido Trotter
          hv_xen.XL_CONFIG_FILE: "77935cee92afd26d162f9e525e3d49b9"
364 170b02b7 Michael Hanselmann
          }
365 170b02b7 Michael Hanselmann
        })),
366 170b02b7 Michael Hanselmann
      "nodata.example.com": rpc.RpcResult(data=(True, {})),
367 170b02b7 Michael Hanselmann
      "offline.example.com": rpc.RpcResult(offline=True),
368 170b02b7 Michael Hanselmann
      }
369 170b02b7 Michael Hanselmann
    assert set(nvinfo.keys()) == set(map(operator.attrgetter("name"), nodeinfo))
370 170b02b7 Michael Hanselmann
371 170b02b7 Michael Hanselmann
    self._VerifyFiles(compat.partial(self._FakeErrorIf, errors), nodeinfo,
372 170b02b7 Michael Hanselmann
                      master_name, nvinfo,
373 0ad1ea40 Guido Trotter
                      (files_all, files_opt, files_mc, files_vm))
374 170b02b7 Michael Hanselmann
    self.assertEqual(sorted(errors), sorted([
375 170b02b7 Michael Hanselmann
      (None, ("File %s found with 2 different checksums (variant 1 on"
376 170b02b7 Michael Hanselmann
              " node2.example.com, node3.example.com, node4.example.com;"
377 a56625a2 Michael Hanselmann
              " variant 2 on master.example.com)" % pathutils.RAPI_CERT_FILE)),
378 170b02b7 Michael Hanselmann
      (None, ("File %s is missing from node(s) node2.example.com" %
379 a56625a2 Michael Hanselmann
              pathutils.CLUSTER_DOMAIN_SECRET_FILE)),
380 170b02b7 Michael Hanselmann
      (None, ("File %s should not exist on node(s) node4.example.com" %
381 a56625a2 Michael Hanselmann
              pathutils.CLUSTER_CONF_FILE)),
382 0ad1ea40 Guido Trotter
      (None, ("File %s is missing from node(s) node4.example.com" %
383 0ad1ea40 Guido Trotter
              hv_xen.XEND_CONFIG_FILE)),
384 170b02b7 Michael Hanselmann
      (None, ("File %s is missing from node(s) node3.example.com" %
385 a56625a2 Michael Hanselmann
              pathutils.CLUSTER_CONF_FILE)),
386 170b02b7 Michael Hanselmann
      (None, ("File %s found with 2 different checksums (variant 1 on"
387 170b02b7 Michael Hanselmann
              " master.example.com; variant 2 on node4.example.com)" %
388 a56625a2 Michael Hanselmann
              pathutils.CLUSTER_CONF_FILE)),
389 170b02b7 Michael Hanselmann
      (None, ("File %s is optional, but it must exist on all or no nodes (not"
390 170b02b7 Michael Hanselmann
              " found on master.example.com, node2.example.com,"
391 a56625a2 Michael Hanselmann
              " node3.example.com)" % pathutils.RAPI_USERS_FILE)),
392 0ad1ea40 Guido Trotter
      (None, ("File %s is optional, but it must exist on all or no nodes (not"
393 0ad1ea40 Guido Trotter
              " found on node2.example.com)" % hv_xen.XL_CONFIG_FILE)),
394 170b02b7 Michael Hanselmann
      ("nodata.example.com", "Node did not return file checksum data"),
395 170b02b7 Michael Hanselmann
      ]))
396 170b02b7 Michael Hanselmann
397 170b02b7 Michael Hanselmann
398 d755483c Michael Hanselmann
class _FakeLU:
399 129cce69 Michael Hanselmann
  def __init__(self, cfg=NotImplemented, proc=NotImplemented,
400 129cce69 Michael Hanselmann
               rpc=NotImplemented):
401 d755483c Michael Hanselmann
    self.warning_log = []
402 d755483c Michael Hanselmann
    self.info_log = []
403 ff02b60f René Nussbaumer
    self.cfg = cfg
404 a8e3e009 Michael Hanselmann
    self.proc = proc
405 129cce69 Michael Hanselmann
    self.rpc = rpc
406 d755483c Michael Hanselmann
407 d755483c Michael Hanselmann
  def LogWarning(self, text, *args):
408 d755483c Michael Hanselmann
    self.warning_log.append((text, args))
409 d755483c Michael Hanselmann
410 d755483c Michael Hanselmann
  def LogInfo(self, text, *args):
411 d755483c Michael Hanselmann
    self.info_log.append((text, args))
412 d755483c Michael Hanselmann
413 d755483c Michael Hanselmann
414 d755483c Michael Hanselmann
class TestLoadNodeEvacResult(unittest.TestCase):
415 d755483c Michael Hanselmann
  def testSuccess(self):
416 d755483c Michael Hanselmann
    for moved in [[], [
417 d755483c Michael Hanselmann
      ("inst20153.example.com", "grp2", ["nodeA4509", "nodeB2912"]),
418 d755483c Michael Hanselmann
      ]]:
419 d755483c Michael Hanselmann
      for early_release in [False, True]:
420 d755483c Michael Hanselmann
        for use_nodes in [False, True]:
421 d755483c Michael Hanselmann
          jobs = [
422 d755483c Michael Hanselmann
            [opcodes.OpInstanceReplaceDisks().__getstate__()],
423 d755483c Michael Hanselmann
            [opcodes.OpInstanceMigrate().__getstate__()],
424 d755483c Michael Hanselmann
            ]
425 d755483c Michael Hanselmann
426 d755483c Michael Hanselmann
          alloc_result = (moved, [], jobs)
427 0fcd0cad René Nussbaumer
          assert iallocator._NEVAC_RESULT(alloc_result)
428 d755483c Michael Hanselmann
429 d755483c Michael Hanselmann
          lu = _FakeLU()
430 d755483c Michael Hanselmann
          result = cmdlib._LoadNodeEvacResult(lu, alloc_result,
431 d755483c Michael Hanselmann
                                              early_release, use_nodes)
432 d755483c Michael Hanselmann
433 d755483c Michael Hanselmann
          if moved:
434 d755483c Michael Hanselmann
            (_, (info_args, )) = lu.info_log.pop(0)
435 d755483c Michael Hanselmann
            for (instname, instgroup, instnodes) in moved:
436 d755483c Michael Hanselmann
              self.assertTrue(instname in info_args)
437 d755483c Michael Hanselmann
              if use_nodes:
438 d755483c Michael Hanselmann
                for i in instnodes:
439 d755483c Michael Hanselmann
                  self.assertTrue(i in info_args)
440 d755483c Michael Hanselmann
              else:
441 d755483c Michael Hanselmann
                self.assertTrue(instgroup in info_args)
442 d755483c Michael Hanselmann
443 d755483c Michael Hanselmann
          self.assertFalse(lu.info_log)
444 d755483c Michael Hanselmann
          self.assertFalse(lu.warning_log)
445 d755483c Michael Hanselmann
446 d755483c Michael Hanselmann
          for op in itertools.chain(*result):
447 d755483c Michael Hanselmann
            if hasattr(op.__class__, "early_release"):
448 d755483c Michael Hanselmann
              self.assertEqual(op.early_release, early_release)
449 d755483c Michael Hanselmann
            else:
450 d755483c Michael Hanselmann
              self.assertFalse(hasattr(op, "early_release"))
451 d755483c Michael Hanselmann
452 d755483c Michael Hanselmann
  def testFailed(self):
453 d755483c Michael Hanselmann
    alloc_result = ([], [
454 d755483c Michael Hanselmann
      ("inst5191.example.com", "errormsg21178"),
455 d755483c Michael Hanselmann
      ], [])
456 0fcd0cad René Nussbaumer
    assert iallocator._NEVAC_RESULT(alloc_result)
457 d755483c Michael Hanselmann
458 d755483c Michael Hanselmann
    lu = _FakeLU()
459 d755483c Michael Hanselmann
    self.assertRaises(errors.OpExecError, cmdlib._LoadNodeEvacResult,
460 d755483c Michael Hanselmann
                      lu, alloc_result, False, False)
461 d755483c Michael Hanselmann
    self.assertFalse(lu.info_log)
462 d755483c Michael Hanselmann
    (_, (args, )) = lu.warning_log.pop(0)
463 d755483c Michael Hanselmann
    self.assertTrue("inst5191.example.com" in args)
464 d755483c Michael Hanselmann
    self.assertTrue("errormsg21178" in args)
465 d755483c Michael Hanselmann
    self.assertFalse(lu.warning_log)
466 d755483c Michael Hanselmann
467 d755483c Michael Hanselmann
468 784cd737 René Nussbaumer
class TestUpdateAndVerifySubDict(unittest.TestCase):
469 784cd737 René Nussbaumer
  def setUp(self):
470 784cd737 René Nussbaumer
    self.type_check = {
471 784cd737 René Nussbaumer
        "a": constants.VTYPE_INT,
472 784cd737 René Nussbaumer
        "b": constants.VTYPE_STRING,
473 784cd737 René Nussbaumer
        "c": constants.VTYPE_BOOL,
474 784cd737 René Nussbaumer
        "d": constants.VTYPE_STRING,
475 784cd737 René Nussbaumer
        }
476 784cd737 René Nussbaumer
477 784cd737 René Nussbaumer
  def test(self):
478 784cd737 René Nussbaumer
    old_test = {
479 784cd737 René Nussbaumer
      "foo": {
480 784cd737 René Nussbaumer
        "d": "blubb",
481 784cd737 René Nussbaumer
        "a": 321,
482 784cd737 René Nussbaumer
        },
483 784cd737 René Nussbaumer
      "baz": {
484 784cd737 René Nussbaumer
        "a": 678,
485 784cd737 René Nussbaumer
        "b": "678",
486 784cd737 René Nussbaumer
        "c": True,
487 784cd737 René Nussbaumer
        },
488 784cd737 René Nussbaumer
      }
489 784cd737 René Nussbaumer
    test = {
490 784cd737 René Nussbaumer
      "foo": {
491 784cd737 René Nussbaumer
        "a": 123,
492 784cd737 René Nussbaumer
        "b": "123",
493 784cd737 René Nussbaumer
        "c": True,
494 784cd737 René Nussbaumer
        },
495 784cd737 René Nussbaumer
      "bar": {
496 784cd737 René Nussbaumer
        "a": 321,
497 784cd737 René Nussbaumer
        "b": "321",
498 784cd737 René Nussbaumer
        "c": False,
499 784cd737 René Nussbaumer
        },
500 784cd737 René Nussbaumer
      }
501 784cd737 René Nussbaumer
502 784cd737 René Nussbaumer
    mv = {
503 784cd737 René Nussbaumer
      "foo": {
504 784cd737 René Nussbaumer
        "a": 123,
505 784cd737 René Nussbaumer
        "b": "123",
506 784cd737 René Nussbaumer
        "c": True,
507 784cd737 René Nussbaumer
        "d": "blubb"
508 784cd737 René Nussbaumer
        },
509 784cd737 René Nussbaumer
      "bar": {
510 784cd737 René Nussbaumer
        "a": 321,
511 784cd737 René Nussbaumer
        "b": "321",
512 784cd737 René Nussbaumer
        "c": False,
513 784cd737 René Nussbaumer
        },
514 784cd737 René Nussbaumer
      "baz": {
515 784cd737 René Nussbaumer
        "a": 678,
516 784cd737 René Nussbaumer
        "b": "678",
517 784cd737 René Nussbaumer
        "c": True,
518 784cd737 René Nussbaumer
        },
519 784cd737 René Nussbaumer
      }
520 784cd737 René Nussbaumer
521 784cd737 René Nussbaumer
    verified = cmdlib._UpdateAndVerifySubDict(old_test, test, self.type_check)
522 784cd737 René Nussbaumer
    self.assertEqual(verified, mv)
523 784cd737 René Nussbaumer
524 784cd737 René Nussbaumer
  def testWrong(self):
525 784cd737 René Nussbaumer
    test = {
526 784cd737 René Nussbaumer
      "foo": {
527 784cd737 René Nussbaumer
        "a": "blubb",
528 784cd737 René Nussbaumer
        "b": "123",
529 784cd737 René Nussbaumer
        "c": True,
530 784cd737 René Nussbaumer
        },
531 784cd737 René Nussbaumer
      "bar": {
532 784cd737 René Nussbaumer
        "a": 321,
533 784cd737 René Nussbaumer
        "b": "321",
534 784cd737 René Nussbaumer
        "c": False,
535 784cd737 René Nussbaumer
        },
536 784cd737 René Nussbaumer
      }
537 784cd737 René Nussbaumer
538 784cd737 René Nussbaumer
    self.assertRaises(errors.TypeEnforcementError,
539 784cd737 René Nussbaumer
                      cmdlib._UpdateAndVerifySubDict, {}, test, self.type_check)
540 784cd737 René Nussbaumer
541 784cd737 René Nussbaumer
542 0ba177e2 René Nussbaumer
class TestHvStateHelper(unittest.TestCase):
543 0ba177e2 René Nussbaumer
  def testWithoutOpData(self):
544 0ba177e2 René Nussbaumer
    self.assertEqual(cmdlib._MergeAndVerifyHvState(None, NotImplemented), None)
545 0ba177e2 René Nussbaumer
546 0ba177e2 René Nussbaumer
  def testWithoutOldData(self):
547 0ba177e2 René Nussbaumer
    new = {
548 0ba177e2 René Nussbaumer
      constants.HT_XEN_PVM: {
549 0ba177e2 René Nussbaumer
        constants.HVST_MEMORY_TOTAL: 4096,
550 0ba177e2 René Nussbaumer
        },
551 0ba177e2 René Nussbaumer
      }
552 0ba177e2 René Nussbaumer
    self.assertEqual(cmdlib._MergeAndVerifyHvState(new, None), new)
553 0ba177e2 René Nussbaumer
554 0ba177e2 René Nussbaumer
  def testWithWrongHv(self):
555 0ba177e2 René Nussbaumer
    new = {
556 0ba177e2 René Nussbaumer
      "i-dont-exist": {
557 0ba177e2 René Nussbaumer
        constants.HVST_MEMORY_TOTAL: 4096,
558 0ba177e2 René Nussbaumer
        },
559 0ba177e2 René Nussbaumer
      }
560 0ba177e2 René Nussbaumer
    self.assertRaises(errors.OpPrereqError, cmdlib._MergeAndVerifyHvState, new,
561 0ba177e2 René Nussbaumer
                      None)
562 0ba177e2 René Nussbaumer
563 0ba177e2 René Nussbaumer
class TestDiskStateHelper(unittest.TestCase):
564 0ba177e2 René Nussbaumer
  def testWithoutOpData(self):
565 0ba177e2 René Nussbaumer
    self.assertEqual(cmdlib._MergeAndVerifyDiskState(None, NotImplemented),
566 0ba177e2 René Nussbaumer
                     None)
567 0ba177e2 René Nussbaumer
568 0ba177e2 René Nussbaumer
  def testWithoutOldData(self):
569 0ba177e2 René Nussbaumer
    new = {
570 0ba177e2 René Nussbaumer
      constants.LD_LV: {
571 0ba177e2 René Nussbaumer
        "xenvg": {
572 0ba177e2 René Nussbaumer
          constants.DS_DISK_RESERVED: 1024,
573 0ba177e2 René Nussbaumer
          },
574 0ba177e2 René Nussbaumer
        },
575 0ba177e2 René Nussbaumer
      }
576 0ba177e2 René Nussbaumer
    self.assertEqual(cmdlib._MergeAndVerifyDiskState(new, None), new)
577 0ba177e2 René Nussbaumer
578 0ba177e2 René Nussbaumer
  def testWithWrongStorageType(self):
579 0ba177e2 René Nussbaumer
    new = {
580 0ba177e2 René Nussbaumer
      "i-dont-exist": {
581 0ba177e2 René Nussbaumer
        "xenvg": {
582 0ba177e2 René Nussbaumer
          constants.DS_DISK_RESERVED: 1024,
583 0ba177e2 René Nussbaumer
          },
584 0ba177e2 René Nussbaumer
        },
585 0ba177e2 René Nussbaumer
      }
586 0ba177e2 René Nussbaumer
    self.assertRaises(errors.OpPrereqError, cmdlib._MergeAndVerifyDiskState,
587 0ba177e2 René Nussbaumer
                      new, None)
588 0ba177e2 René Nussbaumer
589 0ba177e2 René Nussbaumer
590 2096d068 René Nussbaumer
class TestComputeMinMaxSpec(unittest.TestCase):
591 2096d068 René Nussbaumer
  def setUp(self):
592 2096d068 René Nussbaumer
    self.ipolicy = {
593 2096d068 René Nussbaumer
      constants.ISPECS_MAX: {
594 2096d068 René Nussbaumer
        constants.ISPEC_MEM_SIZE: 512,
595 2096d068 René Nussbaumer
        constants.ISPEC_DISK_SIZE: 1024,
596 2096d068 René Nussbaumer
        },
597 2096d068 René Nussbaumer
      constants.ISPECS_MIN: {
598 2096d068 René Nussbaumer
        constants.ISPEC_MEM_SIZE: 128,
599 2096d068 René Nussbaumer
        constants.ISPEC_DISK_COUNT: 1,
600 2096d068 René Nussbaumer
        },
601 2096d068 René Nussbaumer
      }
602 2096d068 René Nussbaumer
603 2096d068 René Nussbaumer
  def testNoneValue(self):
604 0c2e59ac Iustin Pop
    self.assertTrue(cmdlib._ComputeMinMaxSpec(constants.ISPEC_MEM_SIZE, None,
605 2096d068 René Nussbaumer
                                              self.ipolicy, None) is None)
606 2096d068 René Nussbaumer
607 2096d068 René Nussbaumer
  def testAutoValue(self):
608 0c2e59ac Iustin Pop
    self.assertTrue(cmdlib._ComputeMinMaxSpec(constants.ISPEC_MEM_SIZE, None,
609 2096d068 René Nussbaumer
                                              self.ipolicy,
610 2096d068 René Nussbaumer
                                              constants.VALUE_AUTO) is None)
611 2096d068 René Nussbaumer
612 2096d068 René Nussbaumer
  def testNotDefined(self):
613 0c2e59ac Iustin Pop
    self.assertTrue(cmdlib._ComputeMinMaxSpec(constants.ISPEC_NIC_COUNT, None,
614 2096d068 René Nussbaumer
                                              self.ipolicy, 3) is None)
615 2096d068 René Nussbaumer
616 2096d068 René Nussbaumer
  def testNoMinDefined(self):
617 0c2e59ac Iustin Pop
    self.assertTrue(cmdlib._ComputeMinMaxSpec(constants.ISPEC_DISK_SIZE, None,
618 2096d068 René Nussbaumer
                                              self.ipolicy, 128) is None)
619 2096d068 René Nussbaumer
620 2096d068 René Nussbaumer
  def testNoMaxDefined(self):
621 0c2e59ac Iustin Pop
    self.assertTrue(cmdlib._ComputeMinMaxSpec(constants.ISPEC_DISK_COUNT, None,
622 2096d068 René Nussbaumer
                                                self.ipolicy, 16) is None)
623 2096d068 René Nussbaumer
624 2096d068 René Nussbaumer
  def testOutOfRange(self):
625 2096d068 René Nussbaumer
    for (name, val) in ((constants.ISPEC_MEM_SIZE, 64),
626 2096d068 René Nussbaumer
                        (constants.ISPEC_MEM_SIZE, 768),
627 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_SIZE, 4096),
628 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_COUNT, 0)):
629 2096d068 René Nussbaumer
      min_v = self.ipolicy[constants.ISPECS_MIN].get(name, val)
630 2096d068 René Nussbaumer
      max_v = self.ipolicy[constants.ISPECS_MAX].get(name, val)
631 0c2e59ac Iustin Pop
      self.assertEqual(cmdlib._ComputeMinMaxSpec(name, None,
632 0c2e59ac Iustin Pop
                                                 self.ipolicy, val),
633 2096d068 René Nussbaumer
                       "%s value %s is not in range [%s, %s]" %
634 2096d068 René Nussbaumer
                       (name, val,min_v, max_v))
635 0c2e59ac Iustin Pop
      self.assertEqual(cmdlib._ComputeMinMaxSpec(name, "1",
636 0c2e59ac Iustin Pop
                                                 self.ipolicy, val),
637 0c2e59ac Iustin Pop
                       "%s/1 value %s is not in range [%s, %s]" %
638 0c2e59ac Iustin Pop
                       (name, val,min_v, max_v))
639 2096d068 René Nussbaumer
640 2096d068 René Nussbaumer
  def test(self):
641 2096d068 René Nussbaumer
    for (name, val) in ((constants.ISPEC_MEM_SIZE, 256),
642 2096d068 René Nussbaumer
                        (constants.ISPEC_MEM_SIZE, 128),
643 2096d068 René Nussbaumer
                        (constants.ISPEC_MEM_SIZE, 512),
644 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_SIZE, 1024),
645 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_SIZE, 0),
646 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_COUNT, 1),
647 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_COUNT, 5)):
648 0c2e59ac Iustin Pop
      self.assertTrue(cmdlib._ComputeMinMaxSpec(name, None, self.ipolicy, val)
649 2096d068 René Nussbaumer
                      is None)
650 2096d068 René Nussbaumer
651 2096d068 René Nussbaumer
652 0e68bf27 René Nussbaumer
def _ValidateComputeMinMaxSpec(name, *_):
653 0fb81174 René Nussbaumer
  assert name in constants.ISPECS_PARAMETERS
654 0fb81174 René Nussbaumer
  return None
655 0fb81174 René Nussbaumer
656 0fb81174 René Nussbaumer
657 cc4b2676 Bernardo Dal Seno
def _NoDiskComputeMinMaxSpec(name, *_):
658 cc4b2676 Bernardo Dal Seno
  if name == constants.ISPEC_DISK_COUNT:
659 cc4b2676 Bernardo Dal Seno
    return name
660 cc4b2676 Bernardo Dal Seno
  else:
661 cc4b2676 Bernardo Dal Seno
    return None
662 cc4b2676 Bernardo Dal Seno
663 cc4b2676 Bernardo Dal Seno
664 0fb81174 René Nussbaumer
class _SpecWrapper:
665 0fb81174 René Nussbaumer
  def __init__(self, spec):
666 0fb81174 René Nussbaumer
    self.spec = spec
667 0fb81174 René Nussbaumer
668 0e68bf27 René Nussbaumer
  def ComputeMinMaxSpec(self, *args):
669 0fb81174 René Nussbaumer
    return self.spec.pop(0)
670 0fb81174 René Nussbaumer
671 0fb81174 René Nussbaumer
672 0fb81174 René Nussbaumer
class TestComputeIPolicySpecViolation(unittest.TestCase):
673 cc4b2676 Bernardo Dal Seno
  # Minimal policy accepted by _ComputeIPolicySpecViolation()
674 cc4b2676 Bernardo Dal Seno
  _MICRO_IPOL = {
675 cc4b2676 Bernardo Dal Seno
    constants.IPOLICY_DTS: [constants.DT_PLAIN, constants.DT_DISKLESS],
676 cc4b2676 Bernardo Dal Seno
    }
677 cc4b2676 Bernardo Dal Seno
678 0fb81174 René Nussbaumer
  def test(self):
679 0e68bf27 René Nussbaumer
    compute_fn = _ValidateComputeMinMaxSpec
680 cc4b2676 Bernardo Dal Seno
    ret = cmdlib._ComputeIPolicySpecViolation(self._MICRO_IPOL, 1024, 1, 1, 1,
681 cc4b2676 Bernardo Dal Seno
                                              [1024], 1, constants.DT_PLAIN,
682 cc4b2676 Bernardo Dal Seno
                                              _compute_fn=compute_fn)
683 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
684 0fb81174 René Nussbaumer
685 cc4b2676 Bernardo Dal Seno
  def testDiskFull(self):
686 cc4b2676 Bernardo Dal Seno
    compute_fn = _NoDiskComputeMinMaxSpec
687 cc4b2676 Bernardo Dal Seno
    ret = cmdlib._ComputeIPolicySpecViolation(self._MICRO_IPOL, 1024, 1, 1, 1,
688 cc4b2676 Bernardo Dal Seno
                                              [1024], 1, constants.DT_PLAIN,
689 cc4b2676 Bernardo Dal Seno
                                              _compute_fn=compute_fn)
690 cc4b2676 Bernardo Dal Seno
    self.assertEqual(ret, [constants.ISPEC_DISK_COUNT])
691 cc4b2676 Bernardo Dal Seno
692 cc4b2676 Bernardo Dal Seno
  def testDiskLess(self):
693 cc4b2676 Bernardo Dal Seno
    compute_fn = _NoDiskComputeMinMaxSpec
694 cc4b2676 Bernardo Dal Seno
    ret = cmdlib._ComputeIPolicySpecViolation(self._MICRO_IPOL, 1024, 1, 1, 1,
695 cc4b2676 Bernardo Dal Seno
                                              [1024], 1, constants.DT_DISKLESS,
696 cc4b2676 Bernardo Dal Seno
                                              _compute_fn=compute_fn)
697 cc4b2676 Bernardo Dal Seno
    self.assertEqual(ret, [])
698 cc4b2676 Bernardo Dal Seno
699 cc4b2676 Bernardo Dal Seno
  def testWrongTemplates(self):
700 cc4b2676 Bernardo Dal Seno
    compute_fn = _ValidateComputeMinMaxSpec
701 cc4b2676 Bernardo Dal Seno
    ret = cmdlib._ComputeIPolicySpecViolation(self._MICRO_IPOL, 1024, 1, 1, 1,
702 cc4b2676 Bernardo Dal Seno
                                              [1024], 1, constants.DT_DRBD8,
703 cc4b2676 Bernardo Dal Seno
                                              _compute_fn=compute_fn)
704 cc4b2676 Bernardo Dal Seno
    self.assertEqual(len(ret), 1)
705 cc4b2676 Bernardo Dal Seno
    self.assertTrue("Disk template" in ret[0])
706 cc4b2676 Bernardo Dal Seno
707 0fb81174 René Nussbaumer
  def testInvalidArguments(self):
708 0fb81174 René Nussbaumer
    self.assertRaises(AssertionError, cmdlib._ComputeIPolicySpecViolation,
709 cc4b2676 Bernardo Dal Seno
                      self._MICRO_IPOL, 1024, 1, 1, 1, [], 1,
710 cc4b2676 Bernardo Dal Seno
                      constants.DT_PLAIN,)
711 0fb81174 René Nussbaumer
712 0fb81174 René Nussbaumer
  def testInvalidSpec(self):
713 553cb5f7 René Nussbaumer
    spec = _SpecWrapper([None, False, "foo", None, "bar", None])
714 0e68bf27 René Nussbaumer
    compute_fn = spec.ComputeMinMaxSpec
715 cc4b2676 Bernardo Dal Seno
    ret = cmdlib._ComputeIPolicySpecViolation(self._MICRO_IPOL, 1024, 1, 1, 1,
716 cc4b2676 Bernardo Dal Seno
                                              [1024], 1, constants.DT_PLAIN,
717 cc4b2676 Bernardo Dal Seno
                                              _compute_fn=compute_fn)
718 0fb81174 René Nussbaumer
    self.assertEqual(ret, ["foo", "bar"])
719 0fb81174 René Nussbaumer
    self.assertFalse(spec.spec)
720 0fb81174 René Nussbaumer
721 0fb81174 René Nussbaumer
722 0fb81174 René Nussbaumer
class _StubComputeIPolicySpecViolation:
723 553cb5f7 René Nussbaumer
  def __init__(self, mem_size, cpu_count, disk_count, nic_count, disk_sizes,
724 cc4b2676 Bernardo Dal Seno
               spindle_use, disk_template):
725 0fb81174 René Nussbaumer
    self.mem_size = mem_size
726 0fb81174 René Nussbaumer
    self.cpu_count = cpu_count
727 0fb81174 René Nussbaumer
    self.disk_count = disk_count
728 0fb81174 René Nussbaumer
    self.nic_count = nic_count
729 0fb81174 René Nussbaumer
    self.disk_sizes = disk_sizes
730 553cb5f7 René Nussbaumer
    self.spindle_use = spindle_use
731 cc4b2676 Bernardo Dal Seno
    self.disk_template = disk_template
732 0fb81174 René Nussbaumer
733 553cb5f7 René Nussbaumer
  def __call__(self, _, mem_size, cpu_count, disk_count, nic_count, disk_sizes,
734 cc4b2676 Bernardo Dal Seno
               spindle_use, disk_template):
735 0fb81174 René Nussbaumer
    assert self.mem_size == mem_size
736 0fb81174 René Nussbaumer
    assert self.cpu_count == cpu_count
737 0fb81174 René Nussbaumer
    assert self.disk_count == disk_count
738 0fb81174 René Nussbaumer
    assert self.nic_count == nic_count
739 0fb81174 René Nussbaumer
    assert self.disk_sizes == disk_sizes
740 553cb5f7 René Nussbaumer
    assert self.spindle_use == spindle_use
741 cc4b2676 Bernardo Dal Seno
    assert self.disk_template == disk_template
742 0fb81174 René Nussbaumer
743 0fb81174 René Nussbaumer
    return []
744 0fb81174 René Nussbaumer
745 0fb81174 René Nussbaumer
746 2477c1c5 Bernardo Dal Seno
class _FakeConfigForComputeIPolicyInstanceViolation:
747 2477c1c5 Bernardo Dal Seno
  def __init__(self, be):
748 2477c1c5 Bernardo Dal Seno
    self.cluster = objects.Cluster(beparams={"default": be})
749 2477c1c5 Bernardo Dal Seno
750 2477c1c5 Bernardo Dal Seno
  def GetClusterInfo(self):
751 2477c1c5 Bernardo Dal Seno
    return self.cluster
752 2477c1c5 Bernardo Dal Seno
753 2477c1c5 Bernardo Dal Seno
754 0fb81174 René Nussbaumer
class TestComputeIPolicyInstanceViolation(unittest.TestCase):
755 0fb81174 René Nussbaumer
  def test(self):
756 0fb81174 René Nussbaumer
    beparams = {
757 0fb81174 René Nussbaumer
      constants.BE_MAXMEM: 2048,
758 0fb81174 René Nussbaumer
      constants.BE_VCPUS: 2,
759 34700f5b René Nussbaumer
      constants.BE_SPINDLE_USE: 4,
760 0fb81174 René Nussbaumer
      }
761 0fb81174 René Nussbaumer
    disks = [objects.Disk(size=512)]
762 2477c1c5 Bernardo Dal Seno
    cfg = _FakeConfigForComputeIPolicyInstanceViolation(beparams)
763 cc4b2676 Bernardo Dal Seno
    instance = objects.Instance(beparams=beparams, disks=disks, nics=[],
764 cc4b2676 Bernardo Dal Seno
                                disk_template=constants.DT_PLAIN)
765 cc4b2676 Bernardo Dal Seno
    stub = _StubComputeIPolicySpecViolation(2048, 2, 1, 0, [512], 4,
766 cc4b2676 Bernardo Dal Seno
                                            constants.DT_PLAIN)
767 0fb81174 René Nussbaumer
    ret = cmdlib._ComputeIPolicyInstanceViolation(NotImplemented, instance,
768 2477c1c5 Bernardo Dal Seno
                                                  cfg, _compute_fn=stub)
769 2477c1c5 Bernardo Dal Seno
    self.assertEqual(ret, [])
770 2477c1c5 Bernardo Dal Seno
    instance2 = objects.Instance(beparams={}, disks=disks, nics=[],
771 2477c1c5 Bernardo Dal Seno
                                 disk_template=constants.DT_PLAIN)
772 2477c1c5 Bernardo Dal Seno
    ret = cmdlib._ComputeIPolicyInstanceViolation(NotImplemented, instance2,
773 2477c1c5 Bernardo Dal Seno
                                                  cfg, _compute_fn=stub)
774 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
775 0fb81174 René Nussbaumer
776 0fb81174 René Nussbaumer
777 0fb81174 René Nussbaumer
class TestComputeIPolicyInstanceSpecViolation(unittest.TestCase):
778 0fb81174 René Nussbaumer
  def test(self):
779 0fb81174 René Nussbaumer
    ispec = {
780 0fb81174 René Nussbaumer
      constants.ISPEC_MEM_SIZE: 2048,
781 0fb81174 René Nussbaumer
      constants.ISPEC_CPU_COUNT: 2,
782 0fb81174 René Nussbaumer
      constants.ISPEC_DISK_COUNT: 1,
783 0fb81174 René Nussbaumer
      constants.ISPEC_DISK_SIZE: [512],
784 0fb81174 René Nussbaumer
      constants.ISPEC_NIC_COUNT: 0,
785 553cb5f7 René Nussbaumer
      constants.ISPEC_SPINDLE_USE: 1,
786 0fb81174 René Nussbaumer
      }
787 cc4b2676 Bernardo Dal Seno
    stub = _StubComputeIPolicySpecViolation(2048, 2, 1, 0, [512], 1,
788 cc4b2676 Bernardo Dal Seno
                                            constants.DT_PLAIN)
789 0fb81174 René Nussbaumer
    ret = cmdlib._ComputeIPolicyInstanceSpecViolation(NotImplemented, ispec,
790 cc4b2676 Bernardo Dal Seno
                                                      constants.DT_PLAIN,
791 0fb81174 René Nussbaumer
                                                      _compute_fn=stub)
792 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
793 0fb81174 René Nussbaumer
794 0fb81174 René Nussbaumer
795 0fb81174 René Nussbaumer
class _CallRecorder:
796 0fb81174 René Nussbaumer
  def __init__(self, return_value=None):
797 0fb81174 René Nussbaumer
    self.called = False
798 0fb81174 René Nussbaumer
    self.return_value = return_value
799 0fb81174 René Nussbaumer
800 0fb81174 René Nussbaumer
  def __call__(self, *args):
801 0fb81174 René Nussbaumer
    self.called = True
802 0fb81174 René Nussbaumer
    return self.return_value
803 0fb81174 René Nussbaumer
804 0fb81174 René Nussbaumer
805 0fb81174 René Nussbaumer
class TestComputeIPolicyNodeViolation(unittest.TestCase):
806 0fb81174 René Nussbaumer
  def setUp(self):
807 0fb81174 René Nussbaumer
    self.recorder = _CallRecorder(return_value=[])
808 0fb81174 René Nussbaumer
809 0fb81174 René Nussbaumer
  def testSameGroup(self):
810 0fb81174 René Nussbaumer
    ret = cmdlib._ComputeIPolicyNodeViolation(NotImplemented, NotImplemented,
811 2477c1c5 Bernardo Dal Seno
                                              "foo", "foo", NotImplemented,
812 0fb81174 René Nussbaumer
                                              _compute_fn=self.recorder)
813 0fb81174 René Nussbaumer
    self.assertFalse(self.recorder.called)
814 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
815 0fb81174 René Nussbaumer
816 0fb81174 René Nussbaumer
  def testDifferentGroup(self):
817 0fb81174 René Nussbaumer
    ret = cmdlib._ComputeIPolicyNodeViolation(NotImplemented, NotImplemented,
818 2477c1c5 Bernardo Dal Seno
                                              "foo", "bar", NotImplemented,
819 0fb81174 René Nussbaumer
                                              _compute_fn=self.recorder)
820 0fb81174 René Nussbaumer
    self.assertTrue(self.recorder.called)
821 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
822 0fb81174 René Nussbaumer
823 0fb81174 René Nussbaumer
824 ff02b60f René Nussbaumer
class _FakeConfigForTargetNodeIPolicy:
825 ff02b60f René Nussbaumer
  def __init__(self, node_info=NotImplemented):
826 ff02b60f René Nussbaumer
    self._node_info = node_info
827 ff02b60f René Nussbaumer
828 ff02b60f René Nussbaumer
  def GetNodeInfo(self, _):
829 ff02b60f René Nussbaumer
    return self._node_info
830 ff02b60f René Nussbaumer
831 ff02b60f René Nussbaumer
832 0fb81174 René Nussbaumer
class TestCheckTargetNodeIPolicy(unittest.TestCase):
833 0fb81174 René Nussbaumer
  def setUp(self):
834 ff02b60f René Nussbaumer
    self.instance = objects.Instance(primary_node="blubb")
835 0fb81174 René Nussbaumer
    self.target_node = objects.Node(group="bar")
836 ff02b60f René Nussbaumer
    node_info = objects.Node(group="foo")
837 ff02b60f René Nussbaumer
    fake_cfg = _FakeConfigForTargetNodeIPolicy(node_info=node_info)
838 ff02b60f René Nussbaumer
    self.lu = _FakeLU(cfg=fake_cfg)
839 0fb81174 René Nussbaumer
840 0fb81174 René Nussbaumer
  def testNoViolation(self):
841 0fb81174 René Nussbaumer
    compute_recoder = _CallRecorder(return_value=[])
842 0fb81174 René Nussbaumer
    cmdlib._CheckTargetNodeIPolicy(self.lu, NotImplemented, self.instance,
843 2477c1c5 Bernardo Dal Seno
                                   self.target_node, NotImplemented,
844 0fb81174 René Nussbaumer
                                   _compute_fn=compute_recoder)
845 0fb81174 René Nussbaumer
    self.assertTrue(compute_recoder.called)
846 0fb81174 René Nussbaumer
    self.assertEqual(self.lu.warning_log, [])
847 0fb81174 René Nussbaumer
848 0fb81174 René Nussbaumer
  def testNoIgnore(self):
849 0fb81174 René Nussbaumer
    compute_recoder = _CallRecorder(return_value=["mem_size not in range"])
850 0fb81174 René Nussbaumer
    self.assertRaises(errors.OpPrereqError, cmdlib._CheckTargetNodeIPolicy,
851 0fb81174 René Nussbaumer
                      self.lu, NotImplemented, self.instance, self.target_node,
852 2477c1c5 Bernardo Dal Seno
                      NotImplemented, _compute_fn=compute_recoder)
853 0fb81174 René Nussbaumer
    self.assertTrue(compute_recoder.called)
854 0fb81174 René Nussbaumer
    self.assertEqual(self.lu.warning_log, [])
855 0fb81174 René Nussbaumer
856 0fb81174 René Nussbaumer
  def testIgnoreViolation(self):
857 0fb81174 René Nussbaumer
    compute_recoder = _CallRecorder(return_value=["mem_size not in range"])
858 0fb81174 René Nussbaumer
    cmdlib._CheckTargetNodeIPolicy(self.lu, NotImplemented, self.instance,
859 2477c1c5 Bernardo Dal Seno
                                   self.target_node, NotImplemented,
860 2477c1c5 Bernardo Dal Seno
                                   ignore=True, _compute_fn=compute_recoder)
861 0fb81174 René Nussbaumer
    self.assertTrue(compute_recoder.called)
862 0fb81174 René Nussbaumer
    msg = ("Instance does not meet target node group's (bar) instance policy:"
863 0fb81174 René Nussbaumer
           " mem_size not in range")
864 0fb81174 René Nussbaumer
    self.assertEqual(self.lu.warning_log, [(msg, ())])
865 0fb81174 René Nussbaumer
866 0fb81174 René Nussbaumer
867 8301885b Michael Hanselmann
class TestApplyContainerMods(unittest.TestCase):
868 8301885b Michael Hanselmann
  def testEmptyContainer(self):
869 8301885b Michael Hanselmann
    container = []
870 8301885b Michael Hanselmann
    chgdesc = []
871 8301885b Michael Hanselmann
    cmdlib.ApplyContainerMods("test", container, chgdesc, [], None, None, None)
872 8301885b Michael Hanselmann
    self.assertEqual(container, [])
873 8301885b Michael Hanselmann
    self.assertEqual(chgdesc, [])
874 8301885b Michael Hanselmann
875 8301885b Michael Hanselmann
  def testAdd(self):
876 8301885b Michael Hanselmann
    container = []
877 8301885b Michael Hanselmann
    chgdesc = []
878 8301885b Michael Hanselmann
    mods = cmdlib.PrepareContainerMods([
879 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "Hello"),
880 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "World"),
881 8301885b Michael Hanselmann
      (constants.DDM_ADD, 0, "Start"),
882 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "End"),
883 8301885b Michael Hanselmann
      ], None)
884 8301885b Michael Hanselmann
    cmdlib.ApplyContainerMods("test", container, chgdesc, mods,
885 8301885b Michael Hanselmann
                              None, None, None)
886 8301885b Michael Hanselmann
    self.assertEqual(container, ["Start", "Hello", "World", "End"])
887 8301885b Michael Hanselmann
    self.assertEqual(chgdesc, [])
888 8301885b Michael Hanselmann
889 35554b4f Michael Hanselmann
    mods = cmdlib.PrepareContainerMods([
890 35554b4f Michael Hanselmann
      (constants.DDM_ADD, 0, "zero"),
891 35554b4f Michael Hanselmann
      (constants.DDM_ADD, 3, "Added"),
892 35554b4f Michael Hanselmann
      (constants.DDM_ADD, 5, "four"),
893 35554b4f Michael Hanselmann
      (constants.DDM_ADD, 7, "xyz"),
894 35554b4f Michael Hanselmann
      ], None)
895 35554b4f Michael Hanselmann
    cmdlib.ApplyContainerMods("test", container, chgdesc, mods,
896 35554b4f Michael Hanselmann
                              None, None, None)
897 35554b4f Michael Hanselmann
    self.assertEqual(container,
898 35554b4f Michael Hanselmann
                     ["zero", "Start", "Hello", "Added", "World", "four",
899 35554b4f Michael Hanselmann
                      "End", "xyz"])
900 35554b4f Michael Hanselmann
    self.assertEqual(chgdesc, [])
901 35554b4f Michael Hanselmann
902 35554b4f Michael Hanselmann
    for idx in [-2, len(container) + 1]:
903 35554b4f Michael Hanselmann
      mods = cmdlib.PrepareContainerMods([
904 35554b4f Michael Hanselmann
        (constants.DDM_ADD, idx, "error"),
905 35554b4f Michael Hanselmann
        ], None)
906 35554b4f Michael Hanselmann
      self.assertRaises(IndexError, cmdlib.ApplyContainerMods,
907 35554b4f Michael Hanselmann
                        "test", container, None, mods, None, None, None)
908 35554b4f Michael Hanselmann
909 8301885b Michael Hanselmann
  def testRemoveError(self):
910 8301885b Michael Hanselmann
    for idx in [0, 1, 2, 100, -1, -4]:
911 8301885b Michael Hanselmann
      mods = cmdlib.PrepareContainerMods([
912 8301885b Michael Hanselmann
        (constants.DDM_REMOVE, idx, None),
913 8301885b Michael Hanselmann
        ], None)
914 8301885b Michael Hanselmann
      self.assertRaises(IndexError, cmdlib.ApplyContainerMods,
915 8301885b Michael Hanselmann
                        "test", [], None, mods, None, None, None)
916 8301885b Michael Hanselmann
917 8301885b Michael Hanselmann
    mods = cmdlib.PrepareContainerMods([
918 8301885b Michael Hanselmann
      (constants.DDM_REMOVE, 0, object()),
919 8301885b Michael Hanselmann
      ], None)
920 8301885b Michael Hanselmann
    self.assertRaises(AssertionError, cmdlib.ApplyContainerMods,
921 8301885b Michael Hanselmann
                      "test", [""], None, mods, None, None, None)
922 8301885b Michael Hanselmann
923 8301885b Michael Hanselmann
  def testAddError(self):
924 35554b4f Michael Hanselmann
    for idx in range(-100, -1) + [100]:
925 8301885b Michael Hanselmann
      mods = cmdlib.PrepareContainerMods([
926 8301885b Michael Hanselmann
        (constants.DDM_ADD, idx, None),
927 8301885b Michael Hanselmann
        ], None)
928 8301885b Michael Hanselmann
      self.assertRaises(IndexError, cmdlib.ApplyContainerMods,
929 8301885b Michael Hanselmann
                        "test", [], None, mods, None, None, None)
930 8301885b Michael Hanselmann
931 8301885b Michael Hanselmann
  def testRemove(self):
932 8301885b Michael Hanselmann
    container = ["item 1", "item 2"]
933 8301885b Michael Hanselmann
    mods = cmdlib.PrepareContainerMods([
934 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "aaa"),
935 8301885b Michael Hanselmann
      (constants.DDM_REMOVE, -1, None),
936 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "bbb"),
937 8301885b Michael Hanselmann
      ], None)
938 8301885b Michael Hanselmann
    chgdesc = []
939 8301885b Michael Hanselmann
    cmdlib.ApplyContainerMods("test", container, chgdesc, mods,
940 8301885b Michael Hanselmann
                              None, None, None)
941 8301885b Michael Hanselmann
    self.assertEqual(container, ["item 1", "item 2", "bbb"])
942 8301885b Michael Hanselmann
    self.assertEqual(chgdesc, [
943 8301885b Michael Hanselmann
      ("test/2", "remove"),
944 8301885b Michael Hanselmann
      ])
945 8301885b Michael Hanselmann
946 35554b4f Michael Hanselmann
  def testModify(self):
947 35554b4f Michael Hanselmann
    container = ["item 1", "item 2"]
948 35554b4f Michael Hanselmann
    mods = cmdlib.PrepareContainerMods([
949 35554b4f Michael Hanselmann
      (constants.DDM_MODIFY, -1, "a"),
950 35554b4f Michael Hanselmann
      (constants.DDM_MODIFY, 0, "b"),
951 35554b4f Michael Hanselmann
      (constants.DDM_MODIFY, 1, "c"),
952 35554b4f Michael Hanselmann
      ], None)
953 35554b4f Michael Hanselmann
    chgdesc = []
954 35554b4f Michael Hanselmann
    cmdlib.ApplyContainerMods("test", container, chgdesc, mods,
955 35554b4f Michael Hanselmann
                              None, None, None)
956 35554b4f Michael Hanselmann
    self.assertEqual(container, ["item 1", "item 2"])
957 35554b4f Michael Hanselmann
    self.assertEqual(chgdesc, [])
958 35554b4f Michael Hanselmann
959 35554b4f Michael Hanselmann
    for idx in [-2, len(container) + 1]:
960 35554b4f Michael Hanselmann
      mods = cmdlib.PrepareContainerMods([
961 35554b4f Michael Hanselmann
        (constants.DDM_MODIFY, idx, "error"),
962 35554b4f Michael Hanselmann
        ], None)
963 35554b4f Michael Hanselmann
      self.assertRaises(IndexError, cmdlib.ApplyContainerMods,
964 35554b4f Michael Hanselmann
                        "test", container, None, mods, None, None, None)
965 35554b4f Michael Hanselmann
966 8301885b Michael Hanselmann
  class _PrivateData:
967 8301885b Michael Hanselmann
    def __init__(self):
968 8301885b Michael Hanselmann
      self.data = None
969 8301885b Michael Hanselmann
970 8301885b Michael Hanselmann
  @staticmethod
971 efcfa99d Michael Hanselmann
  def _CreateTestFn(idx, params, private):
972 8301885b Michael Hanselmann
    private.data = ("add", idx, params)
973 efcfa99d Michael Hanselmann
    return ((100 * idx, params), [
974 efcfa99d Michael Hanselmann
      ("test/%s" % idx, hex(idx)),
975 efcfa99d Michael Hanselmann
      ])
976 8301885b Michael Hanselmann
977 8301885b Michael Hanselmann
  @staticmethod
978 efcfa99d Michael Hanselmann
  def _ModifyTestFn(idx, item, params, private):
979 8301885b Michael Hanselmann
    private.data = ("modify", idx, params)
980 efcfa99d Michael Hanselmann
    return [
981 efcfa99d Michael Hanselmann
      ("test/%s" % idx, "modify %s" % params),
982 efcfa99d Michael Hanselmann
      ]
983 8301885b Michael Hanselmann
984 8301885b Michael Hanselmann
  @staticmethod
985 efcfa99d Michael Hanselmann
  def _RemoveTestFn(idx, item, private):
986 8301885b Michael Hanselmann
    private.data = ("remove", idx, item)
987 8301885b Michael Hanselmann
988 8301885b Michael Hanselmann
  def testAddWithCreateFunction(self):
989 8301885b Michael Hanselmann
    container = []
990 8301885b Michael Hanselmann
    chgdesc = []
991 8301885b Michael Hanselmann
    mods = cmdlib.PrepareContainerMods([
992 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "Hello"),
993 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "World"),
994 8301885b Michael Hanselmann
      (constants.DDM_ADD, 0, "Start"),
995 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "End"),
996 8301885b Michael Hanselmann
      (constants.DDM_REMOVE, 2, None),
997 8301885b Michael Hanselmann
      (constants.DDM_MODIFY, -1, "foobar"),
998 8301885b Michael Hanselmann
      (constants.DDM_REMOVE, 2, None),
999 8301885b Michael Hanselmann
      (constants.DDM_ADD, 1, "More"),
1000 8301885b Michael Hanselmann
      ], self._PrivateData)
1001 8301885b Michael Hanselmann
    cmdlib.ApplyContainerMods("test", container, chgdesc, mods,
1002 8301885b Michael Hanselmann
      self._CreateTestFn, self._ModifyTestFn, self._RemoveTestFn)
1003 8301885b Michael Hanselmann
    self.assertEqual(container, [
1004 35554b4f Michael Hanselmann
      (000, "Start"),
1005 35554b4f Michael Hanselmann
      (100, "More"),
1006 35554b4f Michael Hanselmann
      (000, "Hello"),
1007 8301885b Michael Hanselmann
      ])
1008 8301885b Michael Hanselmann
    self.assertEqual(chgdesc, [
1009 8301885b Michael Hanselmann
      ("test/0", "0x0"),
1010 8301885b Michael Hanselmann
      ("test/1", "0x1"),
1011 35554b4f Michael Hanselmann
      ("test/0", "0x0"),
1012 8301885b Michael Hanselmann
      ("test/3", "0x3"),
1013 8301885b Michael Hanselmann
      ("test/2", "remove"),
1014 8301885b Michael Hanselmann
      ("test/2", "modify foobar"),
1015 8301885b Michael Hanselmann
      ("test/2", "remove"),
1016 35554b4f Michael Hanselmann
      ("test/1", "0x1")
1017 8301885b Michael Hanselmann
      ])
1018 8301885b Michael Hanselmann
    self.assertTrue(compat.all(op == private.data[0]
1019 8301885b Michael Hanselmann
                               for (op, _, _, private) in mods))
1020 8301885b Michael Hanselmann
    self.assertEqual([private.data for (op, _, _, private) in mods], [
1021 8301885b Michael Hanselmann
      ("add", 0, "Hello"),
1022 8301885b Michael Hanselmann
      ("add", 1, "World"),
1023 35554b4f Michael Hanselmann
      ("add", 0, "Start"),
1024 8301885b Michael Hanselmann
      ("add", 3, "End"),
1025 8301885b Michael Hanselmann
      ("remove", 2, (100, "World")),
1026 8301885b Michael Hanselmann
      ("modify", 2, "foobar"),
1027 8301885b Michael Hanselmann
      ("remove", 2, (300, "End")),
1028 35554b4f Michael Hanselmann
      ("add", 1, "More"),
1029 8301885b Michael Hanselmann
      ])
1030 8301885b Michael Hanselmann
1031 8301885b Michael Hanselmann
1032 a8e3e009 Michael Hanselmann
class _FakeConfigForGenDiskTemplate:
1033 a8e3e009 Michael Hanselmann
  def __init__(self):
1034 a8e3e009 Michael Hanselmann
    self._unique_id = itertools.count()
1035 a8e3e009 Michael Hanselmann
    self._drbd_minor = itertools.count(20)
1036 a8e3e009 Michael Hanselmann
    self._port = itertools.count(constants.FIRST_DRBD_PORT)
1037 a8e3e009 Michael Hanselmann
    self._secret = itertools.count()
1038 a8e3e009 Michael Hanselmann
1039 a8e3e009 Michael Hanselmann
  def GetVGName(self):
1040 a8e3e009 Michael Hanselmann
    return "testvg"
1041 a8e3e009 Michael Hanselmann
1042 a8e3e009 Michael Hanselmann
  def GenerateUniqueID(self, ec_id):
1043 a8e3e009 Michael Hanselmann
    return "ec%s-uq%s" % (ec_id, self._unique_id.next())
1044 a8e3e009 Michael Hanselmann
1045 a8e3e009 Michael Hanselmann
  def AllocateDRBDMinor(self, nodes, instance):
1046 a8e3e009 Michael Hanselmann
    return [self._drbd_minor.next()
1047 a8e3e009 Michael Hanselmann
            for _ in nodes]
1048 a8e3e009 Michael Hanselmann
1049 a8e3e009 Michael Hanselmann
  def AllocatePort(self):
1050 a8e3e009 Michael Hanselmann
    return self._port.next()
1051 a8e3e009 Michael Hanselmann
1052 a8e3e009 Michael Hanselmann
  def GenerateDRBDSecret(self, ec_id):
1053 a8e3e009 Michael Hanselmann
    return "ec%s-secret%s" % (ec_id, self._secret.next())
1054 a8e3e009 Michael Hanselmann
1055 99ccf8b9 René Nussbaumer
  def GetInstanceInfo(self, _):
1056 99ccf8b9 René Nussbaumer
    return "foobar"
1057 99ccf8b9 René Nussbaumer
1058 a8e3e009 Michael Hanselmann
1059 a8e3e009 Michael Hanselmann
class _FakeProcForGenDiskTemplate:
1060 a8e3e009 Michael Hanselmann
  def GetECId(self):
1061 a8e3e009 Michael Hanselmann
    return 0
1062 a8e3e009 Michael Hanselmann
1063 a8e3e009 Michael Hanselmann
1064 a8e3e009 Michael Hanselmann
class TestGenerateDiskTemplate(unittest.TestCase):
1065 a8e3e009 Michael Hanselmann
  def setUp(self):
1066 a8e3e009 Michael Hanselmann
    nodegroup = objects.NodeGroup(name="ng")
1067 a8e3e009 Michael Hanselmann
    nodegroup.UpgradeConfig()
1068 a8e3e009 Michael Hanselmann
1069 a8e3e009 Michael Hanselmann
    cfg = _FakeConfigForGenDiskTemplate()
1070 a8e3e009 Michael Hanselmann
    proc = _FakeProcForGenDiskTemplate()
1071 a8e3e009 Michael Hanselmann
1072 a8e3e009 Michael Hanselmann
    self.lu = _FakeLU(cfg=cfg, proc=proc)
1073 a8e3e009 Michael Hanselmann
    self.nodegroup = nodegroup
1074 a8e3e009 Michael Hanselmann
1075 99ccf8b9 René Nussbaumer
  @staticmethod
1076 99ccf8b9 René Nussbaumer
  def GetDiskParams():
1077 99ccf8b9 René Nussbaumer
    return copy.deepcopy(constants.DISK_DT_DEFAULTS)
1078 99ccf8b9 René Nussbaumer
1079 a8e3e009 Michael Hanselmann
  def testWrongDiskTemplate(self):
1080 a8e3e009 Michael Hanselmann
    gdt = cmdlib._GenerateDiskTemplate
1081 a8e3e009 Michael Hanselmann
    disk_template = "##unknown##"
1082 a8e3e009 Michael Hanselmann
1083 a8e3e009 Michael Hanselmann
    assert disk_template not in constants.DISK_TEMPLATES
1084 a8e3e009 Michael Hanselmann
1085 a8e3e009 Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, gdt, self.lu, disk_template,
1086 a8e3e009 Michael Hanselmann
                      "inst26831.example.com", "node30113.example.com", [], [],
1087 a8e3e009 Michael Hanselmann
                      NotImplemented, NotImplemented, 0, self.lu.LogInfo,
1088 99ccf8b9 René Nussbaumer
                      self.GetDiskParams())
1089 a8e3e009 Michael Hanselmann
1090 a8e3e009 Michael Hanselmann
  def testDiskless(self):
1091 a8e3e009 Michael Hanselmann
    gdt = cmdlib._GenerateDiskTemplate
1092 a8e3e009 Michael Hanselmann
1093 a8e3e009 Michael Hanselmann
    result = gdt(self.lu, constants.DT_DISKLESS, "inst27734.example.com",
1094 a8e3e009 Michael Hanselmann
                 "node30113.example.com", [], [],
1095 a8e3e009 Michael Hanselmann
                 NotImplemented, NotImplemented, 0, self.lu.LogInfo,
1096 99ccf8b9 René Nussbaumer
                 self.GetDiskParams())
1097 a8e3e009 Michael Hanselmann
    self.assertEqual(result, [])
1098 a8e3e009 Michael Hanselmann
1099 a8e3e009 Michael Hanselmann
  def _TestTrivialDisk(self, template, disk_info, base_index, exp_dev_type,
1100 a8e3e009 Michael Hanselmann
                       file_storage_dir=NotImplemented,
1101 a8e3e009 Michael Hanselmann
                       file_driver=NotImplemented,
1102 a8e3e009 Michael Hanselmann
                       req_file_storage=NotImplemented,
1103 a8e3e009 Michael Hanselmann
                       req_shr_file_storage=NotImplemented):
1104 a8e3e009 Michael Hanselmann
    gdt = cmdlib._GenerateDiskTemplate
1105 a8e3e009 Michael Hanselmann
1106 a8e3e009 Michael Hanselmann
    map(lambda params: utils.ForceDictType(params,
1107 a8e3e009 Michael Hanselmann
                                           constants.IDISK_PARAMS_TYPES),
1108 a8e3e009 Michael Hanselmann
        disk_info)
1109 a8e3e009 Michael Hanselmann
1110 a8e3e009 Michael Hanselmann
    # Check if non-empty list of secondaries is rejected
1111 a8e3e009 Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, gdt, self.lu,
1112 a8e3e009 Michael Hanselmann
                      template, "inst25088.example.com",
1113 a8e3e009 Michael Hanselmann
                      "node185.example.com", ["node323.example.com"], [],
1114 a8e3e009 Michael Hanselmann
                      NotImplemented, NotImplemented, base_index,
1115 99ccf8b9 René Nussbaumer
                      self.lu.LogInfo, self.GetDiskParams(),
1116 a8e3e009 Michael Hanselmann
                      _req_file_storage=req_file_storage,
1117 a8e3e009 Michael Hanselmann
                      _req_shr_file_storage=req_shr_file_storage)
1118 a8e3e009 Michael Hanselmann
1119 a8e3e009 Michael Hanselmann
    result = gdt(self.lu, template, "inst21662.example.com",
1120 a8e3e009 Michael Hanselmann
                 "node21741.example.com", [],
1121 a8e3e009 Michael Hanselmann
                 disk_info, file_storage_dir, file_driver, base_index,
1122 99ccf8b9 René Nussbaumer
                 self.lu.LogInfo, self.GetDiskParams(),
1123 a8e3e009 Michael Hanselmann
                 _req_file_storage=req_file_storage,
1124 a8e3e009 Michael Hanselmann
                 _req_shr_file_storage=req_shr_file_storage)
1125 a8e3e009 Michael Hanselmann
1126 a8e3e009 Michael Hanselmann
    for (idx, disk) in enumerate(result):
1127 a8e3e009 Michael Hanselmann
      self.assertTrue(isinstance(disk, objects.Disk))
1128 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.dev_type, exp_dev_type)
1129 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.size, disk_info[idx][constants.IDISK_SIZE])
1130 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.mode, disk_info[idx][constants.IDISK_MODE])
1131 a8e3e009 Michael Hanselmann
      self.assertTrue(disk.children is None)
1132 a8e3e009 Michael Hanselmann
1133 0356a13d Michael Hanselmann
    self._CheckIvNames(result, base_index, base_index + len(disk_info))
1134 0356a13d Michael Hanselmann
    cmdlib._UpdateIvNames(base_index, result)
1135 0356a13d Michael Hanselmann
    self._CheckIvNames(result, base_index, base_index + len(disk_info))
1136 a8e3e009 Michael Hanselmann
1137 a8e3e009 Michael Hanselmann
    return result
1138 a8e3e009 Michael Hanselmann
1139 0356a13d Michael Hanselmann
  def _CheckIvNames(self, disks, base_index, end_index):
1140 0356a13d Michael Hanselmann
    self.assertEqual(map(operator.attrgetter("iv_name"), disks),
1141 0356a13d Michael Hanselmann
                     ["disk/%s" % i for i in range(base_index, end_index)])
1142 0356a13d Michael Hanselmann
1143 a8e3e009 Michael Hanselmann
  def testPlain(self):
1144 a8e3e009 Michael Hanselmann
    disk_info = [{
1145 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 1024,
1146 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDWR,
1147 a8e3e009 Michael Hanselmann
      }, {
1148 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 4096,
1149 a8e3e009 Michael Hanselmann
      constants.IDISK_VG: "othervg",
1150 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDWR,
1151 a8e3e009 Michael Hanselmann
      }]
1152 a8e3e009 Michael Hanselmann
1153 a8e3e009 Michael Hanselmann
    result = self._TestTrivialDisk(constants.DT_PLAIN, disk_info, 3,
1154 a8e3e009 Michael Hanselmann
                                   constants.LD_LV)
1155 a8e3e009 Michael Hanselmann
1156 a8e3e009 Michael Hanselmann
    self.assertEqual(map(operator.attrgetter("logical_id"), result), [
1157 a8e3e009 Michael Hanselmann
      ("testvg", "ec0-uq0.disk3"),
1158 a8e3e009 Michael Hanselmann
      ("othervg", "ec0-uq1.disk4"),
1159 a8e3e009 Michael Hanselmann
      ])
1160 a8e3e009 Michael Hanselmann
1161 a8e3e009 Michael Hanselmann
  @staticmethod
1162 a8e3e009 Michael Hanselmann
  def _AllowFileStorage():
1163 a8e3e009 Michael Hanselmann
    pass
1164 a8e3e009 Michael Hanselmann
1165 a8e3e009 Michael Hanselmann
  @staticmethod
1166 a8e3e009 Michael Hanselmann
  def _ForbidFileStorage():
1167 a8e3e009 Michael Hanselmann
    raise errors.OpPrereqError("Disallowed in test")
1168 a8e3e009 Michael Hanselmann
1169 a8e3e009 Michael Hanselmann
  def testFile(self):
1170 a8e3e009 Michael Hanselmann
    self.assertRaises(errors.OpPrereqError, self._TestTrivialDisk,
1171 a8e3e009 Michael Hanselmann
                      constants.DT_FILE, [], 0, NotImplemented,
1172 a8e3e009 Michael Hanselmann
                      req_file_storage=self._ForbidFileStorage)
1173 a8e3e009 Michael Hanselmann
    self.assertRaises(errors.OpPrereqError, self._TestTrivialDisk,
1174 a8e3e009 Michael Hanselmann
                      constants.DT_SHARED_FILE, [], 0, NotImplemented,
1175 a8e3e009 Michael Hanselmann
                      req_shr_file_storage=self._ForbidFileStorage)
1176 a8e3e009 Michael Hanselmann
1177 a8e3e009 Michael Hanselmann
    for disk_template in [constants.DT_FILE, constants.DT_SHARED_FILE]:
1178 a8e3e009 Michael Hanselmann
      disk_info = [{
1179 a8e3e009 Michael Hanselmann
        constants.IDISK_SIZE: 80 * 1024,
1180 a8e3e009 Michael Hanselmann
        constants.IDISK_MODE: constants.DISK_RDONLY,
1181 a8e3e009 Michael Hanselmann
        }, {
1182 a8e3e009 Michael Hanselmann
        constants.IDISK_SIZE: 4096,
1183 a8e3e009 Michael Hanselmann
        constants.IDISK_MODE: constants.DISK_RDWR,
1184 a8e3e009 Michael Hanselmann
        }, {
1185 a8e3e009 Michael Hanselmann
        constants.IDISK_SIZE: 6 * 1024,
1186 a8e3e009 Michael Hanselmann
        constants.IDISK_MODE: constants.DISK_RDWR,
1187 a8e3e009 Michael Hanselmann
        }]
1188 a8e3e009 Michael Hanselmann
1189 a8e3e009 Michael Hanselmann
      result = self._TestTrivialDisk(disk_template, disk_info, 2,
1190 a8e3e009 Michael Hanselmann
        constants.LD_FILE, file_storage_dir="/tmp",
1191 a8e3e009 Michael Hanselmann
        file_driver=constants.FD_BLKTAP,
1192 a8e3e009 Michael Hanselmann
        req_file_storage=self._AllowFileStorage,
1193 a8e3e009 Michael Hanselmann
        req_shr_file_storage=self._AllowFileStorage)
1194 a8e3e009 Michael Hanselmann
1195 a8e3e009 Michael Hanselmann
      self.assertEqual(map(operator.attrgetter("logical_id"), result), [
1196 a8e3e009 Michael Hanselmann
        (constants.FD_BLKTAP, "/tmp/disk2"),
1197 a8e3e009 Michael Hanselmann
        (constants.FD_BLKTAP, "/tmp/disk3"),
1198 a8e3e009 Michael Hanselmann
        (constants.FD_BLKTAP, "/tmp/disk4"),
1199 a8e3e009 Michael Hanselmann
        ])
1200 a8e3e009 Michael Hanselmann
1201 a8e3e009 Michael Hanselmann
  def testBlock(self):
1202 a8e3e009 Michael Hanselmann
    disk_info = [{
1203 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 8 * 1024,
1204 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDWR,
1205 a8e3e009 Michael Hanselmann
      constants.IDISK_ADOPT: "/tmp/some/block/dev",
1206 a8e3e009 Michael Hanselmann
      }]
1207 a8e3e009 Michael Hanselmann
1208 a8e3e009 Michael Hanselmann
    result = self._TestTrivialDisk(constants.DT_BLOCK, disk_info, 10,
1209 a8e3e009 Michael Hanselmann
                                   constants.LD_BLOCKDEV)
1210 a8e3e009 Michael Hanselmann
1211 a8e3e009 Michael Hanselmann
    self.assertEqual(map(operator.attrgetter("logical_id"), result), [
1212 a8e3e009 Michael Hanselmann
      (constants.BLOCKDEV_DRIVER_MANUAL, "/tmp/some/block/dev"),
1213 a8e3e009 Michael Hanselmann
      ])
1214 a8e3e009 Michael Hanselmann
1215 a8e3e009 Michael Hanselmann
  def testRbd(self):
1216 a8e3e009 Michael Hanselmann
    disk_info = [{
1217 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 8 * 1024,
1218 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDONLY,
1219 a8e3e009 Michael Hanselmann
      }, {
1220 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 100 * 1024,
1221 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDWR,
1222 a8e3e009 Michael Hanselmann
      }]
1223 a8e3e009 Michael Hanselmann
1224 a8e3e009 Michael Hanselmann
    result = self._TestTrivialDisk(constants.DT_RBD, disk_info, 0,
1225 a8e3e009 Michael Hanselmann
                                   constants.LD_RBD)
1226 a8e3e009 Michael Hanselmann
1227 a8e3e009 Michael Hanselmann
    self.assertEqual(map(operator.attrgetter("logical_id"), result), [
1228 a8e3e009 Michael Hanselmann
      ("rbd", "ec0-uq0.rbd.disk0"),
1229 a8e3e009 Michael Hanselmann
      ("rbd", "ec0-uq1.rbd.disk1"),
1230 a8e3e009 Michael Hanselmann
      ])
1231 a8e3e009 Michael Hanselmann
1232 a8e3e009 Michael Hanselmann
  def testDrbd8(self):
1233 a8e3e009 Michael Hanselmann
    gdt = cmdlib._GenerateDiskTemplate
1234 a8e3e009 Michael Hanselmann
    drbd8_defaults = constants.DISK_LD_DEFAULTS[constants.LD_DRBD8]
1235 a8e3e009 Michael Hanselmann
    drbd8_default_metavg = drbd8_defaults[constants.LDP_DEFAULT_METAVG]
1236 a8e3e009 Michael Hanselmann
1237 a8e3e009 Michael Hanselmann
    disk_info = [{
1238 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 1024,
1239 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDWR,
1240 a8e3e009 Michael Hanselmann
      }, {
1241 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 100 * 1024,
1242 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDONLY,
1243 a8e3e009 Michael Hanselmann
      constants.IDISK_METAVG: "metavg",
1244 a8e3e009 Michael Hanselmann
      }, {
1245 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 4096,
1246 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDWR,
1247 a8e3e009 Michael Hanselmann
      constants.IDISK_VG: "vgxyz",
1248 a8e3e009 Michael Hanselmann
      },
1249 a8e3e009 Michael Hanselmann
      ]
1250 a8e3e009 Michael Hanselmann
1251 a8e3e009 Michael Hanselmann
    exp_logical_ids = [[
1252 a8e3e009 Michael Hanselmann
      (self.lu.cfg.GetVGName(), "ec0-uq0.disk0_data"),
1253 a8e3e009 Michael Hanselmann
      (drbd8_default_metavg, "ec0-uq0.disk0_meta"),
1254 a8e3e009 Michael Hanselmann
      ], [
1255 a8e3e009 Michael Hanselmann
      (self.lu.cfg.GetVGName(), "ec0-uq1.disk1_data"),
1256 a8e3e009 Michael Hanselmann
      ("metavg", "ec0-uq1.disk1_meta"),
1257 a8e3e009 Michael Hanselmann
      ], [
1258 a8e3e009 Michael Hanselmann
      ("vgxyz", "ec0-uq2.disk2_data"),
1259 a8e3e009 Michael Hanselmann
      (drbd8_default_metavg, "ec0-uq2.disk2_meta"),
1260 a8e3e009 Michael Hanselmann
      ]]
1261 a8e3e009 Michael Hanselmann
1262 a8e3e009 Michael Hanselmann
    assert len(exp_logical_ids) == len(disk_info)
1263 a8e3e009 Michael Hanselmann
1264 a8e3e009 Michael Hanselmann
    map(lambda params: utils.ForceDictType(params,
1265 a8e3e009 Michael Hanselmann
                                           constants.IDISK_PARAMS_TYPES),
1266 a8e3e009 Michael Hanselmann
        disk_info)
1267 a8e3e009 Michael Hanselmann
1268 a8e3e009 Michael Hanselmann
    # Check if empty list of secondaries is rejected
1269 a8e3e009 Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, gdt, self.lu, constants.DT_DRBD8,
1270 a8e3e009 Michael Hanselmann
                      "inst827.example.com", "node1334.example.com", [],
1271 a8e3e009 Michael Hanselmann
                      disk_info, NotImplemented, NotImplemented, 0,
1272 99ccf8b9 René Nussbaumer
                      self.lu.LogInfo, self.GetDiskParams())
1273 a8e3e009 Michael Hanselmann
1274 a8e3e009 Michael Hanselmann
    result = gdt(self.lu, constants.DT_DRBD8, "inst827.example.com",
1275 a8e3e009 Michael Hanselmann
                 "node1334.example.com", ["node12272.example.com"],
1276 a8e3e009 Michael Hanselmann
                 disk_info, NotImplemented, NotImplemented, 0, self.lu.LogInfo,
1277 99ccf8b9 René Nussbaumer
                 self.GetDiskParams())
1278 a8e3e009 Michael Hanselmann
1279 a8e3e009 Michael Hanselmann
    for (idx, disk) in enumerate(result):
1280 a8e3e009 Michael Hanselmann
      self.assertTrue(isinstance(disk, objects.Disk))
1281 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.dev_type, constants.LD_DRBD8)
1282 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.size, disk_info[idx][constants.IDISK_SIZE])
1283 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.mode, disk_info[idx][constants.IDISK_MODE])
1284 a8e3e009 Michael Hanselmann
1285 a8e3e009 Michael Hanselmann
      for child in disk.children:
1286 a8e3e009 Michael Hanselmann
        self.assertTrue(isinstance(disk, objects.Disk))
1287 a8e3e009 Michael Hanselmann
        self.assertEqual(child.dev_type, constants.LD_LV)
1288 a8e3e009 Michael Hanselmann
        self.assertTrue(child.children is None)
1289 a8e3e009 Michael Hanselmann
1290 a8e3e009 Michael Hanselmann
      self.assertEqual(map(operator.attrgetter("logical_id"), disk.children),
1291 a8e3e009 Michael Hanselmann
                       exp_logical_ids[idx])
1292 a8e3e009 Michael Hanselmann
1293 a8e3e009 Michael Hanselmann
      self.assertEqual(len(disk.children), 2)
1294 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.children[0].size, disk.size)
1295 0c77c331 René Nussbaumer
      self.assertEqual(disk.children[1].size, constants.DRBD_META_SIZE)
1296 a8e3e009 Michael Hanselmann
1297 0356a13d Michael Hanselmann
    self._CheckIvNames(result, 0, len(disk_info))
1298 0356a13d Michael Hanselmann
    cmdlib._UpdateIvNames(0, result)
1299 0356a13d Michael Hanselmann
    self._CheckIvNames(result, 0, len(disk_info))
1300 a8e3e009 Michael Hanselmann
1301 a8e3e009 Michael Hanselmann
    self.assertEqual(map(operator.attrgetter("logical_id"), result), [
1302 a8e3e009 Michael Hanselmann
      ("node1334.example.com", "node12272.example.com",
1303 a8e3e009 Michael Hanselmann
       constants.FIRST_DRBD_PORT, 20, 21, "ec0-secret0"),
1304 a8e3e009 Michael Hanselmann
      ("node1334.example.com", "node12272.example.com",
1305 a8e3e009 Michael Hanselmann
       constants.FIRST_DRBD_PORT + 1, 22, 23, "ec0-secret1"),
1306 a8e3e009 Michael Hanselmann
      ("node1334.example.com", "node12272.example.com",
1307 a8e3e009 Michael Hanselmann
       constants.FIRST_DRBD_PORT + 2, 24, 25, "ec0-secret2"),
1308 a8e3e009 Michael Hanselmann
      ])
1309 a8e3e009 Michael Hanselmann
1310 a8e3e009 Michael Hanselmann
1311 129cce69 Michael Hanselmann
class _ConfigForDiskWipe:
1312 555b6cb1 Michael Hanselmann
  def __init__(self, exp_node):
1313 555b6cb1 Michael Hanselmann
    self._exp_node = exp_node
1314 555b6cb1 Michael Hanselmann
1315 129cce69 Michael Hanselmann
  def SetDiskID(self, device, node):
1316 129cce69 Michael Hanselmann
    assert isinstance(device, objects.Disk)
1317 555b6cb1 Michael Hanselmann
    assert node == self._exp_node
1318 129cce69 Michael Hanselmann
1319 129cce69 Michael Hanselmann
1320 129cce69 Michael Hanselmann
class _RpcForDiskWipe:
1321 555b6cb1 Michael Hanselmann
  def __init__(self, exp_node, pause_cb, wipe_cb):
1322 555b6cb1 Michael Hanselmann
    self._exp_node = exp_node
1323 129cce69 Michael Hanselmann
    self._pause_cb = pause_cb
1324 129cce69 Michael Hanselmann
    self._wipe_cb = wipe_cb
1325 129cce69 Michael Hanselmann
1326 129cce69 Michael Hanselmann
  def call_blockdev_pause_resume_sync(self, node, disks, pause):
1327 555b6cb1 Michael Hanselmann
    assert node == self._exp_node
1328 129cce69 Michael Hanselmann
    return rpc.RpcResult(data=self._pause_cb(disks, pause))
1329 129cce69 Michael Hanselmann
1330 129cce69 Michael Hanselmann
  def call_blockdev_wipe(self, node, bdev, offset, size):
1331 555b6cb1 Michael Hanselmann
    assert node == self._exp_node
1332 129cce69 Michael Hanselmann
    return rpc.RpcResult(data=self._wipe_cb(bdev, offset, size))
1333 129cce69 Michael Hanselmann
1334 129cce69 Michael Hanselmann
1335 129cce69 Michael Hanselmann
class _DiskPauseTracker:
1336 129cce69 Michael Hanselmann
  def __init__(self):
1337 129cce69 Michael Hanselmann
    self.history = []
1338 129cce69 Michael Hanselmann
1339 129cce69 Michael Hanselmann
  def __call__(self, (disks, instance), pause):
1340 fa8ef9d6 Michael Hanselmann
    assert not (set(disks) - set(instance.disks))
1341 129cce69 Michael Hanselmann
1342 129cce69 Michael Hanselmann
    self.history.extend((i.logical_id, i.size, pause)
1343 129cce69 Michael Hanselmann
                        for i in disks)
1344 129cce69 Michael Hanselmann
1345 129cce69 Michael Hanselmann
    return (True, [True] * len(disks))
1346 129cce69 Michael Hanselmann
1347 129cce69 Michael Hanselmann
1348 555b6cb1 Michael Hanselmann
class _DiskWipeProgressTracker:
1349 555b6cb1 Michael Hanselmann
  def __init__(self, start_offset):
1350 555b6cb1 Michael Hanselmann
    self._start_offset = start_offset
1351 555b6cb1 Michael Hanselmann
    self.progress = {}
1352 555b6cb1 Michael Hanselmann
1353 555b6cb1 Michael Hanselmann
  def __call__(self, (disk, _), offset, size):
1354 555b6cb1 Michael Hanselmann
    assert isinstance(offset, (long, int))
1355 555b6cb1 Michael Hanselmann
    assert isinstance(size, (long, int))
1356 555b6cb1 Michael Hanselmann
1357 555b6cb1 Michael Hanselmann
    max_chunk_size = (disk.size / 100.0 * constants.MIN_WIPE_CHUNK_PERCENT)
1358 555b6cb1 Michael Hanselmann
1359 555b6cb1 Michael Hanselmann
    assert offset >= self._start_offset
1360 555b6cb1 Michael Hanselmann
    assert (offset + size) <= disk.size
1361 555b6cb1 Michael Hanselmann
1362 555b6cb1 Michael Hanselmann
    assert size > 0
1363 555b6cb1 Michael Hanselmann
    assert size <= constants.MAX_WIPE_CHUNK
1364 555b6cb1 Michael Hanselmann
    assert size <= max_chunk_size
1365 555b6cb1 Michael Hanselmann
1366 555b6cb1 Michael Hanselmann
    assert offset == self._start_offset or disk.logical_id in self.progress
1367 555b6cb1 Michael Hanselmann
1368 555b6cb1 Michael Hanselmann
    # Keep track of progress
1369 555b6cb1 Michael Hanselmann
    cur_progress = self.progress.setdefault(disk.logical_id, self._start_offset)
1370 555b6cb1 Michael Hanselmann
1371 555b6cb1 Michael Hanselmann
    assert cur_progress == offset
1372 555b6cb1 Michael Hanselmann
1373 555b6cb1 Michael Hanselmann
    # Record progress
1374 555b6cb1 Michael Hanselmann
    self.progress[disk.logical_id] += size
1375 555b6cb1 Michael Hanselmann
1376 555b6cb1 Michael Hanselmann
    return (True, None)
1377 555b6cb1 Michael Hanselmann
1378 555b6cb1 Michael Hanselmann
1379 129cce69 Michael Hanselmann
class TestWipeDisks(unittest.TestCase):
1380 555b6cb1 Michael Hanselmann
  def _FailingPauseCb(self, (disks, _), pause):
1381 555b6cb1 Michael Hanselmann
    self.assertEqual(len(disks), 3)
1382 555b6cb1 Michael Hanselmann
    self.assertTrue(pause)
1383 555b6cb1 Michael Hanselmann
    # Simulate an RPC error
1384 555b6cb1 Michael Hanselmann
    return (False, "error")
1385 555b6cb1 Michael Hanselmann
1386 129cce69 Michael Hanselmann
  def testPauseFailure(self):
1387 555b6cb1 Michael Hanselmann
    node_name = "node1372.example.com"
1388 129cce69 Michael Hanselmann
1389 555b6cb1 Michael Hanselmann
    lu = _FakeLU(rpc=_RpcForDiskWipe(node_name, self._FailingPauseCb,
1390 555b6cb1 Michael Hanselmann
                                     NotImplemented),
1391 555b6cb1 Michael Hanselmann
                 cfg=_ConfigForDiskWipe(node_name))
1392 129cce69 Michael Hanselmann
1393 129cce69 Michael Hanselmann
    disks = [
1394 129cce69 Michael Hanselmann
      objects.Disk(dev_type=constants.LD_LV),
1395 129cce69 Michael Hanselmann
      objects.Disk(dev_type=constants.LD_LV),
1396 129cce69 Michael Hanselmann
      objects.Disk(dev_type=constants.LD_LV),
1397 129cce69 Michael Hanselmann
      ]
1398 129cce69 Michael Hanselmann
1399 129cce69 Michael Hanselmann
    instance = objects.Instance(name="inst21201",
1400 555b6cb1 Michael Hanselmann
                                primary_node=node_name,
1401 129cce69 Michael Hanselmann
                                disk_template=constants.DT_PLAIN,
1402 129cce69 Michael Hanselmann
                                disks=disks)
1403 129cce69 Michael Hanselmann
1404 129cce69 Michael Hanselmann
    self.assertRaises(errors.OpExecError, cmdlib._WipeDisks, lu, instance)
1405 129cce69 Michael Hanselmann
1406 555b6cb1 Michael Hanselmann
  def _FailingWipeCb(self, (disk, _), offset, size):
1407 555b6cb1 Michael Hanselmann
    # This should only ever be called for the first disk
1408 555b6cb1 Michael Hanselmann
    self.assertEqual(disk.logical_id, "disk0")
1409 555b6cb1 Michael Hanselmann
    return (False, None)
1410 555b6cb1 Michael Hanselmann
1411 129cce69 Michael Hanselmann
  def testFailingWipe(self):
1412 555b6cb1 Michael Hanselmann
    node_name = "node13445.example.com"
1413 129cce69 Michael Hanselmann
    pt = _DiskPauseTracker()
1414 129cce69 Michael Hanselmann
1415 555b6cb1 Michael Hanselmann
    lu = _FakeLU(rpc=_RpcForDiskWipe(node_name, pt, self._FailingWipeCb),
1416 555b6cb1 Michael Hanselmann
                 cfg=_ConfigForDiskWipe(node_name))
1417 129cce69 Michael Hanselmann
1418 129cce69 Michael Hanselmann
    disks = [
1419 129cce69 Michael Hanselmann
      objects.Disk(dev_type=constants.LD_LV, logical_id="disk0",
1420 129cce69 Michael Hanselmann
                   size=100 * 1024),
1421 129cce69 Michael Hanselmann
      objects.Disk(dev_type=constants.LD_LV, logical_id="disk1",
1422 129cce69 Michael Hanselmann
                   size=500 * 1024),
1423 129cce69 Michael Hanselmann
      objects.Disk(dev_type=constants.LD_LV, logical_id="disk2", size=256),
1424 129cce69 Michael Hanselmann
      ]
1425 129cce69 Michael Hanselmann
1426 129cce69 Michael Hanselmann
    instance = objects.Instance(name="inst562",
1427 555b6cb1 Michael Hanselmann
                                primary_node=node_name,
1428 129cce69 Michael Hanselmann
                                disk_template=constants.DT_PLAIN,
1429 129cce69 Michael Hanselmann
                                disks=disks)
1430 129cce69 Michael Hanselmann
1431 129cce69 Michael Hanselmann
    try:
1432 129cce69 Michael Hanselmann
      cmdlib._WipeDisks(lu, instance)
1433 129cce69 Michael Hanselmann
    except errors.OpExecError, err:
1434 129cce69 Michael Hanselmann
      self.assertTrue(str(err), "Could not wipe disk 0 at offset 0 ")
1435 129cce69 Michael Hanselmann
    else:
1436 129cce69 Michael Hanselmann
      self.fail("Did not raise exception")
1437 129cce69 Michael Hanselmann
1438 555b6cb1 Michael Hanselmann
    # Check if all disks were paused and resumed
1439 129cce69 Michael Hanselmann
    self.assertEqual(pt.history, [
1440 129cce69 Michael Hanselmann
      ("disk0", 100 * 1024, True),
1441 129cce69 Michael Hanselmann
      ("disk1", 500 * 1024, True),
1442 129cce69 Michael Hanselmann
      ("disk2", 256, True),
1443 129cce69 Michael Hanselmann
      ("disk0", 100 * 1024, False),
1444 129cce69 Michael Hanselmann
      ("disk1", 500 * 1024, False),
1445 129cce69 Michael Hanselmann
      ("disk2", 256, False),
1446 129cce69 Michael Hanselmann
      ])
1447 129cce69 Michael Hanselmann
1448 555b6cb1 Michael Hanselmann
  def _PrepareWipeTest(self, start_offset, disks):
1449 555b6cb1 Michael Hanselmann
    node_name = "node-with-offset%s.example.com" % start_offset
1450 555b6cb1 Michael Hanselmann
    pauset = _DiskPauseTracker()
1451 555b6cb1 Michael Hanselmann
    progresst = _DiskWipeProgressTracker(start_offset)
1452 129cce69 Michael Hanselmann
1453 555b6cb1 Michael Hanselmann
    lu = _FakeLU(rpc=_RpcForDiskWipe(node_name, pauset, progresst),
1454 555b6cb1 Michael Hanselmann
                 cfg=_ConfigForDiskWipe(node_name))
1455 129cce69 Michael Hanselmann
1456 555b6cb1 Michael Hanselmann
    instance = objects.Instance(name="inst3560",
1457 555b6cb1 Michael Hanselmann
                                primary_node=node_name,
1458 555b6cb1 Michael Hanselmann
                                disk_template=constants.DT_PLAIN,
1459 555b6cb1 Michael Hanselmann
                                disks=disks)
1460 129cce69 Michael Hanselmann
1461 555b6cb1 Michael Hanselmann
    return (lu, instance, pauset, progresst)
1462 555b6cb1 Michael Hanselmann
1463 555b6cb1 Michael Hanselmann
  def testNormalWipe(self):
1464 555b6cb1 Michael Hanselmann
    disks = [
1465 555b6cb1 Michael Hanselmann
      objects.Disk(dev_type=constants.LD_LV, logical_id="disk0", size=1024),
1466 555b6cb1 Michael Hanselmann
      objects.Disk(dev_type=constants.LD_LV, logical_id="disk1",
1467 555b6cb1 Michael Hanselmann
                   size=500 * 1024),
1468 555b6cb1 Michael Hanselmann
      objects.Disk(dev_type=constants.LD_LV, logical_id="disk2", size=128),
1469 555b6cb1 Michael Hanselmann
      objects.Disk(dev_type=constants.LD_LV, logical_id="disk3",
1470 555b6cb1 Michael Hanselmann
                   size=constants.MAX_WIPE_CHUNK),
1471 555b6cb1 Michael Hanselmann
      ]
1472 129cce69 Michael Hanselmann
1473 555b6cb1 Michael Hanselmann
    (lu, instance, pauset, progresst) = self._PrepareWipeTest(0, disks)
1474 129cce69 Michael Hanselmann
1475 555b6cb1 Michael Hanselmann
    cmdlib._WipeDisks(lu, instance)
1476 129cce69 Michael Hanselmann
1477 555b6cb1 Michael Hanselmann
    self.assertEqual(pauset.history, [
1478 555b6cb1 Michael Hanselmann
      ("disk0", 1024, True),
1479 555b6cb1 Michael Hanselmann
      ("disk1", 500 * 1024, True),
1480 555b6cb1 Michael Hanselmann
      ("disk2", 128, True),
1481 555b6cb1 Michael Hanselmann
      ("disk3", constants.MAX_WIPE_CHUNK, True),
1482 555b6cb1 Michael Hanselmann
      ("disk0", 1024, False),
1483 555b6cb1 Michael Hanselmann
      ("disk1", 500 * 1024, False),
1484 555b6cb1 Michael Hanselmann
      ("disk2", 128, False),
1485 555b6cb1 Michael Hanselmann
      ("disk3", constants.MAX_WIPE_CHUNK, False),
1486 555b6cb1 Michael Hanselmann
      ])
1487 129cce69 Michael Hanselmann
1488 555b6cb1 Michael Hanselmann
    # Ensure the complete disk has been wiped
1489 555b6cb1 Michael Hanselmann
    self.assertEqual(progresst.progress,
1490 555b6cb1 Michael Hanselmann
                     dict((i.logical_id, i.size) for i in disks))
1491 129cce69 Michael Hanselmann
1492 555b6cb1 Michael Hanselmann
  def testWipeWithStartOffset(self):
1493 555b6cb1 Michael Hanselmann
    for start_offset in [0, 280, 8895, 1563204]:
1494 555b6cb1 Michael Hanselmann
      disks = [
1495 555b6cb1 Michael Hanselmann
        objects.Disk(dev_type=constants.LD_LV, logical_id="disk0",
1496 555b6cb1 Michael Hanselmann
                     size=128),
1497 555b6cb1 Michael Hanselmann
        objects.Disk(dev_type=constants.LD_LV, logical_id="disk1",
1498 555b6cb1 Michael Hanselmann
                     size=start_offset + (100 * 1024)),
1499 555b6cb1 Michael Hanselmann
        ]
1500 129cce69 Michael Hanselmann
1501 555b6cb1 Michael Hanselmann
      (lu, instance, pauset, progresst) = \
1502 555b6cb1 Michael Hanselmann
        self._PrepareWipeTest(start_offset, disks)
1503 129cce69 Michael Hanselmann
1504 555b6cb1 Michael Hanselmann
      # Test start offset with only one disk
1505 555b6cb1 Michael Hanselmann
      cmdlib._WipeDisks(lu, instance,
1506 555b6cb1 Michael Hanselmann
                        disks=[(1, disks[1], start_offset)])
1507 129cce69 Michael Hanselmann
1508 555b6cb1 Michael Hanselmann
      # Only the second disk may have been paused and wiped
1509 555b6cb1 Michael Hanselmann
      self.assertEqual(pauset.history, [
1510 555b6cb1 Michael Hanselmann
        ("disk1", start_offset + (100 * 1024), True),
1511 555b6cb1 Michael Hanselmann
        ("disk1", start_offset + (100 * 1024), False),
1512 555b6cb1 Michael Hanselmann
        ])
1513 555b6cb1 Michael Hanselmann
      self.assertEqual(progresst.progress, {
1514 555b6cb1 Michael Hanselmann
        "disk1": disks[1].size,
1515 555b6cb1 Michael Hanselmann
        })
1516 fa8ef9d6 Michael Hanselmann
1517 fa8ef9d6 Michael Hanselmann
1518 fa8ef9d6 Michael Hanselmann
class TestDiskSizeInBytesToMebibytes(unittest.TestCase):
1519 fa8ef9d6 Michael Hanselmann
  def testLessThanOneMebibyte(self):
1520 fa8ef9d6 Michael Hanselmann
    for i in [1, 2, 7, 512, 1000, 1023]:
1521 fa8ef9d6 Michael Hanselmann
      lu = _FakeLU()
1522 fa8ef9d6 Michael Hanselmann
      result = cmdlib._DiskSizeInBytesToMebibytes(lu, i)
1523 fa8ef9d6 Michael Hanselmann
      self.assertEqual(result, 1)
1524 fa8ef9d6 Michael Hanselmann
      self.assertEqual(len(lu.warning_log), 1)
1525 fa8ef9d6 Michael Hanselmann
      self.assertEqual(len(lu.warning_log[0]), 2)
1526 fa8ef9d6 Michael Hanselmann
      (_, (warnsize, )) = lu.warning_log[0]
1527 fa8ef9d6 Michael Hanselmann
      self.assertEqual(warnsize, (1024 * 1024) - i)
1528 fa8ef9d6 Michael Hanselmann
1529 fa8ef9d6 Michael Hanselmann
  def testEven(self):
1530 fa8ef9d6 Michael Hanselmann
    for i in [1, 2, 7, 512, 1000, 1023]:
1531 fa8ef9d6 Michael Hanselmann
      lu = _FakeLU()
1532 fa8ef9d6 Michael Hanselmann
      result = cmdlib._DiskSizeInBytesToMebibytes(lu, i * 1024 * 1024)
1533 fa8ef9d6 Michael Hanselmann
      self.assertEqual(result, i)
1534 fa8ef9d6 Michael Hanselmann
      self.assertFalse(lu.warning_log)
1535 fa8ef9d6 Michael Hanselmann
1536 fa8ef9d6 Michael Hanselmann
  def testLargeNumber(self):
1537 fa8ef9d6 Michael Hanselmann
    for i in [1, 2, 7, 512, 1000, 1023, 2724, 12420]:
1538 fa8ef9d6 Michael Hanselmann
      for j in [1, 2, 486, 326, 986, 1023]:
1539 fa8ef9d6 Michael Hanselmann
        lu = _FakeLU()
1540 fa8ef9d6 Michael Hanselmann
        size = (1024 * 1024 * i) + j
1541 fa8ef9d6 Michael Hanselmann
        result = cmdlib._DiskSizeInBytesToMebibytes(lu, size)
1542 fa8ef9d6 Michael Hanselmann
        self.assertEqual(result, i + 1, msg="Amount was not rounded up")
1543 fa8ef9d6 Michael Hanselmann
        self.assertEqual(len(lu.warning_log), 1)
1544 fa8ef9d6 Michael Hanselmann
        self.assertEqual(len(lu.warning_log[0]), 2)
1545 fa8ef9d6 Michael Hanselmann
        (_, (warnsize, )) = lu.warning_log[0]
1546 fa8ef9d6 Michael Hanselmann
        self.assertEqual(warnsize, (1024 * 1024) - j)
1547 129cce69 Michael Hanselmann
1548 129cce69 Michael Hanselmann
1549 ef86bf28 Michael Hanselmann
class TestCopyLockList(unittest.TestCase):
1550 ef86bf28 Michael Hanselmann
  def test(self):
1551 ef86bf28 Michael Hanselmann
    self.assertEqual(cmdlib._CopyLockList([]), [])
1552 ef86bf28 Michael Hanselmann
    self.assertEqual(cmdlib._CopyLockList(None), None)
1553 ef86bf28 Michael Hanselmann
    self.assertEqual(cmdlib._CopyLockList(locking.ALL_SET), locking.ALL_SET)
1554 ef86bf28 Michael Hanselmann
1555 ef86bf28 Michael Hanselmann
    names = ["foo", "bar"]
1556 ef86bf28 Michael Hanselmann
    output = cmdlib._CopyLockList(names)
1557 ef86bf28 Michael Hanselmann
    self.assertEqual(names, output)
1558 ef86bf28 Michael Hanselmann
    self.assertNotEqual(id(names), id(output), msg="List was not copied")
1559 ef86bf28 Michael Hanselmann
1560 ef86bf28 Michael Hanselmann
1561 cfa79a23 Michael Hanselmann
class TestCheckOpportunisticLocking(unittest.TestCase):
1562 cfa79a23 Michael Hanselmann
  class OpTest(opcodes.OpCode):
1563 cfa79a23 Michael Hanselmann
    OP_PARAMS = [
1564 cfa79a23 Michael Hanselmann
      opcodes._POpportunisticLocking,
1565 cfa79a23 Michael Hanselmann
      opcodes._PIAllocFromDesc(""),
1566 cfa79a23 Michael Hanselmann
      ]
1567 cfa79a23 Michael Hanselmann
1568 cfa79a23 Michael Hanselmann
  @classmethod
1569 cfa79a23 Michael Hanselmann
  def _MakeOp(cls, **kwargs):
1570 cfa79a23 Michael Hanselmann
    op = cls.OpTest(**kwargs)
1571 cfa79a23 Michael Hanselmann
    op.Validate(True)
1572 cfa79a23 Michael Hanselmann
    return op
1573 cfa79a23 Michael Hanselmann
1574 cfa79a23 Michael Hanselmann
  def testMissingAttributes(self):
1575 cfa79a23 Michael Hanselmann
    self.assertRaises(AttributeError, cmdlib._CheckOpportunisticLocking,
1576 cfa79a23 Michael Hanselmann
                      object())
1577 cfa79a23 Michael Hanselmann
1578 cfa79a23 Michael Hanselmann
  def testDefaults(self):
1579 cfa79a23 Michael Hanselmann
    op = self._MakeOp()
1580 cfa79a23 Michael Hanselmann
    cmdlib._CheckOpportunisticLocking(op)
1581 cfa79a23 Michael Hanselmann
1582 cfa79a23 Michael Hanselmann
  def test(self):
1583 cfa79a23 Michael Hanselmann
    for iallocator in [None, "something", "other"]:
1584 cfa79a23 Michael Hanselmann
      for opplock in [False, True]:
1585 cfa79a23 Michael Hanselmann
        op = self._MakeOp(iallocator=iallocator, opportunistic_locking=opplock)
1586 cfa79a23 Michael Hanselmann
        if opplock and not iallocator:
1587 cfa79a23 Michael Hanselmann
          self.assertRaises(errors.OpPrereqError,
1588 cfa79a23 Michael Hanselmann
                            cmdlib._CheckOpportunisticLocking, op)
1589 cfa79a23 Michael Hanselmann
        else:
1590 cfa79a23 Michael Hanselmann
          cmdlib._CheckOpportunisticLocking(op)
1591 cfa79a23 Michael Hanselmann
1592 cfa79a23 Michael Hanselmann
1593 8bb2df7d Bernardo Dal Seno
class _OpTestVerifyErrors(opcodes.OpCode):
1594 8bb2df7d Bernardo Dal Seno
  OP_PARAMS = [
1595 8bb2df7d Bernardo Dal Seno
    opcodes._PDebugSimulateErrors,
1596 8bb2df7d Bernardo Dal Seno
    opcodes._PErrorCodes,
1597 8bb2df7d Bernardo Dal Seno
    opcodes._PIgnoreErrors,
1598 8bb2df7d Bernardo Dal Seno
    ]
1599 8bb2df7d Bernardo Dal Seno
1600 8bb2df7d Bernardo Dal Seno
1601 8bb2df7d Bernardo Dal Seno
class _LuTestVerifyErrors(cmdlib._VerifyErrors):
1602 8bb2df7d Bernardo Dal Seno
  def __init__(self, **kwargs):
1603 8bb2df7d Bernardo Dal Seno
    cmdlib._VerifyErrors.__init__(self)
1604 8bb2df7d Bernardo Dal Seno
    self.op = _OpTestVerifyErrors(**kwargs)
1605 8bb2df7d Bernardo Dal Seno
    self.op.Validate(True)
1606 8bb2df7d Bernardo Dal Seno
    self.msglist = []
1607 8bb2df7d Bernardo Dal Seno
    self._feedback_fn = self.msglist.append
1608 8bb2df7d Bernardo Dal Seno
    self.bad = False
1609 8bb2df7d Bernardo Dal Seno
1610 8bb2df7d Bernardo Dal Seno
  def DispatchCallError(self, which, *args, **kwargs):
1611 8bb2df7d Bernardo Dal Seno
    if which:
1612 8bb2df7d Bernardo Dal Seno
      self._Error(*args, **kwargs)
1613 8bb2df7d Bernardo Dal Seno
    else:
1614 8bb2df7d Bernardo Dal Seno
      self._ErrorIf(True, *args, **kwargs)
1615 8bb2df7d Bernardo Dal Seno
1616 8bb2df7d Bernardo Dal Seno
  def CallErrorIf(self, c, *args, **kwargs):
1617 8bb2df7d Bernardo Dal Seno
    self._ErrorIf(c, *args, **kwargs)
1618 8bb2df7d Bernardo Dal Seno
1619 8bb2df7d Bernardo Dal Seno
1620 8bb2df7d Bernardo Dal Seno
class TestVerifyErrors(unittest.TestCase):
1621 8bb2df7d Bernardo Dal Seno
  # Fake cluster-verify error code structures; we use two arbitary real error
1622 8bb2df7d Bernardo Dal Seno
  # codes to pass validation of ignore_errors
1623 8bb2df7d Bernardo Dal Seno
  (_, _ERR1ID, _) = constants.CV_ECLUSTERCFG
1624 8bb2df7d Bernardo Dal Seno
  _NODESTR = "node"
1625 8bb2df7d Bernardo Dal Seno
  _NODENAME = "mynode"
1626 8bb2df7d Bernardo Dal Seno
  _ERR1CODE = (_NODESTR, _ERR1ID, "Error one")
1627 8bb2df7d Bernardo Dal Seno
  (_, _ERR2ID, _) = constants.CV_ECLUSTERCERT
1628 8bb2df7d Bernardo Dal Seno
  _INSTSTR = "instance"
1629 8bb2df7d Bernardo Dal Seno
  _INSTNAME = "myinstance"
1630 8bb2df7d Bernardo Dal Seno
  _ERR2CODE = (_INSTSTR, _ERR2ID, "Error two")
1631 8bb2df7d Bernardo Dal Seno
  # Arguments used to call _Error() or _ErrorIf()
1632 8bb2df7d Bernardo Dal Seno
  _ERR1ARGS = (_ERR1CODE, _NODENAME, "Error1 is %s", "an error")
1633 8bb2df7d Bernardo Dal Seno
  _ERR2ARGS = (_ERR2CODE, _INSTNAME, "Error2 has no argument")
1634 8bb2df7d Bernardo Dal Seno
  # Expected error messages
1635 8bb2df7d Bernardo Dal Seno
  _ERR1MSG = _ERR1ARGS[2] % _ERR1ARGS[3]
1636 8bb2df7d Bernardo Dal Seno
  _ERR2MSG = _ERR2ARGS[2]
1637 8bb2df7d Bernardo Dal Seno
1638 8bb2df7d Bernardo Dal Seno
  def testNoError(self):
1639 8bb2df7d Bernardo Dal Seno
    lu = _LuTestVerifyErrors()
1640 8bb2df7d Bernardo Dal Seno
    lu.CallErrorIf(False, self._ERR1CODE, *self._ERR1ARGS)
1641 8bb2df7d Bernardo Dal Seno
    self.assertFalse(lu.bad)
1642 8bb2df7d Bernardo Dal Seno
    self.assertFalse(lu.msglist)
1643 8bb2df7d Bernardo Dal Seno
1644 8bb2df7d Bernardo Dal Seno
  def _InitTest(self, **kwargs):
1645 8bb2df7d Bernardo Dal Seno
    self.lu1 = _LuTestVerifyErrors(**kwargs)
1646 8bb2df7d Bernardo Dal Seno
    self.lu2 = _LuTestVerifyErrors(**kwargs)
1647 8bb2df7d Bernardo Dal Seno
1648 8bb2df7d Bernardo Dal Seno
  def _CallError(self, *args, **kwargs):
1649 8bb2df7d Bernardo Dal Seno
    # Check that _Error() and _ErrorIf() produce the same results
1650 8bb2df7d Bernardo Dal Seno
    self.lu1.DispatchCallError(True, *args, **kwargs)
1651 8bb2df7d Bernardo Dal Seno
    self.lu2.DispatchCallError(False, *args, **kwargs)
1652 8bb2df7d Bernardo Dal Seno
    self.assertEqual(self.lu1.bad, self.lu2.bad)
1653 8bb2df7d Bernardo Dal Seno
    self.assertEqual(self.lu1.msglist, self.lu2.msglist)
1654 8bb2df7d Bernardo Dal Seno
    # Test-specific checks are made on one LU
1655 8bb2df7d Bernardo Dal Seno
    return self.lu1
1656 8bb2df7d Bernardo Dal Seno
1657 8bb2df7d Bernardo Dal Seno
  def _checkMsgCommon(self, logstr, errmsg, itype, item, warning):
1658 8bb2df7d Bernardo Dal Seno
    self.assertTrue(errmsg in logstr)
1659 8bb2df7d Bernardo Dal Seno
    if warning:
1660 8bb2df7d Bernardo Dal Seno
      self.assertTrue("WARNING" in logstr)
1661 8bb2df7d Bernardo Dal Seno
    else:
1662 8bb2df7d Bernardo Dal Seno
      self.assertTrue("ERROR" in logstr)
1663 8bb2df7d Bernardo Dal Seno
    self.assertTrue(itype in logstr)
1664 8bb2df7d Bernardo Dal Seno
    self.assertTrue(item in logstr)
1665 8bb2df7d Bernardo Dal Seno
1666 8bb2df7d Bernardo Dal Seno
  def _checkMsg1(self, logstr, warning=False):
1667 8bb2df7d Bernardo Dal Seno
    self._checkMsgCommon(logstr, self._ERR1MSG, self._NODESTR,
1668 8bb2df7d Bernardo Dal Seno
                         self._NODENAME, warning)
1669 8bb2df7d Bernardo Dal Seno
1670 8bb2df7d Bernardo Dal Seno
  def _checkMsg2(self, logstr, warning=False):
1671 8bb2df7d Bernardo Dal Seno
    self._checkMsgCommon(logstr, self._ERR2MSG, self._INSTSTR,
1672 8bb2df7d Bernardo Dal Seno
                         self._INSTNAME, warning)
1673 8bb2df7d Bernardo Dal Seno
1674 8bb2df7d Bernardo Dal Seno
  def testPlain(self):
1675 8bb2df7d Bernardo Dal Seno
    self._InitTest()
1676 8bb2df7d Bernardo Dal Seno
    lu = self._CallError(*self._ERR1ARGS)
1677 8bb2df7d Bernardo Dal Seno
    self.assertTrue(lu.bad)
1678 8bb2df7d Bernardo Dal Seno
    self.assertEqual(len(lu.msglist), 1)
1679 8bb2df7d Bernardo Dal Seno
    self._checkMsg1(lu.msglist[0])
1680 8bb2df7d Bernardo Dal Seno
1681 8bb2df7d Bernardo Dal Seno
  def testMultiple(self):
1682 8bb2df7d Bernardo Dal Seno
    self._InitTest()
1683 8bb2df7d Bernardo Dal Seno
    self._CallError(*self._ERR1ARGS)
1684 8bb2df7d Bernardo Dal Seno
    lu = self._CallError(*self._ERR2ARGS)
1685 8bb2df7d Bernardo Dal Seno
    self.assertTrue(lu.bad)
1686 8bb2df7d Bernardo Dal Seno
    self.assertEqual(len(lu.msglist), 2)
1687 8bb2df7d Bernardo Dal Seno
    self._checkMsg1(lu.msglist[0])
1688 8bb2df7d Bernardo Dal Seno
    self._checkMsg2(lu.msglist[1])
1689 8bb2df7d Bernardo Dal Seno
1690 8bb2df7d Bernardo Dal Seno
  def testIgnore(self):
1691 8bb2df7d Bernardo Dal Seno
    self._InitTest(ignore_errors=[self._ERR1ID])
1692 8bb2df7d Bernardo Dal Seno
    lu = self._CallError(*self._ERR1ARGS)
1693 8bb2df7d Bernardo Dal Seno
    self.assertFalse(lu.bad)
1694 8bb2df7d Bernardo Dal Seno
    self.assertEqual(len(lu.msglist), 1)
1695 8bb2df7d Bernardo Dal Seno
    self._checkMsg1(lu.msglist[0], warning=True)
1696 8bb2df7d Bernardo Dal Seno
1697 8bb2df7d Bernardo Dal Seno
  def testWarning(self):
1698 8bb2df7d Bernardo Dal Seno
    self._InitTest()
1699 8bb2df7d Bernardo Dal Seno
    lu = self._CallError(*self._ERR1ARGS,
1700 8bb2df7d Bernardo Dal Seno
                         code=_LuTestVerifyErrors.ETYPE_WARNING)
1701 8bb2df7d Bernardo Dal Seno
    self.assertFalse(lu.bad)
1702 8bb2df7d Bernardo Dal Seno
    self.assertEqual(len(lu.msglist), 1)
1703 8bb2df7d Bernardo Dal Seno
    self._checkMsg1(lu.msglist[0], warning=True)
1704 8bb2df7d Bernardo Dal Seno
1705 8bb2df7d Bernardo Dal Seno
  def testWarning2(self):
1706 8bb2df7d Bernardo Dal Seno
    self._InitTest()
1707 8bb2df7d Bernardo Dal Seno
    self._CallError(*self._ERR1ARGS)
1708 8bb2df7d Bernardo Dal Seno
    lu = self._CallError(*self._ERR2ARGS,
1709 8bb2df7d Bernardo Dal Seno
                         code=_LuTestVerifyErrors.ETYPE_WARNING)
1710 8bb2df7d Bernardo Dal Seno
    self.assertTrue(lu.bad)
1711 8bb2df7d Bernardo Dal Seno
    self.assertEqual(len(lu.msglist), 2)
1712 8bb2df7d Bernardo Dal Seno
    self._checkMsg1(lu.msglist[0])
1713 8bb2df7d Bernardo Dal Seno
    self._checkMsg2(lu.msglist[1], warning=True)
1714 8bb2df7d Bernardo Dal Seno
1715 8bb2df7d Bernardo Dal Seno
  def testDebugSimulate(self):
1716 8bb2df7d Bernardo Dal Seno
    lu = _LuTestVerifyErrors(debug_simulate_errors=True)
1717 8bb2df7d Bernardo Dal Seno
    lu.CallErrorIf(False, *self._ERR1ARGS)
1718 8bb2df7d Bernardo Dal Seno
    self.assertTrue(lu.bad)
1719 8bb2df7d Bernardo Dal Seno
    self.assertEqual(len(lu.msglist), 1)
1720 8bb2df7d Bernardo Dal Seno
    self._checkMsg1(lu.msglist[0])
1721 8bb2df7d Bernardo Dal Seno
1722 8bb2df7d Bernardo Dal Seno
  def testErrCodes(self):
1723 8bb2df7d Bernardo Dal Seno
    self._InitTest(error_codes=True)
1724 8bb2df7d Bernardo Dal Seno
    lu = self._CallError(*self._ERR1ARGS)
1725 8bb2df7d Bernardo Dal Seno
    self.assertTrue(lu.bad)
1726 8bb2df7d Bernardo Dal Seno
    self.assertEqual(len(lu.msglist), 1)
1727 8bb2df7d Bernardo Dal Seno
    self._checkMsg1(lu.msglist[0])
1728 8bb2df7d Bernardo Dal Seno
    self.assertTrue(self._ERR1ID in lu.msglist[0])
1729 8bb2df7d Bernardo Dal Seno
1730 8bb2df7d Bernardo Dal Seno
1731 5dd7d15b Bernardo Dal Seno
class TestGetUpdatedIPolicy(unittest.TestCase):
1732 5dd7d15b Bernardo Dal Seno
  """Tests for cmdlib._GetUpdatedIPolicy()"""
1733 5dd7d15b Bernardo Dal Seno
  _OLD_CLUSTER_POLICY = {
1734 5dd7d15b Bernardo Dal Seno
    constants.IPOLICY_VCPU_RATIO: 1.5,
1735 5dd7d15b Bernardo Dal Seno
    constants.ISPECS_MIN: {
1736 5dd7d15b Bernardo Dal Seno
      constants.ISPEC_MEM_SIZE: 20,
1737 5dd7d15b Bernardo Dal Seno
      constants.ISPEC_CPU_COUNT: 2,
1738 5dd7d15b Bernardo Dal Seno
      },
1739 5dd7d15b Bernardo Dal Seno
    constants.ISPECS_MAX: {},
1740 5dd7d15b Bernardo Dal Seno
    constants.ISPECS_STD: {},
1741 5dd7d15b Bernardo Dal Seno
    }
1742 5dd7d15b Bernardo Dal Seno
1743 5dd7d15b Bernardo Dal Seno
  _OLD_GROUP_POLICY = {
1744 5dd7d15b Bernardo Dal Seno
    constants.IPOLICY_SPINDLE_RATIO: 2.5,
1745 5dd7d15b Bernardo Dal Seno
    constants.ISPECS_MIN: {
1746 5dd7d15b Bernardo Dal Seno
      constants.ISPEC_DISK_SIZE: 20,
1747 5dd7d15b Bernardo Dal Seno
      constants.ISPEC_NIC_COUNT: 2,
1748 5dd7d15b Bernardo Dal Seno
      },
1749 5dd7d15b Bernardo Dal Seno
    constants.ISPECS_MAX: {},
1750 5dd7d15b Bernardo Dal Seno
    }
1751 5dd7d15b Bernardo Dal Seno
1752 5dd7d15b Bernardo Dal Seno
  def _TestSetSpecs(self, old_policy, isgroup):
1753 5dd7d15b Bernardo Dal Seno
    ispec_key = constants.ISPECS_MIN
1754 5dd7d15b Bernardo Dal Seno
    diff_ispec = {
1755 5dd7d15b Bernardo Dal Seno
      constants.ISPEC_MEM_SIZE: 50,
1756 5dd7d15b Bernardo Dal Seno
      constants.ISPEC_DISK_SIZE: 30,
1757 5dd7d15b Bernardo Dal Seno
      }
1758 5dd7d15b Bernardo Dal Seno
    diff_policy = {
1759 5dd7d15b Bernardo Dal Seno
      ispec_key: diff_ispec
1760 5dd7d15b Bernardo Dal Seno
      }
1761 5dd7d15b Bernardo Dal Seno
    new_policy = cmdlib._GetUpdatedIPolicy(old_policy, diff_policy,
1762 5dd7d15b Bernardo Dal Seno
                                           group_policy=isgroup)
1763 5dd7d15b Bernardo Dal Seno
    new_ispec = new_policy[ispec_key]
1764 5dd7d15b Bernardo Dal Seno
    for key in diff_ispec:
1765 5dd7d15b Bernardo Dal Seno
      self.assertTrue(key in new_ispec)
1766 5dd7d15b Bernardo Dal Seno
      self.assertEqual(new_ispec[key], diff_ispec[key])
1767 5dd7d15b Bernardo Dal Seno
    for key in old_policy:
1768 5dd7d15b Bernardo Dal Seno
      if not key in diff_policy:
1769 5dd7d15b Bernardo Dal Seno
        self.assertTrue(key in new_policy)
1770 5dd7d15b Bernardo Dal Seno
        self.assertEqual(new_policy[key], old_policy[key])
1771 5dd7d15b Bernardo Dal Seno
    old_ispec = old_policy[ispec_key]
1772 5dd7d15b Bernardo Dal Seno
    for key in old_ispec:
1773 5dd7d15b Bernardo Dal Seno
      if not key in diff_ispec:
1774 5dd7d15b Bernardo Dal Seno
        self.assertTrue(key in new_ispec)
1775 5dd7d15b Bernardo Dal Seno
        self.assertEqual(new_ispec[key], old_ispec[key])
1776 5dd7d15b Bernardo Dal Seno
1777 5dd7d15b Bernardo Dal Seno
  def _TestSet(self, old_policy, isgroup):
1778 5dd7d15b Bernardo Dal Seno
    diff_policy = {
1779 5dd7d15b Bernardo Dal Seno
      constants.IPOLICY_VCPU_RATIO: 3,
1780 5dd7d15b Bernardo Dal Seno
      constants.IPOLICY_SPINDLE_RATIO: 1.9,
1781 5dd7d15b Bernardo Dal Seno
      }
1782 5dd7d15b Bernardo Dal Seno
    new_policy = cmdlib._GetUpdatedIPolicy(old_policy, diff_policy,
1783 5dd7d15b Bernardo Dal Seno
                                           group_policy=isgroup)
1784 5dd7d15b Bernardo Dal Seno
    for key in diff_policy:
1785 5dd7d15b Bernardo Dal Seno
      self.assertTrue(key in new_policy)
1786 5dd7d15b Bernardo Dal Seno
      self.assertEqual(new_policy[key], diff_policy[key])
1787 5dd7d15b Bernardo Dal Seno
    for key in old_policy:
1788 5dd7d15b Bernardo Dal Seno
      if not key in diff_policy:
1789 5dd7d15b Bernardo Dal Seno
        self.assertTrue(key in new_policy)
1790 5dd7d15b Bernardo Dal Seno
        self.assertEqual(new_policy[key], old_policy[key])
1791 5dd7d15b Bernardo Dal Seno
1792 5dd7d15b Bernardo Dal Seno
  def testSet(self):
1793 5dd7d15b Bernardo Dal Seno
    self._TestSet(self._OLD_GROUP_POLICY, True)
1794 5dd7d15b Bernardo Dal Seno
    self._TestSetSpecs(self._OLD_GROUP_POLICY, True)
1795 5dd7d15b Bernardo Dal Seno
    self._TestSet(self._OLD_CLUSTER_POLICY, False)
1796 5dd7d15b Bernardo Dal Seno
    self._TestSetSpecs(self._OLD_CLUSTER_POLICY, False)
1797 5dd7d15b Bernardo Dal Seno
1798 5dd7d15b Bernardo Dal Seno
  def testUnset(self):
1799 5dd7d15b Bernardo Dal Seno
    old_policy = self._OLD_GROUP_POLICY
1800 5dd7d15b Bernardo Dal Seno
    diff_policy = {
1801 5dd7d15b Bernardo Dal Seno
      constants.IPOLICY_SPINDLE_RATIO: constants.VALUE_DEFAULT,
1802 5dd7d15b Bernardo Dal Seno
      }
1803 5dd7d15b Bernardo Dal Seno
    new_policy = cmdlib._GetUpdatedIPolicy(old_policy, diff_policy,
1804 5dd7d15b Bernardo Dal Seno
                                           group_policy=True)
1805 5dd7d15b Bernardo Dal Seno
    for key in diff_policy:
1806 5dd7d15b Bernardo Dal Seno
      self.assertFalse(key in new_policy)
1807 5dd7d15b Bernardo Dal Seno
    for key in old_policy:
1808 5dd7d15b Bernardo Dal Seno
      if not key in diff_policy:
1809 5dd7d15b Bernardo Dal Seno
        self.assertTrue(key in new_policy)
1810 5dd7d15b Bernardo Dal Seno
        self.assertEqual(new_policy[key], old_policy[key])
1811 5dd7d15b Bernardo Dal Seno
1812 5dd7d15b Bernardo Dal Seno
  def _TestInvalidKeys(self, old_policy, isgroup):
1813 5dd7d15b Bernardo Dal Seno
    INVALID_DICT = {
1814 5dd7d15b Bernardo Dal Seno
      "this_key_shouldnt_be_allowed": 3,
1815 5dd7d15b Bernardo Dal Seno
      }
1816 5dd7d15b Bernardo Dal Seno
    invalid_policy = INVALID_DICT
1817 5dd7d15b Bernardo Dal Seno
    self.assertRaises(errors.OpPrereqError, cmdlib._GetUpdatedIPolicy,
1818 5dd7d15b Bernardo Dal Seno
                      old_policy, invalid_policy, group_policy=isgroup)
1819 5dd7d15b Bernardo Dal Seno
    for key in constants.IPOLICY_ISPECS:
1820 5dd7d15b Bernardo Dal Seno
      invalid_ispec = {
1821 5dd7d15b Bernardo Dal Seno
        key: INVALID_DICT,
1822 5dd7d15b Bernardo Dal Seno
        }
1823 5dd7d15b Bernardo Dal Seno
      self.assertRaises(errors.TypeEnforcementError, cmdlib._GetUpdatedIPolicy,
1824 5dd7d15b Bernardo Dal Seno
                        old_policy, invalid_ispec, group_policy=isgroup)
1825 5dd7d15b Bernardo Dal Seno
1826 5dd7d15b Bernardo Dal Seno
  def testInvalidKeys(self):
1827 5dd7d15b Bernardo Dal Seno
    self._TestInvalidKeys(self._OLD_GROUP_POLICY, True)
1828 5dd7d15b Bernardo Dal Seno
    self._TestInvalidKeys(self._OLD_CLUSTER_POLICY, False)
1829 5dd7d15b Bernardo Dal Seno
1830 5dd7d15b Bernardo Dal Seno
1831 b98bf262 Michael Hanselmann
if __name__ == "__main__":
1832 25231ec5 Michael Hanselmann
  testutils.GanetiTestProgram()