Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.cmdlib_unittest.py @ ad0e078e

History | View | Annotate | Download (26.7 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 ff02b60f René Nussbaumer
  def __init__(self, cfg=NotImplemented):
386 d755483c Michael Hanselmann
    self.warning_log = []
387 d755483c Michael Hanselmann
    self.info_log = []
388 ff02b60f René Nussbaumer
    self.cfg = cfg
389 d755483c Michael Hanselmann
390 d755483c Michael Hanselmann
  def LogWarning(self, text, *args):
391 d755483c Michael Hanselmann
    self.warning_log.append((text, args))
392 d755483c Michael Hanselmann
393 d755483c Michael Hanselmann
  def LogInfo(self, text, *args):
394 d755483c Michael Hanselmann
    self.info_log.append((text, args))
395 d755483c Michael Hanselmann
396 d755483c Michael Hanselmann
397 d755483c Michael Hanselmann
class TestLoadNodeEvacResult(unittest.TestCase):
398 d755483c Michael Hanselmann
  def testSuccess(self):
399 d755483c Michael Hanselmann
    for moved in [[], [
400 d755483c Michael Hanselmann
      ("inst20153.example.com", "grp2", ["nodeA4509", "nodeB2912"]),
401 d755483c Michael Hanselmann
      ]]:
402 d755483c Michael Hanselmann
      for early_release in [False, True]:
403 d755483c Michael Hanselmann
        for use_nodes in [False, True]:
404 d755483c Michael Hanselmann
          jobs = [
405 d755483c Michael Hanselmann
            [opcodes.OpInstanceReplaceDisks().__getstate__()],
406 d755483c Michael Hanselmann
            [opcodes.OpInstanceMigrate().__getstate__()],
407 d755483c Michael Hanselmann
            ]
408 d755483c Michael Hanselmann
409 d755483c Michael Hanselmann
          alloc_result = (moved, [], jobs)
410 d755483c Michael Hanselmann
          assert cmdlib.IAllocator._NEVAC_RESULT(alloc_result)
411 d755483c Michael Hanselmann
412 d755483c Michael Hanselmann
          lu = _FakeLU()
413 d755483c Michael Hanselmann
          result = cmdlib._LoadNodeEvacResult(lu, alloc_result,
414 d755483c Michael Hanselmann
                                              early_release, use_nodes)
415 d755483c Michael Hanselmann
416 d755483c Michael Hanselmann
          if moved:
417 d755483c Michael Hanselmann
            (_, (info_args, )) = lu.info_log.pop(0)
418 d755483c Michael Hanselmann
            for (instname, instgroup, instnodes) in moved:
419 d755483c Michael Hanselmann
              self.assertTrue(instname in info_args)
420 d755483c Michael Hanselmann
              if use_nodes:
421 d755483c Michael Hanselmann
                for i in instnodes:
422 d755483c Michael Hanselmann
                  self.assertTrue(i in info_args)
423 d755483c Michael Hanselmann
              else:
424 d755483c Michael Hanselmann
                self.assertTrue(instgroup in info_args)
425 d755483c Michael Hanselmann
426 d755483c Michael Hanselmann
          self.assertFalse(lu.info_log)
427 d755483c Michael Hanselmann
          self.assertFalse(lu.warning_log)
428 d755483c Michael Hanselmann
429 d755483c Michael Hanselmann
          for op in itertools.chain(*result):
430 d755483c Michael Hanselmann
            if hasattr(op.__class__, "early_release"):
431 d755483c Michael Hanselmann
              self.assertEqual(op.early_release, early_release)
432 d755483c Michael Hanselmann
            else:
433 d755483c Michael Hanselmann
              self.assertFalse(hasattr(op, "early_release"))
434 d755483c Michael Hanselmann
435 d755483c Michael Hanselmann
  def testFailed(self):
436 d755483c Michael Hanselmann
    alloc_result = ([], [
437 d755483c Michael Hanselmann
      ("inst5191.example.com", "errormsg21178"),
438 d755483c Michael Hanselmann
      ], [])
439 d755483c Michael Hanselmann
    assert cmdlib.IAllocator._NEVAC_RESULT(alloc_result)
440 d755483c Michael Hanselmann
441 d755483c Michael Hanselmann
    lu = _FakeLU()
442 d755483c Michael Hanselmann
    self.assertRaises(errors.OpExecError, cmdlib._LoadNodeEvacResult,
443 d755483c Michael Hanselmann
                      lu, alloc_result, False, False)
444 d755483c Michael Hanselmann
    self.assertFalse(lu.info_log)
445 d755483c Michael Hanselmann
    (_, (args, )) = lu.warning_log.pop(0)
446 d755483c Michael Hanselmann
    self.assertTrue("inst5191.example.com" in args)
447 d755483c Michael Hanselmann
    self.assertTrue("errormsg21178" in args)
448 d755483c Michael Hanselmann
    self.assertFalse(lu.warning_log)
449 d755483c Michael Hanselmann
450 d755483c Michael Hanselmann
451 784cd737 René Nussbaumer
class TestUpdateAndVerifySubDict(unittest.TestCase):
452 784cd737 René Nussbaumer
  def setUp(self):
453 784cd737 René Nussbaumer
    self.type_check = {
454 784cd737 René Nussbaumer
        "a": constants.VTYPE_INT,
455 784cd737 René Nussbaumer
        "b": constants.VTYPE_STRING,
456 784cd737 René Nussbaumer
        "c": constants.VTYPE_BOOL,
457 784cd737 René Nussbaumer
        "d": constants.VTYPE_STRING,
458 784cd737 René Nussbaumer
        }
459 784cd737 René Nussbaumer
460 784cd737 René Nussbaumer
  def test(self):
461 784cd737 René Nussbaumer
    old_test = {
462 784cd737 René Nussbaumer
      "foo": {
463 784cd737 René Nussbaumer
        "d": "blubb",
464 784cd737 René Nussbaumer
        "a": 321,
465 784cd737 René Nussbaumer
        },
466 784cd737 René Nussbaumer
      "baz": {
467 784cd737 René Nussbaumer
        "a": 678,
468 784cd737 René Nussbaumer
        "b": "678",
469 784cd737 René Nussbaumer
        "c": True,
470 784cd737 René Nussbaumer
        },
471 784cd737 René Nussbaumer
      }
472 784cd737 René Nussbaumer
    test = {
473 784cd737 René Nussbaumer
      "foo": {
474 784cd737 René Nussbaumer
        "a": 123,
475 784cd737 René Nussbaumer
        "b": "123",
476 784cd737 René Nussbaumer
        "c": True,
477 784cd737 René Nussbaumer
        },
478 784cd737 René Nussbaumer
      "bar": {
479 784cd737 René Nussbaumer
        "a": 321,
480 784cd737 René Nussbaumer
        "b": "321",
481 784cd737 René Nussbaumer
        "c": False,
482 784cd737 René Nussbaumer
        },
483 784cd737 René Nussbaumer
      }
484 784cd737 René Nussbaumer
485 784cd737 René Nussbaumer
    mv = {
486 784cd737 René Nussbaumer
      "foo": {
487 784cd737 René Nussbaumer
        "a": 123,
488 784cd737 René Nussbaumer
        "b": "123",
489 784cd737 René Nussbaumer
        "c": True,
490 784cd737 René Nussbaumer
        "d": "blubb"
491 784cd737 René Nussbaumer
        },
492 784cd737 René Nussbaumer
      "bar": {
493 784cd737 René Nussbaumer
        "a": 321,
494 784cd737 René Nussbaumer
        "b": "321",
495 784cd737 René Nussbaumer
        "c": False,
496 784cd737 René Nussbaumer
        },
497 784cd737 René Nussbaumer
      "baz": {
498 784cd737 René Nussbaumer
        "a": 678,
499 784cd737 René Nussbaumer
        "b": "678",
500 784cd737 René Nussbaumer
        "c": True,
501 784cd737 René Nussbaumer
        },
502 784cd737 René Nussbaumer
      }
503 784cd737 René Nussbaumer
504 784cd737 René Nussbaumer
    verified = cmdlib._UpdateAndVerifySubDict(old_test, test, self.type_check)
505 784cd737 René Nussbaumer
    self.assertEqual(verified, mv)
506 784cd737 René Nussbaumer
507 784cd737 René Nussbaumer
  def testWrong(self):
508 784cd737 René Nussbaumer
    test = {
509 784cd737 René Nussbaumer
      "foo": {
510 784cd737 René Nussbaumer
        "a": "blubb",
511 784cd737 René Nussbaumer
        "b": "123",
512 784cd737 René Nussbaumer
        "c": True,
513 784cd737 René Nussbaumer
        },
514 784cd737 René Nussbaumer
      "bar": {
515 784cd737 René Nussbaumer
        "a": 321,
516 784cd737 René Nussbaumer
        "b": "321",
517 784cd737 René Nussbaumer
        "c": False,
518 784cd737 René Nussbaumer
        },
519 784cd737 René Nussbaumer
      }
520 784cd737 René Nussbaumer
521 784cd737 René Nussbaumer
    self.assertRaises(errors.TypeEnforcementError,
522 784cd737 René Nussbaumer
                      cmdlib._UpdateAndVerifySubDict, {}, test, self.type_check)
523 784cd737 René Nussbaumer
524 784cd737 René Nussbaumer
525 0ba177e2 René Nussbaumer
class TestHvStateHelper(unittest.TestCase):
526 0ba177e2 René Nussbaumer
  def testWithoutOpData(self):
527 0ba177e2 René Nussbaumer
    self.assertEqual(cmdlib._MergeAndVerifyHvState(None, NotImplemented), None)
528 0ba177e2 René Nussbaumer
529 0ba177e2 René Nussbaumer
  def testWithoutOldData(self):
530 0ba177e2 René Nussbaumer
    new = {
531 0ba177e2 René Nussbaumer
      constants.HT_XEN_PVM: {
532 0ba177e2 René Nussbaumer
        constants.HVST_MEMORY_TOTAL: 4096,
533 0ba177e2 René Nussbaumer
        },
534 0ba177e2 René Nussbaumer
      }
535 0ba177e2 René Nussbaumer
    self.assertEqual(cmdlib._MergeAndVerifyHvState(new, None), new)
536 0ba177e2 René Nussbaumer
537 0ba177e2 René Nussbaumer
  def testWithWrongHv(self):
538 0ba177e2 René Nussbaumer
    new = {
539 0ba177e2 René Nussbaumer
      "i-dont-exist": {
540 0ba177e2 René Nussbaumer
        constants.HVST_MEMORY_TOTAL: 4096,
541 0ba177e2 René Nussbaumer
        },
542 0ba177e2 René Nussbaumer
      }
543 0ba177e2 René Nussbaumer
    self.assertRaises(errors.OpPrereqError, cmdlib._MergeAndVerifyHvState, new,
544 0ba177e2 René Nussbaumer
                      None)
545 0ba177e2 René Nussbaumer
546 0ba177e2 René Nussbaumer
class TestDiskStateHelper(unittest.TestCase):
547 0ba177e2 René Nussbaumer
  def testWithoutOpData(self):
548 0ba177e2 René Nussbaumer
    self.assertEqual(cmdlib._MergeAndVerifyDiskState(None, NotImplemented),
549 0ba177e2 René Nussbaumer
                     None)
550 0ba177e2 René Nussbaumer
551 0ba177e2 René Nussbaumer
  def testWithoutOldData(self):
552 0ba177e2 René Nussbaumer
    new = {
553 0ba177e2 René Nussbaumer
      constants.LD_LV: {
554 0ba177e2 René Nussbaumer
        "xenvg": {
555 0ba177e2 René Nussbaumer
          constants.DS_DISK_RESERVED: 1024,
556 0ba177e2 René Nussbaumer
          },
557 0ba177e2 René Nussbaumer
        },
558 0ba177e2 René Nussbaumer
      }
559 0ba177e2 René Nussbaumer
    self.assertEqual(cmdlib._MergeAndVerifyDiskState(new, None), new)
560 0ba177e2 René Nussbaumer
561 0ba177e2 René Nussbaumer
  def testWithWrongStorageType(self):
562 0ba177e2 René Nussbaumer
    new = {
563 0ba177e2 René Nussbaumer
      "i-dont-exist": {
564 0ba177e2 René Nussbaumer
        "xenvg": {
565 0ba177e2 René Nussbaumer
          constants.DS_DISK_RESERVED: 1024,
566 0ba177e2 René Nussbaumer
          },
567 0ba177e2 René Nussbaumer
        },
568 0ba177e2 René Nussbaumer
      }
569 0ba177e2 René Nussbaumer
    self.assertRaises(errors.OpPrereqError, cmdlib._MergeAndVerifyDiskState,
570 0ba177e2 René Nussbaumer
                      new, None)
571 0ba177e2 René Nussbaumer
572 0ba177e2 René Nussbaumer
573 2096d068 René Nussbaumer
class TestComputeMinMaxSpec(unittest.TestCase):
574 2096d068 René Nussbaumer
  def setUp(self):
575 2096d068 René Nussbaumer
    self.ipolicy = {
576 2096d068 René Nussbaumer
      constants.ISPECS_MAX: {
577 2096d068 René Nussbaumer
        constants.ISPEC_MEM_SIZE: 512,
578 2096d068 René Nussbaumer
        constants.ISPEC_DISK_SIZE: 1024,
579 2096d068 René Nussbaumer
        },
580 2096d068 René Nussbaumer
      constants.ISPECS_MIN: {
581 2096d068 René Nussbaumer
        constants.ISPEC_MEM_SIZE: 128,
582 2096d068 René Nussbaumer
        constants.ISPEC_DISK_COUNT: 1,
583 2096d068 René Nussbaumer
        },
584 2096d068 René Nussbaumer
      }
585 2096d068 René Nussbaumer
586 2096d068 René Nussbaumer
  def testNoneValue(self):
587 2096d068 René Nussbaumer
    self.assertTrue(cmdlib._ComputeMinMaxSpec(constants.ISPEC_MEM_SIZE,
588 2096d068 René Nussbaumer
                                              self.ipolicy, None) is None)
589 2096d068 René Nussbaumer
590 2096d068 René Nussbaumer
  def testAutoValue(self):
591 2096d068 René Nussbaumer
    self.assertTrue(cmdlib._ComputeMinMaxSpec(constants.ISPEC_MEM_SIZE,
592 2096d068 René Nussbaumer
                                              self.ipolicy,
593 2096d068 René Nussbaumer
                                              constants.VALUE_AUTO) is None)
594 2096d068 René Nussbaumer
595 2096d068 René Nussbaumer
  def testNotDefined(self):
596 2096d068 René Nussbaumer
    self.assertTrue(cmdlib._ComputeMinMaxSpec(constants.ISPEC_NIC_COUNT,
597 2096d068 René Nussbaumer
                                              self.ipolicy, 3) is None)
598 2096d068 René Nussbaumer
599 2096d068 René Nussbaumer
  def testNoMinDefined(self):
600 2096d068 René Nussbaumer
    self.assertTrue(cmdlib._ComputeMinMaxSpec(constants.ISPEC_DISK_SIZE,
601 2096d068 René Nussbaumer
                                              self.ipolicy, 128) is None)
602 2096d068 René Nussbaumer
603 2096d068 René Nussbaumer
  def testNoMaxDefined(self):
604 2096d068 René Nussbaumer
    self.assertTrue(cmdlib._ComputeMinMaxSpec(constants.ISPEC_DISK_COUNT,
605 2096d068 René Nussbaumer
                                                self.ipolicy, 16) is None)
606 2096d068 René Nussbaumer
607 2096d068 René Nussbaumer
  def testOutOfRange(self):
608 2096d068 René Nussbaumer
    for (name, val) in ((constants.ISPEC_MEM_SIZE, 64),
609 2096d068 René Nussbaumer
                        (constants.ISPEC_MEM_SIZE, 768),
610 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_SIZE, 4096),
611 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_COUNT, 0)):
612 2096d068 René Nussbaumer
      min_v = self.ipolicy[constants.ISPECS_MIN].get(name, val)
613 2096d068 René Nussbaumer
      max_v = self.ipolicy[constants.ISPECS_MAX].get(name, val)
614 2096d068 René Nussbaumer
      self.assertEqual(cmdlib._ComputeMinMaxSpec(name, self.ipolicy, val),
615 2096d068 René Nussbaumer
                       "%s value %s is not in range [%s, %s]" %
616 2096d068 René Nussbaumer
                       (name, val,min_v, max_v))
617 2096d068 René Nussbaumer
618 2096d068 René Nussbaumer
  def test(self):
619 2096d068 René Nussbaumer
    for (name, val) in ((constants.ISPEC_MEM_SIZE, 256),
620 2096d068 René Nussbaumer
                        (constants.ISPEC_MEM_SIZE, 128),
621 2096d068 René Nussbaumer
                        (constants.ISPEC_MEM_SIZE, 512),
622 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_SIZE, 1024),
623 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_SIZE, 0),
624 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_COUNT, 1),
625 2096d068 René Nussbaumer
                        (constants.ISPEC_DISK_COUNT, 5)):
626 2096d068 René Nussbaumer
      self.assertTrue(cmdlib._ComputeMinMaxSpec(name, self.ipolicy, val)
627 2096d068 René Nussbaumer
                      is None)
628 2096d068 René Nussbaumer
629 2096d068 René Nussbaumer
630 0e68bf27 René Nussbaumer
def _ValidateComputeMinMaxSpec(name, *_):
631 0fb81174 René Nussbaumer
  assert name in constants.ISPECS_PARAMETERS
632 0fb81174 René Nussbaumer
  return None
633 0fb81174 René Nussbaumer
634 0fb81174 René Nussbaumer
635 0fb81174 René Nussbaumer
class _SpecWrapper:
636 0fb81174 René Nussbaumer
  def __init__(self, spec):
637 0fb81174 René Nussbaumer
    self.spec = spec
638 0fb81174 René Nussbaumer
639 0e68bf27 René Nussbaumer
  def ComputeMinMaxSpec(self, *args):
640 0fb81174 René Nussbaumer
    return self.spec.pop(0)
641 0fb81174 René Nussbaumer
642 0fb81174 René Nussbaumer
643 0fb81174 René Nussbaumer
class TestComputeIPolicySpecViolation(unittest.TestCase):
644 0fb81174 René Nussbaumer
  def test(self):
645 0e68bf27 René Nussbaumer
    compute_fn = _ValidateComputeMinMaxSpec
646 0fb81174 René Nussbaumer
    ret = cmdlib._ComputeIPolicySpecViolation(NotImplemented, 1024, 1, 1, 1,
647 0e68bf27 René Nussbaumer
                                              [1024], _compute_fn=compute_fn)
648 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
649 0fb81174 René Nussbaumer
650 0fb81174 René Nussbaumer
  def testInvalidArguments(self):
651 0fb81174 René Nussbaumer
    self.assertRaises(AssertionError, cmdlib._ComputeIPolicySpecViolation,
652 0fb81174 René Nussbaumer
                      NotImplemented, 1024, 1, 1, 1, [])
653 0fb81174 René Nussbaumer
654 0fb81174 René Nussbaumer
  def testInvalidSpec(self):
655 0fb81174 René Nussbaumer
    spec = _SpecWrapper([None, False, "foo", None, "bar"])
656 0e68bf27 René Nussbaumer
    compute_fn = spec.ComputeMinMaxSpec
657 0fb81174 René Nussbaumer
    ret = cmdlib._ComputeIPolicySpecViolation(NotImplemented, 1024, 1, 1, 1,
658 0e68bf27 René Nussbaumer
                                              [1024], _compute_fn=compute_fn)
659 0fb81174 René Nussbaumer
    self.assertEqual(ret, ["foo", "bar"])
660 0fb81174 René Nussbaumer
    self.assertFalse(spec.spec)
661 0fb81174 René Nussbaumer
662 0fb81174 René Nussbaumer
663 0fb81174 René Nussbaumer
class _StubComputeIPolicySpecViolation:
664 0fb81174 René Nussbaumer
  def __init__(self, mem_size, cpu_count, disk_count, nic_count, disk_sizes):
665 0fb81174 René Nussbaumer
    self.mem_size = mem_size
666 0fb81174 René Nussbaumer
    self.cpu_count = cpu_count
667 0fb81174 René Nussbaumer
    self.disk_count = disk_count
668 0fb81174 René Nussbaumer
    self.nic_count = nic_count
669 0fb81174 René Nussbaumer
    self.disk_sizes = disk_sizes
670 0fb81174 René Nussbaumer
671 0fb81174 René Nussbaumer
  def __call__(self, _, mem_size, cpu_count, disk_count, nic_count, disk_sizes):
672 0fb81174 René Nussbaumer
    assert self.mem_size == mem_size
673 0fb81174 René Nussbaumer
    assert self.cpu_count == cpu_count
674 0fb81174 René Nussbaumer
    assert self.disk_count == disk_count
675 0fb81174 René Nussbaumer
    assert self.nic_count == nic_count
676 0fb81174 René Nussbaumer
    assert self.disk_sizes == disk_sizes
677 0fb81174 René Nussbaumer
678 0fb81174 René Nussbaumer
    return []
679 0fb81174 René Nussbaumer
680 0fb81174 René Nussbaumer
681 0fb81174 René Nussbaumer
class TestComputeIPolicyInstanceViolation(unittest.TestCase):
682 0fb81174 René Nussbaumer
  def test(self):
683 0fb81174 René Nussbaumer
    beparams = {
684 0fb81174 René Nussbaumer
      constants.BE_MAXMEM: 2048,
685 0fb81174 René Nussbaumer
      constants.BE_VCPUS: 2,
686 0fb81174 René Nussbaumer
      }
687 0fb81174 René Nussbaumer
    disks = [objects.Disk(size=512)]
688 0fb81174 René Nussbaumer
    instance = objects.Instance(beparams=beparams, disks=disks, nics=[])
689 0fb81174 René Nussbaumer
    stub = _StubComputeIPolicySpecViolation(2048, 2, 1, 0, [512])
690 0fb81174 René Nussbaumer
    ret = cmdlib._ComputeIPolicyInstanceViolation(NotImplemented, instance,
691 0fb81174 René Nussbaumer
                                                  _compute_fn=stub)
692 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
693 0fb81174 René Nussbaumer
694 0fb81174 René Nussbaumer
695 0fb81174 René Nussbaumer
class TestComputeIPolicyInstanceSpecViolation(unittest.TestCase):
696 0fb81174 René Nussbaumer
  def test(self):
697 0fb81174 René Nussbaumer
    ispec = {
698 0fb81174 René Nussbaumer
      constants.ISPEC_MEM_SIZE: 2048,
699 0fb81174 René Nussbaumer
      constants.ISPEC_CPU_COUNT: 2,
700 0fb81174 René Nussbaumer
      constants.ISPEC_DISK_COUNT: 1,
701 0fb81174 René Nussbaumer
      constants.ISPEC_DISK_SIZE: [512],
702 0fb81174 René Nussbaumer
      constants.ISPEC_NIC_COUNT: 0,
703 0fb81174 René Nussbaumer
      }
704 0fb81174 René Nussbaumer
    stub = _StubComputeIPolicySpecViolation(2048, 2, 1, 0, [512])
705 0fb81174 René Nussbaumer
    ret = cmdlib._ComputeIPolicyInstanceSpecViolation(NotImplemented, ispec,
706 0fb81174 René Nussbaumer
                                                      _compute_fn=stub)
707 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
708 0fb81174 René Nussbaumer
709 0fb81174 René Nussbaumer
710 0fb81174 René Nussbaumer
class _CallRecorder:
711 0fb81174 René Nussbaumer
  def __init__(self, return_value=None):
712 0fb81174 René Nussbaumer
    self.called = False
713 0fb81174 René Nussbaumer
    self.return_value = return_value
714 0fb81174 René Nussbaumer
715 0fb81174 René Nussbaumer
  def __call__(self, *args):
716 0fb81174 René Nussbaumer
    self.called = True
717 0fb81174 René Nussbaumer
    return self.return_value
718 0fb81174 René Nussbaumer
719 0fb81174 René Nussbaumer
720 0fb81174 René Nussbaumer
class TestComputeIPolicyNodeViolation(unittest.TestCase):
721 0fb81174 René Nussbaumer
  def setUp(self):
722 0fb81174 René Nussbaumer
    self.recorder = _CallRecorder(return_value=[])
723 0fb81174 René Nussbaumer
724 0fb81174 René Nussbaumer
  def testSameGroup(self):
725 0fb81174 René Nussbaumer
    ret = cmdlib._ComputeIPolicyNodeViolation(NotImplemented, NotImplemented,
726 0fb81174 René Nussbaumer
                                              "foo", "foo",
727 0fb81174 René Nussbaumer
                                              _compute_fn=self.recorder)
728 0fb81174 René Nussbaumer
    self.assertFalse(self.recorder.called)
729 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
730 0fb81174 René Nussbaumer
731 0fb81174 René Nussbaumer
  def testDifferentGroup(self):
732 0fb81174 René Nussbaumer
    ret = cmdlib._ComputeIPolicyNodeViolation(NotImplemented, NotImplemented,
733 0fb81174 René Nussbaumer
                                              "foo", "bar",
734 0fb81174 René Nussbaumer
                                              _compute_fn=self.recorder)
735 0fb81174 René Nussbaumer
    self.assertTrue(self.recorder.called)
736 0fb81174 René Nussbaumer
    self.assertEqual(ret, [])
737 0fb81174 René Nussbaumer
738 0fb81174 René Nussbaumer
739 ff02b60f René Nussbaumer
class _FakeConfigForTargetNodeIPolicy:
740 ff02b60f René Nussbaumer
  def __init__(self, node_info=NotImplemented):
741 ff02b60f René Nussbaumer
    self._node_info = node_info
742 ff02b60f René Nussbaumer
743 ff02b60f René Nussbaumer
  def GetNodeInfo(self, _):
744 ff02b60f René Nussbaumer
    return self._node_info
745 ff02b60f René Nussbaumer
746 ff02b60f René Nussbaumer
747 0fb81174 René Nussbaumer
class TestCheckTargetNodeIPolicy(unittest.TestCase):
748 0fb81174 René Nussbaumer
  def setUp(self):
749 ff02b60f René Nussbaumer
    self.instance = objects.Instance(primary_node="blubb")
750 0fb81174 René Nussbaumer
    self.target_node = objects.Node(group="bar")
751 ff02b60f René Nussbaumer
    node_info = objects.Node(group="foo")
752 ff02b60f René Nussbaumer
    fake_cfg = _FakeConfigForTargetNodeIPolicy(node_info=node_info)
753 ff02b60f René Nussbaumer
    self.lu = _FakeLU(cfg=fake_cfg)
754 0fb81174 René Nussbaumer
755 0fb81174 René Nussbaumer
  def testNoViolation(self):
756 0fb81174 René Nussbaumer
    compute_recoder = _CallRecorder(return_value=[])
757 0fb81174 René Nussbaumer
    cmdlib._CheckTargetNodeIPolicy(self.lu, NotImplemented, self.instance,
758 0fb81174 René Nussbaumer
                                   self.target_node,
759 0fb81174 René Nussbaumer
                                   _compute_fn=compute_recoder)
760 0fb81174 René Nussbaumer
    self.assertTrue(compute_recoder.called)
761 0fb81174 René Nussbaumer
    self.assertEqual(self.lu.warning_log, [])
762 0fb81174 René Nussbaumer
763 0fb81174 René Nussbaumer
  def testNoIgnore(self):
764 0fb81174 René Nussbaumer
    compute_recoder = _CallRecorder(return_value=["mem_size not in range"])
765 0fb81174 René Nussbaumer
    self.assertRaises(errors.OpPrereqError, cmdlib._CheckTargetNodeIPolicy,
766 0fb81174 René Nussbaumer
                      self.lu, NotImplemented, self.instance, self.target_node,
767 0fb81174 René Nussbaumer
                      _compute_fn=compute_recoder)
768 0fb81174 René Nussbaumer
    self.assertTrue(compute_recoder.called)
769 0fb81174 René Nussbaumer
    self.assertEqual(self.lu.warning_log, [])
770 0fb81174 René Nussbaumer
771 0fb81174 René Nussbaumer
  def testIgnoreViolation(self):
772 0fb81174 René Nussbaumer
    compute_recoder = _CallRecorder(return_value=["mem_size not in range"])
773 0fb81174 René Nussbaumer
    cmdlib._CheckTargetNodeIPolicy(self.lu, NotImplemented, self.instance,
774 0fb81174 René Nussbaumer
                                   self.target_node, ignore=True,
775 0fb81174 René Nussbaumer
                                   _compute_fn=compute_recoder)
776 0fb81174 René Nussbaumer
    self.assertTrue(compute_recoder.called)
777 0fb81174 René Nussbaumer
    msg = ("Instance does not meet target node group's (bar) instance policy:"
778 0fb81174 René Nussbaumer
           " mem_size not in range")
779 0fb81174 René Nussbaumer
    self.assertEqual(self.lu.warning_log, [(msg, ())])
780 0fb81174 René Nussbaumer
781 0fb81174 René Nussbaumer
782 b98bf262 Michael Hanselmann
if __name__ == "__main__":
783 25231ec5 Michael Hanselmann
  testutils.GanetiTestProgram()