Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (63.6 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 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 da5f09ef Bernardo Dal Seno
    self.ispecs = {
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 da5f09ef Bernardo Dal Seno
                                              self.ispecs, 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 da5f09ef Bernardo Dal Seno
                                              self.ispecs,
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 da5f09ef Bernardo Dal Seno
                                              self.ispecs, 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 da5f09ef Bernardo Dal Seno
                                              self.ispecs, 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 da5f09ef Bernardo Dal Seno
                                                self.ispecs, 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 da5f09ef Bernardo Dal Seno
      min_v = self.ispecs[constants.ISPECS_MIN].get(name, val)
630 da5f09ef Bernardo Dal Seno
      max_v = self.ispecs[constants.ISPECS_MAX].get(name, val)
631 0c2e59ac Iustin Pop
      self.assertEqual(cmdlib._ComputeMinMaxSpec(name, None,
632 da5f09ef Bernardo Dal Seno
                                                 self.ispecs, 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 da5f09ef Bernardo Dal Seno
                                                 self.ispecs, 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 da5f09ef Bernardo Dal Seno
      self.assertTrue(cmdlib._ComputeMinMaxSpec(name, None, self.ispecs, 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 da5f09ef Bernardo Dal Seno
    constants.ISPECS_MINMAX: NotImplemented,
677 cc4b2676 Bernardo Dal Seno
    }
678 cc4b2676 Bernardo Dal Seno
679 0fb81174 René Nussbaumer
  def test(self):
680 0e68bf27 René Nussbaumer
    compute_fn = _ValidateComputeMinMaxSpec
681 cc4b2676 Bernardo Dal Seno
    ret = cmdlib._ComputeIPolicySpecViolation(self._MICRO_IPOL, 1024, 1, 1, 1,
682 cc4b2676 Bernardo Dal Seno
                                              [1024], 1, constants.DT_PLAIN,
683 cc4b2676 Bernardo Dal Seno
                                              _compute_fn=compute_fn)
684 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
685 0fb81174 René Nussbaumer
686 cc4b2676 Bernardo Dal Seno
  def testDiskFull(self):
687 cc4b2676 Bernardo Dal Seno
    compute_fn = _NoDiskComputeMinMaxSpec
688 cc4b2676 Bernardo Dal Seno
    ret = cmdlib._ComputeIPolicySpecViolation(self._MICRO_IPOL, 1024, 1, 1, 1,
689 cc4b2676 Bernardo Dal Seno
                                              [1024], 1, constants.DT_PLAIN,
690 cc4b2676 Bernardo Dal Seno
                                              _compute_fn=compute_fn)
691 cc4b2676 Bernardo Dal Seno
    self.assertEqual(ret, [constants.ISPEC_DISK_COUNT])
692 cc4b2676 Bernardo Dal Seno
693 cc4b2676 Bernardo Dal Seno
  def testDiskLess(self):
694 cc4b2676 Bernardo Dal Seno
    compute_fn = _NoDiskComputeMinMaxSpec
695 cc4b2676 Bernardo Dal Seno
    ret = cmdlib._ComputeIPolicySpecViolation(self._MICRO_IPOL, 1024, 1, 1, 1,
696 cc4b2676 Bernardo Dal Seno
                                              [1024], 1, constants.DT_DISKLESS,
697 cc4b2676 Bernardo Dal Seno
                                              _compute_fn=compute_fn)
698 cc4b2676 Bernardo Dal Seno
    self.assertEqual(ret, [])
699 cc4b2676 Bernardo Dal Seno
700 cc4b2676 Bernardo Dal Seno
  def testWrongTemplates(self):
701 cc4b2676 Bernardo Dal Seno
    compute_fn = _ValidateComputeMinMaxSpec
702 cc4b2676 Bernardo Dal Seno
    ret = cmdlib._ComputeIPolicySpecViolation(self._MICRO_IPOL, 1024, 1, 1, 1,
703 cc4b2676 Bernardo Dal Seno
                                              [1024], 1, constants.DT_DRBD8,
704 cc4b2676 Bernardo Dal Seno
                                              _compute_fn=compute_fn)
705 cc4b2676 Bernardo Dal Seno
    self.assertEqual(len(ret), 1)
706 cc4b2676 Bernardo Dal Seno
    self.assertTrue("Disk template" in ret[0])
707 cc4b2676 Bernardo Dal Seno
708 0fb81174 René Nussbaumer
  def testInvalidArguments(self):
709 0fb81174 René Nussbaumer
    self.assertRaises(AssertionError, cmdlib._ComputeIPolicySpecViolation,
710 cc4b2676 Bernardo Dal Seno
                      self._MICRO_IPOL, 1024, 1, 1, 1, [], 1,
711 cc4b2676 Bernardo Dal Seno
                      constants.DT_PLAIN,)
712 0fb81174 René Nussbaumer
713 0fb81174 René Nussbaumer
  def testInvalidSpec(self):
714 553cb5f7 René Nussbaumer
    spec = _SpecWrapper([None, False, "foo", None, "bar", None])
715 0e68bf27 René Nussbaumer
    compute_fn = spec.ComputeMinMaxSpec
716 cc4b2676 Bernardo Dal Seno
    ret = cmdlib._ComputeIPolicySpecViolation(self._MICRO_IPOL, 1024, 1, 1, 1,
717 cc4b2676 Bernardo Dal Seno
                                              [1024], 1, constants.DT_PLAIN,
718 cc4b2676 Bernardo Dal Seno
                                              _compute_fn=compute_fn)
719 0fb81174 René Nussbaumer
    self.assertEqual(ret, ["foo", "bar"])
720 0fb81174 René Nussbaumer
    self.assertFalse(spec.spec)
721 0fb81174 René Nussbaumer
722 0fb81174 René Nussbaumer
723 0fb81174 René Nussbaumer
class _StubComputeIPolicySpecViolation:
724 553cb5f7 René Nussbaumer
  def __init__(self, mem_size, cpu_count, disk_count, nic_count, disk_sizes,
725 cc4b2676 Bernardo Dal Seno
               spindle_use, disk_template):
726 0fb81174 René Nussbaumer
    self.mem_size = mem_size
727 0fb81174 René Nussbaumer
    self.cpu_count = cpu_count
728 0fb81174 René Nussbaumer
    self.disk_count = disk_count
729 0fb81174 René Nussbaumer
    self.nic_count = nic_count
730 0fb81174 René Nussbaumer
    self.disk_sizes = disk_sizes
731 553cb5f7 René Nussbaumer
    self.spindle_use = spindle_use
732 cc4b2676 Bernardo Dal Seno
    self.disk_template = disk_template
733 0fb81174 René Nussbaumer
734 553cb5f7 René Nussbaumer
  def __call__(self, _, mem_size, cpu_count, disk_count, nic_count, disk_sizes,
735 cc4b2676 Bernardo Dal Seno
               spindle_use, disk_template):
736 0fb81174 René Nussbaumer
    assert self.mem_size == mem_size
737 0fb81174 René Nussbaumer
    assert self.cpu_count == cpu_count
738 0fb81174 René Nussbaumer
    assert self.disk_count == disk_count
739 0fb81174 René Nussbaumer
    assert self.nic_count == nic_count
740 0fb81174 René Nussbaumer
    assert self.disk_sizes == disk_sizes
741 553cb5f7 René Nussbaumer
    assert self.spindle_use == spindle_use
742 cc4b2676 Bernardo Dal Seno
    assert self.disk_template == disk_template
743 0fb81174 René Nussbaumer
744 0fb81174 René Nussbaumer
    return []
745 0fb81174 René Nussbaumer
746 0fb81174 René Nussbaumer
747 2477c1c5 Bernardo Dal Seno
class _FakeConfigForComputeIPolicyInstanceViolation:
748 2477c1c5 Bernardo Dal Seno
  def __init__(self, be):
749 2477c1c5 Bernardo Dal Seno
    self.cluster = objects.Cluster(beparams={"default": be})
750 2477c1c5 Bernardo Dal Seno
751 2477c1c5 Bernardo Dal Seno
  def GetClusterInfo(self):
752 2477c1c5 Bernardo Dal Seno
    return self.cluster
753 2477c1c5 Bernardo Dal Seno
754 2477c1c5 Bernardo Dal Seno
755 0fb81174 René Nussbaumer
class TestComputeIPolicyInstanceViolation(unittest.TestCase):
756 0fb81174 René Nussbaumer
  def test(self):
757 0fb81174 René Nussbaumer
    beparams = {
758 0fb81174 René Nussbaumer
      constants.BE_MAXMEM: 2048,
759 0fb81174 René Nussbaumer
      constants.BE_VCPUS: 2,
760 34700f5b René Nussbaumer
      constants.BE_SPINDLE_USE: 4,
761 0fb81174 René Nussbaumer
      }
762 0fb81174 René Nussbaumer
    disks = [objects.Disk(size=512)]
763 2477c1c5 Bernardo Dal Seno
    cfg = _FakeConfigForComputeIPolicyInstanceViolation(beparams)
764 cc4b2676 Bernardo Dal Seno
    instance = objects.Instance(beparams=beparams, disks=disks, nics=[],
765 cc4b2676 Bernardo Dal Seno
                                disk_template=constants.DT_PLAIN)
766 cc4b2676 Bernardo Dal Seno
    stub = _StubComputeIPolicySpecViolation(2048, 2, 1, 0, [512], 4,
767 cc4b2676 Bernardo Dal Seno
                                            constants.DT_PLAIN)
768 0fb81174 René Nussbaumer
    ret = cmdlib._ComputeIPolicyInstanceViolation(NotImplemented, instance,
769 2477c1c5 Bernardo Dal Seno
                                                  cfg, _compute_fn=stub)
770 2477c1c5 Bernardo Dal Seno
    self.assertEqual(ret, [])
771 2477c1c5 Bernardo Dal Seno
    instance2 = objects.Instance(beparams={}, disks=disks, nics=[],
772 2477c1c5 Bernardo Dal Seno
                                 disk_template=constants.DT_PLAIN)
773 2477c1c5 Bernardo Dal Seno
    ret = cmdlib._ComputeIPolicyInstanceViolation(NotImplemented, instance2,
774 2477c1c5 Bernardo Dal Seno
                                                  cfg, _compute_fn=stub)
775 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
776 0fb81174 René Nussbaumer
777 0fb81174 René Nussbaumer
778 0fb81174 René Nussbaumer
class TestComputeIPolicyInstanceSpecViolation(unittest.TestCase):
779 0fb81174 René Nussbaumer
  def test(self):
780 0fb81174 René Nussbaumer
    ispec = {
781 0fb81174 René Nussbaumer
      constants.ISPEC_MEM_SIZE: 2048,
782 0fb81174 René Nussbaumer
      constants.ISPEC_CPU_COUNT: 2,
783 0fb81174 René Nussbaumer
      constants.ISPEC_DISK_COUNT: 1,
784 0fb81174 René Nussbaumer
      constants.ISPEC_DISK_SIZE: [512],
785 0fb81174 René Nussbaumer
      constants.ISPEC_NIC_COUNT: 0,
786 553cb5f7 René Nussbaumer
      constants.ISPEC_SPINDLE_USE: 1,
787 0fb81174 René Nussbaumer
      }
788 cc4b2676 Bernardo Dal Seno
    stub = _StubComputeIPolicySpecViolation(2048, 2, 1, 0, [512], 1,
789 cc4b2676 Bernardo Dal Seno
                                            constants.DT_PLAIN)
790 0fb81174 René Nussbaumer
    ret = cmdlib._ComputeIPolicyInstanceSpecViolation(NotImplemented, ispec,
791 cc4b2676 Bernardo Dal Seno
                                                      constants.DT_PLAIN,
792 0fb81174 René Nussbaumer
                                                      _compute_fn=stub)
793 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
794 0fb81174 René Nussbaumer
795 0fb81174 René Nussbaumer
796 0fb81174 René Nussbaumer
class _CallRecorder:
797 0fb81174 René Nussbaumer
  def __init__(self, return_value=None):
798 0fb81174 René Nussbaumer
    self.called = False
799 0fb81174 René Nussbaumer
    self.return_value = return_value
800 0fb81174 René Nussbaumer
801 0fb81174 René Nussbaumer
  def __call__(self, *args):
802 0fb81174 René Nussbaumer
    self.called = True
803 0fb81174 René Nussbaumer
    return self.return_value
804 0fb81174 René Nussbaumer
805 0fb81174 René Nussbaumer
806 0fb81174 René Nussbaumer
class TestComputeIPolicyNodeViolation(unittest.TestCase):
807 0fb81174 René Nussbaumer
  def setUp(self):
808 0fb81174 René Nussbaumer
    self.recorder = _CallRecorder(return_value=[])
809 0fb81174 René Nussbaumer
810 0fb81174 René Nussbaumer
  def testSameGroup(self):
811 0fb81174 René Nussbaumer
    ret = cmdlib._ComputeIPolicyNodeViolation(NotImplemented, NotImplemented,
812 2477c1c5 Bernardo Dal Seno
                                              "foo", "foo", NotImplemented,
813 0fb81174 René Nussbaumer
                                              _compute_fn=self.recorder)
814 0fb81174 René Nussbaumer
    self.assertFalse(self.recorder.called)
815 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
816 0fb81174 René Nussbaumer
817 0fb81174 René Nussbaumer
  def testDifferentGroup(self):
818 0fb81174 René Nussbaumer
    ret = cmdlib._ComputeIPolicyNodeViolation(NotImplemented, NotImplemented,
819 2477c1c5 Bernardo Dal Seno
                                              "foo", "bar", NotImplemented,
820 0fb81174 René Nussbaumer
                                              _compute_fn=self.recorder)
821 0fb81174 René Nussbaumer
    self.assertTrue(self.recorder.called)
822 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
823 0fb81174 René Nussbaumer
824 0fb81174 René Nussbaumer
825 ff02b60f René Nussbaumer
class _FakeConfigForTargetNodeIPolicy:
826 ff02b60f René Nussbaumer
  def __init__(self, node_info=NotImplemented):
827 ff02b60f René Nussbaumer
    self._node_info = node_info
828 ff02b60f René Nussbaumer
829 ff02b60f René Nussbaumer
  def GetNodeInfo(self, _):
830 ff02b60f René Nussbaumer
    return self._node_info
831 ff02b60f René Nussbaumer
832 ff02b60f René Nussbaumer
833 0fb81174 René Nussbaumer
class TestCheckTargetNodeIPolicy(unittest.TestCase):
834 0fb81174 René Nussbaumer
  def setUp(self):
835 ff02b60f René Nussbaumer
    self.instance = objects.Instance(primary_node="blubb")
836 0fb81174 René Nussbaumer
    self.target_node = objects.Node(group="bar")
837 ff02b60f René Nussbaumer
    node_info = objects.Node(group="foo")
838 ff02b60f René Nussbaumer
    fake_cfg = _FakeConfigForTargetNodeIPolicy(node_info=node_info)
839 ff02b60f René Nussbaumer
    self.lu = _FakeLU(cfg=fake_cfg)
840 0fb81174 René Nussbaumer
841 0fb81174 René Nussbaumer
  def testNoViolation(self):
842 0fb81174 René Nussbaumer
    compute_recoder = _CallRecorder(return_value=[])
843 0fb81174 René Nussbaumer
    cmdlib._CheckTargetNodeIPolicy(self.lu, NotImplemented, self.instance,
844 2477c1c5 Bernardo Dal Seno
                                   self.target_node, NotImplemented,
845 0fb81174 René Nussbaumer
                                   _compute_fn=compute_recoder)
846 0fb81174 René Nussbaumer
    self.assertTrue(compute_recoder.called)
847 0fb81174 René Nussbaumer
    self.assertEqual(self.lu.warning_log, [])
848 0fb81174 René Nussbaumer
849 0fb81174 René Nussbaumer
  def testNoIgnore(self):
850 0fb81174 René Nussbaumer
    compute_recoder = _CallRecorder(return_value=["mem_size not in range"])
851 0fb81174 René Nussbaumer
    self.assertRaises(errors.OpPrereqError, cmdlib._CheckTargetNodeIPolicy,
852 0fb81174 René Nussbaumer
                      self.lu, NotImplemented, self.instance, self.target_node,
853 2477c1c5 Bernardo Dal Seno
                      NotImplemented, _compute_fn=compute_recoder)
854 0fb81174 René Nussbaumer
    self.assertTrue(compute_recoder.called)
855 0fb81174 René Nussbaumer
    self.assertEqual(self.lu.warning_log, [])
856 0fb81174 René Nussbaumer
857 0fb81174 René Nussbaumer
  def testIgnoreViolation(self):
858 0fb81174 René Nussbaumer
    compute_recoder = _CallRecorder(return_value=["mem_size not in range"])
859 0fb81174 René Nussbaumer
    cmdlib._CheckTargetNodeIPolicy(self.lu, NotImplemented, self.instance,
860 2477c1c5 Bernardo Dal Seno
                                   self.target_node, NotImplemented,
861 2477c1c5 Bernardo Dal Seno
                                   ignore=True, _compute_fn=compute_recoder)
862 0fb81174 René Nussbaumer
    self.assertTrue(compute_recoder.called)
863 0fb81174 René Nussbaumer
    msg = ("Instance does not meet target node group's (bar) instance policy:"
864 0fb81174 René Nussbaumer
           " mem_size not in range")
865 0fb81174 René Nussbaumer
    self.assertEqual(self.lu.warning_log, [(msg, ())])
866 0fb81174 René Nussbaumer
867 0fb81174 René Nussbaumer
868 8301885b Michael Hanselmann
class TestApplyContainerMods(unittest.TestCase):
869 8301885b Michael Hanselmann
  def testEmptyContainer(self):
870 8301885b Michael Hanselmann
    container = []
871 8301885b Michael Hanselmann
    chgdesc = []
872 8301885b Michael Hanselmann
    cmdlib.ApplyContainerMods("test", container, chgdesc, [], None, None, None)
873 8301885b Michael Hanselmann
    self.assertEqual(container, [])
874 8301885b Michael Hanselmann
    self.assertEqual(chgdesc, [])
875 8301885b Michael Hanselmann
876 8301885b Michael Hanselmann
  def testAdd(self):
877 8301885b Michael Hanselmann
    container = []
878 8301885b Michael Hanselmann
    chgdesc = []
879 8301885b Michael Hanselmann
    mods = cmdlib.PrepareContainerMods([
880 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "Hello"),
881 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "World"),
882 8301885b Michael Hanselmann
      (constants.DDM_ADD, 0, "Start"),
883 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "End"),
884 8301885b Michael Hanselmann
      ], None)
885 8301885b Michael Hanselmann
    cmdlib.ApplyContainerMods("test", container, chgdesc, mods,
886 8301885b Michael Hanselmann
                              None, None, None)
887 8301885b Michael Hanselmann
    self.assertEqual(container, ["Start", "Hello", "World", "End"])
888 8301885b Michael Hanselmann
    self.assertEqual(chgdesc, [])
889 8301885b Michael Hanselmann
890 35554b4f Michael Hanselmann
    mods = cmdlib.PrepareContainerMods([
891 35554b4f Michael Hanselmann
      (constants.DDM_ADD, 0, "zero"),
892 35554b4f Michael Hanselmann
      (constants.DDM_ADD, 3, "Added"),
893 35554b4f Michael Hanselmann
      (constants.DDM_ADD, 5, "four"),
894 35554b4f Michael Hanselmann
      (constants.DDM_ADD, 7, "xyz"),
895 35554b4f Michael Hanselmann
      ], None)
896 35554b4f Michael Hanselmann
    cmdlib.ApplyContainerMods("test", container, chgdesc, mods,
897 35554b4f Michael Hanselmann
                              None, None, None)
898 35554b4f Michael Hanselmann
    self.assertEqual(container,
899 35554b4f Michael Hanselmann
                     ["zero", "Start", "Hello", "Added", "World", "four",
900 35554b4f Michael Hanselmann
                      "End", "xyz"])
901 35554b4f Michael Hanselmann
    self.assertEqual(chgdesc, [])
902 35554b4f Michael Hanselmann
903 35554b4f Michael Hanselmann
    for idx in [-2, len(container) + 1]:
904 35554b4f Michael Hanselmann
      mods = cmdlib.PrepareContainerMods([
905 35554b4f Michael Hanselmann
        (constants.DDM_ADD, idx, "error"),
906 35554b4f Michael Hanselmann
        ], None)
907 35554b4f Michael Hanselmann
      self.assertRaises(IndexError, cmdlib.ApplyContainerMods,
908 35554b4f Michael Hanselmann
                        "test", container, None, mods, None, None, None)
909 35554b4f Michael Hanselmann
910 8301885b Michael Hanselmann
  def testRemoveError(self):
911 8301885b Michael Hanselmann
    for idx in [0, 1, 2, 100, -1, -4]:
912 8301885b Michael Hanselmann
      mods = cmdlib.PrepareContainerMods([
913 8301885b Michael Hanselmann
        (constants.DDM_REMOVE, idx, None),
914 8301885b Michael Hanselmann
        ], None)
915 8301885b Michael Hanselmann
      self.assertRaises(IndexError, cmdlib.ApplyContainerMods,
916 8301885b Michael Hanselmann
                        "test", [], None, mods, None, None, None)
917 8301885b Michael Hanselmann
918 8301885b Michael Hanselmann
    mods = cmdlib.PrepareContainerMods([
919 8301885b Michael Hanselmann
      (constants.DDM_REMOVE, 0, object()),
920 8301885b Michael Hanselmann
      ], None)
921 8301885b Michael Hanselmann
    self.assertRaises(AssertionError, cmdlib.ApplyContainerMods,
922 8301885b Michael Hanselmann
                      "test", [""], None, mods, None, None, None)
923 8301885b Michael Hanselmann
924 8301885b Michael Hanselmann
  def testAddError(self):
925 35554b4f Michael Hanselmann
    for idx in range(-100, -1) + [100]:
926 8301885b Michael Hanselmann
      mods = cmdlib.PrepareContainerMods([
927 8301885b Michael Hanselmann
        (constants.DDM_ADD, idx, None),
928 8301885b Michael Hanselmann
        ], None)
929 8301885b Michael Hanselmann
      self.assertRaises(IndexError, cmdlib.ApplyContainerMods,
930 8301885b Michael Hanselmann
                        "test", [], None, mods, None, None, None)
931 8301885b Michael Hanselmann
932 8301885b Michael Hanselmann
  def testRemove(self):
933 8301885b Michael Hanselmann
    container = ["item 1", "item 2"]
934 8301885b Michael Hanselmann
    mods = cmdlib.PrepareContainerMods([
935 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "aaa"),
936 8301885b Michael Hanselmann
      (constants.DDM_REMOVE, -1, None),
937 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "bbb"),
938 8301885b Michael Hanselmann
      ], None)
939 8301885b Michael Hanselmann
    chgdesc = []
940 8301885b Michael Hanselmann
    cmdlib.ApplyContainerMods("test", container, chgdesc, mods,
941 8301885b Michael Hanselmann
                              None, None, None)
942 8301885b Michael Hanselmann
    self.assertEqual(container, ["item 1", "item 2", "bbb"])
943 8301885b Michael Hanselmann
    self.assertEqual(chgdesc, [
944 8301885b Michael Hanselmann
      ("test/2", "remove"),
945 8301885b Michael Hanselmann
      ])
946 8301885b Michael Hanselmann
947 35554b4f Michael Hanselmann
  def testModify(self):
948 35554b4f Michael Hanselmann
    container = ["item 1", "item 2"]
949 35554b4f Michael Hanselmann
    mods = cmdlib.PrepareContainerMods([
950 35554b4f Michael Hanselmann
      (constants.DDM_MODIFY, -1, "a"),
951 35554b4f Michael Hanselmann
      (constants.DDM_MODIFY, 0, "b"),
952 35554b4f Michael Hanselmann
      (constants.DDM_MODIFY, 1, "c"),
953 35554b4f Michael Hanselmann
      ], None)
954 35554b4f Michael Hanselmann
    chgdesc = []
955 35554b4f Michael Hanselmann
    cmdlib.ApplyContainerMods("test", container, chgdesc, mods,
956 35554b4f Michael Hanselmann
                              None, None, None)
957 35554b4f Michael Hanselmann
    self.assertEqual(container, ["item 1", "item 2"])
958 35554b4f Michael Hanselmann
    self.assertEqual(chgdesc, [])
959 35554b4f Michael Hanselmann
960 35554b4f Michael Hanselmann
    for idx in [-2, len(container) + 1]:
961 35554b4f Michael Hanselmann
      mods = cmdlib.PrepareContainerMods([
962 35554b4f Michael Hanselmann
        (constants.DDM_MODIFY, idx, "error"),
963 35554b4f Michael Hanselmann
        ], None)
964 35554b4f Michael Hanselmann
      self.assertRaises(IndexError, cmdlib.ApplyContainerMods,
965 35554b4f Michael Hanselmann
                        "test", container, None, mods, None, None, None)
966 35554b4f Michael Hanselmann
967 8301885b Michael Hanselmann
  class _PrivateData:
968 8301885b Michael Hanselmann
    def __init__(self):
969 8301885b Michael Hanselmann
      self.data = None
970 8301885b Michael Hanselmann
971 8301885b Michael Hanselmann
  @staticmethod
972 efcfa99d Michael Hanselmann
  def _CreateTestFn(idx, params, private):
973 8301885b Michael Hanselmann
    private.data = ("add", idx, params)
974 efcfa99d Michael Hanselmann
    return ((100 * idx, params), [
975 efcfa99d Michael Hanselmann
      ("test/%s" % idx, hex(idx)),
976 efcfa99d Michael Hanselmann
      ])
977 8301885b Michael Hanselmann
978 8301885b Michael Hanselmann
  @staticmethod
979 efcfa99d Michael Hanselmann
  def _ModifyTestFn(idx, item, params, private):
980 8301885b Michael Hanselmann
    private.data = ("modify", idx, params)
981 efcfa99d Michael Hanselmann
    return [
982 efcfa99d Michael Hanselmann
      ("test/%s" % idx, "modify %s" % params),
983 efcfa99d Michael Hanselmann
      ]
984 8301885b Michael Hanselmann
985 8301885b Michael Hanselmann
  @staticmethod
986 efcfa99d Michael Hanselmann
  def _RemoveTestFn(idx, item, private):
987 8301885b Michael Hanselmann
    private.data = ("remove", idx, item)
988 8301885b Michael Hanselmann
989 8301885b Michael Hanselmann
  def testAddWithCreateFunction(self):
990 8301885b Michael Hanselmann
    container = []
991 8301885b Michael Hanselmann
    chgdesc = []
992 8301885b Michael Hanselmann
    mods = cmdlib.PrepareContainerMods([
993 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "Hello"),
994 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "World"),
995 8301885b Michael Hanselmann
      (constants.DDM_ADD, 0, "Start"),
996 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "End"),
997 8301885b Michael Hanselmann
      (constants.DDM_REMOVE, 2, None),
998 8301885b Michael Hanselmann
      (constants.DDM_MODIFY, -1, "foobar"),
999 8301885b Michael Hanselmann
      (constants.DDM_REMOVE, 2, None),
1000 8301885b Michael Hanselmann
      (constants.DDM_ADD, 1, "More"),
1001 8301885b Michael Hanselmann
      ], self._PrivateData)
1002 8301885b Michael Hanselmann
    cmdlib.ApplyContainerMods("test", container, chgdesc, mods,
1003 8301885b Michael Hanselmann
      self._CreateTestFn, self._ModifyTestFn, self._RemoveTestFn)
1004 8301885b Michael Hanselmann
    self.assertEqual(container, [
1005 35554b4f Michael Hanselmann
      (000, "Start"),
1006 35554b4f Michael Hanselmann
      (100, "More"),
1007 35554b4f Michael Hanselmann
      (000, "Hello"),
1008 8301885b Michael Hanselmann
      ])
1009 8301885b Michael Hanselmann
    self.assertEqual(chgdesc, [
1010 8301885b Michael Hanselmann
      ("test/0", "0x0"),
1011 8301885b Michael Hanselmann
      ("test/1", "0x1"),
1012 35554b4f Michael Hanselmann
      ("test/0", "0x0"),
1013 8301885b Michael Hanselmann
      ("test/3", "0x3"),
1014 8301885b Michael Hanselmann
      ("test/2", "remove"),
1015 8301885b Michael Hanselmann
      ("test/2", "modify foobar"),
1016 8301885b Michael Hanselmann
      ("test/2", "remove"),
1017 35554b4f Michael Hanselmann
      ("test/1", "0x1")
1018 8301885b Michael Hanselmann
      ])
1019 8301885b Michael Hanselmann
    self.assertTrue(compat.all(op == private.data[0]
1020 8301885b Michael Hanselmann
                               for (op, _, _, private) in mods))
1021 8301885b Michael Hanselmann
    self.assertEqual([private.data for (op, _, _, private) in mods], [
1022 8301885b Michael Hanselmann
      ("add", 0, "Hello"),
1023 8301885b Michael Hanselmann
      ("add", 1, "World"),
1024 35554b4f Michael Hanselmann
      ("add", 0, "Start"),
1025 8301885b Michael Hanselmann
      ("add", 3, "End"),
1026 8301885b Michael Hanselmann
      ("remove", 2, (100, "World")),
1027 8301885b Michael Hanselmann
      ("modify", 2, "foobar"),
1028 8301885b Michael Hanselmann
      ("remove", 2, (300, "End")),
1029 35554b4f Michael Hanselmann
      ("add", 1, "More"),
1030 8301885b Michael Hanselmann
      ])
1031 8301885b Michael Hanselmann
1032 8301885b Michael Hanselmann
1033 a8e3e009 Michael Hanselmann
class _FakeConfigForGenDiskTemplate:
1034 a8e3e009 Michael Hanselmann
  def __init__(self):
1035 a8e3e009 Michael Hanselmann
    self._unique_id = itertools.count()
1036 a8e3e009 Michael Hanselmann
    self._drbd_minor = itertools.count(20)
1037 a8e3e009 Michael Hanselmann
    self._port = itertools.count(constants.FIRST_DRBD_PORT)
1038 a8e3e009 Michael Hanselmann
    self._secret = itertools.count()
1039 a8e3e009 Michael Hanselmann
1040 a8e3e009 Michael Hanselmann
  def GetVGName(self):
1041 a8e3e009 Michael Hanselmann
    return "testvg"
1042 a8e3e009 Michael Hanselmann
1043 a8e3e009 Michael Hanselmann
  def GenerateUniqueID(self, ec_id):
1044 a8e3e009 Michael Hanselmann
    return "ec%s-uq%s" % (ec_id, self._unique_id.next())
1045 a8e3e009 Michael Hanselmann
1046 a8e3e009 Michael Hanselmann
  def AllocateDRBDMinor(self, nodes, instance):
1047 a8e3e009 Michael Hanselmann
    return [self._drbd_minor.next()
1048 a8e3e009 Michael Hanselmann
            for _ in nodes]
1049 a8e3e009 Michael Hanselmann
1050 a8e3e009 Michael Hanselmann
  def AllocatePort(self):
1051 a8e3e009 Michael Hanselmann
    return self._port.next()
1052 a8e3e009 Michael Hanselmann
1053 a8e3e009 Michael Hanselmann
  def GenerateDRBDSecret(self, ec_id):
1054 a8e3e009 Michael Hanselmann
    return "ec%s-secret%s" % (ec_id, self._secret.next())
1055 a8e3e009 Michael Hanselmann
1056 99ccf8b9 René Nussbaumer
  def GetInstanceInfo(self, _):
1057 99ccf8b9 René Nussbaumer
    return "foobar"
1058 99ccf8b9 René Nussbaumer
1059 a8e3e009 Michael Hanselmann
1060 a8e3e009 Michael Hanselmann
class _FakeProcForGenDiskTemplate:
1061 a8e3e009 Michael Hanselmann
  def GetECId(self):
1062 a8e3e009 Michael Hanselmann
    return 0
1063 a8e3e009 Michael Hanselmann
1064 a8e3e009 Michael Hanselmann
1065 a8e3e009 Michael Hanselmann
class TestGenerateDiskTemplate(unittest.TestCase):
1066 a8e3e009 Michael Hanselmann
  def setUp(self):
1067 a8e3e009 Michael Hanselmann
    nodegroup = objects.NodeGroup(name="ng")
1068 a8e3e009 Michael Hanselmann
    nodegroup.UpgradeConfig()
1069 a8e3e009 Michael Hanselmann
1070 a8e3e009 Michael Hanselmann
    cfg = _FakeConfigForGenDiskTemplate()
1071 a8e3e009 Michael Hanselmann
    proc = _FakeProcForGenDiskTemplate()
1072 a8e3e009 Michael Hanselmann
1073 a8e3e009 Michael Hanselmann
    self.lu = _FakeLU(cfg=cfg, proc=proc)
1074 a8e3e009 Michael Hanselmann
    self.nodegroup = nodegroup
1075 a8e3e009 Michael Hanselmann
1076 99ccf8b9 René Nussbaumer
  @staticmethod
1077 99ccf8b9 René Nussbaumer
  def GetDiskParams():
1078 99ccf8b9 René Nussbaumer
    return copy.deepcopy(constants.DISK_DT_DEFAULTS)
1079 99ccf8b9 René Nussbaumer
1080 a8e3e009 Michael Hanselmann
  def testWrongDiskTemplate(self):
1081 a8e3e009 Michael Hanselmann
    gdt = cmdlib._GenerateDiskTemplate
1082 a8e3e009 Michael Hanselmann
    disk_template = "##unknown##"
1083 a8e3e009 Michael Hanselmann
1084 a8e3e009 Michael Hanselmann
    assert disk_template not in constants.DISK_TEMPLATES
1085 a8e3e009 Michael Hanselmann
1086 a8e3e009 Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, gdt, self.lu, disk_template,
1087 a8e3e009 Michael Hanselmann
                      "inst26831.example.com", "node30113.example.com", [], [],
1088 a8e3e009 Michael Hanselmann
                      NotImplemented, NotImplemented, 0, self.lu.LogInfo,
1089 99ccf8b9 René Nussbaumer
                      self.GetDiskParams())
1090 a8e3e009 Michael Hanselmann
1091 a8e3e009 Michael Hanselmann
  def testDiskless(self):
1092 a8e3e009 Michael Hanselmann
    gdt = cmdlib._GenerateDiskTemplate
1093 a8e3e009 Michael Hanselmann
1094 a8e3e009 Michael Hanselmann
    result = gdt(self.lu, constants.DT_DISKLESS, "inst27734.example.com",
1095 a8e3e009 Michael Hanselmann
                 "node30113.example.com", [], [],
1096 a8e3e009 Michael Hanselmann
                 NotImplemented, NotImplemented, 0, self.lu.LogInfo,
1097 99ccf8b9 René Nussbaumer
                 self.GetDiskParams())
1098 a8e3e009 Michael Hanselmann
    self.assertEqual(result, [])
1099 a8e3e009 Michael Hanselmann
1100 a8e3e009 Michael Hanselmann
  def _TestTrivialDisk(self, template, disk_info, base_index, exp_dev_type,
1101 a8e3e009 Michael Hanselmann
                       file_storage_dir=NotImplemented,
1102 a8e3e009 Michael Hanselmann
                       file_driver=NotImplemented,
1103 a8e3e009 Michael Hanselmann
                       req_file_storage=NotImplemented,
1104 a8e3e009 Michael Hanselmann
                       req_shr_file_storage=NotImplemented):
1105 a8e3e009 Michael Hanselmann
    gdt = cmdlib._GenerateDiskTemplate
1106 a8e3e009 Michael Hanselmann
1107 a8e3e009 Michael Hanselmann
    map(lambda params: utils.ForceDictType(params,
1108 a8e3e009 Michael Hanselmann
                                           constants.IDISK_PARAMS_TYPES),
1109 a8e3e009 Michael Hanselmann
        disk_info)
1110 a8e3e009 Michael Hanselmann
1111 a8e3e009 Michael Hanselmann
    # Check if non-empty list of secondaries is rejected
1112 a8e3e009 Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, gdt, self.lu,
1113 a8e3e009 Michael Hanselmann
                      template, "inst25088.example.com",
1114 a8e3e009 Michael Hanselmann
                      "node185.example.com", ["node323.example.com"], [],
1115 a8e3e009 Michael Hanselmann
                      NotImplemented, NotImplemented, base_index,
1116 99ccf8b9 René Nussbaumer
                      self.lu.LogInfo, self.GetDiskParams(),
1117 a8e3e009 Michael Hanselmann
                      _req_file_storage=req_file_storage,
1118 a8e3e009 Michael Hanselmann
                      _req_shr_file_storage=req_shr_file_storage)
1119 a8e3e009 Michael Hanselmann
1120 a8e3e009 Michael Hanselmann
    result = gdt(self.lu, template, "inst21662.example.com",
1121 a8e3e009 Michael Hanselmann
                 "node21741.example.com", [],
1122 a8e3e009 Michael Hanselmann
                 disk_info, file_storage_dir, file_driver, base_index,
1123 99ccf8b9 René Nussbaumer
                 self.lu.LogInfo, self.GetDiskParams(),
1124 a8e3e009 Michael Hanselmann
                 _req_file_storage=req_file_storage,
1125 a8e3e009 Michael Hanselmann
                 _req_shr_file_storage=req_shr_file_storage)
1126 a8e3e009 Michael Hanselmann
1127 a8e3e009 Michael Hanselmann
    for (idx, disk) in enumerate(result):
1128 a8e3e009 Michael Hanselmann
      self.assertTrue(isinstance(disk, objects.Disk))
1129 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.dev_type, exp_dev_type)
1130 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.size, disk_info[idx][constants.IDISK_SIZE])
1131 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.mode, disk_info[idx][constants.IDISK_MODE])
1132 a8e3e009 Michael Hanselmann
      self.assertTrue(disk.children is None)
1133 a8e3e009 Michael Hanselmann
1134 0356a13d Michael Hanselmann
    self._CheckIvNames(result, base_index, base_index + len(disk_info))
1135 0356a13d Michael Hanselmann
    cmdlib._UpdateIvNames(base_index, result)
1136 0356a13d Michael Hanselmann
    self._CheckIvNames(result, base_index, base_index + len(disk_info))
1137 a8e3e009 Michael Hanselmann
1138 a8e3e009 Michael Hanselmann
    return result
1139 a8e3e009 Michael Hanselmann
1140 0356a13d Michael Hanselmann
  def _CheckIvNames(self, disks, base_index, end_index):
1141 0356a13d Michael Hanselmann
    self.assertEqual(map(operator.attrgetter("iv_name"), disks),
1142 0356a13d Michael Hanselmann
                     ["disk/%s" % i for i in range(base_index, end_index)])
1143 0356a13d Michael Hanselmann
1144 a8e3e009 Michael Hanselmann
  def testPlain(self):
1145 a8e3e009 Michael Hanselmann
    disk_info = [{
1146 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 1024,
1147 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDWR,
1148 a8e3e009 Michael Hanselmann
      }, {
1149 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 4096,
1150 a8e3e009 Michael Hanselmann
      constants.IDISK_VG: "othervg",
1151 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDWR,
1152 a8e3e009 Michael Hanselmann
      }]
1153 a8e3e009 Michael Hanselmann
1154 a8e3e009 Michael Hanselmann
    result = self._TestTrivialDisk(constants.DT_PLAIN, disk_info, 3,
1155 a8e3e009 Michael Hanselmann
                                   constants.LD_LV)
1156 a8e3e009 Michael Hanselmann
1157 a8e3e009 Michael Hanselmann
    self.assertEqual(map(operator.attrgetter("logical_id"), result), [
1158 a8e3e009 Michael Hanselmann
      ("testvg", "ec0-uq0.disk3"),
1159 a8e3e009 Michael Hanselmann
      ("othervg", "ec0-uq1.disk4"),
1160 a8e3e009 Michael Hanselmann
      ])
1161 a8e3e009 Michael Hanselmann
1162 a8e3e009 Michael Hanselmann
  @staticmethod
1163 a8e3e009 Michael Hanselmann
  def _AllowFileStorage():
1164 a8e3e009 Michael Hanselmann
    pass
1165 a8e3e009 Michael Hanselmann
1166 a8e3e009 Michael Hanselmann
  @staticmethod
1167 a8e3e009 Michael Hanselmann
  def _ForbidFileStorage():
1168 a8e3e009 Michael Hanselmann
    raise errors.OpPrereqError("Disallowed in test")
1169 a8e3e009 Michael Hanselmann
1170 a8e3e009 Michael Hanselmann
  def testFile(self):
1171 a8e3e009 Michael Hanselmann
    self.assertRaises(errors.OpPrereqError, self._TestTrivialDisk,
1172 a8e3e009 Michael Hanselmann
                      constants.DT_FILE, [], 0, NotImplemented,
1173 a8e3e009 Michael Hanselmann
                      req_file_storage=self._ForbidFileStorage)
1174 a8e3e009 Michael Hanselmann
    self.assertRaises(errors.OpPrereqError, self._TestTrivialDisk,
1175 a8e3e009 Michael Hanselmann
                      constants.DT_SHARED_FILE, [], 0, NotImplemented,
1176 a8e3e009 Michael Hanselmann
                      req_shr_file_storage=self._ForbidFileStorage)
1177 a8e3e009 Michael Hanselmann
1178 a8e3e009 Michael Hanselmann
    for disk_template in [constants.DT_FILE, constants.DT_SHARED_FILE]:
1179 a8e3e009 Michael Hanselmann
      disk_info = [{
1180 a8e3e009 Michael Hanselmann
        constants.IDISK_SIZE: 80 * 1024,
1181 a8e3e009 Michael Hanselmann
        constants.IDISK_MODE: constants.DISK_RDONLY,
1182 a8e3e009 Michael Hanselmann
        }, {
1183 a8e3e009 Michael Hanselmann
        constants.IDISK_SIZE: 4096,
1184 a8e3e009 Michael Hanselmann
        constants.IDISK_MODE: constants.DISK_RDWR,
1185 a8e3e009 Michael Hanselmann
        }, {
1186 a8e3e009 Michael Hanselmann
        constants.IDISK_SIZE: 6 * 1024,
1187 a8e3e009 Michael Hanselmann
        constants.IDISK_MODE: constants.DISK_RDWR,
1188 a8e3e009 Michael Hanselmann
        }]
1189 a8e3e009 Michael Hanselmann
1190 a8e3e009 Michael Hanselmann
      result = self._TestTrivialDisk(disk_template, disk_info, 2,
1191 a8e3e009 Michael Hanselmann
        constants.LD_FILE, file_storage_dir="/tmp",
1192 a8e3e009 Michael Hanselmann
        file_driver=constants.FD_BLKTAP,
1193 a8e3e009 Michael Hanselmann
        req_file_storage=self._AllowFileStorage,
1194 a8e3e009 Michael Hanselmann
        req_shr_file_storage=self._AllowFileStorage)
1195 a8e3e009 Michael Hanselmann
1196 a8e3e009 Michael Hanselmann
      self.assertEqual(map(operator.attrgetter("logical_id"), result), [
1197 a8e3e009 Michael Hanselmann
        (constants.FD_BLKTAP, "/tmp/disk2"),
1198 a8e3e009 Michael Hanselmann
        (constants.FD_BLKTAP, "/tmp/disk3"),
1199 a8e3e009 Michael Hanselmann
        (constants.FD_BLKTAP, "/tmp/disk4"),
1200 a8e3e009 Michael Hanselmann
        ])
1201 a8e3e009 Michael Hanselmann
1202 a8e3e009 Michael Hanselmann
  def testBlock(self):
1203 a8e3e009 Michael Hanselmann
    disk_info = [{
1204 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 8 * 1024,
1205 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDWR,
1206 a8e3e009 Michael Hanselmann
      constants.IDISK_ADOPT: "/tmp/some/block/dev",
1207 a8e3e009 Michael Hanselmann
      }]
1208 a8e3e009 Michael Hanselmann
1209 a8e3e009 Michael Hanselmann
    result = self._TestTrivialDisk(constants.DT_BLOCK, disk_info, 10,
1210 a8e3e009 Michael Hanselmann
                                   constants.LD_BLOCKDEV)
1211 a8e3e009 Michael Hanselmann
1212 a8e3e009 Michael Hanselmann
    self.assertEqual(map(operator.attrgetter("logical_id"), result), [
1213 a8e3e009 Michael Hanselmann
      (constants.BLOCKDEV_DRIVER_MANUAL, "/tmp/some/block/dev"),
1214 a8e3e009 Michael Hanselmann
      ])
1215 a8e3e009 Michael Hanselmann
1216 a8e3e009 Michael Hanselmann
  def testRbd(self):
1217 a8e3e009 Michael Hanselmann
    disk_info = [{
1218 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 8 * 1024,
1219 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDONLY,
1220 a8e3e009 Michael Hanselmann
      }, {
1221 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 100 * 1024,
1222 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDWR,
1223 a8e3e009 Michael Hanselmann
      }]
1224 a8e3e009 Michael Hanselmann
1225 a8e3e009 Michael Hanselmann
    result = self._TestTrivialDisk(constants.DT_RBD, disk_info, 0,
1226 a8e3e009 Michael Hanselmann
                                   constants.LD_RBD)
1227 a8e3e009 Michael Hanselmann
1228 a8e3e009 Michael Hanselmann
    self.assertEqual(map(operator.attrgetter("logical_id"), result), [
1229 a8e3e009 Michael Hanselmann
      ("rbd", "ec0-uq0.rbd.disk0"),
1230 a8e3e009 Michael Hanselmann
      ("rbd", "ec0-uq1.rbd.disk1"),
1231 a8e3e009 Michael Hanselmann
      ])
1232 a8e3e009 Michael Hanselmann
1233 a8e3e009 Michael Hanselmann
  def testDrbd8(self):
1234 a8e3e009 Michael Hanselmann
    gdt = cmdlib._GenerateDiskTemplate
1235 a8e3e009 Michael Hanselmann
    drbd8_defaults = constants.DISK_LD_DEFAULTS[constants.LD_DRBD8]
1236 a8e3e009 Michael Hanselmann
    drbd8_default_metavg = drbd8_defaults[constants.LDP_DEFAULT_METAVG]
1237 a8e3e009 Michael Hanselmann
1238 a8e3e009 Michael Hanselmann
    disk_info = [{
1239 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 1024,
1240 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDWR,
1241 a8e3e009 Michael Hanselmann
      }, {
1242 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 100 * 1024,
1243 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDONLY,
1244 a8e3e009 Michael Hanselmann
      constants.IDISK_METAVG: "metavg",
1245 a8e3e009 Michael Hanselmann
      }, {
1246 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 4096,
1247 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDWR,
1248 a8e3e009 Michael Hanselmann
      constants.IDISK_VG: "vgxyz",
1249 a8e3e009 Michael Hanselmann
      },
1250 a8e3e009 Michael Hanselmann
      ]
1251 a8e3e009 Michael Hanselmann
1252 a8e3e009 Michael Hanselmann
    exp_logical_ids = [[
1253 a8e3e009 Michael Hanselmann
      (self.lu.cfg.GetVGName(), "ec0-uq0.disk0_data"),
1254 a8e3e009 Michael Hanselmann
      (drbd8_default_metavg, "ec0-uq0.disk0_meta"),
1255 a8e3e009 Michael Hanselmann
      ], [
1256 a8e3e009 Michael Hanselmann
      (self.lu.cfg.GetVGName(), "ec0-uq1.disk1_data"),
1257 a8e3e009 Michael Hanselmann
      ("metavg", "ec0-uq1.disk1_meta"),
1258 a8e3e009 Michael Hanselmann
      ], [
1259 a8e3e009 Michael Hanselmann
      ("vgxyz", "ec0-uq2.disk2_data"),
1260 a8e3e009 Michael Hanselmann
      (drbd8_default_metavg, "ec0-uq2.disk2_meta"),
1261 a8e3e009 Michael Hanselmann
      ]]
1262 a8e3e009 Michael Hanselmann
1263 a8e3e009 Michael Hanselmann
    assert len(exp_logical_ids) == len(disk_info)
1264 a8e3e009 Michael Hanselmann
1265 a8e3e009 Michael Hanselmann
    map(lambda params: utils.ForceDictType(params,
1266 a8e3e009 Michael Hanselmann
                                           constants.IDISK_PARAMS_TYPES),
1267 a8e3e009 Michael Hanselmann
        disk_info)
1268 a8e3e009 Michael Hanselmann
1269 a8e3e009 Michael Hanselmann
    # Check if empty list of secondaries is rejected
1270 a8e3e009 Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, gdt, self.lu, constants.DT_DRBD8,
1271 a8e3e009 Michael Hanselmann
                      "inst827.example.com", "node1334.example.com", [],
1272 a8e3e009 Michael Hanselmann
                      disk_info, NotImplemented, NotImplemented, 0,
1273 99ccf8b9 René Nussbaumer
                      self.lu.LogInfo, self.GetDiskParams())
1274 a8e3e009 Michael Hanselmann
1275 a8e3e009 Michael Hanselmann
    result = gdt(self.lu, constants.DT_DRBD8, "inst827.example.com",
1276 a8e3e009 Michael Hanselmann
                 "node1334.example.com", ["node12272.example.com"],
1277 a8e3e009 Michael Hanselmann
                 disk_info, NotImplemented, NotImplemented, 0, self.lu.LogInfo,
1278 99ccf8b9 René Nussbaumer
                 self.GetDiskParams())
1279 a8e3e009 Michael Hanselmann
1280 a8e3e009 Michael Hanselmann
    for (idx, disk) in enumerate(result):
1281 a8e3e009 Michael Hanselmann
      self.assertTrue(isinstance(disk, objects.Disk))
1282 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.dev_type, constants.LD_DRBD8)
1283 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.size, disk_info[idx][constants.IDISK_SIZE])
1284 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.mode, disk_info[idx][constants.IDISK_MODE])
1285 a8e3e009 Michael Hanselmann
1286 a8e3e009 Michael Hanselmann
      for child in disk.children:
1287 a8e3e009 Michael Hanselmann
        self.assertTrue(isinstance(disk, objects.Disk))
1288 a8e3e009 Michael Hanselmann
        self.assertEqual(child.dev_type, constants.LD_LV)
1289 a8e3e009 Michael Hanselmann
        self.assertTrue(child.children is None)
1290 a8e3e009 Michael Hanselmann
1291 a8e3e009 Michael Hanselmann
      self.assertEqual(map(operator.attrgetter("logical_id"), disk.children),
1292 a8e3e009 Michael Hanselmann
                       exp_logical_ids[idx])
1293 a8e3e009 Michael Hanselmann
1294 a8e3e009 Michael Hanselmann
      self.assertEqual(len(disk.children), 2)
1295 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.children[0].size, disk.size)
1296 0c77c331 René Nussbaumer
      self.assertEqual(disk.children[1].size, constants.DRBD_META_SIZE)
1297 a8e3e009 Michael Hanselmann
1298 0356a13d Michael Hanselmann
    self._CheckIvNames(result, 0, len(disk_info))
1299 0356a13d Michael Hanselmann
    cmdlib._UpdateIvNames(0, result)
1300 0356a13d Michael Hanselmann
    self._CheckIvNames(result, 0, len(disk_info))
1301 a8e3e009 Michael Hanselmann
1302 a8e3e009 Michael Hanselmann
    self.assertEqual(map(operator.attrgetter("logical_id"), result), [
1303 a8e3e009 Michael Hanselmann
      ("node1334.example.com", "node12272.example.com",
1304 a8e3e009 Michael Hanselmann
       constants.FIRST_DRBD_PORT, 20, 21, "ec0-secret0"),
1305 a8e3e009 Michael Hanselmann
      ("node1334.example.com", "node12272.example.com",
1306 a8e3e009 Michael Hanselmann
       constants.FIRST_DRBD_PORT + 1, 22, 23, "ec0-secret1"),
1307 a8e3e009 Michael Hanselmann
      ("node1334.example.com", "node12272.example.com",
1308 a8e3e009 Michael Hanselmann
       constants.FIRST_DRBD_PORT + 2, 24, 25, "ec0-secret2"),
1309 a8e3e009 Michael Hanselmann
      ])
1310 a8e3e009 Michael Hanselmann
1311 a8e3e009 Michael Hanselmann
1312 129cce69 Michael Hanselmann
class _ConfigForDiskWipe:
1313 555b6cb1 Michael Hanselmann
  def __init__(self, exp_node):
1314 555b6cb1 Michael Hanselmann
    self._exp_node = exp_node
1315 555b6cb1 Michael Hanselmann
1316 129cce69 Michael Hanselmann
  def SetDiskID(self, device, node):
1317 129cce69 Michael Hanselmann
    assert isinstance(device, objects.Disk)
1318 555b6cb1 Michael Hanselmann
    assert node == self._exp_node
1319 129cce69 Michael Hanselmann
1320 129cce69 Michael Hanselmann
1321 129cce69 Michael Hanselmann
class _RpcForDiskWipe:
1322 555b6cb1 Michael Hanselmann
  def __init__(self, exp_node, pause_cb, wipe_cb):
1323 555b6cb1 Michael Hanselmann
    self._exp_node = exp_node
1324 129cce69 Michael Hanselmann
    self._pause_cb = pause_cb
1325 129cce69 Michael Hanselmann
    self._wipe_cb = wipe_cb
1326 129cce69 Michael Hanselmann
1327 129cce69 Michael Hanselmann
  def call_blockdev_pause_resume_sync(self, node, disks, pause):
1328 555b6cb1 Michael Hanselmann
    assert node == self._exp_node
1329 129cce69 Michael Hanselmann
    return rpc.RpcResult(data=self._pause_cb(disks, pause))
1330 129cce69 Michael Hanselmann
1331 129cce69 Michael Hanselmann
  def call_blockdev_wipe(self, node, bdev, offset, size):
1332 555b6cb1 Michael Hanselmann
    assert node == self._exp_node
1333 129cce69 Michael Hanselmann
    return rpc.RpcResult(data=self._wipe_cb(bdev, offset, size))
1334 129cce69 Michael Hanselmann
1335 129cce69 Michael Hanselmann
1336 129cce69 Michael Hanselmann
class _DiskPauseTracker:
1337 129cce69 Michael Hanselmann
  def __init__(self):
1338 129cce69 Michael Hanselmann
    self.history = []
1339 129cce69 Michael Hanselmann
1340 129cce69 Michael Hanselmann
  def __call__(self, (disks, instance), pause):
1341 fa8ef9d6 Michael Hanselmann
    assert not (set(disks) - set(instance.disks))
1342 129cce69 Michael Hanselmann
1343 129cce69 Michael Hanselmann
    self.history.extend((i.logical_id, i.size, pause)
1344 129cce69 Michael Hanselmann
                        for i in disks)
1345 129cce69 Michael Hanselmann
1346 129cce69 Michael Hanselmann
    return (True, [True] * len(disks))
1347 129cce69 Michael Hanselmann
1348 129cce69 Michael Hanselmann
1349 555b6cb1 Michael Hanselmann
class _DiskWipeProgressTracker:
1350 555b6cb1 Michael Hanselmann
  def __init__(self, start_offset):
1351 555b6cb1 Michael Hanselmann
    self._start_offset = start_offset
1352 555b6cb1 Michael Hanselmann
    self.progress = {}
1353 555b6cb1 Michael Hanselmann
1354 555b6cb1 Michael Hanselmann
  def __call__(self, (disk, _), offset, size):
1355 555b6cb1 Michael Hanselmann
    assert isinstance(offset, (long, int))
1356 555b6cb1 Michael Hanselmann
    assert isinstance(size, (long, int))
1357 555b6cb1 Michael Hanselmann
1358 555b6cb1 Michael Hanselmann
    max_chunk_size = (disk.size / 100.0 * constants.MIN_WIPE_CHUNK_PERCENT)
1359 555b6cb1 Michael Hanselmann
1360 555b6cb1 Michael Hanselmann
    assert offset >= self._start_offset
1361 555b6cb1 Michael Hanselmann
    assert (offset + size) <= disk.size
1362 555b6cb1 Michael Hanselmann
1363 555b6cb1 Michael Hanselmann
    assert size > 0
1364 555b6cb1 Michael Hanselmann
    assert size <= constants.MAX_WIPE_CHUNK
1365 555b6cb1 Michael Hanselmann
    assert size <= max_chunk_size
1366 555b6cb1 Michael Hanselmann
1367 555b6cb1 Michael Hanselmann
    assert offset == self._start_offset or disk.logical_id in self.progress
1368 555b6cb1 Michael Hanselmann
1369 555b6cb1 Michael Hanselmann
    # Keep track of progress
1370 555b6cb1 Michael Hanselmann
    cur_progress = self.progress.setdefault(disk.logical_id, self._start_offset)
1371 555b6cb1 Michael Hanselmann
1372 555b6cb1 Michael Hanselmann
    assert cur_progress == offset
1373 555b6cb1 Michael Hanselmann
1374 555b6cb1 Michael Hanselmann
    # Record progress
1375 555b6cb1 Michael Hanselmann
    self.progress[disk.logical_id] += size
1376 555b6cb1 Michael Hanselmann
1377 555b6cb1 Michael Hanselmann
    return (True, None)
1378 555b6cb1 Michael Hanselmann
1379 555b6cb1 Michael Hanselmann
1380 129cce69 Michael Hanselmann
class TestWipeDisks(unittest.TestCase):
1381 555b6cb1 Michael Hanselmann
  def _FailingPauseCb(self, (disks, _), pause):
1382 555b6cb1 Michael Hanselmann
    self.assertEqual(len(disks), 3)
1383 555b6cb1 Michael Hanselmann
    self.assertTrue(pause)
1384 555b6cb1 Michael Hanselmann
    # Simulate an RPC error
1385 555b6cb1 Michael Hanselmann
    return (False, "error")
1386 555b6cb1 Michael Hanselmann
1387 129cce69 Michael Hanselmann
  def testPauseFailure(self):
1388 555b6cb1 Michael Hanselmann
    node_name = "node1372.example.com"
1389 129cce69 Michael Hanselmann
1390 555b6cb1 Michael Hanselmann
    lu = _FakeLU(rpc=_RpcForDiskWipe(node_name, self._FailingPauseCb,
1391 555b6cb1 Michael Hanselmann
                                     NotImplemented),
1392 555b6cb1 Michael Hanselmann
                 cfg=_ConfigForDiskWipe(node_name))
1393 129cce69 Michael Hanselmann
1394 129cce69 Michael Hanselmann
    disks = [
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
      objects.Disk(dev_type=constants.LD_LV),
1398 129cce69 Michael Hanselmann
      ]
1399 129cce69 Michael Hanselmann
1400 129cce69 Michael Hanselmann
    instance = objects.Instance(name="inst21201",
1401 555b6cb1 Michael Hanselmann
                                primary_node=node_name,
1402 129cce69 Michael Hanselmann
                                disk_template=constants.DT_PLAIN,
1403 129cce69 Michael Hanselmann
                                disks=disks)
1404 129cce69 Michael Hanselmann
1405 129cce69 Michael Hanselmann
    self.assertRaises(errors.OpExecError, cmdlib._WipeDisks, lu, instance)
1406 129cce69 Michael Hanselmann
1407 555b6cb1 Michael Hanselmann
  def _FailingWipeCb(self, (disk, _), offset, size):
1408 555b6cb1 Michael Hanselmann
    # This should only ever be called for the first disk
1409 555b6cb1 Michael Hanselmann
    self.assertEqual(disk.logical_id, "disk0")
1410 555b6cb1 Michael Hanselmann
    return (False, None)
1411 555b6cb1 Michael Hanselmann
1412 129cce69 Michael Hanselmann
  def testFailingWipe(self):
1413 555b6cb1 Michael Hanselmann
    node_name = "node13445.example.com"
1414 129cce69 Michael Hanselmann
    pt = _DiskPauseTracker()
1415 129cce69 Michael Hanselmann
1416 555b6cb1 Michael Hanselmann
    lu = _FakeLU(rpc=_RpcForDiskWipe(node_name, pt, self._FailingWipeCb),
1417 555b6cb1 Michael Hanselmann
                 cfg=_ConfigForDiskWipe(node_name))
1418 129cce69 Michael Hanselmann
1419 129cce69 Michael Hanselmann
    disks = [
1420 129cce69 Michael Hanselmann
      objects.Disk(dev_type=constants.LD_LV, logical_id="disk0",
1421 129cce69 Michael Hanselmann
                   size=100 * 1024),
1422 129cce69 Michael Hanselmann
      objects.Disk(dev_type=constants.LD_LV, logical_id="disk1",
1423 129cce69 Michael Hanselmann
                   size=500 * 1024),
1424 129cce69 Michael Hanselmann
      objects.Disk(dev_type=constants.LD_LV, logical_id="disk2", size=256),
1425 129cce69 Michael Hanselmann
      ]
1426 129cce69 Michael Hanselmann
1427 129cce69 Michael Hanselmann
    instance = objects.Instance(name="inst562",
1428 555b6cb1 Michael Hanselmann
                                primary_node=node_name,
1429 129cce69 Michael Hanselmann
                                disk_template=constants.DT_PLAIN,
1430 129cce69 Michael Hanselmann
                                disks=disks)
1431 129cce69 Michael Hanselmann
1432 129cce69 Michael Hanselmann
    try:
1433 129cce69 Michael Hanselmann
      cmdlib._WipeDisks(lu, instance)
1434 129cce69 Michael Hanselmann
    except errors.OpExecError, err:
1435 129cce69 Michael Hanselmann
      self.assertTrue(str(err), "Could not wipe disk 0 at offset 0 ")
1436 129cce69 Michael Hanselmann
    else:
1437 129cce69 Michael Hanselmann
      self.fail("Did not raise exception")
1438 129cce69 Michael Hanselmann
1439 555b6cb1 Michael Hanselmann
    # Check if all disks were paused and resumed
1440 129cce69 Michael Hanselmann
    self.assertEqual(pt.history, [
1441 129cce69 Michael Hanselmann
      ("disk0", 100 * 1024, True),
1442 129cce69 Michael Hanselmann
      ("disk1", 500 * 1024, True),
1443 129cce69 Michael Hanselmann
      ("disk2", 256, True),
1444 129cce69 Michael Hanselmann
      ("disk0", 100 * 1024, False),
1445 129cce69 Michael Hanselmann
      ("disk1", 500 * 1024, False),
1446 129cce69 Michael Hanselmann
      ("disk2", 256, False),
1447 129cce69 Michael Hanselmann
      ])
1448 129cce69 Michael Hanselmann
1449 555b6cb1 Michael Hanselmann
  def _PrepareWipeTest(self, start_offset, disks):
1450 555b6cb1 Michael Hanselmann
    node_name = "node-with-offset%s.example.com" % start_offset
1451 555b6cb1 Michael Hanselmann
    pauset = _DiskPauseTracker()
1452 555b6cb1 Michael Hanselmann
    progresst = _DiskWipeProgressTracker(start_offset)
1453 129cce69 Michael Hanselmann
1454 555b6cb1 Michael Hanselmann
    lu = _FakeLU(rpc=_RpcForDiskWipe(node_name, pauset, progresst),
1455 555b6cb1 Michael Hanselmann
                 cfg=_ConfigForDiskWipe(node_name))
1456 129cce69 Michael Hanselmann
1457 555b6cb1 Michael Hanselmann
    instance = objects.Instance(name="inst3560",
1458 555b6cb1 Michael Hanselmann
                                primary_node=node_name,
1459 555b6cb1 Michael Hanselmann
                                disk_template=constants.DT_PLAIN,
1460 555b6cb1 Michael Hanselmann
                                disks=disks)
1461 129cce69 Michael Hanselmann
1462 555b6cb1 Michael Hanselmann
    return (lu, instance, pauset, progresst)
1463 555b6cb1 Michael Hanselmann
1464 555b6cb1 Michael Hanselmann
  def testNormalWipe(self):
1465 555b6cb1 Michael Hanselmann
    disks = [
1466 555b6cb1 Michael Hanselmann
      objects.Disk(dev_type=constants.LD_LV, logical_id="disk0", size=1024),
1467 555b6cb1 Michael Hanselmann
      objects.Disk(dev_type=constants.LD_LV, logical_id="disk1",
1468 555b6cb1 Michael Hanselmann
                   size=500 * 1024),
1469 555b6cb1 Michael Hanselmann
      objects.Disk(dev_type=constants.LD_LV, logical_id="disk2", size=128),
1470 555b6cb1 Michael Hanselmann
      objects.Disk(dev_type=constants.LD_LV, logical_id="disk3",
1471 555b6cb1 Michael Hanselmann
                   size=constants.MAX_WIPE_CHUNK),
1472 555b6cb1 Michael Hanselmann
      ]
1473 129cce69 Michael Hanselmann
1474 555b6cb1 Michael Hanselmann
    (lu, instance, pauset, progresst) = self._PrepareWipeTest(0, disks)
1475 129cce69 Michael Hanselmann
1476 555b6cb1 Michael Hanselmann
    cmdlib._WipeDisks(lu, instance)
1477 129cce69 Michael Hanselmann
1478 555b6cb1 Michael Hanselmann
    self.assertEqual(pauset.history, [
1479 555b6cb1 Michael Hanselmann
      ("disk0", 1024, True),
1480 555b6cb1 Michael Hanselmann
      ("disk1", 500 * 1024, True),
1481 555b6cb1 Michael Hanselmann
      ("disk2", 128, True),
1482 555b6cb1 Michael Hanselmann
      ("disk3", constants.MAX_WIPE_CHUNK, True),
1483 555b6cb1 Michael Hanselmann
      ("disk0", 1024, False),
1484 555b6cb1 Michael Hanselmann
      ("disk1", 500 * 1024, False),
1485 555b6cb1 Michael Hanselmann
      ("disk2", 128, False),
1486 555b6cb1 Michael Hanselmann
      ("disk3", constants.MAX_WIPE_CHUNK, False),
1487 555b6cb1 Michael Hanselmann
      ])
1488 129cce69 Michael Hanselmann
1489 555b6cb1 Michael Hanselmann
    # Ensure the complete disk has been wiped
1490 555b6cb1 Michael Hanselmann
    self.assertEqual(progresst.progress,
1491 555b6cb1 Michael Hanselmann
                     dict((i.logical_id, i.size) for i in disks))
1492 129cce69 Michael Hanselmann
1493 555b6cb1 Michael Hanselmann
  def testWipeWithStartOffset(self):
1494 555b6cb1 Michael Hanselmann
    for start_offset in [0, 280, 8895, 1563204]:
1495 555b6cb1 Michael Hanselmann
      disks = [
1496 555b6cb1 Michael Hanselmann
        objects.Disk(dev_type=constants.LD_LV, logical_id="disk0",
1497 555b6cb1 Michael Hanselmann
                     size=128),
1498 555b6cb1 Michael Hanselmann
        objects.Disk(dev_type=constants.LD_LV, logical_id="disk1",
1499 555b6cb1 Michael Hanselmann
                     size=start_offset + (100 * 1024)),
1500 555b6cb1 Michael Hanselmann
        ]
1501 129cce69 Michael Hanselmann
1502 555b6cb1 Michael Hanselmann
      (lu, instance, pauset, progresst) = \
1503 555b6cb1 Michael Hanselmann
        self._PrepareWipeTest(start_offset, disks)
1504 129cce69 Michael Hanselmann
1505 555b6cb1 Michael Hanselmann
      # Test start offset with only one disk
1506 555b6cb1 Michael Hanselmann
      cmdlib._WipeDisks(lu, instance,
1507 555b6cb1 Michael Hanselmann
                        disks=[(1, disks[1], start_offset)])
1508 129cce69 Michael Hanselmann
1509 555b6cb1 Michael Hanselmann
      # Only the second disk may have been paused and wiped
1510 555b6cb1 Michael Hanselmann
      self.assertEqual(pauset.history, [
1511 555b6cb1 Michael Hanselmann
        ("disk1", start_offset + (100 * 1024), True),
1512 555b6cb1 Michael Hanselmann
        ("disk1", start_offset + (100 * 1024), False),
1513 555b6cb1 Michael Hanselmann
        ])
1514 555b6cb1 Michael Hanselmann
      self.assertEqual(progresst.progress, {
1515 555b6cb1 Michael Hanselmann
        "disk1": disks[1].size,
1516 555b6cb1 Michael Hanselmann
        })
1517 fa8ef9d6 Michael Hanselmann
1518 fa8ef9d6 Michael Hanselmann
1519 fa8ef9d6 Michael Hanselmann
class TestDiskSizeInBytesToMebibytes(unittest.TestCase):
1520 fa8ef9d6 Michael Hanselmann
  def testLessThanOneMebibyte(self):
1521 fa8ef9d6 Michael Hanselmann
    for i in [1, 2, 7, 512, 1000, 1023]:
1522 fa8ef9d6 Michael Hanselmann
      lu = _FakeLU()
1523 fa8ef9d6 Michael Hanselmann
      result = cmdlib._DiskSizeInBytesToMebibytes(lu, i)
1524 fa8ef9d6 Michael Hanselmann
      self.assertEqual(result, 1)
1525 fa8ef9d6 Michael Hanselmann
      self.assertEqual(len(lu.warning_log), 1)
1526 fa8ef9d6 Michael Hanselmann
      self.assertEqual(len(lu.warning_log[0]), 2)
1527 fa8ef9d6 Michael Hanselmann
      (_, (warnsize, )) = lu.warning_log[0]
1528 fa8ef9d6 Michael Hanselmann
      self.assertEqual(warnsize, (1024 * 1024) - i)
1529 fa8ef9d6 Michael Hanselmann
1530 fa8ef9d6 Michael Hanselmann
  def testEven(self):
1531 fa8ef9d6 Michael Hanselmann
    for i in [1, 2, 7, 512, 1000, 1023]:
1532 fa8ef9d6 Michael Hanselmann
      lu = _FakeLU()
1533 fa8ef9d6 Michael Hanselmann
      result = cmdlib._DiskSizeInBytesToMebibytes(lu, i * 1024 * 1024)
1534 fa8ef9d6 Michael Hanselmann
      self.assertEqual(result, i)
1535 fa8ef9d6 Michael Hanselmann
      self.assertFalse(lu.warning_log)
1536 fa8ef9d6 Michael Hanselmann
1537 fa8ef9d6 Michael Hanselmann
  def testLargeNumber(self):
1538 fa8ef9d6 Michael Hanselmann
    for i in [1, 2, 7, 512, 1000, 1023, 2724, 12420]:
1539 fa8ef9d6 Michael Hanselmann
      for j in [1, 2, 486, 326, 986, 1023]:
1540 fa8ef9d6 Michael Hanselmann
        lu = _FakeLU()
1541 fa8ef9d6 Michael Hanselmann
        size = (1024 * 1024 * i) + j
1542 fa8ef9d6 Michael Hanselmann
        result = cmdlib._DiskSizeInBytesToMebibytes(lu, size)
1543 fa8ef9d6 Michael Hanselmann
        self.assertEqual(result, i + 1, msg="Amount was not rounded up")
1544 fa8ef9d6 Michael Hanselmann
        self.assertEqual(len(lu.warning_log), 1)
1545 fa8ef9d6 Michael Hanselmann
        self.assertEqual(len(lu.warning_log[0]), 2)
1546 fa8ef9d6 Michael Hanselmann
        (_, (warnsize, )) = lu.warning_log[0]
1547 fa8ef9d6 Michael Hanselmann
        self.assertEqual(warnsize, (1024 * 1024) - j)
1548 129cce69 Michael Hanselmann
1549 129cce69 Michael Hanselmann
1550 ef86bf28 Michael Hanselmann
class TestCopyLockList(unittest.TestCase):
1551 ef86bf28 Michael Hanselmann
  def test(self):
1552 ef86bf28 Michael Hanselmann
    self.assertEqual(cmdlib._CopyLockList([]), [])
1553 ef86bf28 Michael Hanselmann
    self.assertEqual(cmdlib._CopyLockList(None), None)
1554 ef86bf28 Michael Hanselmann
    self.assertEqual(cmdlib._CopyLockList(locking.ALL_SET), locking.ALL_SET)
1555 ef86bf28 Michael Hanselmann
1556 ef86bf28 Michael Hanselmann
    names = ["foo", "bar"]
1557 ef86bf28 Michael Hanselmann
    output = cmdlib._CopyLockList(names)
1558 ef86bf28 Michael Hanselmann
    self.assertEqual(names, output)
1559 ef86bf28 Michael Hanselmann
    self.assertNotEqual(id(names), id(output), msg="List was not copied")
1560 ef86bf28 Michael Hanselmann
1561 ef86bf28 Michael Hanselmann
1562 cfa79a23 Michael Hanselmann
class TestCheckOpportunisticLocking(unittest.TestCase):
1563 cfa79a23 Michael Hanselmann
  class OpTest(opcodes.OpCode):
1564 cfa79a23 Michael Hanselmann
    OP_PARAMS = [
1565 cfa79a23 Michael Hanselmann
      opcodes._POpportunisticLocking,
1566 cfa79a23 Michael Hanselmann
      opcodes._PIAllocFromDesc(""),
1567 cfa79a23 Michael Hanselmann
      ]
1568 cfa79a23 Michael Hanselmann
1569 cfa79a23 Michael Hanselmann
  @classmethod
1570 cfa79a23 Michael Hanselmann
  def _MakeOp(cls, **kwargs):
1571 cfa79a23 Michael Hanselmann
    op = cls.OpTest(**kwargs)
1572 cfa79a23 Michael Hanselmann
    op.Validate(True)
1573 cfa79a23 Michael Hanselmann
    return op
1574 cfa79a23 Michael Hanselmann
1575 cfa79a23 Michael Hanselmann
  def testMissingAttributes(self):
1576 cfa79a23 Michael Hanselmann
    self.assertRaises(AttributeError, cmdlib._CheckOpportunisticLocking,
1577 cfa79a23 Michael Hanselmann
                      object())
1578 cfa79a23 Michael Hanselmann
1579 cfa79a23 Michael Hanselmann
  def testDefaults(self):
1580 cfa79a23 Michael Hanselmann
    op = self._MakeOp()
1581 cfa79a23 Michael Hanselmann
    cmdlib._CheckOpportunisticLocking(op)
1582 cfa79a23 Michael Hanselmann
1583 cfa79a23 Michael Hanselmann
  def test(self):
1584 cfa79a23 Michael Hanselmann
    for iallocator in [None, "something", "other"]:
1585 cfa79a23 Michael Hanselmann
      for opplock in [False, True]:
1586 cfa79a23 Michael Hanselmann
        op = self._MakeOp(iallocator=iallocator, opportunistic_locking=opplock)
1587 cfa79a23 Michael Hanselmann
        if opplock and not iallocator:
1588 cfa79a23 Michael Hanselmann
          self.assertRaises(errors.OpPrereqError,
1589 cfa79a23 Michael Hanselmann
                            cmdlib._CheckOpportunisticLocking, op)
1590 cfa79a23 Michael Hanselmann
        else:
1591 cfa79a23 Michael Hanselmann
          cmdlib._CheckOpportunisticLocking(op)
1592 cfa79a23 Michael Hanselmann
1593 cfa79a23 Michael Hanselmann
1594 8bb2df7d Bernardo Dal Seno
class _OpTestVerifyErrors(opcodes.OpCode):
1595 8bb2df7d Bernardo Dal Seno
  OP_PARAMS = [
1596 8bb2df7d Bernardo Dal Seno
    opcodes._PDebugSimulateErrors,
1597 8bb2df7d Bernardo Dal Seno
    opcodes._PErrorCodes,
1598 8bb2df7d Bernardo Dal Seno
    opcodes._PIgnoreErrors,
1599 8bb2df7d Bernardo Dal Seno
    ]
1600 8bb2df7d Bernardo Dal Seno
1601 8bb2df7d Bernardo Dal Seno
1602 8bb2df7d Bernardo Dal Seno
class _LuTestVerifyErrors(cmdlib._VerifyErrors):
1603 8bb2df7d Bernardo Dal Seno
  def __init__(self, **kwargs):
1604 8bb2df7d Bernardo Dal Seno
    cmdlib._VerifyErrors.__init__(self)
1605 8bb2df7d Bernardo Dal Seno
    self.op = _OpTestVerifyErrors(**kwargs)
1606 8bb2df7d Bernardo Dal Seno
    self.op.Validate(True)
1607 8bb2df7d Bernardo Dal Seno
    self.msglist = []
1608 8bb2df7d Bernardo Dal Seno
    self._feedback_fn = self.msglist.append
1609 8bb2df7d Bernardo Dal Seno
    self.bad = False
1610 8bb2df7d Bernardo Dal Seno
1611 8bb2df7d Bernardo Dal Seno
  def DispatchCallError(self, which, *args, **kwargs):
1612 8bb2df7d Bernardo Dal Seno
    if which:
1613 8bb2df7d Bernardo Dal Seno
      self._Error(*args, **kwargs)
1614 8bb2df7d Bernardo Dal Seno
    else:
1615 8bb2df7d Bernardo Dal Seno
      self._ErrorIf(True, *args, **kwargs)
1616 8bb2df7d Bernardo Dal Seno
1617 8bb2df7d Bernardo Dal Seno
  def CallErrorIf(self, c, *args, **kwargs):
1618 8bb2df7d Bernardo Dal Seno
    self._ErrorIf(c, *args, **kwargs)
1619 8bb2df7d Bernardo Dal Seno
1620 8bb2df7d Bernardo Dal Seno
1621 8bb2df7d Bernardo Dal Seno
class TestVerifyErrors(unittest.TestCase):
1622 8bb2df7d Bernardo Dal Seno
  # Fake cluster-verify error code structures; we use two arbitary real error
1623 8bb2df7d Bernardo Dal Seno
  # codes to pass validation of ignore_errors
1624 8bb2df7d Bernardo Dal Seno
  (_, _ERR1ID, _) = constants.CV_ECLUSTERCFG
1625 8bb2df7d Bernardo Dal Seno
  _NODESTR = "node"
1626 8bb2df7d Bernardo Dal Seno
  _NODENAME = "mynode"
1627 8bb2df7d Bernardo Dal Seno
  _ERR1CODE = (_NODESTR, _ERR1ID, "Error one")
1628 8bb2df7d Bernardo Dal Seno
  (_, _ERR2ID, _) = constants.CV_ECLUSTERCERT
1629 8bb2df7d Bernardo Dal Seno
  _INSTSTR = "instance"
1630 8bb2df7d Bernardo Dal Seno
  _INSTNAME = "myinstance"
1631 8bb2df7d Bernardo Dal Seno
  _ERR2CODE = (_INSTSTR, _ERR2ID, "Error two")
1632 8bb2df7d Bernardo Dal Seno
  # Arguments used to call _Error() or _ErrorIf()
1633 8bb2df7d Bernardo Dal Seno
  _ERR1ARGS = (_ERR1CODE, _NODENAME, "Error1 is %s", "an error")
1634 8bb2df7d Bernardo Dal Seno
  _ERR2ARGS = (_ERR2CODE, _INSTNAME, "Error2 has no argument")
1635 8bb2df7d Bernardo Dal Seno
  # Expected error messages
1636 8bb2df7d Bernardo Dal Seno
  _ERR1MSG = _ERR1ARGS[2] % _ERR1ARGS[3]
1637 8bb2df7d Bernardo Dal Seno
  _ERR2MSG = _ERR2ARGS[2]
1638 8bb2df7d Bernardo Dal Seno
1639 8bb2df7d Bernardo Dal Seno
  def testNoError(self):
1640 8bb2df7d Bernardo Dal Seno
    lu = _LuTestVerifyErrors()
1641 8bb2df7d Bernardo Dal Seno
    lu.CallErrorIf(False, self._ERR1CODE, *self._ERR1ARGS)
1642 8bb2df7d Bernardo Dal Seno
    self.assertFalse(lu.bad)
1643 8bb2df7d Bernardo Dal Seno
    self.assertFalse(lu.msglist)
1644 8bb2df7d Bernardo Dal Seno
1645 8bb2df7d Bernardo Dal Seno
  def _InitTest(self, **kwargs):
1646 8bb2df7d Bernardo Dal Seno
    self.lu1 = _LuTestVerifyErrors(**kwargs)
1647 8bb2df7d Bernardo Dal Seno
    self.lu2 = _LuTestVerifyErrors(**kwargs)
1648 8bb2df7d Bernardo Dal Seno
1649 8bb2df7d Bernardo Dal Seno
  def _CallError(self, *args, **kwargs):
1650 8bb2df7d Bernardo Dal Seno
    # Check that _Error() and _ErrorIf() produce the same results
1651 8bb2df7d Bernardo Dal Seno
    self.lu1.DispatchCallError(True, *args, **kwargs)
1652 8bb2df7d Bernardo Dal Seno
    self.lu2.DispatchCallError(False, *args, **kwargs)
1653 8bb2df7d Bernardo Dal Seno
    self.assertEqual(self.lu1.bad, self.lu2.bad)
1654 8bb2df7d Bernardo Dal Seno
    self.assertEqual(self.lu1.msglist, self.lu2.msglist)
1655 8bb2df7d Bernardo Dal Seno
    # Test-specific checks are made on one LU
1656 8bb2df7d Bernardo Dal Seno
    return self.lu1
1657 8bb2df7d Bernardo Dal Seno
1658 8bb2df7d Bernardo Dal Seno
  def _checkMsgCommon(self, logstr, errmsg, itype, item, warning):
1659 8bb2df7d Bernardo Dal Seno
    self.assertTrue(errmsg in logstr)
1660 8bb2df7d Bernardo Dal Seno
    if warning:
1661 8bb2df7d Bernardo Dal Seno
      self.assertTrue("WARNING" in logstr)
1662 8bb2df7d Bernardo Dal Seno
    else:
1663 8bb2df7d Bernardo Dal Seno
      self.assertTrue("ERROR" in logstr)
1664 8bb2df7d Bernardo Dal Seno
    self.assertTrue(itype in logstr)
1665 8bb2df7d Bernardo Dal Seno
    self.assertTrue(item in logstr)
1666 8bb2df7d Bernardo Dal Seno
1667 8bb2df7d Bernardo Dal Seno
  def _checkMsg1(self, logstr, warning=False):
1668 8bb2df7d Bernardo Dal Seno
    self._checkMsgCommon(logstr, self._ERR1MSG, self._NODESTR,
1669 8bb2df7d Bernardo Dal Seno
                         self._NODENAME, warning)
1670 8bb2df7d Bernardo Dal Seno
1671 8bb2df7d Bernardo Dal Seno
  def _checkMsg2(self, logstr, warning=False):
1672 8bb2df7d Bernardo Dal Seno
    self._checkMsgCommon(logstr, self._ERR2MSG, self._INSTSTR,
1673 8bb2df7d Bernardo Dal Seno
                         self._INSTNAME, warning)
1674 8bb2df7d Bernardo Dal Seno
1675 8bb2df7d Bernardo Dal Seno
  def testPlain(self):
1676 8bb2df7d Bernardo Dal Seno
    self._InitTest()
1677 8bb2df7d Bernardo Dal Seno
    lu = self._CallError(*self._ERR1ARGS)
1678 8bb2df7d Bernardo Dal Seno
    self.assertTrue(lu.bad)
1679 8bb2df7d Bernardo Dal Seno
    self.assertEqual(len(lu.msglist), 1)
1680 8bb2df7d Bernardo Dal Seno
    self._checkMsg1(lu.msglist[0])
1681 8bb2df7d Bernardo Dal Seno
1682 8bb2df7d Bernardo Dal Seno
  def testMultiple(self):
1683 8bb2df7d Bernardo Dal Seno
    self._InitTest()
1684 8bb2df7d Bernardo Dal Seno
    self._CallError(*self._ERR1ARGS)
1685 8bb2df7d Bernardo Dal Seno
    lu = self._CallError(*self._ERR2ARGS)
1686 8bb2df7d Bernardo Dal Seno
    self.assertTrue(lu.bad)
1687 8bb2df7d Bernardo Dal Seno
    self.assertEqual(len(lu.msglist), 2)
1688 8bb2df7d Bernardo Dal Seno
    self._checkMsg1(lu.msglist[0])
1689 8bb2df7d Bernardo Dal Seno
    self._checkMsg2(lu.msglist[1])
1690 8bb2df7d Bernardo Dal Seno
1691 8bb2df7d Bernardo Dal Seno
  def testIgnore(self):
1692 8bb2df7d Bernardo Dal Seno
    self._InitTest(ignore_errors=[self._ERR1ID])
1693 8bb2df7d Bernardo Dal Seno
    lu = self._CallError(*self._ERR1ARGS)
1694 8bb2df7d Bernardo Dal Seno
    self.assertFalse(lu.bad)
1695 8bb2df7d Bernardo Dal Seno
    self.assertEqual(len(lu.msglist), 1)
1696 8bb2df7d Bernardo Dal Seno
    self._checkMsg1(lu.msglist[0], warning=True)
1697 8bb2df7d Bernardo Dal Seno
1698 8bb2df7d Bernardo Dal Seno
  def testWarning(self):
1699 8bb2df7d Bernardo Dal Seno
    self._InitTest()
1700 8bb2df7d Bernardo Dal Seno
    lu = self._CallError(*self._ERR1ARGS,
1701 8bb2df7d Bernardo Dal Seno
                         code=_LuTestVerifyErrors.ETYPE_WARNING)
1702 8bb2df7d Bernardo Dal Seno
    self.assertFalse(lu.bad)
1703 8bb2df7d Bernardo Dal Seno
    self.assertEqual(len(lu.msglist), 1)
1704 8bb2df7d Bernardo Dal Seno
    self._checkMsg1(lu.msglist[0], warning=True)
1705 8bb2df7d Bernardo Dal Seno
1706 8bb2df7d Bernardo Dal Seno
  def testWarning2(self):
1707 8bb2df7d Bernardo Dal Seno
    self._InitTest()
1708 8bb2df7d Bernardo Dal Seno
    self._CallError(*self._ERR1ARGS)
1709 8bb2df7d Bernardo Dal Seno
    lu = self._CallError(*self._ERR2ARGS,
1710 8bb2df7d Bernardo Dal Seno
                         code=_LuTestVerifyErrors.ETYPE_WARNING)
1711 8bb2df7d Bernardo Dal Seno
    self.assertTrue(lu.bad)
1712 8bb2df7d Bernardo Dal Seno
    self.assertEqual(len(lu.msglist), 2)
1713 8bb2df7d Bernardo Dal Seno
    self._checkMsg1(lu.msglist[0])
1714 8bb2df7d Bernardo Dal Seno
    self._checkMsg2(lu.msglist[1], warning=True)
1715 8bb2df7d Bernardo Dal Seno
1716 8bb2df7d Bernardo Dal Seno
  def testDebugSimulate(self):
1717 8bb2df7d Bernardo Dal Seno
    lu = _LuTestVerifyErrors(debug_simulate_errors=True)
1718 8bb2df7d Bernardo Dal Seno
    lu.CallErrorIf(False, *self._ERR1ARGS)
1719 8bb2df7d Bernardo Dal Seno
    self.assertTrue(lu.bad)
1720 8bb2df7d Bernardo Dal Seno
    self.assertEqual(len(lu.msglist), 1)
1721 8bb2df7d Bernardo Dal Seno
    self._checkMsg1(lu.msglist[0])
1722 8bb2df7d Bernardo Dal Seno
1723 8bb2df7d Bernardo Dal Seno
  def testErrCodes(self):
1724 8bb2df7d Bernardo Dal Seno
    self._InitTest(error_codes=True)
1725 8bb2df7d Bernardo Dal Seno
    lu = self._CallError(*self._ERR1ARGS)
1726 8bb2df7d Bernardo Dal Seno
    self.assertTrue(lu.bad)
1727 8bb2df7d Bernardo Dal Seno
    self.assertEqual(len(lu.msglist), 1)
1728 8bb2df7d Bernardo Dal Seno
    self._checkMsg1(lu.msglist[0])
1729 8bb2df7d Bernardo Dal Seno
    self.assertTrue(self._ERR1ID in lu.msglist[0])
1730 8bb2df7d Bernardo Dal Seno
1731 8bb2df7d Bernardo Dal Seno
1732 5dd7d15b Bernardo Dal Seno
class TestGetUpdatedIPolicy(unittest.TestCase):
1733 5dd7d15b Bernardo Dal Seno
  """Tests for cmdlib._GetUpdatedIPolicy()"""
1734 5dd7d15b Bernardo Dal Seno
  _OLD_CLUSTER_POLICY = {
1735 5dd7d15b Bernardo Dal Seno
    constants.IPOLICY_VCPU_RATIO: 1.5,
1736 da5f09ef Bernardo Dal Seno
    constants.ISPECS_MINMAX: {
1737 da5f09ef Bernardo Dal Seno
      constants.ISPECS_MIN: {
1738 da5f09ef Bernardo Dal Seno
        constants.ISPEC_MEM_SIZE: 20,
1739 da5f09ef Bernardo Dal Seno
        constants.ISPEC_CPU_COUNT: 2,
1740 da5f09ef Bernardo Dal Seno
        },
1741 da5f09ef Bernardo Dal Seno
      constants.ISPECS_MAX: {},
1742 5dd7d15b Bernardo Dal Seno
      },
1743 5dd7d15b Bernardo Dal Seno
    constants.ISPECS_STD: {},
1744 5dd7d15b Bernardo Dal Seno
    }
1745 5dd7d15b Bernardo Dal Seno
  _OLD_GROUP_POLICY = {
1746 5dd7d15b Bernardo Dal Seno
    constants.IPOLICY_SPINDLE_RATIO: 2.5,
1747 da5f09ef Bernardo Dal Seno
    constants.ISPECS_MINMAX: {
1748 da5f09ef Bernardo Dal Seno
      constants.ISPECS_MIN: {
1749 da5f09ef Bernardo Dal Seno
        constants.ISPEC_DISK_SIZE: 20,
1750 da5f09ef Bernardo Dal Seno
        constants.ISPEC_NIC_COUNT: 2,
1751 da5f09ef Bernardo Dal Seno
        },
1752 da5f09ef Bernardo Dal Seno
      constants.ISPECS_MAX: {},
1753 5dd7d15b Bernardo Dal Seno
      },
1754 5dd7d15b Bernardo Dal Seno
    }
1755 5dd7d15b Bernardo Dal Seno
1756 5dd7d15b Bernardo Dal Seno
  def _TestSetSpecs(self, old_policy, isgroup):
1757 5dd7d15b Bernardo Dal Seno
    ispec_key = constants.ISPECS_MIN
1758 5dd7d15b Bernardo Dal Seno
    diff_ispec = {
1759 5dd7d15b Bernardo Dal Seno
      constants.ISPEC_MEM_SIZE: 50,
1760 5dd7d15b Bernardo Dal Seno
      constants.ISPEC_DISK_SIZE: 30,
1761 5dd7d15b Bernardo Dal Seno
      }
1762 5dd7d15b Bernardo Dal Seno
    diff_policy = {
1763 da5f09ef Bernardo Dal Seno
      constants.ISPECS_MINMAX: {
1764 da5f09ef Bernardo Dal Seno
        ispec_key: diff_ispec,
1765 da5f09ef Bernardo Dal Seno
        },
1766 5dd7d15b Bernardo Dal Seno
      }
1767 da5f09ef Bernardo Dal Seno
    if not isgroup:
1768 da5f09ef Bernardo Dal Seno
      diff_std = {
1769 da5f09ef Bernardo Dal Seno
        constants.ISPEC_CPU_COUNT: 3,
1770 da5f09ef Bernardo Dal Seno
        constants.ISPEC_DISK_COUNT: 3,
1771 da5f09ef Bernardo Dal Seno
        }
1772 da5f09ef Bernardo Dal Seno
      diff_policy[constants.ISPECS_STD] = diff_std
1773 5dd7d15b Bernardo Dal Seno
    new_policy = cmdlib._GetUpdatedIPolicy(old_policy, diff_policy,
1774 5dd7d15b Bernardo Dal Seno
                                           group_policy=isgroup)
1775 da5f09ef Bernardo Dal Seno
1776 da5f09ef Bernardo Dal Seno
    self.assertTrue(constants.ISPECS_MINMAX in new_policy)
1777 da5f09ef Bernardo Dal Seno
    new_ispec = new_policy[constants.ISPECS_MINMAX][ispec_key]
1778 5dd7d15b Bernardo Dal Seno
    for key in diff_ispec:
1779 5dd7d15b Bernardo Dal Seno
      self.assertTrue(key in new_ispec)
1780 5dd7d15b Bernardo Dal Seno
      self.assertEqual(new_ispec[key], diff_ispec[key])
1781 5dd7d15b Bernardo Dal Seno
    for key in old_policy:
1782 5dd7d15b Bernardo Dal Seno
      if not key in diff_policy:
1783 5dd7d15b Bernardo Dal Seno
        self.assertTrue(key in new_policy)
1784 5dd7d15b Bernardo Dal Seno
        self.assertEqual(new_policy[key], old_policy[key])
1785 da5f09ef Bernardo Dal Seno
1786 da5f09ef Bernardo Dal Seno
    if constants.ISPECS_MINMAX in old_policy:
1787 da5f09ef Bernardo Dal Seno
      old_minmax = old_policy[constants.ISPECS_MINMAX]
1788 da5f09ef Bernardo Dal Seno
      for key in old_minmax:
1789 da5f09ef Bernardo Dal Seno
        if key != ispec_key:
1790 da5f09ef Bernardo Dal Seno
          self.assertTrue(key in new_policy[constants.ISPECS_MINMAX])
1791 da5f09ef Bernardo Dal Seno
          self.assertEqual(new_policy[constants.ISPECS_MINMAX][key],
1792 da5f09ef Bernardo Dal Seno
                           old_minmax[key])
1793 da5f09ef Bernardo Dal Seno
      old_ispec = old_policy[constants.ISPECS_MINMAX][ispec_key]
1794 da5f09ef Bernardo Dal Seno
      for key in old_ispec:
1795 da5f09ef Bernardo Dal Seno
        if not key in diff_ispec:
1796 da5f09ef Bernardo Dal Seno
          self.assertTrue(key in new_ispec)
1797 da5f09ef Bernardo Dal Seno
          self.assertEqual(new_ispec[key], old_ispec[key])
1798 da5f09ef Bernardo Dal Seno
1799 da5f09ef Bernardo Dal Seno
    if not isgroup:
1800 da5f09ef Bernardo Dal Seno
      new_std = new_policy[constants.ISPECS_STD]
1801 da5f09ef Bernardo Dal Seno
      for key in diff_std:
1802 da5f09ef Bernardo Dal Seno
        self.assertTrue(key in new_std)
1803 da5f09ef Bernardo Dal Seno
        self.assertEqual(new_std[key], diff_std[key])
1804 da5f09ef Bernardo Dal Seno
1805 5dd7d15b Bernardo Dal Seno
1806 5dd7d15b Bernardo Dal Seno
  def _TestSet(self, old_policy, isgroup):
1807 5dd7d15b Bernardo Dal Seno
    diff_policy = {
1808 5dd7d15b Bernardo Dal Seno
      constants.IPOLICY_VCPU_RATIO: 3,
1809 5dd7d15b Bernardo Dal Seno
      constants.IPOLICY_SPINDLE_RATIO: 1.9,
1810 5dd7d15b Bernardo Dal Seno
      }
1811 5dd7d15b Bernardo Dal Seno
    new_policy = cmdlib._GetUpdatedIPolicy(old_policy, diff_policy,
1812 5dd7d15b Bernardo Dal Seno
                                           group_policy=isgroup)
1813 5dd7d15b Bernardo Dal Seno
    for key in diff_policy:
1814 5dd7d15b Bernardo Dal Seno
      self.assertTrue(key in new_policy)
1815 5dd7d15b Bernardo Dal Seno
      self.assertEqual(new_policy[key], diff_policy[key])
1816 5dd7d15b Bernardo Dal Seno
    for key in old_policy:
1817 5dd7d15b Bernardo Dal Seno
      if not key in diff_policy:
1818 5dd7d15b Bernardo Dal Seno
        self.assertTrue(key in new_policy)
1819 5dd7d15b Bernardo Dal Seno
        self.assertEqual(new_policy[key], old_policy[key])
1820 5dd7d15b Bernardo Dal Seno
1821 5dd7d15b Bernardo Dal Seno
  def testSet(self):
1822 5dd7d15b Bernardo Dal Seno
    self._TestSet(self._OLD_GROUP_POLICY, True)
1823 5dd7d15b Bernardo Dal Seno
    self._TestSetSpecs(self._OLD_GROUP_POLICY, True)
1824 5dd7d15b Bernardo Dal Seno
    self._TestSet(self._OLD_CLUSTER_POLICY, False)
1825 5dd7d15b Bernardo Dal Seno
    self._TestSetSpecs(self._OLD_CLUSTER_POLICY, False)
1826 5dd7d15b Bernardo Dal Seno
1827 5dd7d15b Bernardo Dal Seno
  def testUnset(self):
1828 5dd7d15b Bernardo Dal Seno
    old_policy = self._OLD_GROUP_POLICY
1829 5dd7d15b Bernardo Dal Seno
    diff_policy = {
1830 5dd7d15b Bernardo Dal Seno
      constants.IPOLICY_SPINDLE_RATIO: constants.VALUE_DEFAULT,
1831 5dd7d15b Bernardo Dal Seno
      }
1832 5dd7d15b Bernardo Dal Seno
    new_policy = cmdlib._GetUpdatedIPolicy(old_policy, diff_policy,
1833 5dd7d15b Bernardo Dal Seno
                                           group_policy=True)
1834 5dd7d15b Bernardo Dal Seno
    for key in diff_policy:
1835 5dd7d15b Bernardo Dal Seno
      self.assertFalse(key in new_policy)
1836 5dd7d15b Bernardo Dal Seno
    for key in old_policy:
1837 5dd7d15b Bernardo Dal Seno
      if not key in diff_policy:
1838 5dd7d15b Bernardo Dal Seno
        self.assertTrue(key in new_policy)
1839 5dd7d15b Bernardo Dal Seno
        self.assertEqual(new_policy[key], old_policy[key])
1840 5dd7d15b Bernardo Dal Seno
1841 5dd7d15b Bernardo Dal Seno
  def _TestInvalidKeys(self, old_policy, isgroup):
1842 5dd7d15b Bernardo Dal Seno
    INVALID_DICT = {
1843 5dd7d15b Bernardo Dal Seno
      "this_key_shouldnt_be_allowed": 3,
1844 5dd7d15b Bernardo Dal Seno
      }
1845 5dd7d15b Bernardo Dal Seno
    invalid_policy = INVALID_DICT
1846 5dd7d15b Bernardo Dal Seno
    self.assertRaises(errors.OpPrereqError, cmdlib._GetUpdatedIPolicy,
1847 5dd7d15b Bernardo Dal Seno
                      old_policy, invalid_policy, group_policy=isgroup)
1848 da5f09ef Bernardo Dal Seno
    invalid_ispecs = {
1849 da5f09ef Bernardo Dal Seno
      constants.ISPECS_MINMAX: INVALID_DICT,
1850 da5f09ef Bernardo Dal Seno
      }
1851 da5f09ef Bernardo Dal Seno
    self.assertRaises(errors.OpPrereqError, cmdlib._GetUpdatedIPolicy,
1852 da5f09ef Bernardo Dal Seno
                      old_policy, invalid_ispecs, group_policy=isgroup)
1853 da5f09ef Bernardo Dal Seno
    for key in constants.ISPECS_MINMAX_KEYS:
1854 5dd7d15b Bernardo Dal Seno
      invalid_ispec = {
1855 da5f09ef Bernardo Dal Seno
        constants.ISPECS_MINMAX: {
1856 da5f09ef Bernardo Dal Seno
          key: INVALID_DICT,
1857 da5f09ef Bernardo Dal Seno
          },
1858 5dd7d15b Bernardo Dal Seno
        }
1859 5dd7d15b Bernardo Dal Seno
      self.assertRaises(errors.TypeEnforcementError, cmdlib._GetUpdatedIPolicy,
1860 5dd7d15b Bernardo Dal Seno
                        old_policy, invalid_ispec, group_policy=isgroup)
1861 5dd7d15b Bernardo Dal Seno
1862 5dd7d15b Bernardo Dal Seno
  def testInvalidKeys(self):
1863 5dd7d15b Bernardo Dal Seno
    self._TestInvalidKeys(self._OLD_GROUP_POLICY, True)
1864 5dd7d15b Bernardo Dal Seno
    self._TestInvalidKeys(self._OLD_CLUSTER_POLICY, False)
1865 5dd7d15b Bernardo Dal Seno
1866 5dd7d15b Bernardo Dal Seno
1867 b98bf262 Michael Hanselmann
if __name__ == "__main__":
1868 25231ec5 Michael Hanselmann
  testutils.GanetiTestProgram()