Statistics
| Branch: | Tag: | Revision:

root / test / py / cmdlib / cmdlib_unittest.py @ b02063fe

History | View | Annotate | Download (34.4 kB)

1 6de7c41d Iustin Pop
#!/usr/bin/python
2 6de7c41d Iustin Pop
#
3 6de7c41d Iustin Pop
4 da5f09ef Bernardo Dal Seno
# Copyright (C) 2008, 2011, 2012, 2013 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 unittest
26 64c7b383 Michael Hanselmann
import operator
27 d755483c Michael Hanselmann
import itertools
28 99ccf8b9 René Nussbaumer
import copy
29 6de7c41d Iustin Pop
30 83f72637 Michael Hanselmann
from ganeti import constants
31 b8812691 Iustin Pop
from ganeti import mcpu
32 6de7c41d Iustin Pop
from ganeti import cmdlib
33 7352d33b Thomas Thrainer
from ganeti.cmdlib import cluster
34 22b7f6f8 Thomas Thrainer
from ganeti.cmdlib import instance
35 763ad5be Thomas Thrainer
from ganeti.cmdlib import instance_storage
36 763ad5be Thomas Thrainer
from ganeti.cmdlib import instance_utils
37 7352d33b Thomas Thrainer
from ganeti.cmdlib import common
38 ec3cc4a8 Thomas Thrainer
from ganeti.cmdlib import query
39 b8812691 Iustin Pop
from ganeti import opcodes
40 6de7c41d Iustin Pop
from ganeti import errors
41 b8812691 Iustin Pop
from ganeti import utils
42 e58f87a9 Michael Hanselmann
from ganeti import luxi
43 65e183af Michael Hanselmann
from ganeti import ht
44 8ec505dd Adeodato Simo
from ganeti import objects
45 170b02b7 Michael Hanselmann
from ganeti import compat
46 170b02b7 Michael Hanselmann
from ganeti import rpc
47 ef86bf28 Michael Hanselmann
from ganeti import locking
48 0fcd0cad René Nussbaumer
from ganeti.masterd import iallocator
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 b8812691 Iustin Pop
class TestOpcodeParams(testutils.GanetiTestCase):
55 b8812691 Iustin Pop
  def testParamsStructures(self):
56 b8812691 Iustin Pop
    for op in sorted(mcpu.Processor.DISPATCH_TABLE):
57 b8812691 Iustin Pop
      lu = mcpu.Processor.DISPATCH_TABLE[op]
58 b8812691 Iustin Pop
      lu_name = lu.__name__
59 0bff0b12 Michael Hanselmann
      self.failIf(hasattr(lu, "_OP_REQP"),
60 0bff0b12 Michael Hanselmann
                  msg=("LU '%s' has old-style _OP_REQP" % lu_name))
61 0bff0b12 Michael Hanselmann
      self.failIf(hasattr(lu, "_OP_DEFS"),
62 0bff0b12 Michael Hanselmann
                  msg=("LU '%s' has old-style _OP_DEFS" % lu_name))
63 0bff0b12 Michael Hanselmann
      self.failIf(hasattr(lu, "_OP_PARAMS"),
64 0bff0b12 Michael Hanselmann
                  msg=("LU '%s' has old-style _OP_PARAMS" % lu_name))
65 b8812691 Iustin Pop
66 b8812691 Iustin Pop
67 bd5f214b Apollon Oikonomopoulos
class TestIAllocatorChecks(testutils.GanetiTestCase):
68 bd5f214b Apollon Oikonomopoulos
  def testFunction(self):
69 bd5f214b Apollon Oikonomopoulos
    class TestLU(object):
70 bd5f214b Apollon Oikonomopoulos
      def __init__(self, opcode):
71 bd5f214b Apollon Oikonomopoulos
        self.cfg = mocks.FakeConfig()
72 bd5f214b Apollon Oikonomopoulos
        self.op = opcode
73 bd5f214b Apollon Oikonomopoulos
74 ff0d18e6 Iustin Pop
    class OpTest(opcodes.OpCode):
75 ff0d18e6 Iustin Pop
       OP_PARAMS = [
76 8e4968ca Jose A. Lopes
        ("iallocator", None, ht.TAny, None),
77 8e4968ca Jose A. Lopes
        ("node", None, ht.TAny, None),
78 65e183af Michael Hanselmann
        ]
79 bd5f214b Apollon Oikonomopoulos
80 bd5f214b Apollon Oikonomopoulos
    default_iallocator = mocks.FakeConfig().GetDefaultIAllocator()
81 bd5f214b Apollon Oikonomopoulos
    other_iallocator = default_iallocator + "_not"
82 bd5f214b Apollon Oikonomopoulos
83 ff0d18e6 Iustin Pop
    op = OpTest()
84 bd5f214b Apollon Oikonomopoulos
    lu = TestLU(op)
85 bd5f214b Apollon Oikonomopoulos
86 5eacbcae Thomas Thrainer
    c_i = lambda: common.CheckIAllocatorOrNode(lu, "iallocator", "node")
87 bd5f214b Apollon Oikonomopoulos
88 bd5f214b Apollon Oikonomopoulos
    # Neither node nor iallocator given
89 43a8f36a Bernardo Dal Seno
    for n in (None, []):
90 43a8f36a Bernardo Dal Seno
      op.iallocator = None
91 43a8f36a Bernardo Dal Seno
      op.node = n
92 43a8f36a Bernardo Dal Seno
      c_i()
93 43a8f36a Bernardo Dal Seno
      self.assertEqual(lu.op.iallocator, default_iallocator)
94 43a8f36a Bernardo Dal Seno
      self.assertEqual(lu.op.node, n)
95 bd5f214b Apollon Oikonomopoulos
96 bd5f214b Apollon Oikonomopoulos
    # Both, iallocator and node given
97 43a8f36a Bernardo Dal Seno
    for a in ("test", constants.DEFAULT_IALLOCATOR_SHORTCUT):
98 43a8f36a Bernardo Dal Seno
      op.iallocator = a
99 43a8f36a Bernardo Dal Seno
      op.node = "test"
100 43a8f36a Bernardo Dal Seno
      self.assertRaises(errors.OpPrereqError, c_i)
101 bd5f214b Apollon Oikonomopoulos
102 bd5f214b Apollon Oikonomopoulos
    # Only iallocator given
103 43a8f36a Bernardo Dal Seno
    for n in (None, []):
104 43a8f36a Bernardo Dal Seno
      op.iallocator = other_iallocator
105 43a8f36a Bernardo Dal Seno
      op.node = n
106 43a8f36a Bernardo Dal Seno
      c_i()
107 43a8f36a Bernardo Dal Seno
      self.assertEqual(lu.op.iallocator, other_iallocator)
108 43a8f36a Bernardo Dal Seno
      self.assertEqual(lu.op.node, n)
109 bd5f214b Apollon Oikonomopoulos
110 bd5f214b Apollon Oikonomopoulos
    # Only node given
111 bd5f214b Apollon Oikonomopoulos
    op.iallocator = None
112 bd5f214b Apollon Oikonomopoulos
    op.node = "node"
113 bd5f214b Apollon Oikonomopoulos
    c_i()
114 bd5f214b Apollon Oikonomopoulos
    self.assertEqual(lu.op.iallocator, None)
115 bd5f214b Apollon Oikonomopoulos
    self.assertEqual(lu.op.node, "node")
116 bd5f214b Apollon Oikonomopoulos
117 43a8f36a Bernardo Dal Seno
    # Asked for default iallocator, no node given
118 43a8f36a Bernardo Dal Seno
    op.iallocator = constants.DEFAULT_IALLOCATOR_SHORTCUT
119 43a8f36a Bernardo Dal Seno
    op.node = None
120 43a8f36a Bernardo Dal Seno
    c_i()
121 43a8f36a Bernardo Dal Seno
    self.assertEqual(lu.op.iallocator, default_iallocator)
122 43a8f36a Bernardo Dal Seno
    self.assertEqual(lu.op.node, None)
123 43a8f36a Bernardo Dal Seno
124 bd5f214b Apollon Oikonomopoulos
    # No node, iallocator or default iallocator
125 bd5f214b Apollon Oikonomopoulos
    op.iallocator = None
126 bd5f214b Apollon Oikonomopoulos
    op.node = None
127 bd5f214b Apollon Oikonomopoulos
    lu.cfg.GetDefaultIAllocator = lambda: None
128 bd5f214b Apollon Oikonomopoulos
    self.assertRaises(errors.OpPrereqError, c_i)
129 bd5f214b Apollon Oikonomopoulos
130 bd5f214b Apollon Oikonomopoulos
131 b469eb4d Iustin Pop
class TestLUTestJqueue(unittest.TestCase):
132 e58f87a9 Michael Hanselmann
  def test(self):
133 b469eb4d Iustin Pop
    self.assert_(cmdlib.LUTestJqueue._CLIENT_CONNECT_TIMEOUT <
134 e58f87a9 Michael Hanselmann
                 (luxi.WFJC_TIMEOUT * 0.75),
135 e58f87a9 Michael Hanselmann
                 msg=("Client timeout too high, might not notice bugs"
136 e58f87a9 Michael Hanselmann
                      " in WaitForJobChange"))
137 e58f87a9 Michael Hanselmann
138 e58f87a9 Michael Hanselmann
139 83f72637 Michael Hanselmann
class TestLUQuery(unittest.TestCase):
140 83f72637 Michael Hanselmann
  def test(self):
141 ec3cc4a8 Thomas Thrainer
    self.assertEqual(sorted(query._QUERY_IMPL.keys()),
142 abd66bf8 Michael Hanselmann
                     sorted(constants.QR_VIA_OP))
143 83f72637 Michael Hanselmann
144 abd66bf8 Michael Hanselmann
    assert constants.QR_NODE in constants.QR_VIA_OP
145 abd66bf8 Michael Hanselmann
    assert constants.QR_INSTANCE in constants.QR_VIA_OP
146 83f72637 Michael Hanselmann
147 abd66bf8 Michael Hanselmann
    for i in constants.QR_VIA_OP:
148 ec3cc4a8 Thomas Thrainer
      self.assert_(query._GetQueryImplementation(i))
149 83f72637 Michael Hanselmann
150 ec3cc4a8 Thomas Thrainer
    self.assertRaises(errors.OpPrereqError, query._GetQueryImplementation,
151 22b7f6f8 Thomas Thrainer
                      "")
152 ec3cc4a8 Thomas Thrainer
    self.assertRaises(errors.OpPrereqError, query._GetQueryImplementation,
153 83f72637 Michael Hanselmann
                      "xyz")
154 83f72637 Michael Hanselmann
155 83f72637 Michael Hanselmann
156 d755483c Michael Hanselmann
class _FakeLU:
157 129cce69 Michael Hanselmann
  def __init__(self, cfg=NotImplemented, proc=NotImplemented,
158 129cce69 Michael Hanselmann
               rpc=NotImplemented):
159 d755483c Michael Hanselmann
    self.warning_log = []
160 d755483c Michael Hanselmann
    self.info_log = []
161 ff02b60f René Nussbaumer
    self.cfg = cfg
162 a8e3e009 Michael Hanselmann
    self.proc = proc
163 129cce69 Michael Hanselmann
    self.rpc = rpc
164 d755483c Michael Hanselmann
165 d755483c Michael Hanselmann
  def LogWarning(self, text, *args):
166 d755483c Michael Hanselmann
    self.warning_log.append((text, args))
167 d755483c Michael Hanselmann
168 d755483c Michael Hanselmann
  def LogInfo(self, text, *args):
169 d755483c Michael Hanselmann
    self.info_log.append((text, args))
170 d755483c Michael Hanselmann
171 d755483c Michael Hanselmann
172 d755483c Michael Hanselmann
class TestLoadNodeEvacResult(unittest.TestCase):
173 d755483c Michael Hanselmann
  def testSuccess(self):
174 d755483c Michael Hanselmann
    for moved in [[], [
175 d755483c Michael Hanselmann
      ("inst20153.example.com", "grp2", ["nodeA4509", "nodeB2912"]),
176 d755483c Michael Hanselmann
      ]]:
177 d755483c Michael Hanselmann
      for early_release in [False, True]:
178 d755483c Michael Hanselmann
        for use_nodes in [False, True]:
179 d755483c Michael Hanselmann
          jobs = [
180 d755483c Michael Hanselmann
            [opcodes.OpInstanceReplaceDisks().__getstate__()],
181 d755483c Michael Hanselmann
            [opcodes.OpInstanceMigrate().__getstate__()],
182 d755483c Michael Hanselmann
            ]
183 d755483c Michael Hanselmann
184 d755483c Michael Hanselmann
          alloc_result = (moved, [], jobs)
185 0fcd0cad René Nussbaumer
          assert iallocator._NEVAC_RESULT(alloc_result)
186 d755483c Michael Hanselmann
187 d755483c Michael Hanselmann
          lu = _FakeLU()
188 5eacbcae Thomas Thrainer
          result = common.LoadNodeEvacResult(lu, alloc_result,
189 5eacbcae Thomas Thrainer
                                             early_release, use_nodes)
190 d755483c Michael Hanselmann
191 d755483c Michael Hanselmann
          if moved:
192 d755483c Michael Hanselmann
            (_, (info_args, )) = lu.info_log.pop(0)
193 d755483c Michael Hanselmann
            for (instname, instgroup, instnodes) in moved:
194 d755483c Michael Hanselmann
              self.assertTrue(instname in info_args)
195 d755483c Michael Hanselmann
              if use_nodes:
196 d755483c Michael Hanselmann
                for i in instnodes:
197 d755483c Michael Hanselmann
                  self.assertTrue(i in info_args)
198 d755483c Michael Hanselmann
              else:
199 d755483c Michael Hanselmann
                self.assertTrue(instgroup in info_args)
200 d755483c Michael Hanselmann
201 d755483c Michael Hanselmann
          self.assertFalse(lu.info_log)
202 d755483c Michael Hanselmann
          self.assertFalse(lu.warning_log)
203 d755483c Michael Hanselmann
204 d755483c Michael Hanselmann
          for op in itertools.chain(*result):
205 d755483c Michael Hanselmann
            if hasattr(op.__class__, "early_release"):
206 d755483c Michael Hanselmann
              self.assertEqual(op.early_release, early_release)
207 d755483c Michael Hanselmann
            else:
208 d755483c Michael Hanselmann
              self.assertFalse(hasattr(op, "early_release"))
209 d755483c Michael Hanselmann
210 d755483c Michael Hanselmann
  def testFailed(self):
211 d755483c Michael Hanselmann
    alloc_result = ([], [
212 d755483c Michael Hanselmann
      ("inst5191.example.com", "errormsg21178"),
213 d755483c Michael Hanselmann
      ], [])
214 0fcd0cad René Nussbaumer
    assert iallocator._NEVAC_RESULT(alloc_result)
215 d755483c Michael Hanselmann
216 d755483c Michael Hanselmann
    lu = _FakeLU()
217 5eacbcae Thomas Thrainer
    self.assertRaises(errors.OpExecError, common.LoadNodeEvacResult,
218 d755483c Michael Hanselmann
                      lu, alloc_result, False, False)
219 d755483c Michael Hanselmann
    self.assertFalse(lu.info_log)
220 d755483c Michael Hanselmann
    (_, (args, )) = lu.warning_log.pop(0)
221 d755483c Michael Hanselmann
    self.assertTrue("inst5191.example.com" in args)
222 d755483c Michael Hanselmann
    self.assertTrue("errormsg21178" in args)
223 d755483c Michael Hanselmann
    self.assertFalse(lu.warning_log)
224 d755483c Michael Hanselmann
225 d755483c Michael Hanselmann
226 784cd737 René Nussbaumer
class TestUpdateAndVerifySubDict(unittest.TestCase):
227 784cd737 René Nussbaumer
  def setUp(self):
228 784cd737 René Nussbaumer
    self.type_check = {
229 784cd737 René Nussbaumer
        "a": constants.VTYPE_INT,
230 784cd737 René Nussbaumer
        "b": constants.VTYPE_STRING,
231 784cd737 René Nussbaumer
        "c": constants.VTYPE_BOOL,
232 784cd737 René Nussbaumer
        "d": constants.VTYPE_STRING,
233 784cd737 René Nussbaumer
        }
234 784cd737 René Nussbaumer
235 784cd737 René Nussbaumer
  def test(self):
236 784cd737 René Nussbaumer
    old_test = {
237 784cd737 René Nussbaumer
      "foo": {
238 784cd737 René Nussbaumer
        "d": "blubb",
239 784cd737 René Nussbaumer
        "a": 321,
240 784cd737 René Nussbaumer
        },
241 784cd737 René Nussbaumer
      "baz": {
242 784cd737 René Nussbaumer
        "a": 678,
243 784cd737 René Nussbaumer
        "b": "678",
244 784cd737 René Nussbaumer
        "c": True,
245 784cd737 René Nussbaumer
        },
246 784cd737 René Nussbaumer
      }
247 784cd737 René Nussbaumer
    test = {
248 784cd737 René Nussbaumer
      "foo": {
249 784cd737 René Nussbaumer
        "a": 123,
250 784cd737 René Nussbaumer
        "b": "123",
251 784cd737 René Nussbaumer
        "c": True,
252 784cd737 René Nussbaumer
        },
253 784cd737 René Nussbaumer
      "bar": {
254 784cd737 René Nussbaumer
        "a": 321,
255 784cd737 René Nussbaumer
        "b": "321",
256 784cd737 René Nussbaumer
        "c": False,
257 784cd737 René Nussbaumer
        },
258 784cd737 René Nussbaumer
      }
259 784cd737 René Nussbaumer
260 784cd737 René Nussbaumer
    mv = {
261 784cd737 René Nussbaumer
      "foo": {
262 784cd737 René Nussbaumer
        "a": 123,
263 784cd737 René Nussbaumer
        "b": "123",
264 784cd737 René Nussbaumer
        "c": True,
265 784cd737 René Nussbaumer
        "d": "blubb"
266 784cd737 René Nussbaumer
        },
267 784cd737 René Nussbaumer
      "bar": {
268 784cd737 René Nussbaumer
        "a": 321,
269 784cd737 René Nussbaumer
        "b": "321",
270 784cd737 René Nussbaumer
        "c": False,
271 784cd737 René Nussbaumer
        },
272 784cd737 René Nussbaumer
      "baz": {
273 784cd737 René Nussbaumer
        "a": 678,
274 784cd737 René Nussbaumer
        "b": "678",
275 784cd737 René Nussbaumer
        "c": True,
276 784cd737 René Nussbaumer
        },
277 784cd737 René Nussbaumer
      }
278 784cd737 René Nussbaumer
279 7352d33b Thomas Thrainer
    verified = common._UpdateAndVerifySubDict(old_test, test, self.type_check)
280 784cd737 René Nussbaumer
    self.assertEqual(verified, mv)
281 784cd737 René Nussbaumer
282 784cd737 René Nussbaumer
  def testWrong(self):
283 784cd737 René Nussbaumer
    test = {
284 784cd737 René Nussbaumer
      "foo": {
285 784cd737 René Nussbaumer
        "a": "blubb",
286 784cd737 René Nussbaumer
        "b": "123",
287 784cd737 René Nussbaumer
        "c": True,
288 784cd737 René Nussbaumer
        },
289 784cd737 René Nussbaumer
      "bar": {
290 784cd737 René Nussbaumer
        "a": 321,
291 784cd737 René Nussbaumer
        "b": "321",
292 784cd737 René Nussbaumer
        "c": False,
293 784cd737 René Nussbaumer
        },
294 784cd737 René Nussbaumer
      }
295 784cd737 René Nussbaumer
296 784cd737 René Nussbaumer
    self.assertRaises(errors.TypeEnforcementError,
297 7352d33b Thomas Thrainer
                      common._UpdateAndVerifySubDict, {}, test,
298 7352d33b Thomas Thrainer
                      self.type_check)
299 784cd737 René Nussbaumer
300 784cd737 René Nussbaumer
301 0ba177e2 René Nussbaumer
class TestHvStateHelper(unittest.TestCase):
302 0ba177e2 René Nussbaumer
  def testWithoutOpData(self):
303 5eacbcae Thomas Thrainer
    self.assertEqual(common.MergeAndVerifyHvState(None, NotImplemented),
304 7352d33b Thomas Thrainer
                     None)
305 0ba177e2 René Nussbaumer
306 0ba177e2 René Nussbaumer
  def testWithoutOldData(self):
307 0ba177e2 René Nussbaumer
    new = {
308 0ba177e2 René Nussbaumer
      constants.HT_XEN_PVM: {
309 0ba177e2 René Nussbaumer
        constants.HVST_MEMORY_TOTAL: 4096,
310 0ba177e2 René Nussbaumer
        },
311 0ba177e2 René Nussbaumer
      }
312 5eacbcae Thomas Thrainer
    self.assertEqual(common.MergeAndVerifyHvState(new, None), new)
313 0ba177e2 René Nussbaumer
314 0ba177e2 René Nussbaumer
  def testWithWrongHv(self):
315 0ba177e2 René Nussbaumer
    new = {
316 0ba177e2 René Nussbaumer
      "i-dont-exist": {
317 0ba177e2 René Nussbaumer
        constants.HVST_MEMORY_TOTAL: 4096,
318 0ba177e2 René Nussbaumer
        },
319 0ba177e2 René Nussbaumer
      }
320 5eacbcae Thomas Thrainer
    self.assertRaises(errors.OpPrereqError, common.MergeAndVerifyHvState,
321 7352d33b Thomas Thrainer
                      new, None)
322 0ba177e2 René Nussbaumer
323 0ba177e2 René Nussbaumer
class TestDiskStateHelper(unittest.TestCase):
324 0ba177e2 René Nussbaumer
  def testWithoutOpData(self):
325 5eacbcae Thomas Thrainer
    self.assertEqual(common.MergeAndVerifyDiskState(None, NotImplemented),
326 0ba177e2 René Nussbaumer
                     None)
327 0ba177e2 René Nussbaumer
328 0ba177e2 René Nussbaumer
  def testWithoutOldData(self):
329 0ba177e2 René Nussbaumer
    new = {
330 0c5f1b13 Thomas Thrainer
      constants.DT_PLAIN: {
331 0ba177e2 René Nussbaumer
        "xenvg": {
332 0ba177e2 René Nussbaumer
          constants.DS_DISK_RESERVED: 1024,
333 0ba177e2 René Nussbaumer
          },
334 0ba177e2 René Nussbaumer
        },
335 0ba177e2 René Nussbaumer
      }
336 5eacbcae Thomas Thrainer
    self.assertEqual(common.MergeAndVerifyDiskState(new, None), new)
337 0ba177e2 René Nussbaumer
338 0ba177e2 René Nussbaumer
  def testWithWrongStorageType(self):
339 0ba177e2 René Nussbaumer
    new = {
340 0ba177e2 René Nussbaumer
      "i-dont-exist": {
341 0ba177e2 René Nussbaumer
        "xenvg": {
342 0ba177e2 René Nussbaumer
          constants.DS_DISK_RESERVED: 1024,
343 0ba177e2 René Nussbaumer
          },
344 0ba177e2 René Nussbaumer
        },
345 0ba177e2 René Nussbaumer
      }
346 5eacbcae Thomas Thrainer
    self.assertRaises(errors.OpPrereqError, common.MergeAndVerifyDiskState,
347 0ba177e2 René Nussbaumer
                      new, None)
348 0ba177e2 René Nussbaumer
349 0ba177e2 René Nussbaumer
350 2096d068 René Nussbaumer
class TestComputeMinMaxSpec(unittest.TestCase):
351 2096d068 René Nussbaumer
  def setUp(self):
352 da5f09ef Bernardo Dal Seno
    self.ispecs = {
353 2096d068 René Nussbaumer
      constants.ISPECS_MAX: {
354 2096d068 René Nussbaumer
        constants.ISPEC_MEM_SIZE: 512,
355 2096d068 René Nussbaumer
        constants.ISPEC_DISK_SIZE: 1024,
356 2096d068 René Nussbaumer
        },
357 2096d068 René Nussbaumer
      constants.ISPECS_MIN: {
358 2096d068 René Nussbaumer
        constants.ISPEC_MEM_SIZE: 128,
359 2096d068 René Nussbaumer
        constants.ISPEC_DISK_COUNT: 1,
360 2096d068 René Nussbaumer
        },
361 2096d068 René Nussbaumer
      }
362 2096d068 René Nussbaumer
363 2096d068 René Nussbaumer
  def testNoneValue(self):
364 7352d33b Thomas Thrainer
    self.assertTrue(common._ComputeMinMaxSpec(constants.ISPEC_MEM_SIZE, None,
365 da5f09ef Bernardo Dal Seno
                                              self.ispecs, None) is None)
366 2096d068 René Nussbaumer
367 2096d068 René Nussbaumer
  def testAutoValue(self):
368 7352d33b Thomas Thrainer
    self.assertTrue(common._ComputeMinMaxSpec(constants.ISPEC_MEM_SIZE, None,
369 da5f09ef Bernardo Dal Seno
                                              self.ispecs,
370 2096d068 René Nussbaumer
                                              constants.VALUE_AUTO) is None)
371 2096d068 René Nussbaumer
372 2096d068 René Nussbaumer
  def testNotDefined(self):
373 7352d33b Thomas Thrainer
    self.assertTrue(common._ComputeMinMaxSpec(constants.ISPEC_NIC_COUNT, None,
374 da5f09ef Bernardo Dal Seno
                                              self.ispecs, 3) is None)
375 2096d068 René Nussbaumer
376 2096d068 René Nussbaumer
  def testNoMinDefined(self):
377 7352d33b Thomas Thrainer
    self.assertTrue(common._ComputeMinMaxSpec(constants.ISPEC_DISK_SIZE, None,
378 da5f09ef Bernardo Dal Seno
                                              self.ispecs, 128) is None)
379 2096d068 René Nussbaumer
380 2096d068 René Nussbaumer
  def testNoMaxDefined(self):
381 7352d33b Thomas Thrainer
    self.assertTrue(common._ComputeMinMaxSpec(constants.ISPEC_DISK_COUNT,
382 7352d33b Thomas Thrainer
                                              None, self.ispecs, 16) is None)
383 2096d068 René Nussbaumer
384 2096d068 René Nussbaumer
  def testOutOfRange(self):
385 2096d068 René Nussbaumer
    for (name, val) in ((constants.ISPEC_MEM_SIZE, 64),
386 2096d068 René Nussbaumer
                        (constants.ISPEC_MEM_SIZE, 768),
387 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_SIZE, 4096),
388 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_COUNT, 0)):
389 da5f09ef Bernardo Dal Seno
      min_v = self.ispecs[constants.ISPECS_MIN].get(name, val)
390 da5f09ef Bernardo Dal Seno
      max_v = self.ispecs[constants.ISPECS_MAX].get(name, val)
391 7352d33b Thomas Thrainer
      self.assertEqual(common._ComputeMinMaxSpec(name, None,
392 da5f09ef Bernardo Dal Seno
                                                 self.ispecs, val),
393 2096d068 René Nussbaumer
                       "%s value %s is not in range [%s, %s]" %
394 2096d068 René Nussbaumer
                       (name, val,min_v, max_v))
395 7352d33b Thomas Thrainer
      self.assertEqual(common._ComputeMinMaxSpec(name, "1",
396 da5f09ef Bernardo Dal Seno
                                                 self.ispecs, val),
397 0c2e59ac Iustin Pop
                       "%s/1 value %s is not in range [%s, %s]" %
398 0c2e59ac Iustin Pop
                       (name, val,min_v, max_v))
399 2096d068 René Nussbaumer
400 2096d068 René Nussbaumer
  def test(self):
401 2096d068 René Nussbaumer
    for (name, val) in ((constants.ISPEC_MEM_SIZE, 256),
402 2096d068 René Nussbaumer
                        (constants.ISPEC_MEM_SIZE, 128),
403 2096d068 René Nussbaumer
                        (constants.ISPEC_MEM_SIZE, 512),
404 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_SIZE, 1024),
405 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_SIZE, 0),
406 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_COUNT, 1),
407 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_COUNT, 5)):
408 7352d33b Thomas Thrainer
      self.assertTrue(common._ComputeMinMaxSpec(name, None, self.ispecs, val)
409 2096d068 René Nussbaumer
                      is None)
410 2096d068 René Nussbaumer
411 2096d068 René Nussbaumer
412 0e68bf27 René Nussbaumer
def _ValidateComputeMinMaxSpec(name, *_):
413 0fb81174 René Nussbaumer
  assert name in constants.ISPECS_PARAMETERS
414 0fb81174 René Nussbaumer
  return None
415 0fb81174 René Nussbaumer
416 0fb81174 René Nussbaumer
417 cc4b2676 Bernardo Dal Seno
def _NoDiskComputeMinMaxSpec(name, *_):
418 cc4b2676 Bernardo Dal Seno
  if name == constants.ISPEC_DISK_COUNT:
419 cc4b2676 Bernardo Dal Seno
    return name
420 cc4b2676 Bernardo Dal Seno
  else:
421 cc4b2676 Bernardo Dal Seno
    return None
422 cc4b2676 Bernardo Dal Seno
423 cc4b2676 Bernardo Dal Seno
424 0fb81174 René Nussbaumer
class _SpecWrapper:
425 0fb81174 René Nussbaumer
  def __init__(self, spec):
426 0fb81174 René Nussbaumer
    self.spec = spec
427 0fb81174 René Nussbaumer
428 0e68bf27 René Nussbaumer
  def ComputeMinMaxSpec(self, *args):
429 0fb81174 René Nussbaumer
    return self.spec.pop(0)
430 0fb81174 René Nussbaumer
431 0fb81174 René Nussbaumer
432 0fb81174 René Nussbaumer
class TestComputeIPolicySpecViolation(unittest.TestCase):
433 cc4b2676 Bernardo Dal Seno
  # Minimal policy accepted by _ComputeIPolicySpecViolation()
434 cc4b2676 Bernardo Dal Seno
  _MICRO_IPOL = {
435 cc4b2676 Bernardo Dal Seno
    constants.IPOLICY_DTS: [constants.DT_PLAIN, constants.DT_DISKLESS],
436 41044e04 Bernardo Dal Seno
    constants.ISPECS_MINMAX: [NotImplemented],
437 cc4b2676 Bernardo Dal Seno
    }
438 cc4b2676 Bernardo Dal Seno
439 0fb81174 René Nussbaumer
  def test(self):
440 0e68bf27 René Nussbaumer
    compute_fn = _ValidateComputeMinMaxSpec
441 5eacbcae Thomas Thrainer
    ret = common.ComputeIPolicySpecViolation(self._MICRO_IPOL, 1024, 1, 1, 1,
442 5eacbcae Thomas Thrainer
                                             [1024], 1, constants.DT_PLAIN,
443 5eacbcae Thomas Thrainer
                                             _compute_fn=compute_fn)
444 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
445 0fb81174 René Nussbaumer
446 cc4b2676 Bernardo Dal Seno
  def testDiskFull(self):
447 cc4b2676 Bernardo Dal Seno
    compute_fn = _NoDiskComputeMinMaxSpec
448 5eacbcae Thomas Thrainer
    ret = common.ComputeIPolicySpecViolation(self._MICRO_IPOL, 1024, 1, 1, 1,
449 5eacbcae Thomas Thrainer
                                             [1024], 1, constants.DT_PLAIN,
450 5eacbcae Thomas Thrainer
                                             _compute_fn=compute_fn)
451 cc4b2676 Bernardo Dal Seno
    self.assertEqual(ret, [constants.ISPEC_DISK_COUNT])
452 cc4b2676 Bernardo Dal Seno
453 cc4b2676 Bernardo Dal Seno
  def testDiskLess(self):
454 cc4b2676 Bernardo Dal Seno
    compute_fn = _NoDiskComputeMinMaxSpec
455 5eacbcae Thomas Thrainer
    ret = common.ComputeIPolicySpecViolation(self._MICRO_IPOL, 1024, 1, 1, 1,
456 5eacbcae Thomas Thrainer
                                             [1024], 1, constants.DT_DISKLESS,
457 5eacbcae Thomas Thrainer
                                             _compute_fn=compute_fn)
458 cc4b2676 Bernardo Dal Seno
    self.assertEqual(ret, [])
459 cc4b2676 Bernardo Dal Seno
460 cc4b2676 Bernardo Dal Seno
  def testWrongTemplates(self):
461 cc4b2676 Bernardo Dal Seno
    compute_fn = _ValidateComputeMinMaxSpec
462 5eacbcae Thomas Thrainer
    ret = common.ComputeIPolicySpecViolation(self._MICRO_IPOL, 1024, 1, 1, 1,
463 5eacbcae Thomas Thrainer
                                             [1024], 1, constants.DT_DRBD8,
464 5eacbcae Thomas Thrainer
                                             _compute_fn=compute_fn)
465 cc4b2676 Bernardo Dal Seno
    self.assertEqual(len(ret), 1)
466 cc4b2676 Bernardo Dal Seno
    self.assertTrue("Disk template" in ret[0])
467 cc4b2676 Bernardo Dal Seno
468 0fb81174 René Nussbaumer
  def testInvalidArguments(self):
469 5eacbcae Thomas Thrainer
    self.assertRaises(AssertionError, common.ComputeIPolicySpecViolation,
470 cc4b2676 Bernardo Dal Seno
                      self._MICRO_IPOL, 1024, 1, 1, 1, [], 1,
471 cc4b2676 Bernardo Dal Seno
                      constants.DT_PLAIN,)
472 0fb81174 René Nussbaumer
473 0fb81174 René Nussbaumer
  def testInvalidSpec(self):
474 553cb5f7 René Nussbaumer
    spec = _SpecWrapper([None, False, "foo", None, "bar", None])
475 0e68bf27 René Nussbaumer
    compute_fn = spec.ComputeMinMaxSpec
476 5eacbcae Thomas Thrainer
    ret = common.ComputeIPolicySpecViolation(self._MICRO_IPOL, 1024, 1, 1, 1,
477 5eacbcae Thomas Thrainer
                                             [1024], 1, constants.DT_PLAIN,
478 5eacbcae Thomas Thrainer
                                             _compute_fn=compute_fn)
479 0fb81174 René Nussbaumer
    self.assertEqual(ret, ["foo", "bar"])
480 0fb81174 René Nussbaumer
    self.assertFalse(spec.spec)
481 0fb81174 René Nussbaumer
482 41044e04 Bernardo Dal Seno
  def testWithIPolicy(self):
483 41044e04 Bernardo Dal Seno
    mem_size = 2048
484 41044e04 Bernardo Dal Seno
    cpu_count = 2
485 41044e04 Bernardo Dal Seno
    disk_count = 1
486 41044e04 Bernardo Dal Seno
    disk_sizes = [512]
487 41044e04 Bernardo Dal Seno
    nic_count = 1
488 41044e04 Bernardo Dal Seno
    spindle_use = 4
489 41044e04 Bernardo Dal Seno
    disk_template = "mytemplate"
490 41044e04 Bernardo Dal Seno
    ispec = {
491 41044e04 Bernardo Dal Seno
      constants.ISPEC_MEM_SIZE: mem_size,
492 41044e04 Bernardo Dal Seno
      constants.ISPEC_CPU_COUNT: cpu_count,
493 41044e04 Bernardo Dal Seno
      constants.ISPEC_DISK_COUNT: disk_count,
494 41044e04 Bernardo Dal Seno
      constants.ISPEC_DISK_SIZE: disk_sizes[0],
495 41044e04 Bernardo Dal Seno
      constants.ISPEC_NIC_COUNT: nic_count,
496 41044e04 Bernardo Dal Seno
      constants.ISPEC_SPINDLE_USE: spindle_use,
497 41044e04 Bernardo Dal Seno
      }
498 41044e04 Bernardo Dal Seno
    ipolicy1 = {
499 41044e04 Bernardo Dal Seno
      constants.ISPECS_MINMAX: [{
500 41044e04 Bernardo Dal Seno
        constants.ISPECS_MIN: ispec,
501 41044e04 Bernardo Dal Seno
        constants.ISPECS_MAX: ispec,
502 41044e04 Bernardo Dal Seno
        }],
503 41044e04 Bernardo Dal Seno
      constants.IPOLICY_DTS: [disk_template],
504 41044e04 Bernardo Dal Seno
      }
505 41044e04 Bernardo Dal Seno
    ispec_copy = copy.deepcopy(ispec)
506 41044e04 Bernardo Dal Seno
    ipolicy2 = {
507 41044e04 Bernardo Dal Seno
      constants.ISPECS_MINMAX: [
508 41044e04 Bernardo Dal Seno
        {
509 41044e04 Bernardo Dal Seno
          constants.ISPECS_MIN: ispec_copy,
510 41044e04 Bernardo Dal Seno
          constants.ISPECS_MAX: ispec_copy,
511 41044e04 Bernardo Dal Seno
          },
512 41044e04 Bernardo Dal Seno
        {
513 41044e04 Bernardo Dal Seno
          constants.ISPECS_MIN: ispec,
514 41044e04 Bernardo Dal Seno
          constants.ISPECS_MAX: ispec,
515 41044e04 Bernardo Dal Seno
          },
516 41044e04 Bernardo Dal Seno
        ],
517 41044e04 Bernardo Dal Seno
      constants.IPOLICY_DTS: [disk_template],
518 41044e04 Bernardo Dal Seno
      }
519 41044e04 Bernardo Dal Seno
    ipolicy3 = {
520 41044e04 Bernardo Dal Seno
      constants.ISPECS_MINMAX: [
521 41044e04 Bernardo Dal Seno
        {
522 41044e04 Bernardo Dal Seno
          constants.ISPECS_MIN: ispec,
523 41044e04 Bernardo Dal Seno
          constants.ISPECS_MAX: ispec,
524 41044e04 Bernardo Dal Seno
          },
525 41044e04 Bernardo Dal Seno
        {
526 41044e04 Bernardo Dal Seno
          constants.ISPECS_MIN: ispec_copy,
527 41044e04 Bernardo Dal Seno
          constants.ISPECS_MAX: ispec_copy,
528 41044e04 Bernardo Dal Seno
          },
529 41044e04 Bernardo Dal Seno
        ],
530 41044e04 Bernardo Dal Seno
      constants.IPOLICY_DTS: [disk_template],
531 41044e04 Bernardo Dal Seno
      }
532 41044e04 Bernardo Dal Seno
    def AssertComputeViolation(ipolicy, violations):
533 5eacbcae Thomas Thrainer
      ret = common.ComputeIPolicySpecViolation(ipolicy, mem_size, cpu_count,
534 5eacbcae Thomas Thrainer
                                               disk_count, nic_count,
535 5eacbcae Thomas Thrainer
                                               disk_sizes, spindle_use,
536 5eacbcae Thomas Thrainer
                                               disk_template)
537 41044e04 Bernardo Dal Seno
      self.assertEqual(len(ret), violations)
538 41044e04 Bernardo Dal Seno
539 41044e04 Bernardo Dal Seno
    AssertComputeViolation(ipolicy1, 0)
540 41044e04 Bernardo Dal Seno
    AssertComputeViolation(ipolicy2, 0)
541 41044e04 Bernardo Dal Seno
    AssertComputeViolation(ipolicy3, 0)
542 41044e04 Bernardo Dal Seno
    for par in constants.ISPECS_PARAMETERS:
543 41044e04 Bernardo Dal Seno
      ispec[par] += 1
544 41044e04 Bernardo Dal Seno
      AssertComputeViolation(ipolicy1, 1)
545 41044e04 Bernardo Dal Seno
      AssertComputeViolation(ipolicy2, 0)
546 41044e04 Bernardo Dal Seno
      AssertComputeViolation(ipolicy3, 0)
547 41044e04 Bernardo Dal Seno
      ispec[par] -= 2
548 41044e04 Bernardo Dal Seno
      AssertComputeViolation(ipolicy1, 1)
549 41044e04 Bernardo Dal Seno
      AssertComputeViolation(ipolicy2, 0)
550 41044e04 Bernardo Dal Seno
      AssertComputeViolation(ipolicy3, 0)
551 41044e04 Bernardo Dal Seno
      ispec[par] += 1 # Restore
552 41044e04 Bernardo Dal Seno
    ipolicy1[constants.IPOLICY_DTS] = ["another_template"]
553 41044e04 Bernardo Dal Seno
    AssertComputeViolation(ipolicy1, 1)
554 41044e04 Bernardo Dal Seno
555 0fb81174 René Nussbaumer
556 0fb81174 René Nussbaumer
class _StubComputeIPolicySpecViolation:
557 553cb5f7 René Nussbaumer
  def __init__(self, mem_size, cpu_count, disk_count, nic_count, disk_sizes,
558 cc4b2676 Bernardo Dal Seno
               spindle_use, disk_template):
559 0fb81174 René Nussbaumer
    self.mem_size = mem_size
560 0fb81174 René Nussbaumer
    self.cpu_count = cpu_count
561 0fb81174 René Nussbaumer
    self.disk_count = disk_count
562 0fb81174 René Nussbaumer
    self.nic_count = nic_count
563 0fb81174 René Nussbaumer
    self.disk_sizes = disk_sizes
564 553cb5f7 René Nussbaumer
    self.spindle_use = spindle_use
565 cc4b2676 Bernardo Dal Seno
    self.disk_template = disk_template
566 0fb81174 René Nussbaumer
567 553cb5f7 René Nussbaumer
  def __call__(self, _, mem_size, cpu_count, disk_count, nic_count, disk_sizes,
568 cc4b2676 Bernardo Dal Seno
               spindle_use, disk_template):
569 0fb81174 René Nussbaumer
    assert self.mem_size == mem_size
570 0fb81174 René Nussbaumer
    assert self.cpu_count == cpu_count
571 0fb81174 René Nussbaumer
    assert self.disk_count == disk_count
572 0fb81174 René Nussbaumer
    assert self.nic_count == nic_count
573 0fb81174 René Nussbaumer
    assert self.disk_sizes == disk_sizes
574 553cb5f7 René Nussbaumer
    assert self.spindle_use == spindle_use
575 cc4b2676 Bernardo Dal Seno
    assert self.disk_template == disk_template
576 0fb81174 René Nussbaumer
577 0fb81174 René Nussbaumer
    return []
578 0fb81174 René Nussbaumer
579 0fb81174 René Nussbaumer
580 2477c1c5 Bernardo Dal Seno
class _FakeConfigForComputeIPolicyInstanceViolation:
581 5a13489b Bernardo Dal Seno
  def __init__(self, be, excl_stor):
582 2477c1c5 Bernardo Dal Seno
    self.cluster = objects.Cluster(beparams={"default": be})
583 5a13489b Bernardo Dal Seno
    self.excl_stor = excl_stor
584 2477c1c5 Bernardo Dal Seno
585 2477c1c5 Bernardo Dal Seno
  def GetClusterInfo(self):
586 2477c1c5 Bernardo Dal Seno
    return self.cluster
587 2477c1c5 Bernardo Dal Seno
588 5a13489b Bernardo Dal Seno
  def GetNodeInfo(self, _):
589 5a13489b Bernardo Dal Seno
    return {}
590 5a13489b Bernardo Dal Seno
591 5a13489b Bernardo Dal Seno
  def GetNdParams(self, _):
592 5a13489b Bernardo Dal Seno
    return {
593 5a13489b Bernardo Dal Seno
      constants.ND_EXCLUSIVE_STORAGE: self.excl_stor,
594 5a13489b Bernardo Dal Seno
      }
595 5a13489b Bernardo Dal Seno
596 2477c1c5 Bernardo Dal Seno
597 0fb81174 René Nussbaumer
class TestComputeIPolicyInstanceViolation(unittest.TestCase):
598 0fb81174 René Nussbaumer
  def test(self):
599 0fb81174 René Nussbaumer
    beparams = {
600 0fb81174 René Nussbaumer
      constants.BE_MAXMEM: 2048,
601 0fb81174 René Nussbaumer
      constants.BE_VCPUS: 2,
602 34700f5b René Nussbaumer
      constants.BE_SPINDLE_USE: 4,
603 0fb81174 René Nussbaumer
      }
604 5a13489b Bernardo Dal Seno
    disks = [objects.Disk(size=512, spindles=13)]
605 5a13489b Bernardo Dal Seno
    cfg = _FakeConfigForComputeIPolicyInstanceViolation(beparams, False)
606 cc4b2676 Bernardo Dal Seno
    instance = objects.Instance(beparams=beparams, disks=disks, nics=[],
607 cc4b2676 Bernardo Dal Seno
                                disk_template=constants.DT_PLAIN)
608 cc4b2676 Bernardo Dal Seno
    stub = _StubComputeIPolicySpecViolation(2048, 2, 1, 0, [512], 4,
609 cc4b2676 Bernardo Dal Seno
                                            constants.DT_PLAIN)
610 5eacbcae Thomas Thrainer
    ret = common.ComputeIPolicyInstanceViolation(NotImplemented, instance,
611 5eacbcae Thomas Thrainer
                                                 cfg, _compute_fn=stub)
612 2477c1c5 Bernardo Dal Seno
    self.assertEqual(ret, [])
613 2477c1c5 Bernardo Dal Seno
    instance2 = objects.Instance(beparams={}, disks=disks, nics=[],
614 2477c1c5 Bernardo Dal Seno
                                 disk_template=constants.DT_PLAIN)
615 5eacbcae Thomas Thrainer
    ret = common.ComputeIPolicyInstanceViolation(NotImplemented, instance2,
616 5eacbcae Thomas Thrainer
                                                 cfg, _compute_fn=stub)
617 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
618 5a13489b Bernardo Dal Seno
    cfg_es = _FakeConfigForComputeIPolicyInstanceViolation(beparams, True)
619 5a13489b Bernardo Dal Seno
    stub_es = _StubComputeIPolicySpecViolation(2048, 2, 1, 0, [512], 13,
620 5a13489b Bernardo Dal Seno
                                               constants.DT_PLAIN)
621 5a13489b Bernardo Dal Seno
    ret = common.ComputeIPolicyInstanceViolation(NotImplemented, instance,
622 5a13489b Bernardo Dal Seno
                                                 cfg_es, _compute_fn=stub_es)
623 5a13489b Bernardo Dal Seno
    self.assertEqual(ret, [])
624 5a13489b Bernardo Dal Seno
    ret = common.ComputeIPolicyInstanceViolation(NotImplemented, instance2,
625 5a13489b Bernardo Dal Seno
                                                 cfg_es, _compute_fn=stub_es)
626 5a13489b Bernardo Dal Seno
    self.assertEqual(ret, [])
627 0fb81174 René Nussbaumer
628 0fb81174 René Nussbaumer
629 0fb81174 René Nussbaumer
class _CallRecorder:
630 0fb81174 René Nussbaumer
  def __init__(self, return_value=None):
631 0fb81174 René Nussbaumer
    self.called = False
632 0fb81174 René Nussbaumer
    self.return_value = return_value
633 0fb81174 René Nussbaumer
634 0fb81174 René Nussbaumer
  def __call__(self, *args):
635 0fb81174 René Nussbaumer
    self.called = True
636 0fb81174 René Nussbaumer
    return self.return_value
637 0fb81174 René Nussbaumer
638 0fb81174 René Nussbaumer
639 0fb81174 René Nussbaumer
class TestComputeIPolicyNodeViolation(unittest.TestCase):
640 0fb81174 René Nussbaumer
  def setUp(self):
641 0fb81174 René Nussbaumer
    self.recorder = _CallRecorder(return_value=[])
642 0fb81174 René Nussbaumer
643 0fb81174 René Nussbaumer
  def testSameGroup(self):
644 763ad5be Thomas Thrainer
    ret = instance_utils._ComputeIPolicyNodeViolation(
645 763ad5be Thomas Thrainer
      NotImplemented,
646 763ad5be Thomas Thrainer
      NotImplemented,
647 763ad5be Thomas Thrainer
      "foo", "foo", NotImplemented,
648 763ad5be Thomas Thrainer
      _compute_fn=self.recorder)
649 0fb81174 René Nussbaumer
    self.assertFalse(self.recorder.called)
650 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
651 0fb81174 René Nussbaumer
652 0fb81174 René Nussbaumer
  def testDifferentGroup(self):
653 763ad5be Thomas Thrainer
    ret = instance_utils._ComputeIPolicyNodeViolation(
654 763ad5be Thomas Thrainer
      NotImplemented,
655 763ad5be Thomas Thrainer
      NotImplemented,
656 763ad5be Thomas Thrainer
      "foo", "bar", NotImplemented,
657 763ad5be Thomas Thrainer
      _compute_fn=self.recorder)
658 0fb81174 René Nussbaumer
    self.assertTrue(self.recorder.called)
659 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
660 0fb81174 René Nussbaumer
661 0fb81174 René Nussbaumer
662 fa8ef9d6 Michael Hanselmann
class TestDiskSizeInBytesToMebibytes(unittest.TestCase):
663 fa8ef9d6 Michael Hanselmann
  def testLessThanOneMebibyte(self):
664 fa8ef9d6 Michael Hanselmann
    for i in [1, 2, 7, 512, 1000, 1023]:
665 fa8ef9d6 Michael Hanselmann
      lu = _FakeLU()
666 763ad5be Thomas Thrainer
      result = instance_storage._DiskSizeInBytesToMebibytes(lu, i)
667 fa8ef9d6 Michael Hanselmann
      self.assertEqual(result, 1)
668 fa8ef9d6 Michael Hanselmann
      self.assertEqual(len(lu.warning_log), 1)
669 fa8ef9d6 Michael Hanselmann
      self.assertEqual(len(lu.warning_log[0]), 2)
670 fa8ef9d6 Michael Hanselmann
      (_, (warnsize, )) = lu.warning_log[0]
671 fa8ef9d6 Michael Hanselmann
      self.assertEqual(warnsize, (1024 * 1024) - i)
672 fa8ef9d6 Michael Hanselmann
673 fa8ef9d6 Michael Hanselmann
  def testEven(self):
674 fa8ef9d6 Michael Hanselmann
    for i in [1, 2, 7, 512, 1000, 1023]:
675 fa8ef9d6 Michael Hanselmann
      lu = _FakeLU()
676 763ad5be Thomas Thrainer
      result = instance_storage._DiskSizeInBytesToMebibytes(lu,
677 763ad5be Thomas Thrainer
                                                            i * 1024 * 1024)
678 fa8ef9d6 Michael Hanselmann
      self.assertEqual(result, i)
679 fa8ef9d6 Michael Hanselmann
      self.assertFalse(lu.warning_log)
680 fa8ef9d6 Michael Hanselmann
681 fa8ef9d6 Michael Hanselmann
  def testLargeNumber(self):
682 fa8ef9d6 Michael Hanselmann
    for i in [1, 2, 7, 512, 1000, 1023, 2724, 12420]:
683 fa8ef9d6 Michael Hanselmann
      for j in [1, 2, 486, 326, 986, 1023]:
684 fa8ef9d6 Michael Hanselmann
        lu = _FakeLU()
685 fa8ef9d6 Michael Hanselmann
        size = (1024 * 1024 * i) + j
686 763ad5be Thomas Thrainer
        result = instance_storage._DiskSizeInBytesToMebibytes(lu, size)
687 fa8ef9d6 Michael Hanselmann
        self.assertEqual(result, i + 1, msg="Amount was not rounded up")
688 fa8ef9d6 Michael Hanselmann
        self.assertEqual(len(lu.warning_log), 1)
689 fa8ef9d6 Michael Hanselmann
        self.assertEqual(len(lu.warning_log[0]), 2)
690 fa8ef9d6 Michael Hanselmann
        (_, (warnsize, )) = lu.warning_log[0]
691 fa8ef9d6 Michael Hanselmann
        self.assertEqual(warnsize, (1024 * 1024) - j)
692 129cce69 Michael Hanselmann
693 129cce69 Michael Hanselmann
694 8bb2df7d Bernardo Dal Seno
class _OpTestVerifyErrors(opcodes.OpCode):
695 8bb2df7d Bernardo Dal Seno
  OP_PARAMS = [
696 61c9a3d6 Jose A. Lopes
    ("debug_simulate_errors", False, ht.TBool, ""),
697 61c9a3d6 Jose A. Lopes
    ("error_codes", False, ht.TBool, ""),
698 61c9a3d6 Jose A. Lopes
    ("ignore_errors",
699 61c9a3d6 Jose A. Lopes
     [],
700 61c9a3d6 Jose A. Lopes
     ht.TListOf(ht.TElemOf(constants.CV_ALL_ECODES_STRINGS)),
701 61c9a3d6 Jose A. Lopes
     "")
702 8bb2df7d Bernardo Dal Seno
    ]
703 8bb2df7d Bernardo Dal Seno
704 8bb2df7d Bernardo Dal Seno
705 7352d33b Thomas Thrainer
class _LuTestVerifyErrors(cluster._VerifyErrors):
706 8bb2df7d Bernardo Dal Seno
  def __init__(self, **kwargs):
707 7352d33b Thomas Thrainer
    cluster._VerifyErrors.__init__(self)
708 8bb2df7d Bernardo Dal Seno
    self.op = _OpTestVerifyErrors(**kwargs)
709 8bb2df7d Bernardo Dal Seno
    self.op.Validate(True)
710 8bb2df7d Bernardo Dal Seno
    self.msglist = []
711 8bb2df7d Bernardo Dal Seno
    self._feedback_fn = self.msglist.append
712 8bb2df7d Bernardo Dal Seno
    self.bad = False
713 8bb2df7d Bernardo Dal Seno
714 8bb2df7d Bernardo Dal Seno
  def DispatchCallError(self, which, *args, **kwargs):
715 8bb2df7d Bernardo Dal Seno
    if which:
716 8bb2df7d Bernardo Dal Seno
      self._Error(*args, **kwargs)
717 8bb2df7d Bernardo Dal Seno
    else:
718 8bb2df7d Bernardo Dal Seno
      self._ErrorIf(True, *args, **kwargs)
719 8bb2df7d Bernardo Dal Seno
720 8bb2df7d Bernardo Dal Seno
  def CallErrorIf(self, c, *args, **kwargs):
721 8bb2df7d Bernardo Dal Seno
    self._ErrorIf(c, *args, **kwargs)
722 8bb2df7d Bernardo Dal Seno
723 8bb2df7d Bernardo Dal Seno
724 8bb2df7d Bernardo Dal Seno
class TestVerifyErrors(unittest.TestCase):
725 8bb2df7d Bernardo Dal Seno
  # Fake cluster-verify error code structures; we use two arbitary real error
726 8bb2df7d Bernardo Dal Seno
  # codes to pass validation of ignore_errors
727 8bb2df7d Bernardo Dal Seno
  (_, _ERR1ID, _) = constants.CV_ECLUSTERCFG
728 8bb2df7d Bernardo Dal Seno
  _NODESTR = "node"
729 8bb2df7d Bernardo Dal Seno
  _NODENAME = "mynode"
730 8bb2df7d Bernardo Dal Seno
  _ERR1CODE = (_NODESTR, _ERR1ID, "Error one")
731 8bb2df7d Bernardo Dal Seno
  (_, _ERR2ID, _) = constants.CV_ECLUSTERCERT
732 8bb2df7d Bernardo Dal Seno
  _INSTSTR = "instance"
733 8bb2df7d Bernardo Dal Seno
  _INSTNAME = "myinstance"
734 8bb2df7d Bernardo Dal Seno
  _ERR2CODE = (_INSTSTR, _ERR2ID, "Error two")
735 8bb2df7d Bernardo Dal Seno
  # Arguments used to call _Error() or _ErrorIf()
736 8bb2df7d Bernardo Dal Seno
  _ERR1ARGS = (_ERR1CODE, _NODENAME, "Error1 is %s", "an error")
737 8bb2df7d Bernardo Dal Seno
  _ERR2ARGS = (_ERR2CODE, _INSTNAME, "Error2 has no argument")
738 8bb2df7d Bernardo Dal Seno
  # Expected error messages
739 8bb2df7d Bernardo Dal Seno
  _ERR1MSG = _ERR1ARGS[2] % _ERR1ARGS[3]
740 8bb2df7d Bernardo Dal Seno
  _ERR2MSG = _ERR2ARGS[2]
741 8bb2df7d Bernardo Dal Seno
742 8bb2df7d Bernardo Dal Seno
  def testNoError(self):
743 8bb2df7d Bernardo Dal Seno
    lu = _LuTestVerifyErrors()
744 8bb2df7d Bernardo Dal Seno
    lu.CallErrorIf(False, self._ERR1CODE, *self._ERR1ARGS)
745 8bb2df7d Bernardo Dal Seno
    self.assertFalse(lu.bad)
746 8bb2df7d Bernardo Dal Seno
    self.assertFalse(lu.msglist)
747 8bb2df7d Bernardo Dal Seno
748 8bb2df7d Bernardo Dal Seno
  def _InitTest(self, **kwargs):
749 8bb2df7d Bernardo Dal Seno
    self.lu1 = _LuTestVerifyErrors(**kwargs)
750 8bb2df7d Bernardo Dal Seno
    self.lu2 = _LuTestVerifyErrors(**kwargs)
751 8bb2df7d Bernardo Dal Seno
752 8bb2df7d Bernardo Dal Seno
  def _CallError(self, *args, **kwargs):
753 8bb2df7d Bernardo Dal Seno
    # Check that _Error() and _ErrorIf() produce the same results
754 8bb2df7d Bernardo Dal Seno
    self.lu1.DispatchCallError(True, *args, **kwargs)
755 8bb2df7d Bernardo Dal Seno
    self.lu2.DispatchCallError(False, *args, **kwargs)
756 8bb2df7d Bernardo Dal Seno
    self.assertEqual(self.lu1.bad, self.lu2.bad)
757 8bb2df7d Bernardo Dal Seno
    self.assertEqual(self.lu1.msglist, self.lu2.msglist)
758 8bb2df7d Bernardo Dal Seno
    # Test-specific checks are made on one LU
759 8bb2df7d Bernardo Dal Seno
    return self.lu1
760 8bb2df7d Bernardo Dal Seno
761 8bb2df7d Bernardo Dal Seno
  def _checkMsgCommon(self, logstr, errmsg, itype, item, warning):
762 8bb2df7d Bernardo Dal Seno
    self.assertTrue(errmsg in logstr)
763 8bb2df7d Bernardo Dal Seno
    if warning:
764 8bb2df7d Bernardo Dal Seno
      self.assertTrue("WARNING" in logstr)
765 8bb2df7d Bernardo Dal Seno
    else:
766 8bb2df7d Bernardo Dal Seno
      self.assertTrue("ERROR" in logstr)
767 8bb2df7d Bernardo Dal Seno
    self.assertTrue(itype in logstr)
768 8bb2df7d Bernardo Dal Seno
    self.assertTrue(item in logstr)
769 8bb2df7d Bernardo Dal Seno
770 8bb2df7d Bernardo Dal Seno
  def _checkMsg1(self, logstr, warning=False):
771 8bb2df7d Bernardo Dal Seno
    self._checkMsgCommon(logstr, self._ERR1MSG, self._NODESTR,
772 8bb2df7d Bernardo Dal Seno
                         self._NODENAME, warning)
773 8bb2df7d Bernardo Dal Seno
774 8bb2df7d Bernardo Dal Seno
  def _checkMsg2(self, logstr, warning=False):
775 8bb2df7d Bernardo Dal Seno
    self._checkMsgCommon(logstr, self._ERR2MSG, self._INSTSTR,
776 8bb2df7d Bernardo Dal Seno
                         self._INSTNAME, warning)
777 8bb2df7d Bernardo Dal Seno
778 8bb2df7d Bernardo Dal Seno
  def testPlain(self):
779 8bb2df7d Bernardo Dal Seno
    self._InitTest()
780 8bb2df7d Bernardo Dal Seno
    lu = self._CallError(*self._ERR1ARGS)
781 8bb2df7d Bernardo Dal Seno
    self.assertTrue(lu.bad)
782 8bb2df7d Bernardo Dal Seno
    self.assertEqual(len(lu.msglist), 1)
783 8bb2df7d Bernardo Dal Seno
    self._checkMsg1(lu.msglist[0])
784 8bb2df7d Bernardo Dal Seno
785 8bb2df7d Bernardo Dal Seno
  def testMultiple(self):
786 8bb2df7d Bernardo Dal Seno
    self._InitTest()
787 8bb2df7d Bernardo Dal Seno
    self._CallError(*self._ERR1ARGS)
788 8bb2df7d Bernardo Dal Seno
    lu = self._CallError(*self._ERR2ARGS)
789 8bb2df7d Bernardo Dal Seno
    self.assertTrue(lu.bad)
790 8bb2df7d Bernardo Dal Seno
    self.assertEqual(len(lu.msglist), 2)
791 8bb2df7d Bernardo Dal Seno
    self._checkMsg1(lu.msglist[0])
792 8bb2df7d Bernardo Dal Seno
    self._checkMsg2(lu.msglist[1])
793 8bb2df7d Bernardo Dal Seno
794 8bb2df7d Bernardo Dal Seno
  def testIgnore(self):
795 8bb2df7d Bernardo Dal Seno
    self._InitTest(ignore_errors=[self._ERR1ID])
796 8bb2df7d Bernardo Dal Seno
    lu = self._CallError(*self._ERR1ARGS)
797 8bb2df7d Bernardo Dal Seno
    self.assertFalse(lu.bad)
798 8bb2df7d Bernardo Dal Seno
    self.assertEqual(len(lu.msglist), 1)
799 8bb2df7d Bernardo Dal Seno
    self._checkMsg1(lu.msglist[0], warning=True)
800 8bb2df7d Bernardo Dal Seno
801 8bb2df7d Bernardo Dal Seno
  def testWarning(self):
802 8bb2df7d Bernardo Dal Seno
    self._InitTest()
803 8bb2df7d Bernardo Dal Seno
    lu = self._CallError(*self._ERR1ARGS,
804 8bb2df7d Bernardo Dal Seno
                         code=_LuTestVerifyErrors.ETYPE_WARNING)
805 8bb2df7d Bernardo Dal Seno
    self.assertFalse(lu.bad)
806 8bb2df7d Bernardo Dal Seno
    self.assertEqual(len(lu.msglist), 1)
807 8bb2df7d Bernardo Dal Seno
    self._checkMsg1(lu.msglist[0], warning=True)
808 8bb2df7d Bernardo Dal Seno
809 8bb2df7d Bernardo Dal Seno
  def testWarning2(self):
810 8bb2df7d Bernardo Dal Seno
    self._InitTest()
811 8bb2df7d Bernardo Dal Seno
    self._CallError(*self._ERR1ARGS)
812 8bb2df7d Bernardo Dal Seno
    lu = self._CallError(*self._ERR2ARGS,
813 8bb2df7d Bernardo Dal Seno
                         code=_LuTestVerifyErrors.ETYPE_WARNING)
814 8bb2df7d Bernardo Dal Seno
    self.assertTrue(lu.bad)
815 8bb2df7d Bernardo Dal Seno
    self.assertEqual(len(lu.msglist), 2)
816 8bb2df7d Bernardo Dal Seno
    self._checkMsg1(lu.msglist[0])
817 8bb2df7d Bernardo Dal Seno
    self._checkMsg2(lu.msglist[1], warning=True)
818 8bb2df7d Bernardo Dal Seno
819 8bb2df7d Bernardo Dal Seno
  def testDebugSimulate(self):
820 8bb2df7d Bernardo Dal Seno
    lu = _LuTestVerifyErrors(debug_simulate_errors=True)
821 8bb2df7d Bernardo Dal Seno
    lu.CallErrorIf(False, *self._ERR1ARGS)
822 8bb2df7d Bernardo Dal Seno
    self.assertTrue(lu.bad)
823 8bb2df7d Bernardo Dal Seno
    self.assertEqual(len(lu.msglist), 1)
824 8bb2df7d Bernardo Dal Seno
    self._checkMsg1(lu.msglist[0])
825 8bb2df7d Bernardo Dal Seno
826 8bb2df7d Bernardo Dal Seno
  def testErrCodes(self):
827 8bb2df7d Bernardo Dal Seno
    self._InitTest(error_codes=True)
828 8bb2df7d Bernardo Dal Seno
    lu = self._CallError(*self._ERR1ARGS)
829 8bb2df7d Bernardo Dal Seno
    self.assertTrue(lu.bad)
830 8bb2df7d Bernardo Dal Seno
    self.assertEqual(len(lu.msglist), 1)
831 8bb2df7d Bernardo Dal Seno
    self._checkMsg1(lu.msglist[0])
832 8bb2df7d Bernardo Dal Seno
    self.assertTrue(self._ERR1ID in lu.msglist[0])
833 8bb2df7d Bernardo Dal Seno
834 8bb2df7d Bernardo Dal Seno
835 5dd7d15b Bernardo Dal Seno
class TestGetUpdatedIPolicy(unittest.TestCase):
836 5dd7d15b Bernardo Dal Seno
  """Tests for cmdlib._GetUpdatedIPolicy()"""
837 5dd7d15b Bernardo Dal Seno
  _OLD_CLUSTER_POLICY = {
838 5dd7d15b Bernardo Dal Seno
    constants.IPOLICY_VCPU_RATIO: 1.5,
839 41044e04 Bernardo Dal Seno
    constants.ISPECS_MINMAX: [
840 41044e04 Bernardo Dal Seno
      {
841 41044e04 Bernardo Dal Seno
        constants.ISPECS_MIN: {
842 41044e04 Bernardo Dal Seno
          constants.ISPEC_MEM_SIZE: 32768,
843 41044e04 Bernardo Dal Seno
          constants.ISPEC_CPU_COUNT: 8,
844 41044e04 Bernardo Dal Seno
          constants.ISPEC_DISK_COUNT: 1,
845 41044e04 Bernardo Dal Seno
          constants.ISPEC_DISK_SIZE: 1024,
846 41044e04 Bernardo Dal Seno
          constants.ISPEC_NIC_COUNT: 1,
847 41044e04 Bernardo Dal Seno
          constants.ISPEC_SPINDLE_USE: 1,
848 41044e04 Bernardo Dal Seno
          },
849 41044e04 Bernardo Dal Seno
        constants.ISPECS_MAX: {
850 41044e04 Bernardo Dal Seno
          constants.ISPEC_MEM_SIZE: 65536,
851 41044e04 Bernardo Dal Seno
          constants.ISPEC_CPU_COUNT: 10,
852 41044e04 Bernardo Dal Seno
          constants.ISPEC_DISK_COUNT: 5,
853 41044e04 Bernardo Dal Seno
          constants.ISPEC_DISK_SIZE: 1024 * 1024,
854 41044e04 Bernardo Dal Seno
          constants.ISPEC_NIC_COUNT: 3,
855 41044e04 Bernardo Dal Seno
          constants.ISPEC_SPINDLE_USE: 12,
856 41044e04 Bernardo Dal Seno
          },
857 41044e04 Bernardo Dal Seno
        },
858 41044e04 Bernardo Dal Seno
      constants.ISPECS_MINMAX_DEFAULTS,
859 41044e04 Bernardo Dal Seno
      ],
860 0f511c8a Bernardo Dal Seno
    constants.ISPECS_STD: constants.IPOLICY_DEFAULTS[constants.ISPECS_STD],
861 5dd7d15b Bernardo Dal Seno
    }
862 5dd7d15b Bernardo Dal Seno
  _OLD_GROUP_POLICY = {
863 5dd7d15b Bernardo Dal Seno
    constants.IPOLICY_SPINDLE_RATIO: 2.5,
864 41044e04 Bernardo Dal Seno
    constants.ISPECS_MINMAX: [{
865 da5f09ef Bernardo Dal Seno
      constants.ISPECS_MIN: {
866 0f511c8a Bernardo Dal Seno
        constants.ISPEC_MEM_SIZE: 128,
867 0f511c8a Bernardo Dal Seno
        constants.ISPEC_CPU_COUNT: 1,
868 0f511c8a Bernardo Dal Seno
        constants.ISPEC_DISK_COUNT: 1,
869 0f511c8a Bernardo Dal Seno
        constants.ISPEC_DISK_SIZE: 1024,
870 0f511c8a Bernardo Dal Seno
        constants.ISPEC_NIC_COUNT: 1,
871 0f511c8a Bernardo Dal Seno
        constants.ISPEC_SPINDLE_USE: 1,
872 0f511c8a Bernardo Dal Seno
        },
873 0f511c8a Bernardo Dal Seno
      constants.ISPECS_MAX: {
874 0f511c8a Bernardo Dal Seno
        constants.ISPEC_MEM_SIZE: 32768,
875 0f511c8a Bernardo Dal Seno
        constants.ISPEC_CPU_COUNT: 8,
876 0f511c8a Bernardo Dal Seno
        constants.ISPEC_DISK_COUNT: 5,
877 0f511c8a Bernardo Dal Seno
        constants.ISPEC_DISK_SIZE: 1024 * 1024,
878 0f511c8a Bernardo Dal Seno
        constants.ISPEC_NIC_COUNT: 3,
879 0f511c8a Bernardo Dal Seno
        constants.ISPEC_SPINDLE_USE: 12,
880 da5f09ef Bernardo Dal Seno
        },
881 41044e04 Bernardo Dal Seno
      }],
882 5dd7d15b Bernardo Dal Seno
    }
883 5dd7d15b Bernardo Dal Seno
884 5dd7d15b Bernardo Dal Seno
  def _TestSetSpecs(self, old_policy, isgroup):
885 41044e04 Bernardo Dal Seno
    diff_minmax = [{
886 0f511c8a Bernardo Dal Seno
      constants.ISPECS_MIN: {
887 0f511c8a Bernardo Dal Seno
        constants.ISPEC_MEM_SIZE: 64,
888 0f511c8a Bernardo Dal Seno
        constants.ISPEC_CPU_COUNT: 1,
889 0f511c8a Bernardo Dal Seno
        constants.ISPEC_DISK_COUNT: 2,
890 0f511c8a Bernardo Dal Seno
        constants.ISPEC_DISK_SIZE: 64,
891 0f511c8a Bernardo Dal Seno
        constants.ISPEC_NIC_COUNT: 1,
892 0f511c8a Bernardo Dal Seno
        constants.ISPEC_SPINDLE_USE: 1,
893 0f511c8a Bernardo Dal Seno
        },
894 0f511c8a Bernardo Dal Seno
      constants.ISPECS_MAX: {
895 0f511c8a Bernardo Dal Seno
        constants.ISPEC_MEM_SIZE: 16384,
896 0f511c8a Bernardo Dal Seno
        constants.ISPEC_CPU_COUNT: 10,
897 0f511c8a Bernardo Dal Seno
        constants.ISPEC_DISK_COUNT: 12,
898 0f511c8a Bernardo Dal Seno
        constants.ISPEC_DISK_SIZE: 1024,
899 0f511c8a Bernardo Dal Seno
        constants.ISPEC_NIC_COUNT: 9,
900 0f511c8a Bernardo Dal Seno
        constants.ISPEC_SPINDLE_USE: 18,
901 0f511c8a Bernardo Dal Seno
        },
902 41044e04 Bernardo Dal Seno
      }]
903 0f511c8a Bernardo Dal Seno
    diff_std = {
904 0f511c8a Bernardo Dal Seno
        constants.ISPEC_DISK_COUNT: 10,
905 0f511c8a Bernardo Dal Seno
        constants.ISPEC_DISK_SIZE: 512,
906 0f511c8a Bernardo Dal Seno
        }
907 5dd7d15b Bernardo Dal Seno
    diff_policy = {
908 0f511c8a Bernardo Dal Seno
      constants.ISPECS_MINMAX: diff_minmax
909 5dd7d15b Bernardo Dal Seno
      }
910 da5f09ef Bernardo Dal Seno
    if not isgroup:
911 da5f09ef Bernardo Dal Seno
      diff_policy[constants.ISPECS_STD] = diff_std
912 5eacbcae Thomas Thrainer
    new_policy = common.GetUpdatedIPolicy(old_policy, diff_policy,
913 5eacbcae Thomas Thrainer
                                          group_policy=isgroup)
914 da5f09ef Bernardo Dal Seno
915 da5f09ef Bernardo Dal Seno
    self.assertTrue(constants.ISPECS_MINMAX in new_policy)
916 0f511c8a Bernardo Dal Seno
    self.assertEqual(new_policy[constants.ISPECS_MINMAX], diff_minmax)
917 5dd7d15b Bernardo Dal Seno
    for key in old_policy:
918 5dd7d15b Bernardo Dal Seno
      if not key in diff_policy:
919 5dd7d15b Bernardo Dal Seno
        self.assertTrue(key in new_policy)
920 5dd7d15b Bernardo Dal Seno
        self.assertEqual(new_policy[key], old_policy[key])
921 da5f09ef Bernardo Dal Seno
922 da5f09ef Bernardo Dal Seno
    if not isgroup:
923 da5f09ef Bernardo Dal Seno
      new_std = new_policy[constants.ISPECS_STD]
924 da5f09ef Bernardo Dal Seno
      for key in diff_std:
925 da5f09ef Bernardo Dal Seno
        self.assertTrue(key in new_std)
926 da5f09ef Bernardo Dal Seno
        self.assertEqual(new_std[key], diff_std[key])
927 0f511c8a Bernardo Dal Seno
      old_std = old_policy.get(constants.ISPECS_STD, {})
928 0f511c8a Bernardo Dal Seno
      for key in old_std:
929 0f511c8a Bernardo Dal Seno
        self.assertTrue(key in new_std)
930 0f511c8a Bernardo Dal Seno
        if key not in diff_std:
931 0f511c8a Bernardo Dal Seno
          self.assertEqual(new_std[key], old_std[key])
932 da5f09ef Bernardo Dal Seno
933 0f511c8a Bernardo Dal Seno
  def _TestSet(self, old_policy, diff_policy, isgroup):
934 5eacbcae Thomas Thrainer
    new_policy = common.GetUpdatedIPolicy(old_policy, diff_policy,
935 5dd7d15b Bernardo Dal Seno
                                           group_policy=isgroup)
936 5dd7d15b Bernardo Dal Seno
    for key in diff_policy:
937 5dd7d15b Bernardo Dal Seno
      self.assertTrue(key in new_policy)
938 5dd7d15b Bernardo Dal Seno
      self.assertEqual(new_policy[key], diff_policy[key])
939 5dd7d15b Bernardo Dal Seno
    for key in old_policy:
940 5dd7d15b Bernardo Dal Seno
      if not key in diff_policy:
941 5dd7d15b Bernardo Dal Seno
        self.assertTrue(key in new_policy)
942 5dd7d15b Bernardo Dal Seno
        self.assertEqual(new_policy[key], old_policy[key])
943 5dd7d15b Bernardo Dal Seno
944 5dd7d15b Bernardo Dal Seno
  def testSet(self):
945 0f511c8a Bernardo Dal Seno
    diff_policy = {
946 0f511c8a Bernardo Dal Seno
      constants.IPOLICY_VCPU_RATIO: 3,
947 0f511c8a Bernardo Dal Seno
      constants.IPOLICY_DTS: [constants.DT_FILE],
948 0f511c8a Bernardo Dal Seno
      }
949 0f511c8a Bernardo Dal Seno
    self._TestSet(self._OLD_GROUP_POLICY, diff_policy, True)
950 5dd7d15b Bernardo Dal Seno
    self._TestSetSpecs(self._OLD_GROUP_POLICY, True)
951 0f511c8a Bernardo Dal Seno
    self._TestSet({}, diff_policy, True)
952 0f511c8a Bernardo Dal Seno
    self._TestSetSpecs({}, True)
953 0f511c8a Bernardo Dal Seno
    self._TestSet(self._OLD_CLUSTER_POLICY, diff_policy, False)
954 5dd7d15b Bernardo Dal Seno
    self._TestSetSpecs(self._OLD_CLUSTER_POLICY, False)
955 5dd7d15b Bernardo Dal Seno
956 5dd7d15b Bernardo Dal Seno
  def testUnset(self):
957 5dd7d15b Bernardo Dal Seno
    old_policy = self._OLD_GROUP_POLICY
958 5dd7d15b Bernardo Dal Seno
    diff_policy = {
959 5dd7d15b Bernardo Dal Seno
      constants.IPOLICY_SPINDLE_RATIO: constants.VALUE_DEFAULT,
960 5dd7d15b Bernardo Dal Seno
      }
961 5eacbcae Thomas Thrainer
    new_policy = common.GetUpdatedIPolicy(old_policy, diff_policy,
962 5eacbcae Thomas Thrainer
                                          group_policy=True)
963 5dd7d15b Bernardo Dal Seno
    for key in diff_policy:
964 5dd7d15b Bernardo Dal Seno
      self.assertFalse(key in new_policy)
965 5dd7d15b Bernardo Dal Seno
    for key in old_policy:
966 5dd7d15b Bernardo Dal Seno
      if not key in diff_policy:
967 5dd7d15b Bernardo Dal Seno
        self.assertTrue(key in new_policy)
968 5dd7d15b Bernardo Dal Seno
        self.assertEqual(new_policy[key], old_policy[key])
969 5dd7d15b Bernardo Dal Seno
970 5eacbcae Thomas Thrainer
    self.assertRaises(errors.OpPrereqError, common.GetUpdatedIPolicy,
971 0f511c8a Bernardo Dal Seno
                      old_policy, diff_policy, group_policy=False)
972 0f511c8a Bernardo Dal Seno
973 41044e04 Bernardo Dal Seno
  def testUnsetEmpty(self):
974 41044e04 Bernardo Dal Seno
    old_policy = {}
975 41044e04 Bernardo Dal Seno
    for key in constants.IPOLICY_ALL_KEYS:
976 41044e04 Bernardo Dal Seno
      diff_policy = {
977 41044e04 Bernardo Dal Seno
        key: constants.VALUE_DEFAULT,
978 41044e04 Bernardo Dal Seno
        }
979 5eacbcae Thomas Thrainer
    new_policy = common.GetUpdatedIPolicy(old_policy, diff_policy,
980 5eacbcae Thomas Thrainer
                                          group_policy=True)
981 41044e04 Bernardo Dal Seno
    self.assertEqual(new_policy, old_policy)
982 41044e04 Bernardo Dal Seno
983 5dd7d15b Bernardo Dal Seno
  def _TestInvalidKeys(self, old_policy, isgroup):
984 0f511c8a Bernardo Dal Seno
    INVALID_KEY = "this_key_shouldnt_be_allowed"
985 5dd7d15b Bernardo Dal Seno
    INVALID_DICT = {
986 0f511c8a Bernardo Dal Seno
      INVALID_KEY: 3,
987 5dd7d15b Bernardo Dal Seno
      }
988 5dd7d15b Bernardo Dal Seno
    invalid_policy = INVALID_DICT
989 5eacbcae Thomas Thrainer
    self.assertRaises(errors.OpPrereqError, common.GetUpdatedIPolicy,
990 5dd7d15b Bernardo Dal Seno
                      old_policy, invalid_policy, group_policy=isgroup)
991 da5f09ef Bernardo Dal Seno
    invalid_ispecs = {
992 41044e04 Bernardo Dal Seno
      constants.ISPECS_MINMAX: [INVALID_DICT],
993 da5f09ef Bernardo Dal Seno
      }
994 5eacbcae Thomas Thrainer
    self.assertRaises(errors.TypeEnforcementError, common.GetUpdatedIPolicy,
995 da5f09ef Bernardo Dal Seno
                      old_policy, invalid_ispecs, group_policy=isgroup)
996 0f511c8a Bernardo Dal Seno
    if isgroup:
997 0f511c8a Bernardo Dal Seno
      invalid_for_group = {
998 0f511c8a Bernardo Dal Seno
        constants.ISPECS_STD: constants.IPOLICY_DEFAULTS[constants.ISPECS_STD],
999 5dd7d15b Bernardo Dal Seno
        }
1000 5eacbcae Thomas Thrainer
      self.assertRaises(errors.OpPrereqError, common.GetUpdatedIPolicy,
1001 0f511c8a Bernardo Dal Seno
                        old_policy, invalid_for_group, group_policy=isgroup)
1002 0f511c8a Bernardo Dal Seno
    good_ispecs = self._OLD_CLUSTER_POLICY[constants.ISPECS_MINMAX]
1003 0f511c8a Bernardo Dal Seno
    invalid_ispecs = copy.deepcopy(good_ispecs)
1004 0f511c8a Bernardo Dal Seno
    invalid_policy = {
1005 0f511c8a Bernardo Dal Seno
      constants.ISPECS_MINMAX: invalid_ispecs,
1006 0f511c8a Bernardo Dal Seno
      }
1007 41044e04 Bernardo Dal Seno
    for minmax in invalid_ispecs:
1008 41044e04 Bernardo Dal Seno
      for key in constants.ISPECS_MINMAX_KEYS:
1009 41044e04 Bernardo Dal Seno
        ispec = minmax[key]
1010 41044e04 Bernardo Dal Seno
        ispec[INVALID_KEY] = None
1011 0f511c8a Bernardo Dal Seno
        self.assertRaises(errors.TypeEnforcementError,
1012 5eacbcae Thomas Thrainer
                          common.GetUpdatedIPolicy, old_policy,
1013 41044e04 Bernardo Dal Seno
                          invalid_policy, group_policy=isgroup)
1014 41044e04 Bernardo Dal Seno
        del ispec[INVALID_KEY]
1015 41044e04 Bernardo Dal Seno
        for par in constants.ISPECS_PARAMETERS:
1016 41044e04 Bernardo Dal Seno
          oldv = ispec[par]
1017 41044e04 Bernardo Dal Seno
          ispec[par] = "this_is_not_good"
1018 41044e04 Bernardo Dal Seno
          self.assertRaises(errors.TypeEnforcementError,
1019 5eacbcae Thomas Thrainer
                            common.GetUpdatedIPolicy,
1020 41044e04 Bernardo Dal Seno
                            old_policy, invalid_policy, group_policy=isgroup)
1021 41044e04 Bernardo Dal Seno
          ispec[par] = oldv
1022 0f511c8a Bernardo Dal Seno
    # This is to make sure that no two errors were present during the tests
1023 5eacbcae Thomas Thrainer
    common.GetUpdatedIPolicy(old_policy, invalid_policy,
1024 5eacbcae Thomas Thrainer
                             group_policy=isgroup)
1025 5dd7d15b Bernardo Dal Seno
1026 5dd7d15b Bernardo Dal Seno
  def testInvalidKeys(self):
1027 5dd7d15b Bernardo Dal Seno
    self._TestInvalidKeys(self._OLD_GROUP_POLICY, True)
1028 5dd7d15b Bernardo Dal Seno
    self._TestInvalidKeys(self._OLD_CLUSTER_POLICY, False)
1029 5dd7d15b Bernardo Dal Seno
1030 0f511c8a Bernardo Dal Seno
  def testInvalidValues(self):
1031 0f511c8a Bernardo Dal Seno
    for par in (constants.IPOLICY_PARAMETERS |
1032 0f511c8a Bernardo Dal Seno
                frozenset([constants.IPOLICY_DTS])):
1033 0f511c8a Bernardo Dal Seno
      bad_policy = {
1034 0f511c8a Bernardo Dal Seno
        par: "invalid_value",
1035 0f511c8a Bernardo Dal Seno
        }
1036 5eacbcae Thomas Thrainer
      self.assertRaises(errors.OpPrereqError, common.GetUpdatedIPolicy, {},
1037 0f511c8a Bernardo Dal Seno
                        bad_policy, group_policy=True)
1038 5dd7d15b Bernardo Dal Seno
1039 66222813 Thomas Thrainer
1040 66222813 Thomas Thrainer
class TestCopyLockList(unittest.TestCase):
1041 66222813 Thomas Thrainer
  def test(self):
1042 66222813 Thomas Thrainer
    self.assertEqual(instance_utils.CopyLockList([]), [])
1043 66222813 Thomas Thrainer
    self.assertEqual(instance_utils.CopyLockList(None), None)
1044 66222813 Thomas Thrainer
    self.assertEqual(instance_utils.CopyLockList(locking.ALL_SET),
1045 66222813 Thomas Thrainer
                     locking.ALL_SET)
1046 66222813 Thomas Thrainer
1047 66222813 Thomas Thrainer
    names = ["foo", "bar"]
1048 66222813 Thomas Thrainer
    output = instance_utils.CopyLockList(names)
1049 66222813 Thomas Thrainer
    self.assertEqual(names, output)
1050 66222813 Thomas Thrainer
    self.assertNotEqual(id(names), id(output), msg="List was not copied")
1051 66222813 Thomas Thrainer
1052 66222813 Thomas Thrainer
1053 b98bf262 Michael Hanselmann
if __name__ == "__main__":
1054 25231ec5 Michael Hanselmann
  testutils.GanetiTestProgram()