Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.cmdlib_unittest.py @ 553cb5f7

History | View | Annotate | Download (42.1 kB)

1 6de7c41d Iustin Pop
#!/usr/bin/python
2 6de7c41d Iustin Pop
#
3 6de7c41d Iustin Pop
4 ff0d18e6 Iustin Pop
# Copyright (C) 2008, 2011 Google Inc.
5 6de7c41d Iustin Pop
#
6 6de7c41d Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 6de7c41d Iustin Pop
# it under the terms of the GNU General Public License as published by
8 6de7c41d Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 6de7c41d Iustin Pop
# (at your option) any later version.
10 6de7c41d Iustin Pop
#
11 6de7c41d Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 6de7c41d Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 6de7c41d Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 6de7c41d Iustin Pop
# General Public License for more details.
15 6de7c41d Iustin Pop
#
16 6de7c41d Iustin Pop
# You should have received a copy of the GNU General Public License
17 6de7c41d Iustin Pop
# along with this program; if not, write to the Free Software
18 6de7c41d Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 fd7b69c0 Michael Hanselmann
# 02110-1301, USA.
20 6de7c41d Iustin Pop
21 6de7c41d Iustin Pop
22 6de7c41d Iustin Pop
"""Script for unittesting the cmdlib module"""
23 6de7c41d Iustin Pop
24 6de7c41d Iustin Pop
25 6de7c41d Iustin Pop
import os
26 6de7c41d Iustin Pop
import unittest
27 6de7c41d Iustin Pop
import time
28 b98bf262 Michael Hanselmann
import tempfile
29 b98bf262 Michael Hanselmann
import shutil
30 64c7b383 Michael Hanselmann
import operator
31 d755483c Michael Hanselmann
import itertools
32 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 b8812691 Iustin Pop
from ganeti import opcodes
37 6de7c41d Iustin Pop
from ganeti import errors
38 b8812691 Iustin Pop
from ganeti import utils
39 e58f87a9 Michael Hanselmann
from ganeti import luxi
40 65e183af Michael Hanselmann
from ganeti import ht
41 8ec505dd Adeodato Simo
from ganeti import objects
42 170b02b7 Michael Hanselmann
from ganeti import compat
43 170b02b7 Michael Hanselmann
from ganeti import rpc
44 0ad1ea40 Guido Trotter
from ganeti.hypervisor import hv_xen
45 6de7c41d Iustin Pop
46 25231ec5 Michael Hanselmann
import testutils
47 bd5f214b Apollon Oikonomopoulos
import mocks
48 25231ec5 Michael Hanselmann
49 6de7c41d Iustin Pop
50 b98bf262 Michael Hanselmann
class TestCertVerification(testutils.GanetiTestCase):
51 b98bf262 Michael Hanselmann
  def setUp(self):
52 b98bf262 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
53 b98bf262 Michael Hanselmann
54 b98bf262 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
55 b98bf262 Michael Hanselmann
56 b98bf262 Michael Hanselmann
  def tearDown(self):
57 b98bf262 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
58 b98bf262 Michael Hanselmann
59 b98bf262 Michael Hanselmann
  def testVerifyCertificate(self):
60 b98bf262 Michael Hanselmann
    cmdlib._VerifyCertificate(self._TestDataFilename("cert1.pem"))
61 b98bf262 Michael Hanselmann
62 b98bf262 Michael Hanselmann
    nonexist_filename = os.path.join(self.tmpdir, "does-not-exist")
63 b98bf262 Michael Hanselmann
64 b98bf262 Michael Hanselmann
    (errcode, msg) = cmdlib._VerifyCertificate(nonexist_filename)
65 bf93ae69 Adeodato Simo
    self.assertEqual(errcode, cmdlib.LUClusterVerifyConfig.ETYPE_ERROR)
66 b98bf262 Michael Hanselmann
67 b98bf262 Michael Hanselmann
    # Try to load non-certificate file
68 24d70417 Michael Hanselmann
    invalid_cert = self._TestDataFilename("bdev-net.txt")
69 b98bf262 Michael Hanselmann
    (errcode, msg) = cmdlib._VerifyCertificate(invalid_cert)
70 bf93ae69 Adeodato Simo
    self.assertEqual(errcode, cmdlib.LUClusterVerifyConfig.ETYPE_ERROR)
71 b98bf262 Michael Hanselmann
72 b98bf262 Michael Hanselmann
73 b8812691 Iustin Pop
class TestOpcodeParams(testutils.GanetiTestCase):
74 b8812691 Iustin Pop
  def testParamsStructures(self):
75 b8812691 Iustin Pop
    for op in sorted(mcpu.Processor.DISPATCH_TABLE):
76 b8812691 Iustin Pop
      lu = mcpu.Processor.DISPATCH_TABLE[op]
77 b8812691 Iustin Pop
      lu_name = lu.__name__
78 0bff0b12 Michael Hanselmann
      self.failIf(hasattr(lu, "_OP_REQP"),
79 0bff0b12 Michael Hanselmann
                  msg=("LU '%s' has old-style _OP_REQP" % lu_name))
80 0bff0b12 Michael Hanselmann
      self.failIf(hasattr(lu, "_OP_DEFS"),
81 0bff0b12 Michael Hanselmann
                  msg=("LU '%s' has old-style _OP_DEFS" % lu_name))
82 0bff0b12 Michael Hanselmann
      self.failIf(hasattr(lu, "_OP_PARAMS"),
83 0bff0b12 Michael Hanselmann
                  msg=("LU '%s' has old-style _OP_PARAMS" % lu_name))
84 b8812691 Iustin Pop
85 b8812691 Iustin Pop
86 bd5f214b Apollon Oikonomopoulos
class TestIAllocatorChecks(testutils.GanetiTestCase):
87 bd5f214b Apollon Oikonomopoulos
  def testFunction(self):
88 bd5f214b Apollon Oikonomopoulos
    class TestLU(object):
89 bd5f214b Apollon Oikonomopoulos
      def __init__(self, opcode):
90 bd5f214b Apollon Oikonomopoulos
        self.cfg = mocks.FakeConfig()
91 bd5f214b Apollon Oikonomopoulos
        self.op = opcode
92 bd5f214b Apollon Oikonomopoulos
93 ff0d18e6 Iustin Pop
    class OpTest(opcodes.OpCode):
94 ff0d18e6 Iustin Pop
       OP_PARAMS = [
95 197b323b Michael Hanselmann
        ("iallocator", None, ht.NoType, None),
96 197b323b Michael Hanselmann
        ("node", None, ht.NoType, None),
97 65e183af Michael Hanselmann
        ]
98 bd5f214b Apollon Oikonomopoulos
99 bd5f214b Apollon Oikonomopoulos
    default_iallocator = mocks.FakeConfig().GetDefaultIAllocator()
100 bd5f214b Apollon Oikonomopoulos
    other_iallocator = default_iallocator + "_not"
101 bd5f214b Apollon Oikonomopoulos
102 ff0d18e6 Iustin Pop
    op = OpTest()
103 bd5f214b Apollon Oikonomopoulos
    lu = TestLU(op)
104 bd5f214b Apollon Oikonomopoulos
105 bd5f214b Apollon Oikonomopoulos
    c_i = lambda: cmdlib._CheckIAllocatorOrNode(lu, "iallocator", "node")
106 bd5f214b Apollon Oikonomopoulos
107 bd5f214b Apollon Oikonomopoulos
    # Neither node nor iallocator given
108 bd5f214b Apollon Oikonomopoulos
    op.iallocator = None
109 bd5f214b Apollon Oikonomopoulos
    op.node = None
110 bd5f214b Apollon Oikonomopoulos
    c_i()
111 bd5f214b Apollon Oikonomopoulos
    self.assertEqual(lu.op.iallocator, default_iallocator)
112 bd5f214b Apollon Oikonomopoulos
    self.assertEqual(lu.op.node, None)
113 bd5f214b Apollon Oikonomopoulos
114 bd5f214b Apollon Oikonomopoulos
    # Both, iallocator and node given
115 bd5f214b Apollon Oikonomopoulos
    op.iallocator = "test"
116 bd5f214b Apollon Oikonomopoulos
    op.node = "test"
117 bd5f214b Apollon Oikonomopoulos
    self.assertRaises(errors.OpPrereqError, c_i)
118 bd5f214b Apollon Oikonomopoulos
119 bd5f214b Apollon Oikonomopoulos
    # Only iallocator given
120 bd5f214b Apollon Oikonomopoulos
    op.iallocator = other_iallocator
121 bd5f214b Apollon Oikonomopoulos
    op.node = None
122 bd5f214b Apollon Oikonomopoulos
    c_i()
123 bd5f214b Apollon Oikonomopoulos
    self.assertEqual(lu.op.iallocator, other_iallocator)
124 bd5f214b Apollon Oikonomopoulos
    self.assertEqual(lu.op.node, None)
125 bd5f214b Apollon Oikonomopoulos
126 bd5f214b Apollon Oikonomopoulos
    # Only node given
127 bd5f214b Apollon Oikonomopoulos
    op.iallocator = None
128 bd5f214b Apollon Oikonomopoulos
    op.node = "node"
129 bd5f214b Apollon Oikonomopoulos
    c_i()
130 bd5f214b Apollon Oikonomopoulos
    self.assertEqual(lu.op.iallocator, None)
131 bd5f214b Apollon Oikonomopoulos
    self.assertEqual(lu.op.node, "node")
132 bd5f214b Apollon Oikonomopoulos
133 bd5f214b Apollon Oikonomopoulos
    # No node, iallocator or default iallocator
134 bd5f214b Apollon Oikonomopoulos
    op.iallocator = None
135 bd5f214b Apollon Oikonomopoulos
    op.node = None
136 bd5f214b Apollon Oikonomopoulos
    lu.cfg.GetDefaultIAllocator = lambda: None
137 bd5f214b Apollon Oikonomopoulos
    self.assertRaises(errors.OpPrereqError, c_i)
138 bd5f214b Apollon Oikonomopoulos
139 bd5f214b Apollon Oikonomopoulos
140 b469eb4d Iustin Pop
class TestLUTestJqueue(unittest.TestCase):
141 e58f87a9 Michael Hanselmann
  def test(self):
142 b469eb4d Iustin Pop
    self.assert_(cmdlib.LUTestJqueue._CLIENT_CONNECT_TIMEOUT <
143 e58f87a9 Michael Hanselmann
                 (luxi.WFJC_TIMEOUT * 0.75),
144 e58f87a9 Michael Hanselmann
                 msg=("Client timeout too high, might not notice bugs"
145 e58f87a9 Michael Hanselmann
                      " in WaitForJobChange"))
146 e58f87a9 Michael Hanselmann
147 e58f87a9 Michael Hanselmann
148 83f72637 Michael Hanselmann
class TestLUQuery(unittest.TestCase):
149 83f72637 Michael Hanselmann
  def test(self):
150 83f72637 Michael Hanselmann
    self.assertEqual(sorted(cmdlib._QUERY_IMPL.keys()),
151 abd66bf8 Michael Hanselmann
                     sorted(constants.QR_VIA_OP))
152 83f72637 Michael Hanselmann
153 abd66bf8 Michael Hanselmann
    assert constants.QR_NODE in constants.QR_VIA_OP
154 abd66bf8 Michael Hanselmann
    assert constants.QR_INSTANCE in constants.QR_VIA_OP
155 83f72637 Michael Hanselmann
156 abd66bf8 Michael Hanselmann
    for i in constants.QR_VIA_OP:
157 83f72637 Michael Hanselmann
      self.assert_(cmdlib._GetQueryImplementation(i))
158 83f72637 Michael Hanselmann
159 83f72637 Michael Hanselmann
    self.assertRaises(errors.OpPrereqError, cmdlib._GetQueryImplementation, "")
160 83f72637 Michael Hanselmann
    self.assertRaises(errors.OpPrereqError, cmdlib._GetQueryImplementation,
161 83f72637 Michael Hanselmann
                      "xyz")
162 83f72637 Michael Hanselmann
163 83f72637 Michael Hanselmann
164 934704ae Iustin Pop
class TestLUGroupAssignNodes(unittest.TestCase):
165 8ec505dd Adeodato Simo
166 8ec505dd Adeodato Simo
  def testCheckAssignmentForSplitInstances(self):
167 8ec505dd Adeodato Simo
    node_data = dict((name, objects.Node(name=name, group=group))
168 8ec505dd Adeodato Simo
                     for (name, group) in [("n1a", "g1"), ("n1b", "g1"),
169 8ec505dd Adeodato Simo
                                           ("n2a", "g2"), ("n2b", "g2"),
170 8ec505dd Adeodato Simo
                                           ("n3a", "g3"), ("n3b", "g3"),
171 8ec505dd Adeodato Simo
                                           ("n3c", "g3"),
172 8ec505dd Adeodato Simo
                                           ])
173 8ec505dd Adeodato Simo
174 8ec505dd Adeodato Simo
    def Instance(name, pnode, snode):
175 8ec505dd Adeodato Simo
      if snode is None:
176 8ec505dd Adeodato Simo
        disks = []
177 8ec505dd Adeodato Simo
        disk_template = constants.DT_DISKLESS
178 8ec505dd Adeodato Simo
      else:
179 8ec505dd Adeodato Simo
        disks = [objects.Disk(dev_type=constants.LD_DRBD8,
180 8ec505dd Adeodato Simo
                              logical_id=[pnode, snode, 1, 17, 17])]
181 8ec505dd Adeodato Simo
        disk_template = constants.DT_DRBD8
182 8ec505dd Adeodato Simo
183 8ec505dd Adeodato Simo
      return objects.Instance(name=name, primary_node=pnode, disks=disks,
184 8ec505dd Adeodato Simo
                              disk_template=disk_template)
185 8ec505dd Adeodato Simo
186 8ec505dd Adeodato Simo
    instance_data = dict((name, Instance(name, pnode, snode))
187 8ec505dd Adeodato Simo
                         for name, pnode, snode in [("inst1a", "n1a", "n1b"),
188 8ec505dd Adeodato Simo
                                                    ("inst1b", "n1b", "n1a"),
189 8ec505dd Adeodato Simo
                                                    ("inst2a", "n2a", "n2b"),
190 8ec505dd Adeodato Simo
                                                    ("inst3a", "n3a", None),
191 8ec505dd Adeodato Simo
                                                    ("inst3b", "n3b", "n1b"),
192 8ec505dd Adeodato Simo
                                                    ("inst3c", "n3b", "n2b"),
193 8ec505dd Adeodato Simo
                                                    ])
194 8ec505dd Adeodato Simo
195 8ec505dd Adeodato Simo
    # Test first with the existing state.
196 8ec505dd Adeodato Simo
    (new, prev) = \
197 934704ae Iustin Pop
      cmdlib.LUGroupAssignNodes.CheckAssignmentForSplitInstances([],
198 8ec505dd Adeodato Simo
                                                                 node_data,
199 8ec505dd Adeodato Simo
                                                                 instance_data)
200 8ec505dd Adeodato Simo
201 8ec505dd Adeodato Simo
    self.assertEqual([], new)
202 8ec505dd Adeodato Simo
    self.assertEqual(set(["inst3b", "inst3c"]), set(prev))
203 8ec505dd Adeodato Simo
204 8ec505dd Adeodato Simo
    # And now some changes.
205 8ec505dd Adeodato Simo
    (new, prev) = \
206 934704ae Iustin Pop
      cmdlib.LUGroupAssignNodes.CheckAssignmentForSplitInstances([("n1b",
207 8ec505dd Adeodato Simo
                                                                   "g3")],
208 8ec505dd Adeodato Simo
                                                                 node_data,
209 8ec505dd Adeodato Simo
                                                                 instance_data)
210 8ec505dd Adeodato Simo
211 8ec505dd Adeodato Simo
    self.assertEqual(set(["inst1a", "inst1b"]), set(new))
212 8ec505dd Adeodato Simo
    self.assertEqual(set(["inst3c"]), set(prev))
213 8ec505dd Adeodato Simo
214 8ec505dd Adeodato Simo
215 64c7b383 Michael Hanselmann
class TestClusterVerifySsh(unittest.TestCase):
216 64c7b383 Michael Hanselmann
  def testMultipleGroups(self):
217 64c7b383 Michael Hanselmann
    fn = cmdlib.LUClusterVerifyGroup._SelectSshCheckNodes
218 64c7b383 Michael Hanselmann
    mygroupnodes = [
219 64c7b383 Michael Hanselmann
      objects.Node(name="node20", group="my", offline=False),
220 64c7b383 Michael Hanselmann
      objects.Node(name="node21", group="my", offline=False),
221 64c7b383 Michael Hanselmann
      objects.Node(name="node22", group="my", offline=False),
222 64c7b383 Michael Hanselmann
      objects.Node(name="node23", group="my", offline=False),
223 64c7b383 Michael Hanselmann
      objects.Node(name="node24", group="my", offline=False),
224 64c7b383 Michael Hanselmann
      objects.Node(name="node25", group="my", offline=False),
225 64c7b383 Michael Hanselmann
      objects.Node(name="node26", group="my", offline=True),
226 64c7b383 Michael Hanselmann
      ]
227 64c7b383 Michael Hanselmann
    nodes = [
228 64c7b383 Michael Hanselmann
      objects.Node(name="node1", group="g1", offline=True),
229 64c7b383 Michael Hanselmann
      objects.Node(name="node2", group="g1", offline=False),
230 64c7b383 Michael Hanselmann
      objects.Node(name="node3", group="g1", offline=False),
231 64c7b383 Michael Hanselmann
      objects.Node(name="node4", group="g1", offline=True),
232 64c7b383 Michael Hanselmann
      objects.Node(name="node5", group="g1", offline=False),
233 64c7b383 Michael Hanselmann
      objects.Node(name="node10", group="xyz", offline=False),
234 64c7b383 Michael Hanselmann
      objects.Node(name="node11", group="xyz", offline=False),
235 64c7b383 Michael Hanselmann
      objects.Node(name="node40", group="alloff", offline=True),
236 64c7b383 Michael Hanselmann
      objects.Node(name="node41", group="alloff", offline=True),
237 64c7b383 Michael Hanselmann
      objects.Node(name="node50", group="aaa", offline=False),
238 64c7b383 Michael Hanselmann
      ] + mygroupnodes
239 64c7b383 Michael Hanselmann
    assert not utils.FindDuplicates(map(operator.attrgetter("name"), nodes))
240 64c7b383 Michael Hanselmann
241 64c7b383 Michael Hanselmann
    (online, perhost) = fn(mygroupnodes, "my", nodes)
242 64c7b383 Michael Hanselmann
    self.assertEqual(online, ["node%s" % i for i in range(20, 26)])
243 64c7b383 Michael Hanselmann
    self.assertEqual(set(perhost.keys()), set(online))
244 64c7b383 Michael Hanselmann
245 64c7b383 Michael Hanselmann
    self.assertEqual(perhost, {
246 64c7b383 Michael Hanselmann
      "node20": ["node10", "node2", "node50"],
247 64c7b383 Michael Hanselmann
      "node21": ["node11", "node3", "node50"],
248 64c7b383 Michael Hanselmann
      "node22": ["node10", "node5", "node50"],
249 64c7b383 Michael Hanselmann
      "node23": ["node11", "node2", "node50"],
250 64c7b383 Michael Hanselmann
      "node24": ["node10", "node3", "node50"],
251 64c7b383 Michael Hanselmann
      "node25": ["node11", "node5", "node50"],
252 64c7b383 Michael Hanselmann
      })
253 64c7b383 Michael Hanselmann
254 64c7b383 Michael Hanselmann
  def testSingleGroup(self):
255 64c7b383 Michael Hanselmann
    fn = cmdlib.LUClusterVerifyGroup._SelectSshCheckNodes
256 64c7b383 Michael Hanselmann
    nodes = [
257 64c7b383 Michael Hanselmann
      objects.Node(name="node1", group="default", offline=True),
258 64c7b383 Michael Hanselmann
      objects.Node(name="node2", group="default", offline=False),
259 64c7b383 Michael Hanselmann
      objects.Node(name="node3", group="default", offline=False),
260 64c7b383 Michael Hanselmann
      objects.Node(name="node4", group="default", offline=True),
261 64c7b383 Michael Hanselmann
      ]
262 64c7b383 Michael Hanselmann
    assert not utils.FindDuplicates(map(operator.attrgetter("name"), nodes))
263 64c7b383 Michael Hanselmann
264 64c7b383 Michael Hanselmann
    (online, perhost) = fn(nodes, "default", nodes)
265 64c7b383 Michael Hanselmann
    self.assertEqual(online, ["node2", "node3"])
266 64c7b383 Michael Hanselmann
    self.assertEqual(set(perhost.keys()), set(online))
267 64c7b383 Michael Hanselmann
268 64c7b383 Michael Hanselmann
    self.assertEqual(perhost, {
269 64c7b383 Michael Hanselmann
      "node2": [],
270 64c7b383 Michael Hanselmann
      "node3": [],
271 64c7b383 Michael Hanselmann
      })
272 64c7b383 Michael Hanselmann
273 64c7b383 Michael Hanselmann
274 170b02b7 Michael Hanselmann
class TestClusterVerifyFiles(unittest.TestCase):
275 170b02b7 Michael Hanselmann
  @staticmethod
276 170b02b7 Michael Hanselmann
  def _FakeErrorIf(errors, cond, ecode, item, msg, *args, **kwargs):
277 eedf99b5 Andrea Spadaccini
    assert ((ecode == constants.CV_ENODEFILECHECK and
278 170b02b7 Michael Hanselmann
             ht.TNonEmptyString(item)) or
279 eedf99b5 Andrea Spadaccini
            (ecode == constants.CV_ECLUSTERFILECHECK and
280 170b02b7 Michael Hanselmann
             item is None))
281 170b02b7 Michael Hanselmann
282 170b02b7 Michael Hanselmann
    if args:
283 170b02b7 Michael Hanselmann
      msg = msg % args
284 170b02b7 Michael Hanselmann
285 170b02b7 Michael Hanselmann
    if cond:
286 170b02b7 Michael Hanselmann
      errors.append((item, msg))
287 170b02b7 Michael Hanselmann
288 170b02b7 Michael Hanselmann
  _VerifyFiles = cmdlib.LUClusterVerifyGroup._VerifyFiles
289 170b02b7 Michael Hanselmann
290 170b02b7 Michael Hanselmann
  def test(self):
291 170b02b7 Michael Hanselmann
    errors = []
292 170b02b7 Michael Hanselmann
    master_name = "master.example.com"
293 170b02b7 Michael Hanselmann
    nodeinfo = [
294 0ad1ea40 Guido Trotter
      objects.Node(name=master_name, offline=False, vm_capable=True),
295 0ad1ea40 Guido Trotter
      objects.Node(name="node2.example.com", offline=False, vm_capable=True),
296 0ad1ea40 Guido Trotter
      objects.Node(name="node3.example.com", master_candidate=True,
297 0ad1ea40 Guido Trotter
                   vm_capable=False),
298 0ad1ea40 Guido Trotter
      objects.Node(name="node4.example.com", offline=False, vm_capable=True),
299 0ad1ea40 Guido Trotter
      objects.Node(name="nodata.example.com", offline=False, vm_capable=True),
300 170b02b7 Michael Hanselmann
      objects.Node(name="offline.example.com", offline=True),
301 170b02b7 Michael Hanselmann
      ]
302 170b02b7 Michael Hanselmann
    cluster = objects.Cluster(modify_etc_hosts=True,
303 170b02b7 Michael Hanselmann
                              enabled_hypervisors=[constants.HT_XEN_HVM])
304 170b02b7 Michael Hanselmann
    files_all = set([
305 170b02b7 Michael Hanselmann
      constants.CLUSTER_DOMAIN_SECRET_FILE,
306 170b02b7 Michael Hanselmann
      constants.RAPI_CERT_FILE,
307 0ad1ea40 Guido Trotter
      constants.RAPI_USERS_FILE,
308 170b02b7 Michael Hanselmann
      ])
309 0ad1ea40 Guido Trotter
    files_opt = set([
310 170b02b7 Michael Hanselmann
      constants.RAPI_USERS_FILE,
311 0ad1ea40 Guido Trotter
      hv_xen.XL_CONFIG_FILE,
312 0ad1ea40 Guido Trotter
      constants.VNC_PASSWORD_FILE,
313 170b02b7 Michael Hanselmann
      ])
314 170b02b7 Michael Hanselmann
    files_mc = set([
315 170b02b7 Michael Hanselmann
      constants.CLUSTER_CONF_FILE,
316 170b02b7 Michael Hanselmann
      ])
317 0ad1ea40 Guido Trotter
    files_vm = set([
318 0ad1ea40 Guido Trotter
      hv_xen.XEND_CONFIG_FILE,
319 0ad1ea40 Guido Trotter
      hv_xen.XL_CONFIG_FILE,
320 0ad1ea40 Guido Trotter
      constants.VNC_PASSWORD_FILE,
321 0ad1ea40 Guido Trotter
      ])
322 170b02b7 Michael Hanselmann
    nvinfo = {
323 170b02b7 Michael Hanselmann
      master_name: rpc.RpcResult(data=(True, {
324 170b02b7 Michael Hanselmann
        constants.NV_FILELIST: {
325 170b02b7 Michael Hanselmann
          constants.CLUSTER_CONF_FILE: "82314f897f38b35f9dab2f7c6b1593e0",
326 170b02b7 Michael Hanselmann
          constants.RAPI_CERT_FILE: "babbce8f387bc082228e544a2146fee4",
327 170b02b7 Michael Hanselmann
          constants.CLUSTER_DOMAIN_SECRET_FILE: "cds-47b5b3f19202936bb4",
328 0ad1ea40 Guido Trotter
          hv_xen.XEND_CONFIG_FILE: "b4a8a824ab3cac3d88839a9adeadf310",
329 0ad1ea40 Guido Trotter
          hv_xen.XL_CONFIG_FILE: "77935cee92afd26d162f9e525e3d49b9"
330 170b02b7 Michael Hanselmann
        }})),
331 170b02b7 Michael Hanselmann
      "node2.example.com": rpc.RpcResult(data=(True, {
332 170b02b7 Michael Hanselmann
        constants.NV_FILELIST: {
333 170b02b7 Michael Hanselmann
          constants.RAPI_CERT_FILE: "97f0356500e866387f4b84233848cc4a",
334 0ad1ea40 Guido Trotter
          hv_xen.XEND_CONFIG_FILE: "b4a8a824ab3cac3d88839a9adeadf310",
335 170b02b7 Michael Hanselmann
          }
336 170b02b7 Michael Hanselmann
        })),
337 170b02b7 Michael Hanselmann
      "node3.example.com": rpc.RpcResult(data=(True, {
338 170b02b7 Michael Hanselmann
        constants.NV_FILELIST: {
339 170b02b7 Michael Hanselmann
          constants.RAPI_CERT_FILE: "97f0356500e866387f4b84233848cc4a",
340 170b02b7 Michael Hanselmann
          constants.CLUSTER_DOMAIN_SECRET_FILE: "cds-47b5b3f19202936bb4",
341 170b02b7 Michael Hanselmann
          }
342 170b02b7 Michael Hanselmann
        })),
343 170b02b7 Michael Hanselmann
      "node4.example.com": rpc.RpcResult(data=(True, {
344 170b02b7 Michael Hanselmann
        constants.NV_FILELIST: {
345 170b02b7 Michael Hanselmann
          constants.RAPI_CERT_FILE: "97f0356500e866387f4b84233848cc4a",
346 170b02b7 Michael Hanselmann
          constants.CLUSTER_CONF_FILE: "conf-a6d4b13e407867f7a7b4f0f232a8f527",
347 170b02b7 Michael Hanselmann
          constants.CLUSTER_DOMAIN_SECRET_FILE: "cds-47b5b3f19202936bb4",
348 170b02b7 Michael Hanselmann
          constants.RAPI_USERS_FILE: "rapiusers-ea3271e8d810ef3",
349 0ad1ea40 Guido Trotter
          hv_xen.XL_CONFIG_FILE: "77935cee92afd26d162f9e525e3d49b9"
350 170b02b7 Michael Hanselmann
          }
351 170b02b7 Michael Hanselmann
        })),
352 170b02b7 Michael Hanselmann
      "nodata.example.com": rpc.RpcResult(data=(True, {})),
353 170b02b7 Michael Hanselmann
      "offline.example.com": rpc.RpcResult(offline=True),
354 170b02b7 Michael Hanselmann
      }
355 170b02b7 Michael Hanselmann
    assert set(nvinfo.keys()) == set(map(operator.attrgetter("name"), nodeinfo))
356 170b02b7 Michael Hanselmann
357 170b02b7 Michael Hanselmann
    self._VerifyFiles(compat.partial(self._FakeErrorIf, errors), nodeinfo,
358 170b02b7 Michael Hanselmann
                      master_name, nvinfo,
359 0ad1ea40 Guido Trotter
                      (files_all, files_opt, files_mc, files_vm))
360 170b02b7 Michael Hanselmann
    self.assertEqual(sorted(errors), sorted([
361 170b02b7 Michael Hanselmann
      (None, ("File %s found with 2 different checksums (variant 1 on"
362 170b02b7 Michael Hanselmann
              " node2.example.com, node3.example.com, node4.example.com;"
363 170b02b7 Michael Hanselmann
              " variant 2 on master.example.com)" % constants.RAPI_CERT_FILE)),
364 170b02b7 Michael Hanselmann
      (None, ("File %s is missing from node(s) node2.example.com" %
365 170b02b7 Michael Hanselmann
              constants.CLUSTER_DOMAIN_SECRET_FILE)),
366 170b02b7 Michael Hanselmann
      (None, ("File %s should not exist on node(s) node4.example.com" %
367 170b02b7 Michael Hanselmann
              constants.CLUSTER_CONF_FILE)),
368 0ad1ea40 Guido Trotter
      (None, ("File %s is missing from node(s) node4.example.com" %
369 0ad1ea40 Guido Trotter
              hv_xen.XEND_CONFIG_FILE)),
370 170b02b7 Michael Hanselmann
      (None, ("File %s is missing from node(s) node3.example.com" %
371 170b02b7 Michael Hanselmann
              constants.CLUSTER_CONF_FILE)),
372 170b02b7 Michael Hanselmann
      (None, ("File %s found with 2 different checksums (variant 1 on"
373 170b02b7 Michael Hanselmann
              " master.example.com; variant 2 on node4.example.com)" %
374 170b02b7 Michael Hanselmann
              constants.CLUSTER_CONF_FILE)),
375 170b02b7 Michael Hanselmann
      (None, ("File %s is optional, but it must exist on all or no nodes (not"
376 170b02b7 Michael Hanselmann
              " found on master.example.com, node2.example.com,"
377 170b02b7 Michael Hanselmann
              " node3.example.com)" % constants.RAPI_USERS_FILE)),
378 0ad1ea40 Guido Trotter
      (None, ("File %s is optional, but it must exist on all or no nodes (not"
379 0ad1ea40 Guido Trotter
              " found on node2.example.com)" % hv_xen.XL_CONFIG_FILE)),
380 170b02b7 Michael Hanselmann
      ("nodata.example.com", "Node did not return file checksum data"),
381 170b02b7 Michael Hanselmann
      ]))
382 170b02b7 Michael Hanselmann
383 170b02b7 Michael Hanselmann
384 d755483c Michael Hanselmann
class _FakeLU:
385 a8e3e009 Michael Hanselmann
  def __init__(self, cfg=NotImplemented, proc=NotImplemented):
386 d755483c Michael Hanselmann
    self.warning_log = []
387 d755483c Michael Hanselmann
    self.info_log = []
388 ff02b60f René Nussbaumer
    self.cfg = cfg
389 a8e3e009 Michael Hanselmann
    self.proc = proc
390 d755483c Michael Hanselmann
391 d755483c Michael Hanselmann
  def LogWarning(self, text, *args):
392 d755483c Michael Hanselmann
    self.warning_log.append((text, args))
393 d755483c Michael Hanselmann
394 d755483c Michael Hanselmann
  def LogInfo(self, text, *args):
395 d755483c Michael Hanselmann
    self.info_log.append((text, args))
396 d755483c Michael Hanselmann
397 d755483c Michael Hanselmann
398 d755483c Michael Hanselmann
class TestLoadNodeEvacResult(unittest.TestCase):
399 d755483c Michael Hanselmann
  def testSuccess(self):
400 d755483c Michael Hanselmann
    for moved in [[], [
401 d755483c Michael Hanselmann
      ("inst20153.example.com", "grp2", ["nodeA4509", "nodeB2912"]),
402 d755483c Michael Hanselmann
      ]]:
403 d755483c Michael Hanselmann
      for early_release in [False, True]:
404 d755483c Michael Hanselmann
        for use_nodes in [False, True]:
405 d755483c Michael Hanselmann
          jobs = [
406 d755483c Michael Hanselmann
            [opcodes.OpInstanceReplaceDisks().__getstate__()],
407 d755483c Michael Hanselmann
            [opcodes.OpInstanceMigrate().__getstate__()],
408 d755483c Michael Hanselmann
            ]
409 d755483c Michael Hanselmann
410 d755483c Michael Hanselmann
          alloc_result = (moved, [], jobs)
411 d755483c Michael Hanselmann
          assert cmdlib.IAllocator._NEVAC_RESULT(alloc_result)
412 d755483c Michael Hanselmann
413 d755483c Michael Hanselmann
          lu = _FakeLU()
414 d755483c Michael Hanselmann
          result = cmdlib._LoadNodeEvacResult(lu, alloc_result,
415 d755483c Michael Hanselmann
                                              early_release, use_nodes)
416 d755483c Michael Hanselmann
417 d755483c Michael Hanselmann
          if moved:
418 d755483c Michael Hanselmann
            (_, (info_args, )) = lu.info_log.pop(0)
419 d755483c Michael Hanselmann
            for (instname, instgroup, instnodes) in moved:
420 d755483c Michael Hanselmann
              self.assertTrue(instname in info_args)
421 d755483c Michael Hanselmann
              if use_nodes:
422 d755483c Michael Hanselmann
                for i in instnodes:
423 d755483c Michael Hanselmann
                  self.assertTrue(i in info_args)
424 d755483c Michael Hanselmann
              else:
425 d755483c Michael Hanselmann
                self.assertTrue(instgroup in info_args)
426 d755483c Michael Hanselmann
427 d755483c Michael Hanselmann
          self.assertFalse(lu.info_log)
428 d755483c Michael Hanselmann
          self.assertFalse(lu.warning_log)
429 d755483c Michael Hanselmann
430 d755483c Michael Hanselmann
          for op in itertools.chain(*result):
431 d755483c Michael Hanselmann
            if hasattr(op.__class__, "early_release"):
432 d755483c Michael Hanselmann
              self.assertEqual(op.early_release, early_release)
433 d755483c Michael Hanselmann
            else:
434 d755483c Michael Hanselmann
              self.assertFalse(hasattr(op, "early_release"))
435 d755483c Michael Hanselmann
436 d755483c Michael Hanselmann
  def testFailed(self):
437 d755483c Michael Hanselmann
    alloc_result = ([], [
438 d755483c Michael Hanselmann
      ("inst5191.example.com", "errormsg21178"),
439 d755483c Michael Hanselmann
      ], [])
440 d755483c Michael Hanselmann
    assert cmdlib.IAllocator._NEVAC_RESULT(alloc_result)
441 d755483c Michael Hanselmann
442 d755483c Michael Hanselmann
    lu = _FakeLU()
443 d755483c Michael Hanselmann
    self.assertRaises(errors.OpExecError, cmdlib._LoadNodeEvacResult,
444 d755483c Michael Hanselmann
                      lu, alloc_result, False, False)
445 d755483c Michael Hanselmann
    self.assertFalse(lu.info_log)
446 d755483c Michael Hanselmann
    (_, (args, )) = lu.warning_log.pop(0)
447 d755483c Michael Hanselmann
    self.assertTrue("inst5191.example.com" in args)
448 d755483c Michael Hanselmann
    self.assertTrue("errormsg21178" in args)
449 d755483c Michael Hanselmann
    self.assertFalse(lu.warning_log)
450 d755483c Michael Hanselmann
451 d755483c Michael Hanselmann
452 784cd737 René Nussbaumer
class TestUpdateAndVerifySubDict(unittest.TestCase):
453 784cd737 René Nussbaumer
  def setUp(self):
454 784cd737 René Nussbaumer
    self.type_check = {
455 784cd737 René Nussbaumer
        "a": constants.VTYPE_INT,
456 784cd737 René Nussbaumer
        "b": constants.VTYPE_STRING,
457 784cd737 René Nussbaumer
        "c": constants.VTYPE_BOOL,
458 784cd737 René Nussbaumer
        "d": constants.VTYPE_STRING,
459 784cd737 René Nussbaumer
        }
460 784cd737 René Nussbaumer
461 784cd737 René Nussbaumer
  def test(self):
462 784cd737 René Nussbaumer
    old_test = {
463 784cd737 René Nussbaumer
      "foo": {
464 784cd737 René Nussbaumer
        "d": "blubb",
465 784cd737 René Nussbaumer
        "a": 321,
466 784cd737 René Nussbaumer
        },
467 784cd737 René Nussbaumer
      "baz": {
468 784cd737 René Nussbaumer
        "a": 678,
469 784cd737 René Nussbaumer
        "b": "678",
470 784cd737 René Nussbaumer
        "c": True,
471 784cd737 René Nussbaumer
        },
472 784cd737 René Nussbaumer
      }
473 784cd737 René Nussbaumer
    test = {
474 784cd737 René Nussbaumer
      "foo": {
475 784cd737 René Nussbaumer
        "a": 123,
476 784cd737 René Nussbaumer
        "b": "123",
477 784cd737 René Nussbaumer
        "c": True,
478 784cd737 René Nussbaumer
        },
479 784cd737 René Nussbaumer
      "bar": {
480 784cd737 René Nussbaumer
        "a": 321,
481 784cd737 René Nussbaumer
        "b": "321",
482 784cd737 René Nussbaumer
        "c": False,
483 784cd737 René Nussbaumer
        },
484 784cd737 René Nussbaumer
      }
485 784cd737 René Nussbaumer
486 784cd737 René Nussbaumer
    mv = {
487 784cd737 René Nussbaumer
      "foo": {
488 784cd737 René Nussbaumer
        "a": 123,
489 784cd737 René Nussbaumer
        "b": "123",
490 784cd737 René Nussbaumer
        "c": True,
491 784cd737 René Nussbaumer
        "d": "blubb"
492 784cd737 René Nussbaumer
        },
493 784cd737 René Nussbaumer
      "bar": {
494 784cd737 René Nussbaumer
        "a": 321,
495 784cd737 René Nussbaumer
        "b": "321",
496 784cd737 René Nussbaumer
        "c": False,
497 784cd737 René Nussbaumer
        },
498 784cd737 René Nussbaumer
      "baz": {
499 784cd737 René Nussbaumer
        "a": 678,
500 784cd737 René Nussbaumer
        "b": "678",
501 784cd737 René Nussbaumer
        "c": True,
502 784cd737 René Nussbaumer
        },
503 784cd737 René Nussbaumer
      }
504 784cd737 René Nussbaumer
505 784cd737 René Nussbaumer
    verified = cmdlib._UpdateAndVerifySubDict(old_test, test, self.type_check)
506 784cd737 René Nussbaumer
    self.assertEqual(verified, mv)
507 784cd737 René Nussbaumer
508 784cd737 René Nussbaumer
  def testWrong(self):
509 784cd737 René Nussbaumer
    test = {
510 784cd737 René Nussbaumer
      "foo": {
511 784cd737 René Nussbaumer
        "a": "blubb",
512 784cd737 René Nussbaumer
        "b": "123",
513 784cd737 René Nussbaumer
        "c": True,
514 784cd737 René Nussbaumer
        },
515 784cd737 René Nussbaumer
      "bar": {
516 784cd737 René Nussbaumer
        "a": 321,
517 784cd737 René Nussbaumer
        "b": "321",
518 784cd737 René Nussbaumer
        "c": False,
519 784cd737 René Nussbaumer
        },
520 784cd737 René Nussbaumer
      }
521 784cd737 René Nussbaumer
522 784cd737 René Nussbaumer
    self.assertRaises(errors.TypeEnforcementError,
523 784cd737 René Nussbaumer
                      cmdlib._UpdateAndVerifySubDict, {}, test, self.type_check)
524 784cd737 René Nussbaumer
525 784cd737 René Nussbaumer
526 0ba177e2 René Nussbaumer
class TestHvStateHelper(unittest.TestCase):
527 0ba177e2 René Nussbaumer
  def testWithoutOpData(self):
528 0ba177e2 René Nussbaumer
    self.assertEqual(cmdlib._MergeAndVerifyHvState(None, NotImplemented), None)
529 0ba177e2 René Nussbaumer
530 0ba177e2 René Nussbaumer
  def testWithoutOldData(self):
531 0ba177e2 René Nussbaumer
    new = {
532 0ba177e2 René Nussbaumer
      constants.HT_XEN_PVM: {
533 0ba177e2 René Nussbaumer
        constants.HVST_MEMORY_TOTAL: 4096,
534 0ba177e2 René Nussbaumer
        },
535 0ba177e2 René Nussbaumer
      }
536 0ba177e2 René Nussbaumer
    self.assertEqual(cmdlib._MergeAndVerifyHvState(new, None), new)
537 0ba177e2 René Nussbaumer
538 0ba177e2 René Nussbaumer
  def testWithWrongHv(self):
539 0ba177e2 René Nussbaumer
    new = {
540 0ba177e2 René Nussbaumer
      "i-dont-exist": {
541 0ba177e2 René Nussbaumer
        constants.HVST_MEMORY_TOTAL: 4096,
542 0ba177e2 René Nussbaumer
        },
543 0ba177e2 René Nussbaumer
      }
544 0ba177e2 René Nussbaumer
    self.assertRaises(errors.OpPrereqError, cmdlib._MergeAndVerifyHvState, new,
545 0ba177e2 René Nussbaumer
                      None)
546 0ba177e2 René Nussbaumer
547 0ba177e2 René Nussbaumer
class TestDiskStateHelper(unittest.TestCase):
548 0ba177e2 René Nussbaumer
  def testWithoutOpData(self):
549 0ba177e2 René Nussbaumer
    self.assertEqual(cmdlib._MergeAndVerifyDiskState(None, NotImplemented),
550 0ba177e2 René Nussbaumer
                     None)
551 0ba177e2 René Nussbaumer
552 0ba177e2 René Nussbaumer
  def testWithoutOldData(self):
553 0ba177e2 René Nussbaumer
    new = {
554 0ba177e2 René Nussbaumer
      constants.LD_LV: {
555 0ba177e2 René Nussbaumer
        "xenvg": {
556 0ba177e2 René Nussbaumer
          constants.DS_DISK_RESERVED: 1024,
557 0ba177e2 René Nussbaumer
          },
558 0ba177e2 René Nussbaumer
        },
559 0ba177e2 René Nussbaumer
      }
560 0ba177e2 René Nussbaumer
    self.assertEqual(cmdlib._MergeAndVerifyDiskState(new, None), new)
561 0ba177e2 René Nussbaumer
562 0ba177e2 René Nussbaumer
  def testWithWrongStorageType(self):
563 0ba177e2 René Nussbaumer
    new = {
564 0ba177e2 René Nussbaumer
      "i-dont-exist": {
565 0ba177e2 René Nussbaumer
        "xenvg": {
566 0ba177e2 René Nussbaumer
          constants.DS_DISK_RESERVED: 1024,
567 0ba177e2 René Nussbaumer
          },
568 0ba177e2 René Nussbaumer
        },
569 0ba177e2 René Nussbaumer
      }
570 0ba177e2 René Nussbaumer
    self.assertRaises(errors.OpPrereqError, cmdlib._MergeAndVerifyDiskState,
571 0ba177e2 René Nussbaumer
                      new, None)
572 0ba177e2 René Nussbaumer
573 0ba177e2 René Nussbaumer
574 2096d068 René Nussbaumer
class TestComputeMinMaxSpec(unittest.TestCase):
575 2096d068 René Nussbaumer
  def setUp(self):
576 2096d068 René Nussbaumer
    self.ipolicy = {
577 2096d068 René Nussbaumer
      constants.ISPECS_MAX: {
578 2096d068 René Nussbaumer
        constants.ISPEC_MEM_SIZE: 512,
579 2096d068 René Nussbaumer
        constants.ISPEC_DISK_SIZE: 1024,
580 2096d068 René Nussbaumer
        },
581 2096d068 René Nussbaumer
      constants.ISPECS_MIN: {
582 2096d068 René Nussbaumer
        constants.ISPEC_MEM_SIZE: 128,
583 2096d068 René Nussbaumer
        constants.ISPEC_DISK_COUNT: 1,
584 2096d068 René Nussbaumer
        },
585 2096d068 René Nussbaumer
      }
586 2096d068 René Nussbaumer
587 2096d068 René Nussbaumer
  def testNoneValue(self):
588 2096d068 René Nussbaumer
    self.assertTrue(cmdlib._ComputeMinMaxSpec(constants.ISPEC_MEM_SIZE,
589 2096d068 René Nussbaumer
                                              self.ipolicy, None) is None)
590 2096d068 René Nussbaumer
591 2096d068 René Nussbaumer
  def testAutoValue(self):
592 2096d068 René Nussbaumer
    self.assertTrue(cmdlib._ComputeMinMaxSpec(constants.ISPEC_MEM_SIZE,
593 2096d068 René Nussbaumer
                                              self.ipolicy,
594 2096d068 René Nussbaumer
                                              constants.VALUE_AUTO) is None)
595 2096d068 René Nussbaumer
596 2096d068 René Nussbaumer
  def testNotDefined(self):
597 2096d068 René Nussbaumer
    self.assertTrue(cmdlib._ComputeMinMaxSpec(constants.ISPEC_NIC_COUNT,
598 2096d068 René Nussbaumer
                                              self.ipolicy, 3) is None)
599 2096d068 René Nussbaumer
600 2096d068 René Nussbaumer
  def testNoMinDefined(self):
601 2096d068 René Nussbaumer
    self.assertTrue(cmdlib._ComputeMinMaxSpec(constants.ISPEC_DISK_SIZE,
602 2096d068 René Nussbaumer
                                              self.ipolicy, 128) is None)
603 2096d068 René Nussbaumer
604 2096d068 René Nussbaumer
  def testNoMaxDefined(self):
605 2096d068 René Nussbaumer
    self.assertTrue(cmdlib._ComputeMinMaxSpec(constants.ISPEC_DISK_COUNT,
606 2096d068 René Nussbaumer
                                                self.ipolicy, 16) is None)
607 2096d068 René Nussbaumer
608 2096d068 René Nussbaumer
  def testOutOfRange(self):
609 2096d068 René Nussbaumer
    for (name, val) in ((constants.ISPEC_MEM_SIZE, 64),
610 2096d068 René Nussbaumer
                        (constants.ISPEC_MEM_SIZE, 768),
611 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_SIZE, 4096),
612 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_COUNT, 0)):
613 2096d068 René Nussbaumer
      min_v = self.ipolicy[constants.ISPECS_MIN].get(name, val)
614 2096d068 René Nussbaumer
      max_v = self.ipolicy[constants.ISPECS_MAX].get(name, val)
615 2096d068 René Nussbaumer
      self.assertEqual(cmdlib._ComputeMinMaxSpec(name, self.ipolicy, val),
616 2096d068 René Nussbaumer
                       "%s value %s is not in range [%s, %s]" %
617 2096d068 René Nussbaumer
                       (name, val,min_v, max_v))
618 2096d068 René Nussbaumer
619 2096d068 René Nussbaumer
  def test(self):
620 2096d068 René Nussbaumer
    for (name, val) in ((constants.ISPEC_MEM_SIZE, 256),
621 2096d068 René Nussbaumer
                        (constants.ISPEC_MEM_SIZE, 128),
622 2096d068 René Nussbaumer
                        (constants.ISPEC_MEM_SIZE, 512),
623 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_SIZE, 1024),
624 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_SIZE, 0),
625 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_COUNT, 1),
626 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_COUNT, 5)):
627 2096d068 René Nussbaumer
      self.assertTrue(cmdlib._ComputeMinMaxSpec(name, self.ipolicy, val)
628 2096d068 René Nussbaumer
                      is None)
629 2096d068 René Nussbaumer
630 2096d068 René Nussbaumer
631 0e68bf27 René Nussbaumer
def _ValidateComputeMinMaxSpec(name, *_):
632 0fb81174 René Nussbaumer
  assert name in constants.ISPECS_PARAMETERS
633 0fb81174 René Nussbaumer
  return None
634 0fb81174 René Nussbaumer
635 0fb81174 René Nussbaumer
636 0fb81174 René Nussbaumer
class _SpecWrapper:
637 0fb81174 René Nussbaumer
  def __init__(self, spec):
638 0fb81174 René Nussbaumer
    self.spec = spec
639 0fb81174 René Nussbaumer
640 0e68bf27 René Nussbaumer
  def ComputeMinMaxSpec(self, *args):
641 0fb81174 René Nussbaumer
    return self.spec.pop(0)
642 0fb81174 René Nussbaumer
643 0fb81174 René Nussbaumer
644 0fb81174 René Nussbaumer
class TestComputeIPolicySpecViolation(unittest.TestCase):
645 0fb81174 René Nussbaumer
  def test(self):
646 0e68bf27 René Nussbaumer
    compute_fn = _ValidateComputeMinMaxSpec
647 0fb81174 René Nussbaumer
    ret = cmdlib._ComputeIPolicySpecViolation(NotImplemented, 1024, 1, 1, 1,
648 553cb5f7 René Nussbaumer
                                              [1024], 1, _compute_fn=compute_fn)
649 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
650 0fb81174 René Nussbaumer
651 0fb81174 René Nussbaumer
  def testInvalidArguments(self):
652 0fb81174 René Nussbaumer
    self.assertRaises(AssertionError, cmdlib._ComputeIPolicySpecViolation,
653 553cb5f7 René Nussbaumer
                      NotImplemented, 1024, 1, 1, 1, [], 1)
654 0fb81174 René Nussbaumer
655 0fb81174 René Nussbaumer
  def testInvalidSpec(self):
656 553cb5f7 René Nussbaumer
    spec = _SpecWrapper([None, False, "foo", None, "bar", None])
657 0e68bf27 René Nussbaumer
    compute_fn = spec.ComputeMinMaxSpec
658 0fb81174 René Nussbaumer
    ret = cmdlib._ComputeIPolicySpecViolation(NotImplemented, 1024, 1, 1, 1,
659 553cb5f7 René Nussbaumer
                                              [1024], 1, _compute_fn=compute_fn)
660 0fb81174 René Nussbaumer
    self.assertEqual(ret, ["foo", "bar"])
661 0fb81174 René Nussbaumer
    self.assertFalse(spec.spec)
662 0fb81174 René Nussbaumer
663 0fb81174 René Nussbaumer
664 0fb81174 René Nussbaumer
class _StubComputeIPolicySpecViolation:
665 553cb5f7 René Nussbaumer
  def __init__(self, mem_size, cpu_count, disk_count, nic_count, disk_sizes,
666 553cb5f7 René Nussbaumer
               spindle_use):
667 0fb81174 René Nussbaumer
    self.mem_size = mem_size
668 0fb81174 René Nussbaumer
    self.cpu_count = cpu_count
669 0fb81174 René Nussbaumer
    self.disk_count = disk_count
670 0fb81174 René Nussbaumer
    self.nic_count = nic_count
671 0fb81174 René Nussbaumer
    self.disk_sizes = disk_sizes
672 553cb5f7 René Nussbaumer
    self.spindle_use = spindle_use
673 0fb81174 René Nussbaumer
674 553cb5f7 René Nussbaumer
  def __call__(self, _, mem_size, cpu_count, disk_count, nic_count, disk_sizes,
675 553cb5f7 René Nussbaumer
               spindle_use):
676 0fb81174 René Nussbaumer
    assert self.mem_size == mem_size
677 0fb81174 René Nussbaumer
    assert self.cpu_count == cpu_count
678 0fb81174 René Nussbaumer
    assert self.disk_count == disk_count
679 0fb81174 René Nussbaumer
    assert self.nic_count == nic_count
680 0fb81174 René Nussbaumer
    assert self.disk_sizes == disk_sizes
681 553cb5f7 René Nussbaumer
    assert self.spindle_use == spindle_use
682 0fb81174 René Nussbaumer
683 0fb81174 René Nussbaumer
    return []
684 0fb81174 René Nussbaumer
685 0fb81174 René Nussbaumer
686 0fb81174 René Nussbaumer
class TestComputeIPolicyInstanceViolation(unittest.TestCase):
687 0fb81174 René Nussbaumer
  def test(self):
688 0fb81174 René Nussbaumer
    beparams = {
689 0fb81174 René Nussbaumer
      constants.BE_MAXMEM: 2048,
690 0fb81174 René Nussbaumer
      constants.BE_VCPUS: 2,
691 553cb5f7 René Nussbaumer
      constants.BE_SPINDLE_USAGE: 4,
692 0fb81174 René Nussbaumer
      }
693 0fb81174 René Nussbaumer
    disks = [objects.Disk(size=512)]
694 0fb81174 René Nussbaumer
    instance = objects.Instance(beparams=beparams, disks=disks, nics=[])
695 553cb5f7 René Nussbaumer
    stub = _StubComputeIPolicySpecViolation(2048, 2, 1, 0, [512], 4)
696 0fb81174 René Nussbaumer
    ret = cmdlib._ComputeIPolicyInstanceViolation(NotImplemented, instance,
697 0fb81174 René Nussbaumer
                                                  _compute_fn=stub)
698 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
699 0fb81174 René Nussbaumer
700 0fb81174 René Nussbaumer
701 0fb81174 René Nussbaumer
class TestComputeIPolicyInstanceSpecViolation(unittest.TestCase):
702 0fb81174 René Nussbaumer
  def test(self):
703 0fb81174 René Nussbaumer
    ispec = {
704 0fb81174 René Nussbaumer
      constants.ISPEC_MEM_SIZE: 2048,
705 0fb81174 René Nussbaumer
      constants.ISPEC_CPU_COUNT: 2,
706 0fb81174 René Nussbaumer
      constants.ISPEC_DISK_COUNT: 1,
707 0fb81174 René Nussbaumer
      constants.ISPEC_DISK_SIZE: [512],
708 0fb81174 René Nussbaumer
      constants.ISPEC_NIC_COUNT: 0,
709 553cb5f7 René Nussbaumer
      constants.ISPEC_SPINDLE_USE: 1,
710 0fb81174 René Nussbaumer
      }
711 553cb5f7 René Nussbaumer
    stub = _StubComputeIPolicySpecViolation(2048, 2, 1, 0, [512], 1)
712 0fb81174 René Nussbaumer
    ret = cmdlib._ComputeIPolicyInstanceSpecViolation(NotImplemented, ispec,
713 0fb81174 René Nussbaumer
                                                      _compute_fn=stub)
714 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
715 0fb81174 René Nussbaumer
716 0fb81174 René Nussbaumer
717 0fb81174 René Nussbaumer
class _CallRecorder:
718 0fb81174 René Nussbaumer
  def __init__(self, return_value=None):
719 0fb81174 René Nussbaumer
    self.called = False
720 0fb81174 René Nussbaumer
    self.return_value = return_value
721 0fb81174 René Nussbaumer
722 0fb81174 René Nussbaumer
  def __call__(self, *args):
723 0fb81174 René Nussbaumer
    self.called = True
724 0fb81174 René Nussbaumer
    return self.return_value
725 0fb81174 René Nussbaumer
726 0fb81174 René Nussbaumer
727 0fb81174 René Nussbaumer
class TestComputeIPolicyNodeViolation(unittest.TestCase):
728 0fb81174 René Nussbaumer
  def setUp(self):
729 0fb81174 René Nussbaumer
    self.recorder = _CallRecorder(return_value=[])
730 0fb81174 René Nussbaumer
731 0fb81174 René Nussbaumer
  def testSameGroup(self):
732 0fb81174 René Nussbaumer
    ret = cmdlib._ComputeIPolicyNodeViolation(NotImplemented, NotImplemented,
733 0fb81174 René Nussbaumer
                                              "foo", "foo",
734 0fb81174 René Nussbaumer
                                              _compute_fn=self.recorder)
735 0fb81174 René Nussbaumer
    self.assertFalse(self.recorder.called)
736 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
737 0fb81174 René Nussbaumer
738 0fb81174 René Nussbaumer
  def testDifferentGroup(self):
739 0fb81174 René Nussbaumer
    ret = cmdlib._ComputeIPolicyNodeViolation(NotImplemented, NotImplemented,
740 0fb81174 René Nussbaumer
                                              "foo", "bar",
741 0fb81174 René Nussbaumer
                                              _compute_fn=self.recorder)
742 0fb81174 René Nussbaumer
    self.assertTrue(self.recorder.called)
743 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
744 0fb81174 René Nussbaumer
745 0fb81174 René Nussbaumer
746 ff02b60f René Nussbaumer
class _FakeConfigForTargetNodeIPolicy:
747 ff02b60f René Nussbaumer
  def __init__(self, node_info=NotImplemented):
748 ff02b60f René Nussbaumer
    self._node_info = node_info
749 ff02b60f René Nussbaumer
750 ff02b60f René Nussbaumer
  def GetNodeInfo(self, _):
751 ff02b60f René Nussbaumer
    return self._node_info
752 ff02b60f René Nussbaumer
753 ff02b60f René Nussbaumer
754 0fb81174 René Nussbaumer
class TestCheckTargetNodeIPolicy(unittest.TestCase):
755 0fb81174 René Nussbaumer
  def setUp(self):
756 ff02b60f René Nussbaumer
    self.instance = objects.Instance(primary_node="blubb")
757 0fb81174 René Nussbaumer
    self.target_node = objects.Node(group="bar")
758 ff02b60f René Nussbaumer
    node_info = objects.Node(group="foo")
759 ff02b60f René Nussbaumer
    fake_cfg = _FakeConfigForTargetNodeIPolicy(node_info=node_info)
760 ff02b60f René Nussbaumer
    self.lu = _FakeLU(cfg=fake_cfg)
761 0fb81174 René Nussbaumer
762 0fb81174 René Nussbaumer
  def testNoViolation(self):
763 0fb81174 René Nussbaumer
    compute_recoder = _CallRecorder(return_value=[])
764 0fb81174 René Nussbaumer
    cmdlib._CheckTargetNodeIPolicy(self.lu, NotImplemented, self.instance,
765 0fb81174 René Nussbaumer
                                   self.target_node,
766 0fb81174 René Nussbaumer
                                   _compute_fn=compute_recoder)
767 0fb81174 René Nussbaumer
    self.assertTrue(compute_recoder.called)
768 0fb81174 René Nussbaumer
    self.assertEqual(self.lu.warning_log, [])
769 0fb81174 René Nussbaumer
770 0fb81174 René Nussbaumer
  def testNoIgnore(self):
771 0fb81174 René Nussbaumer
    compute_recoder = _CallRecorder(return_value=["mem_size not in range"])
772 0fb81174 René Nussbaumer
    self.assertRaises(errors.OpPrereqError, cmdlib._CheckTargetNodeIPolicy,
773 0fb81174 René Nussbaumer
                      self.lu, NotImplemented, self.instance, self.target_node,
774 0fb81174 René Nussbaumer
                      _compute_fn=compute_recoder)
775 0fb81174 René Nussbaumer
    self.assertTrue(compute_recoder.called)
776 0fb81174 René Nussbaumer
    self.assertEqual(self.lu.warning_log, [])
777 0fb81174 René Nussbaumer
778 0fb81174 René Nussbaumer
  def testIgnoreViolation(self):
779 0fb81174 René Nussbaumer
    compute_recoder = _CallRecorder(return_value=["mem_size not in range"])
780 0fb81174 René Nussbaumer
    cmdlib._CheckTargetNodeIPolicy(self.lu, NotImplemented, self.instance,
781 0fb81174 René Nussbaumer
                                   self.target_node, ignore=True,
782 0fb81174 René Nussbaumer
                                   _compute_fn=compute_recoder)
783 0fb81174 René Nussbaumer
    self.assertTrue(compute_recoder.called)
784 0fb81174 René Nussbaumer
    msg = ("Instance does not meet target node group's (bar) instance policy:"
785 0fb81174 René Nussbaumer
           " mem_size not in range")
786 0fb81174 René Nussbaumer
    self.assertEqual(self.lu.warning_log, [(msg, ())])
787 0fb81174 René Nussbaumer
788 0fb81174 René Nussbaumer
789 8301885b Michael Hanselmann
class TestApplyContainerMods(unittest.TestCase):
790 8301885b Michael Hanselmann
  def testEmptyContainer(self):
791 8301885b Michael Hanselmann
    container = []
792 8301885b Michael Hanselmann
    chgdesc = []
793 8301885b Michael Hanselmann
    cmdlib.ApplyContainerMods("test", container, chgdesc, [], None, None, None)
794 8301885b Michael Hanselmann
    self.assertEqual(container, [])
795 8301885b Michael Hanselmann
    self.assertEqual(chgdesc, [])
796 8301885b Michael Hanselmann
797 8301885b Michael Hanselmann
  def testAdd(self):
798 8301885b Michael Hanselmann
    container = []
799 8301885b Michael Hanselmann
    chgdesc = []
800 8301885b Michael Hanselmann
    mods = cmdlib.PrepareContainerMods([
801 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "Hello"),
802 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "World"),
803 8301885b Michael Hanselmann
      (constants.DDM_ADD, 0, "Start"),
804 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "End"),
805 8301885b Michael Hanselmann
      ], None)
806 8301885b Michael Hanselmann
    cmdlib.ApplyContainerMods("test", container, chgdesc, mods,
807 8301885b Michael Hanselmann
                              None, None, None)
808 8301885b Michael Hanselmann
    self.assertEqual(container, ["Start", "Hello", "World", "End"])
809 8301885b Michael Hanselmann
    self.assertEqual(chgdesc, [])
810 8301885b Michael Hanselmann
811 35554b4f Michael Hanselmann
    mods = cmdlib.PrepareContainerMods([
812 35554b4f Michael Hanselmann
      (constants.DDM_ADD, 0, "zero"),
813 35554b4f Michael Hanselmann
      (constants.DDM_ADD, 3, "Added"),
814 35554b4f Michael Hanselmann
      (constants.DDM_ADD, 5, "four"),
815 35554b4f Michael Hanselmann
      (constants.DDM_ADD, 7, "xyz"),
816 35554b4f Michael Hanselmann
      ], None)
817 35554b4f Michael Hanselmann
    cmdlib.ApplyContainerMods("test", container, chgdesc, mods,
818 35554b4f Michael Hanselmann
                              None, None, None)
819 35554b4f Michael Hanselmann
    self.assertEqual(container,
820 35554b4f Michael Hanselmann
                     ["zero", "Start", "Hello", "Added", "World", "four",
821 35554b4f Michael Hanselmann
                      "End", "xyz"])
822 35554b4f Michael Hanselmann
    self.assertEqual(chgdesc, [])
823 35554b4f Michael Hanselmann
824 35554b4f Michael Hanselmann
    for idx in [-2, len(container) + 1]:
825 35554b4f Michael Hanselmann
      mods = cmdlib.PrepareContainerMods([
826 35554b4f Michael Hanselmann
        (constants.DDM_ADD, idx, "error"),
827 35554b4f Michael Hanselmann
        ], None)
828 35554b4f Michael Hanselmann
      self.assertRaises(IndexError, cmdlib.ApplyContainerMods,
829 35554b4f Michael Hanselmann
                        "test", container, None, mods, None, None, None)
830 35554b4f Michael Hanselmann
831 8301885b Michael Hanselmann
  def testRemoveError(self):
832 8301885b Michael Hanselmann
    for idx in [0, 1, 2, 100, -1, -4]:
833 8301885b Michael Hanselmann
      mods = cmdlib.PrepareContainerMods([
834 8301885b Michael Hanselmann
        (constants.DDM_REMOVE, idx, None),
835 8301885b Michael Hanselmann
        ], None)
836 8301885b Michael Hanselmann
      self.assertRaises(IndexError, cmdlib.ApplyContainerMods,
837 8301885b Michael Hanselmann
                        "test", [], None, mods, None, None, None)
838 8301885b Michael Hanselmann
839 8301885b Michael Hanselmann
    mods = cmdlib.PrepareContainerMods([
840 8301885b Michael Hanselmann
      (constants.DDM_REMOVE, 0, object()),
841 8301885b Michael Hanselmann
      ], None)
842 8301885b Michael Hanselmann
    self.assertRaises(AssertionError, cmdlib.ApplyContainerMods,
843 8301885b Michael Hanselmann
                      "test", [""], None, mods, None, None, None)
844 8301885b Michael Hanselmann
845 8301885b Michael Hanselmann
  def testAddError(self):
846 35554b4f Michael Hanselmann
    for idx in range(-100, -1) + [100]:
847 8301885b Michael Hanselmann
      mods = cmdlib.PrepareContainerMods([
848 8301885b Michael Hanselmann
        (constants.DDM_ADD, idx, None),
849 8301885b Michael Hanselmann
        ], None)
850 8301885b Michael Hanselmann
      self.assertRaises(IndexError, cmdlib.ApplyContainerMods,
851 8301885b Michael Hanselmann
                        "test", [], None, mods, None, None, None)
852 8301885b Michael Hanselmann
853 8301885b Michael Hanselmann
  def testRemove(self):
854 8301885b Michael Hanselmann
    container = ["item 1", "item 2"]
855 8301885b Michael Hanselmann
    mods = cmdlib.PrepareContainerMods([
856 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "aaa"),
857 8301885b Michael Hanselmann
      (constants.DDM_REMOVE, -1, None),
858 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "bbb"),
859 8301885b Michael Hanselmann
      ], None)
860 8301885b Michael Hanselmann
    chgdesc = []
861 8301885b Michael Hanselmann
    cmdlib.ApplyContainerMods("test", container, chgdesc, mods,
862 8301885b Michael Hanselmann
                              None, None, None)
863 8301885b Michael Hanselmann
    self.assertEqual(container, ["item 1", "item 2", "bbb"])
864 8301885b Michael Hanselmann
    self.assertEqual(chgdesc, [
865 8301885b Michael Hanselmann
      ("test/2", "remove"),
866 8301885b Michael Hanselmann
      ])
867 8301885b Michael Hanselmann
868 35554b4f Michael Hanselmann
  def testModify(self):
869 35554b4f Michael Hanselmann
    container = ["item 1", "item 2"]
870 35554b4f Michael Hanselmann
    mods = cmdlib.PrepareContainerMods([
871 35554b4f Michael Hanselmann
      (constants.DDM_MODIFY, -1, "a"),
872 35554b4f Michael Hanselmann
      (constants.DDM_MODIFY, 0, "b"),
873 35554b4f Michael Hanselmann
      (constants.DDM_MODIFY, 1, "c"),
874 35554b4f Michael Hanselmann
      ], None)
875 35554b4f Michael Hanselmann
    chgdesc = []
876 35554b4f Michael Hanselmann
    cmdlib.ApplyContainerMods("test", container, chgdesc, mods,
877 35554b4f Michael Hanselmann
                              None, None, None)
878 35554b4f Michael Hanselmann
    self.assertEqual(container, ["item 1", "item 2"])
879 35554b4f Michael Hanselmann
    self.assertEqual(chgdesc, [])
880 35554b4f Michael Hanselmann
881 35554b4f Michael Hanselmann
    for idx in [-2, len(container) + 1]:
882 35554b4f Michael Hanselmann
      mods = cmdlib.PrepareContainerMods([
883 35554b4f Michael Hanselmann
        (constants.DDM_MODIFY, idx, "error"),
884 35554b4f Michael Hanselmann
        ], None)
885 35554b4f Michael Hanselmann
      self.assertRaises(IndexError, cmdlib.ApplyContainerMods,
886 35554b4f Michael Hanselmann
                        "test", container, None, mods, None, None, None)
887 35554b4f Michael Hanselmann
888 8301885b Michael Hanselmann
  class _PrivateData:
889 8301885b Michael Hanselmann
    def __init__(self):
890 8301885b Michael Hanselmann
      self.data = None
891 8301885b Michael Hanselmann
892 8301885b Michael Hanselmann
  @staticmethod
893 efcfa99d Michael Hanselmann
  def _CreateTestFn(idx, params, private):
894 8301885b Michael Hanselmann
    private.data = ("add", idx, params)
895 efcfa99d Michael Hanselmann
    return ((100 * idx, params), [
896 efcfa99d Michael Hanselmann
      ("test/%s" % idx, hex(idx)),
897 efcfa99d Michael Hanselmann
      ])
898 8301885b Michael Hanselmann
899 8301885b Michael Hanselmann
  @staticmethod
900 efcfa99d Michael Hanselmann
  def _ModifyTestFn(idx, item, params, private):
901 8301885b Michael Hanselmann
    private.data = ("modify", idx, params)
902 efcfa99d Michael Hanselmann
    return [
903 efcfa99d Michael Hanselmann
      ("test/%s" % idx, "modify %s" % params),
904 efcfa99d Michael Hanselmann
      ]
905 8301885b Michael Hanselmann
906 8301885b Michael Hanselmann
  @staticmethod
907 efcfa99d Michael Hanselmann
  def _RemoveTestFn(idx, item, private):
908 8301885b Michael Hanselmann
    private.data = ("remove", idx, item)
909 8301885b Michael Hanselmann
910 8301885b Michael Hanselmann
  def testAddWithCreateFunction(self):
911 8301885b Michael Hanselmann
    container = []
912 8301885b Michael Hanselmann
    chgdesc = []
913 8301885b Michael Hanselmann
    mods = cmdlib.PrepareContainerMods([
914 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "Hello"),
915 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "World"),
916 8301885b Michael Hanselmann
      (constants.DDM_ADD, 0, "Start"),
917 8301885b Michael Hanselmann
      (constants.DDM_ADD, -1, "End"),
918 8301885b Michael Hanselmann
      (constants.DDM_REMOVE, 2, None),
919 8301885b Michael Hanselmann
      (constants.DDM_MODIFY, -1, "foobar"),
920 8301885b Michael Hanselmann
      (constants.DDM_REMOVE, 2, None),
921 8301885b Michael Hanselmann
      (constants.DDM_ADD, 1, "More"),
922 8301885b Michael Hanselmann
      ], self._PrivateData)
923 8301885b Michael Hanselmann
    cmdlib.ApplyContainerMods("test", container, chgdesc, mods,
924 8301885b Michael Hanselmann
      self._CreateTestFn, self._ModifyTestFn, self._RemoveTestFn)
925 8301885b Michael Hanselmann
    self.assertEqual(container, [
926 35554b4f Michael Hanselmann
      (000, "Start"),
927 35554b4f Michael Hanselmann
      (100, "More"),
928 35554b4f Michael Hanselmann
      (000, "Hello"),
929 8301885b Michael Hanselmann
      ])
930 8301885b Michael Hanselmann
    self.assertEqual(chgdesc, [
931 8301885b Michael Hanselmann
      ("test/0", "0x0"),
932 8301885b Michael Hanselmann
      ("test/1", "0x1"),
933 35554b4f Michael Hanselmann
      ("test/0", "0x0"),
934 8301885b Michael Hanselmann
      ("test/3", "0x3"),
935 8301885b Michael Hanselmann
      ("test/2", "remove"),
936 8301885b Michael Hanselmann
      ("test/2", "modify foobar"),
937 8301885b Michael Hanselmann
      ("test/2", "remove"),
938 35554b4f Michael Hanselmann
      ("test/1", "0x1")
939 8301885b Michael Hanselmann
      ])
940 8301885b Michael Hanselmann
    self.assertTrue(compat.all(op == private.data[0]
941 8301885b Michael Hanselmann
                               for (op, _, _, private) in mods))
942 8301885b Michael Hanselmann
    self.assertEqual([private.data for (op, _, _, private) in mods], [
943 8301885b Michael Hanselmann
      ("add", 0, "Hello"),
944 8301885b Michael Hanselmann
      ("add", 1, "World"),
945 35554b4f Michael Hanselmann
      ("add", 0, "Start"),
946 8301885b Michael Hanselmann
      ("add", 3, "End"),
947 8301885b Michael Hanselmann
      ("remove", 2, (100, "World")),
948 8301885b Michael Hanselmann
      ("modify", 2, "foobar"),
949 8301885b Michael Hanselmann
      ("remove", 2, (300, "End")),
950 35554b4f Michael Hanselmann
      ("add", 1, "More"),
951 8301885b Michael Hanselmann
      ])
952 8301885b Michael Hanselmann
953 8301885b Michael Hanselmann
954 a8e3e009 Michael Hanselmann
class _FakeConfigForGenDiskTemplate:
955 a8e3e009 Michael Hanselmann
  def __init__(self):
956 a8e3e009 Michael Hanselmann
    self._unique_id = itertools.count()
957 a8e3e009 Michael Hanselmann
    self._drbd_minor = itertools.count(20)
958 a8e3e009 Michael Hanselmann
    self._port = itertools.count(constants.FIRST_DRBD_PORT)
959 a8e3e009 Michael Hanselmann
    self._secret = itertools.count()
960 a8e3e009 Michael Hanselmann
961 a8e3e009 Michael Hanselmann
  def GetVGName(self):
962 a8e3e009 Michael Hanselmann
    return "testvg"
963 a8e3e009 Michael Hanselmann
964 a8e3e009 Michael Hanselmann
  def GenerateUniqueID(self, ec_id):
965 a8e3e009 Michael Hanselmann
    return "ec%s-uq%s" % (ec_id, self._unique_id.next())
966 a8e3e009 Michael Hanselmann
967 a8e3e009 Michael Hanselmann
  def AllocateDRBDMinor(self, nodes, instance):
968 a8e3e009 Michael Hanselmann
    return [self._drbd_minor.next()
969 a8e3e009 Michael Hanselmann
            for _ in nodes]
970 a8e3e009 Michael Hanselmann
971 a8e3e009 Michael Hanselmann
  def AllocatePort(self):
972 a8e3e009 Michael Hanselmann
    return self._port.next()
973 a8e3e009 Michael Hanselmann
974 a8e3e009 Michael Hanselmann
  def GenerateDRBDSecret(self, ec_id):
975 a8e3e009 Michael Hanselmann
    return "ec%s-secret%s" % (ec_id, self._secret.next())
976 a8e3e009 Michael Hanselmann
977 a8e3e009 Michael Hanselmann
978 a8e3e009 Michael Hanselmann
class _FakeProcForGenDiskTemplate:
979 a8e3e009 Michael Hanselmann
  def GetECId(self):
980 a8e3e009 Michael Hanselmann
    return 0
981 a8e3e009 Michael Hanselmann
982 a8e3e009 Michael Hanselmann
983 a8e3e009 Michael Hanselmann
class TestGenerateDiskTemplate(unittest.TestCase):
984 a8e3e009 Michael Hanselmann
  def setUp(self):
985 a8e3e009 Michael Hanselmann
    nodegroup = objects.NodeGroup(name="ng")
986 a8e3e009 Michael Hanselmann
    nodegroup.UpgradeConfig()
987 a8e3e009 Michael Hanselmann
988 a8e3e009 Michael Hanselmann
    cfg = _FakeConfigForGenDiskTemplate()
989 a8e3e009 Michael Hanselmann
    proc = _FakeProcForGenDiskTemplate()
990 a8e3e009 Michael Hanselmann
991 a8e3e009 Michael Hanselmann
    self.lu = _FakeLU(cfg=cfg, proc=proc)
992 a8e3e009 Michael Hanselmann
    self.nodegroup = nodegroup
993 a8e3e009 Michael Hanselmann
994 a8e3e009 Michael Hanselmann
  def testWrongDiskTemplate(self):
995 a8e3e009 Michael Hanselmann
    gdt = cmdlib._GenerateDiskTemplate
996 a8e3e009 Michael Hanselmann
    disk_template = "##unknown##"
997 a8e3e009 Michael Hanselmann
998 a8e3e009 Michael Hanselmann
    assert disk_template not in constants.DISK_TEMPLATES
999 a8e3e009 Michael Hanselmann
1000 a8e3e009 Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, gdt, self.lu, disk_template,
1001 a8e3e009 Michael Hanselmann
                      "inst26831.example.com", "node30113.example.com", [], [],
1002 a8e3e009 Michael Hanselmann
                      NotImplemented, NotImplemented, 0, self.lu.LogInfo,
1003 a8e3e009 Michael Hanselmann
                      self.nodegroup.diskparams)
1004 a8e3e009 Michael Hanselmann
1005 a8e3e009 Michael Hanselmann
  def testDiskless(self):
1006 a8e3e009 Michael Hanselmann
    gdt = cmdlib._GenerateDiskTemplate
1007 a8e3e009 Michael Hanselmann
1008 a8e3e009 Michael Hanselmann
    result = gdt(self.lu, constants.DT_DISKLESS, "inst27734.example.com",
1009 a8e3e009 Michael Hanselmann
                 "node30113.example.com", [], [],
1010 a8e3e009 Michael Hanselmann
                 NotImplemented, NotImplemented, 0, self.lu.LogInfo,
1011 a8e3e009 Michael Hanselmann
                 self.nodegroup.diskparams)
1012 a8e3e009 Michael Hanselmann
    self.assertEqual(result, [])
1013 a8e3e009 Michael Hanselmann
1014 a8e3e009 Michael Hanselmann
  def _TestTrivialDisk(self, template, disk_info, base_index, exp_dev_type,
1015 a8e3e009 Michael Hanselmann
                       file_storage_dir=NotImplemented,
1016 a8e3e009 Michael Hanselmann
                       file_driver=NotImplemented,
1017 a8e3e009 Michael Hanselmann
                       req_file_storage=NotImplemented,
1018 a8e3e009 Michael Hanselmann
                       req_shr_file_storage=NotImplemented):
1019 a8e3e009 Michael Hanselmann
    gdt = cmdlib._GenerateDiskTemplate
1020 a8e3e009 Michael Hanselmann
1021 a8e3e009 Michael Hanselmann
    map(lambda params: utils.ForceDictType(params,
1022 a8e3e009 Michael Hanselmann
                                           constants.IDISK_PARAMS_TYPES),
1023 a8e3e009 Michael Hanselmann
        disk_info)
1024 a8e3e009 Michael Hanselmann
1025 a8e3e009 Michael Hanselmann
    # Check if non-empty list of secondaries is rejected
1026 a8e3e009 Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, gdt, self.lu,
1027 a8e3e009 Michael Hanselmann
                      template, "inst25088.example.com",
1028 a8e3e009 Michael Hanselmann
                      "node185.example.com", ["node323.example.com"], [],
1029 a8e3e009 Michael Hanselmann
                      NotImplemented, NotImplemented, base_index,
1030 a8e3e009 Michael Hanselmann
                      self.lu.LogInfo, self.nodegroup.diskparams,
1031 a8e3e009 Michael Hanselmann
                      _req_file_storage=req_file_storage,
1032 a8e3e009 Michael Hanselmann
                      _req_shr_file_storage=req_shr_file_storage)
1033 a8e3e009 Michael Hanselmann
1034 a8e3e009 Michael Hanselmann
    result = gdt(self.lu, template, "inst21662.example.com",
1035 a8e3e009 Michael Hanselmann
                 "node21741.example.com", [],
1036 a8e3e009 Michael Hanselmann
                 disk_info, file_storage_dir, file_driver, base_index,
1037 a8e3e009 Michael Hanselmann
                 self.lu.LogInfo, self.nodegroup.diskparams,
1038 a8e3e009 Michael Hanselmann
                 _req_file_storage=req_file_storage,
1039 a8e3e009 Michael Hanselmann
                 _req_shr_file_storage=req_shr_file_storage)
1040 a8e3e009 Michael Hanselmann
1041 a8e3e009 Michael Hanselmann
    for (idx, disk) in enumerate(result):
1042 a8e3e009 Michael Hanselmann
      self.assertTrue(isinstance(disk, objects.Disk))
1043 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.dev_type, exp_dev_type)
1044 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.size, disk_info[idx][constants.IDISK_SIZE])
1045 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.mode, disk_info[idx][constants.IDISK_MODE])
1046 a8e3e009 Michael Hanselmann
      self.assertTrue(disk.children is None)
1047 a8e3e009 Michael Hanselmann
1048 0356a13d Michael Hanselmann
    self._CheckIvNames(result, base_index, base_index + len(disk_info))
1049 0356a13d Michael Hanselmann
    cmdlib._UpdateIvNames(base_index, result)
1050 0356a13d Michael Hanselmann
    self._CheckIvNames(result, base_index, base_index + len(disk_info))
1051 a8e3e009 Michael Hanselmann
1052 a8e3e009 Michael Hanselmann
    return result
1053 a8e3e009 Michael Hanselmann
1054 0356a13d Michael Hanselmann
  def _CheckIvNames(self, disks, base_index, end_index):
1055 0356a13d Michael Hanselmann
    self.assertEqual(map(operator.attrgetter("iv_name"), disks),
1056 0356a13d Michael Hanselmann
                     ["disk/%s" % i for i in range(base_index, end_index)])
1057 0356a13d Michael Hanselmann
1058 a8e3e009 Michael Hanselmann
  def testPlain(self):
1059 a8e3e009 Michael Hanselmann
    disk_info = [{
1060 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 1024,
1061 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDWR,
1062 a8e3e009 Michael Hanselmann
      }, {
1063 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 4096,
1064 a8e3e009 Michael Hanselmann
      constants.IDISK_VG: "othervg",
1065 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDWR,
1066 a8e3e009 Michael Hanselmann
      }]
1067 a8e3e009 Michael Hanselmann
1068 a8e3e009 Michael Hanselmann
    result = self._TestTrivialDisk(constants.DT_PLAIN, disk_info, 3,
1069 a8e3e009 Michael Hanselmann
                                   constants.LD_LV)
1070 a8e3e009 Michael Hanselmann
1071 a8e3e009 Michael Hanselmann
    self.assertEqual(map(operator.attrgetter("logical_id"), result), [
1072 a8e3e009 Michael Hanselmann
      ("testvg", "ec0-uq0.disk3"),
1073 a8e3e009 Michael Hanselmann
      ("othervg", "ec0-uq1.disk4"),
1074 a8e3e009 Michael Hanselmann
      ])
1075 a8e3e009 Michael Hanselmann
1076 a8e3e009 Michael Hanselmann
  @staticmethod
1077 a8e3e009 Michael Hanselmann
  def _AllowFileStorage():
1078 a8e3e009 Michael Hanselmann
    pass
1079 a8e3e009 Michael Hanselmann
1080 a8e3e009 Michael Hanselmann
  @staticmethod
1081 a8e3e009 Michael Hanselmann
  def _ForbidFileStorage():
1082 a8e3e009 Michael Hanselmann
    raise errors.OpPrereqError("Disallowed in test")
1083 a8e3e009 Michael Hanselmann
1084 a8e3e009 Michael Hanselmann
  def testFile(self):
1085 a8e3e009 Michael Hanselmann
    self.assertRaises(errors.OpPrereqError, self._TestTrivialDisk,
1086 a8e3e009 Michael Hanselmann
                      constants.DT_FILE, [], 0, NotImplemented,
1087 a8e3e009 Michael Hanselmann
                      req_file_storage=self._ForbidFileStorage)
1088 a8e3e009 Michael Hanselmann
    self.assertRaises(errors.OpPrereqError, self._TestTrivialDisk,
1089 a8e3e009 Michael Hanselmann
                      constants.DT_SHARED_FILE, [], 0, NotImplemented,
1090 a8e3e009 Michael Hanselmann
                      req_shr_file_storage=self._ForbidFileStorage)
1091 a8e3e009 Michael Hanselmann
1092 a8e3e009 Michael Hanselmann
    for disk_template in [constants.DT_FILE, constants.DT_SHARED_FILE]:
1093 a8e3e009 Michael Hanselmann
      disk_info = [{
1094 a8e3e009 Michael Hanselmann
        constants.IDISK_SIZE: 80 * 1024,
1095 a8e3e009 Michael Hanselmann
        constants.IDISK_MODE: constants.DISK_RDONLY,
1096 a8e3e009 Michael Hanselmann
        }, {
1097 a8e3e009 Michael Hanselmann
        constants.IDISK_SIZE: 4096,
1098 a8e3e009 Michael Hanselmann
        constants.IDISK_MODE: constants.DISK_RDWR,
1099 a8e3e009 Michael Hanselmann
        }, {
1100 a8e3e009 Michael Hanselmann
        constants.IDISK_SIZE: 6 * 1024,
1101 a8e3e009 Michael Hanselmann
        constants.IDISK_MODE: constants.DISK_RDWR,
1102 a8e3e009 Michael Hanselmann
        }]
1103 a8e3e009 Michael Hanselmann
1104 a8e3e009 Michael Hanselmann
      result = self._TestTrivialDisk(disk_template, disk_info, 2,
1105 a8e3e009 Michael Hanselmann
        constants.LD_FILE, file_storage_dir="/tmp",
1106 a8e3e009 Michael Hanselmann
        file_driver=constants.FD_BLKTAP,
1107 a8e3e009 Michael Hanselmann
        req_file_storage=self._AllowFileStorage,
1108 a8e3e009 Michael Hanselmann
        req_shr_file_storage=self._AllowFileStorage)
1109 a8e3e009 Michael Hanselmann
1110 a8e3e009 Michael Hanselmann
      self.assertEqual(map(operator.attrgetter("logical_id"), result), [
1111 a8e3e009 Michael Hanselmann
        (constants.FD_BLKTAP, "/tmp/disk2"),
1112 a8e3e009 Michael Hanselmann
        (constants.FD_BLKTAP, "/tmp/disk3"),
1113 a8e3e009 Michael Hanselmann
        (constants.FD_BLKTAP, "/tmp/disk4"),
1114 a8e3e009 Michael Hanselmann
        ])
1115 a8e3e009 Michael Hanselmann
1116 a8e3e009 Michael Hanselmann
  def testBlock(self):
1117 a8e3e009 Michael Hanselmann
    disk_info = [{
1118 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 8 * 1024,
1119 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDWR,
1120 a8e3e009 Michael Hanselmann
      constants.IDISK_ADOPT: "/tmp/some/block/dev",
1121 a8e3e009 Michael Hanselmann
      }]
1122 a8e3e009 Michael Hanselmann
1123 a8e3e009 Michael Hanselmann
    result = self._TestTrivialDisk(constants.DT_BLOCK, disk_info, 10,
1124 a8e3e009 Michael Hanselmann
                                   constants.LD_BLOCKDEV)
1125 a8e3e009 Michael Hanselmann
1126 a8e3e009 Michael Hanselmann
    self.assertEqual(map(operator.attrgetter("logical_id"), result), [
1127 a8e3e009 Michael Hanselmann
      (constants.BLOCKDEV_DRIVER_MANUAL, "/tmp/some/block/dev"),
1128 a8e3e009 Michael Hanselmann
      ])
1129 a8e3e009 Michael Hanselmann
1130 a8e3e009 Michael Hanselmann
  def testRbd(self):
1131 a8e3e009 Michael Hanselmann
    disk_info = [{
1132 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 8 * 1024,
1133 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDONLY,
1134 a8e3e009 Michael Hanselmann
      }, {
1135 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 100 * 1024,
1136 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDWR,
1137 a8e3e009 Michael Hanselmann
      }]
1138 a8e3e009 Michael Hanselmann
1139 a8e3e009 Michael Hanselmann
    result = self._TestTrivialDisk(constants.DT_RBD, disk_info, 0,
1140 a8e3e009 Michael Hanselmann
                                   constants.LD_RBD)
1141 a8e3e009 Michael Hanselmann
1142 a8e3e009 Michael Hanselmann
    self.assertEqual(map(operator.attrgetter("logical_id"), result), [
1143 a8e3e009 Michael Hanselmann
      ("rbd", "ec0-uq0.rbd.disk0"),
1144 a8e3e009 Michael Hanselmann
      ("rbd", "ec0-uq1.rbd.disk1"),
1145 a8e3e009 Michael Hanselmann
      ])
1146 a8e3e009 Michael Hanselmann
1147 a8e3e009 Michael Hanselmann
  def testDrbd8(self):
1148 a8e3e009 Michael Hanselmann
    gdt = cmdlib._GenerateDiskTemplate
1149 a8e3e009 Michael Hanselmann
    drbd8_defaults = constants.DISK_LD_DEFAULTS[constants.LD_DRBD8]
1150 a8e3e009 Michael Hanselmann
    drbd8_default_metavg = drbd8_defaults[constants.LDP_DEFAULT_METAVG]
1151 a8e3e009 Michael Hanselmann
1152 a8e3e009 Michael Hanselmann
    disk_info = [{
1153 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 1024,
1154 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDWR,
1155 a8e3e009 Michael Hanselmann
      }, {
1156 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 100 * 1024,
1157 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDONLY,
1158 a8e3e009 Michael Hanselmann
      constants.IDISK_METAVG: "metavg",
1159 a8e3e009 Michael Hanselmann
      }, {
1160 a8e3e009 Michael Hanselmann
      constants.IDISK_SIZE: 4096,
1161 a8e3e009 Michael Hanselmann
      constants.IDISK_MODE: constants.DISK_RDWR,
1162 a8e3e009 Michael Hanselmann
      constants.IDISK_VG: "vgxyz",
1163 a8e3e009 Michael Hanselmann
      },
1164 a8e3e009 Michael Hanselmann
      ]
1165 a8e3e009 Michael Hanselmann
1166 a8e3e009 Michael Hanselmann
    exp_logical_ids = [[
1167 a8e3e009 Michael Hanselmann
      (self.lu.cfg.GetVGName(), "ec0-uq0.disk0_data"),
1168 a8e3e009 Michael Hanselmann
      (drbd8_default_metavg, "ec0-uq0.disk0_meta"),
1169 a8e3e009 Michael Hanselmann
      ], [
1170 a8e3e009 Michael Hanselmann
      (self.lu.cfg.GetVGName(), "ec0-uq1.disk1_data"),
1171 a8e3e009 Michael Hanselmann
      ("metavg", "ec0-uq1.disk1_meta"),
1172 a8e3e009 Michael Hanselmann
      ], [
1173 a8e3e009 Michael Hanselmann
      ("vgxyz", "ec0-uq2.disk2_data"),
1174 a8e3e009 Michael Hanselmann
      (drbd8_default_metavg, "ec0-uq2.disk2_meta"),
1175 a8e3e009 Michael Hanselmann
      ]]
1176 a8e3e009 Michael Hanselmann
1177 a8e3e009 Michael Hanselmann
    assert len(exp_logical_ids) == len(disk_info)
1178 a8e3e009 Michael Hanselmann
1179 a8e3e009 Michael Hanselmann
    map(lambda params: utils.ForceDictType(params,
1180 a8e3e009 Michael Hanselmann
                                           constants.IDISK_PARAMS_TYPES),
1181 a8e3e009 Michael Hanselmann
        disk_info)
1182 a8e3e009 Michael Hanselmann
1183 a8e3e009 Michael Hanselmann
    # Check if empty list of secondaries is rejected
1184 a8e3e009 Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, gdt, self.lu, constants.DT_DRBD8,
1185 a8e3e009 Michael Hanselmann
                      "inst827.example.com", "node1334.example.com", [],
1186 a8e3e009 Michael Hanselmann
                      disk_info, NotImplemented, NotImplemented, 0,
1187 a8e3e009 Michael Hanselmann
                      self.lu.LogInfo, self.nodegroup.diskparams)
1188 a8e3e009 Michael Hanselmann
1189 a8e3e009 Michael Hanselmann
    result = gdt(self.lu, constants.DT_DRBD8, "inst827.example.com",
1190 a8e3e009 Michael Hanselmann
                 "node1334.example.com", ["node12272.example.com"],
1191 a8e3e009 Michael Hanselmann
                 disk_info, NotImplemented, NotImplemented, 0, self.lu.LogInfo,
1192 a8e3e009 Michael Hanselmann
                 self.nodegroup.diskparams)
1193 a8e3e009 Michael Hanselmann
1194 a8e3e009 Michael Hanselmann
    for (idx, disk) in enumerate(result):
1195 a8e3e009 Michael Hanselmann
      self.assertTrue(isinstance(disk, objects.Disk))
1196 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.dev_type, constants.LD_DRBD8)
1197 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.size, disk_info[idx][constants.IDISK_SIZE])
1198 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.mode, disk_info[idx][constants.IDISK_MODE])
1199 a8e3e009 Michael Hanselmann
1200 a8e3e009 Michael Hanselmann
      for child in disk.children:
1201 a8e3e009 Michael Hanselmann
        self.assertTrue(isinstance(disk, objects.Disk))
1202 a8e3e009 Michael Hanselmann
        self.assertEqual(child.dev_type, constants.LD_LV)
1203 a8e3e009 Michael Hanselmann
        self.assertTrue(child.children is None)
1204 a8e3e009 Michael Hanselmann
1205 a8e3e009 Michael Hanselmann
      self.assertEqual(map(operator.attrgetter("logical_id"), disk.children),
1206 a8e3e009 Michael Hanselmann
                       exp_logical_ids[idx])
1207 a8e3e009 Michael Hanselmann
1208 a8e3e009 Michael Hanselmann
      self.assertEqual(len(disk.children), 2)
1209 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.children[0].size, disk.size)
1210 a8e3e009 Michael Hanselmann
      self.assertEqual(disk.children[1].size, cmdlib.DRBD_META_SIZE)
1211 a8e3e009 Michael Hanselmann
1212 0356a13d Michael Hanselmann
    self._CheckIvNames(result, 0, len(disk_info))
1213 0356a13d Michael Hanselmann
    cmdlib._UpdateIvNames(0, result)
1214 0356a13d Michael Hanselmann
    self._CheckIvNames(result, 0, len(disk_info))
1215 a8e3e009 Michael Hanselmann
1216 a8e3e009 Michael Hanselmann
    self.assertEqual(map(operator.attrgetter("logical_id"), result), [
1217 a8e3e009 Michael Hanselmann
      ("node1334.example.com", "node12272.example.com",
1218 a8e3e009 Michael Hanselmann
       constants.FIRST_DRBD_PORT, 20, 21, "ec0-secret0"),
1219 a8e3e009 Michael Hanselmann
      ("node1334.example.com", "node12272.example.com",
1220 a8e3e009 Michael Hanselmann
       constants.FIRST_DRBD_PORT + 1, 22, 23, "ec0-secret1"),
1221 a8e3e009 Michael Hanselmann
      ("node1334.example.com", "node12272.example.com",
1222 a8e3e009 Michael Hanselmann
       constants.FIRST_DRBD_PORT + 2, 24, 25, "ec0-secret2"),
1223 a8e3e009 Michael Hanselmann
      ])
1224 a8e3e009 Michael Hanselmann
1225 a8e3e009 Michael Hanselmann
1226 b98bf262 Michael Hanselmann
if __name__ == "__main__":
1227 25231ec5 Michael Hanselmann
  testutils.GanetiTestProgram()