Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.cmdlib_unittest.py @ f14a8b15

History | View | Annotate | Download (42.6 kB)

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