Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.cmdlib_unittest.py @ 7352d33b

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