Statistics
| Branch: | Tag: | Revision:

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

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