Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.mcpu_unittest.py @ 91c17910

History | View | Annotate | Download (8.9 kB)

1 407339d0 Michael Hanselmann
#!/usr/bin/python
2 407339d0 Michael Hanselmann
#
3 407339d0 Michael Hanselmann
4 687c10d9 Iustin Pop
# Copyright (C) 2009, 2011 Google Inc.
5 407339d0 Michael Hanselmann
#
6 407339d0 Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 407339d0 Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 407339d0 Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 407339d0 Michael Hanselmann
# (at your option) any later version.
10 407339d0 Michael Hanselmann
#
11 407339d0 Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 407339d0 Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 407339d0 Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 407339d0 Michael Hanselmann
# General Public License for more details.
15 407339d0 Michael Hanselmann
#
16 407339d0 Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 407339d0 Michael Hanselmann
# along with this program; if not, write to the Free Software
18 407339d0 Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 407339d0 Michael Hanselmann
# 02110-1301, USA.
20 407339d0 Michael Hanselmann
21 407339d0 Michael Hanselmann
22 407339d0 Michael Hanselmann
"""Script for unittesting the mcpu module"""
23 407339d0 Michael Hanselmann
24 407339d0 Michael Hanselmann
25 407339d0 Michael Hanselmann
import unittest
26 07923a3c Michael Hanselmann
import itertools
27 407339d0 Michael Hanselmann
28 b8028dcf Michael Hanselmann
from ganeti import compat
29 407339d0 Michael Hanselmann
from ganeti import mcpu
30 0a31dda0 Michael Hanselmann
from ganeti import opcodes
31 07923a3c Michael Hanselmann
from ganeti import cmdlib
32 e9a81214 Michael Hanselmann
from ganeti import locking
33 07923a3c Michael Hanselmann
from ganeti import constants
34 d385a174 Iustin Pop
from ganeti.constants import \
35 d385a174 Iustin Pop
    LOCK_ATTEMPTS_TIMEOUT, \
36 d385a174 Iustin Pop
    LOCK_ATTEMPTS_MAXWAIT, \
37 d385a174 Iustin Pop
    LOCK_ATTEMPTS_MINWAIT
38 407339d0 Michael Hanselmann
39 25231ec5 Michael Hanselmann
import testutils
40 25231ec5 Michael Hanselmann
41 407339d0 Michael Hanselmann
42 b8028dcf Michael Hanselmann
REQ_BGL_WHITELIST = compat.UniqueFrozenset([
43 c9c33a28 Michael Hanselmann
  opcodes.OpClusterActivateMasterIp,
44 c9c33a28 Michael Hanselmann
  opcodes.OpClusterDeactivateMasterIp,
45 c9c33a28 Michael Hanselmann
  opcodes.OpClusterDestroy,
46 c9c33a28 Michael Hanselmann
  opcodes.OpClusterPostInit,
47 c9c33a28 Michael Hanselmann
  opcodes.OpClusterRename,
48 c9c33a28 Michael Hanselmann
  opcodes.OpInstanceRename,
49 c9c33a28 Michael Hanselmann
  opcodes.OpNodeAdd,
50 c9c33a28 Michael Hanselmann
  opcodes.OpNodeRemove,
51 c9c33a28 Michael Hanselmann
  opcodes.OpTestAllocator,
52 c9c33a28 Michael Hanselmann
  ])
53 c9c33a28 Michael Hanselmann
54 c9c33a28 Michael Hanselmann
55 e3200b18 Michael Hanselmann
class TestLockAttemptTimeoutStrategy(unittest.TestCase):
56 407339d0 Michael Hanselmann
  def testConstants(self):
57 a7770f03 Michael Hanselmann
    tpa = mcpu.LockAttemptTimeoutStrategy._TIMEOUT_PER_ATTEMPT
58 d385a174 Iustin Pop
    self.assert_(len(tpa) > LOCK_ATTEMPTS_TIMEOUT / LOCK_ATTEMPTS_MAXWAIT)
59 d385a174 Iustin Pop
    self.assert_(sum(tpa) >= LOCK_ATTEMPTS_TIMEOUT)
60 407339d0 Michael Hanselmann
61 0b04b188 Michael Hanselmann
    self.assertTrue(LOCK_ATTEMPTS_TIMEOUT >= 1800,
62 0b04b188 Michael Hanselmann
                    msg="Waiting less than half an hour per priority")
63 0b04b188 Michael Hanselmann
    self.assertTrue(LOCK_ATTEMPTS_TIMEOUT <= 3600,
64 0b04b188 Michael Hanselmann
                    msg="Waiting more than an hour per priority")
65 0b04b188 Michael Hanselmann
66 407339d0 Michael Hanselmann
  def testSimple(self):
67 a7770f03 Michael Hanselmann
    strat = mcpu.LockAttemptTimeoutStrategy(_random_fn=lambda: 0.5,
68 a7770f03 Michael Hanselmann
                                            _time_fn=lambda: 0.0)
69 407339d0 Michael Hanselmann
70 407339d0 Michael Hanselmann
    prev = None
71 a7770f03 Michael Hanselmann
    for i in range(len(strat._TIMEOUT_PER_ATTEMPT)):
72 a7770f03 Michael Hanselmann
      timeout = strat.NextAttempt()
73 407339d0 Michael Hanselmann
      self.assert_(timeout is not None)
74 407339d0 Michael Hanselmann
75 d385a174 Iustin Pop
      self.assert_(timeout <= LOCK_ATTEMPTS_MAXWAIT)
76 d385a174 Iustin Pop
      self.assert_(timeout >= LOCK_ATTEMPTS_MINWAIT)
77 407339d0 Michael Hanselmann
      self.assert_(prev is None or timeout >= prev)
78 407339d0 Michael Hanselmann
79 407339d0 Michael Hanselmann
      prev = timeout
80 407339d0 Michael Hanselmann
81 a6db1af2 Michael Hanselmann
    for _ in range(10):
82 a7770f03 Michael Hanselmann
      self.assert_(strat.NextAttempt() is None)
83 407339d0 Michael Hanselmann
84 407339d0 Michael Hanselmann
85 0a31dda0 Michael Hanselmann
class TestDispatchTable(unittest.TestCase):
86 0a31dda0 Michael Hanselmann
  def test(self):
87 0a31dda0 Michael Hanselmann
    for opcls in opcodes.OP_MAPPING.values():
88 687c10d9 Iustin Pop
      if not opcls.WITH_LU:
89 0a31dda0 Michael Hanselmann
        continue
90 687c10d9 Iustin Pop
      self.assertTrue(opcls in mcpu.Processor.DISPATCH_TABLE,
91 687c10d9 Iustin Pop
                      msg="%s missing handler class" % opcls)
92 0a31dda0 Michael Hanselmann
93 c9c33a28 Michael Hanselmann
      # Check against BGL whitelist
94 c9c33a28 Michael Hanselmann
      lucls = mcpu.Processor.DISPATCH_TABLE[opcls]
95 c9c33a28 Michael Hanselmann
      if lucls.REQ_BGL:
96 c9c33a28 Michael Hanselmann
        self.assertTrue(opcls in REQ_BGL_WHITELIST,
97 c9c33a28 Michael Hanselmann
                        msg=("%s not whitelisted for BGL" % opcls.OP_ID))
98 c9c33a28 Michael Hanselmann
      else:
99 c9c33a28 Michael Hanselmann
        self.assertFalse(opcls in REQ_BGL_WHITELIST,
100 c9c33a28 Michael Hanselmann
                         msg=("%s whitelisted for BGL, but doesn't use it" %
101 c9c33a28 Michael Hanselmann
                              opcls.OP_ID))
102 c9c33a28 Michael Hanselmann
103 0a31dda0 Michael Hanselmann
104 07923a3c Michael Hanselmann
class TestProcessResult(unittest.TestCase):
105 07923a3c Michael Hanselmann
  def setUp(self):
106 07923a3c Michael Hanselmann
    self._submitted = []
107 07923a3c Michael Hanselmann
    self._count = itertools.count(200)
108 07923a3c Michael Hanselmann
109 07923a3c Michael Hanselmann
  def _Submit(self, jobs):
110 07923a3c Michael Hanselmann
    job_ids = [self._count.next() for _ in jobs]
111 07923a3c Michael Hanselmann
    self._submitted.extend(zip(job_ids, jobs))
112 07923a3c Michael Hanselmann
    return job_ids
113 07923a3c Michael Hanselmann
114 07923a3c Michael Hanselmann
  def testNoJobs(self):
115 07923a3c Michael Hanselmann
    for i in [object(), [], False, True, None, 1, 929, {}]:
116 07923a3c Michael Hanselmann
      self.assertEqual(mcpu._ProcessResult(NotImplemented, NotImplemented, i),
117 07923a3c Michael Hanselmann
                       i)
118 07923a3c Michael Hanselmann
119 07923a3c Michael Hanselmann
  def testDefaults(self):
120 07923a3c Michael Hanselmann
    src = opcodes.OpTestDummy()
121 07923a3c Michael Hanselmann
122 07923a3c Michael Hanselmann
    res = mcpu._ProcessResult(self._Submit, src, cmdlib.ResultWithJobs([[
123 07923a3c Michael Hanselmann
      opcodes.OpTestDelay(),
124 07923a3c Michael Hanselmann
      opcodes.OpTestDelay(),
125 07923a3c Michael Hanselmann
      ], [
126 07923a3c Michael Hanselmann
      opcodes.OpTestDelay(),
127 07923a3c Michael Hanselmann
      ]]))
128 07923a3c Michael Hanselmann
129 07923a3c Michael Hanselmann
    self.assertEqual(res, {
130 07923a3c Michael Hanselmann
      constants.JOB_IDS_KEY: [200, 201],
131 07923a3c Michael Hanselmann
      })
132 07923a3c Michael Hanselmann
133 07923a3c Michael Hanselmann
    (_, (op1, op2)) = self._submitted.pop(0)
134 07923a3c Michael Hanselmann
    (_, (op3, )) = self._submitted.pop(0)
135 07923a3c Michael Hanselmann
    self.assertRaises(IndexError, self._submitted.pop)
136 07923a3c Michael Hanselmann
137 07923a3c Michael Hanselmann
    for op in [op1, op2, op3]:
138 07923a3c Michael Hanselmann
      self.assertTrue("OP_TEST_DUMMY" in op.comment)
139 07923a3c Michael Hanselmann
      self.assertFalse(hasattr(op, "priority"))
140 07923a3c Michael Hanselmann
      self.assertFalse(hasattr(op, "debug_level"))
141 07923a3c Michael Hanselmann
142 07923a3c Michael Hanselmann
  def testParams(self):
143 07923a3c Michael Hanselmann
    src = opcodes.OpTestDummy(priority=constants.OP_PRIO_HIGH,
144 07923a3c Michael Hanselmann
                              debug_level=3)
145 07923a3c Michael Hanselmann
146 07923a3c Michael Hanselmann
    res = mcpu._ProcessResult(self._Submit, src, cmdlib.ResultWithJobs([[
147 07923a3c Michael Hanselmann
      opcodes.OpTestDelay(priority=constants.OP_PRIO_LOW),
148 07923a3c Michael Hanselmann
      ], [
149 07923a3c Michael Hanselmann
      opcodes.OpTestDelay(comment="foobar", debug_level=10),
150 07923a3c Michael Hanselmann
      ]], other=True, value=range(10)))
151 07923a3c Michael Hanselmann
152 07923a3c Michael Hanselmann
    self.assertEqual(res, {
153 07923a3c Michael Hanselmann
      constants.JOB_IDS_KEY: [200, 201],
154 07923a3c Michael Hanselmann
      "other": True,
155 07923a3c Michael Hanselmann
      "value": range(10),
156 07923a3c Michael Hanselmann
      })
157 07923a3c Michael Hanselmann
158 07923a3c Michael Hanselmann
    (_, (op1, )) = self._submitted.pop(0)
159 07923a3c Michael Hanselmann
    (_, (op2, )) = self._submitted.pop(0)
160 07923a3c Michael Hanselmann
    self.assertRaises(IndexError, self._submitted.pop)
161 07923a3c Michael Hanselmann
162 07923a3c Michael Hanselmann
    self.assertEqual(op1.priority, constants.OP_PRIO_LOW)
163 07923a3c Michael Hanselmann
    self.assertTrue("OP_TEST_DUMMY" in op1.comment)
164 07923a3c Michael Hanselmann
    self.assertEqual(op1.debug_level, 3)
165 07923a3c Michael Hanselmann
166 07923a3c Michael Hanselmann
    self.assertEqual(op2.priority, constants.OP_PRIO_HIGH)
167 07923a3c Michael Hanselmann
    self.assertEqual(op2.comment, "foobar")
168 07923a3c Michael Hanselmann
    self.assertEqual(op2.debug_level, 3)
169 07923a3c Michael Hanselmann
170 07923a3c Michael Hanselmann
171 e9a81214 Michael Hanselmann
class _FakeLuWithLocks:
172 e9a81214 Michael Hanselmann
  def __init__(self, needed_locks, share_locks):
173 e9a81214 Michael Hanselmann
    self.needed_locks = needed_locks
174 e9a81214 Michael Hanselmann
    self.share_locks = share_locks
175 e9a81214 Michael Hanselmann
176 e9a81214 Michael Hanselmann
177 e9a81214 Michael Hanselmann
class _FakeGlm:
178 e9a81214 Michael Hanselmann
  def __init__(self, owning_nal):
179 e9a81214 Michael Hanselmann
    self._owning_nal = owning_nal
180 e9a81214 Michael Hanselmann
181 e9a81214 Michael Hanselmann
  def check_owned(self, level, names):
182 e9a81214 Michael Hanselmann
    assert level == locking.LEVEL_NODE_ALLOC
183 e9a81214 Michael Hanselmann
    assert names == locking.NAL
184 e9a81214 Michael Hanselmann
    return self._owning_nal
185 e9a81214 Michael Hanselmann
186 e9a81214 Michael Hanselmann
  def owning_all(self, level):
187 e9a81214 Michael Hanselmann
    return False
188 e9a81214 Michael Hanselmann
189 e9a81214 Michael Hanselmann
190 e9a81214 Michael Hanselmann
class TestVerifyLocks(unittest.TestCase):
191 e9a81214 Michael Hanselmann
  def testNoLocks(self):
192 e9a81214 Michael Hanselmann
    lu = _FakeLuWithLocks({}, {})
193 e9a81214 Michael Hanselmann
    glm = _FakeGlm(False)
194 e9a81214 Michael Hanselmann
    mcpu._VerifyLocks(lu, glm,
195 e9a81214 Michael Hanselmann
                      _mode_whitelist=NotImplemented,
196 e9a81214 Michael Hanselmann
                      _nal_whitelist=NotImplemented)
197 e9a81214 Michael Hanselmann
198 e9a81214 Michael Hanselmann
  def testNotAllSameMode(self):
199 e9a81214 Michael Hanselmann
    for level in [locking.LEVEL_NODE, locking.LEVEL_NODE_RES]:
200 e9a81214 Michael Hanselmann
      lu = _FakeLuWithLocks({
201 e9a81214 Michael Hanselmann
        level: ["foo"],
202 e9a81214 Michael Hanselmann
        }, {
203 e9a81214 Michael Hanselmann
        level: 0,
204 e9a81214 Michael Hanselmann
        locking.LEVEL_NODE_ALLOC: 0,
205 e9a81214 Michael Hanselmann
        })
206 e9a81214 Michael Hanselmann
      glm = _FakeGlm(False)
207 e9a81214 Michael Hanselmann
      mcpu._VerifyLocks(lu, glm, _mode_whitelist=[], _nal_whitelist=[])
208 e9a81214 Michael Hanselmann
209 e9a81214 Michael Hanselmann
  def testDifferentMode(self):
210 e9a81214 Michael Hanselmann
    for level in [locking.LEVEL_NODE, locking.LEVEL_NODE_RES]:
211 e9a81214 Michael Hanselmann
      lu = _FakeLuWithLocks({
212 e9a81214 Michael Hanselmann
        level: ["foo"],
213 e9a81214 Michael Hanselmann
        }, {
214 e9a81214 Michael Hanselmann
        level: 0,
215 e9a81214 Michael Hanselmann
        locking.LEVEL_NODE_ALLOC: 1,
216 e9a81214 Michael Hanselmann
        })
217 e9a81214 Michael Hanselmann
      glm = _FakeGlm(False)
218 e9a81214 Michael Hanselmann
      try:
219 e9a81214 Michael Hanselmann
        mcpu._VerifyLocks(lu, glm, _mode_whitelist=[], _nal_whitelist=[])
220 e9a81214 Michael Hanselmann
      except AssertionError, err:
221 e9a81214 Michael Hanselmann
        self.assertTrue("using the same mode as nodes" in str(err))
222 e9a81214 Michael Hanselmann
      else:
223 e9a81214 Michael Hanselmann
        self.fail("Exception not raised")
224 e9a81214 Michael Hanselmann
225 e9a81214 Michael Hanselmann
      # Once more with the whitelist
226 e9a81214 Michael Hanselmann
      mcpu._VerifyLocks(lu, glm, _mode_whitelist=[_FakeLuWithLocks],
227 e9a81214 Michael Hanselmann
                        _nal_whitelist=[])
228 e9a81214 Michael Hanselmann
229 e9a81214 Michael Hanselmann
  def testSameMode(self):
230 e9a81214 Michael Hanselmann
    for level in [locking.LEVEL_NODE, locking.LEVEL_NODE_RES]:
231 e9a81214 Michael Hanselmann
      lu = _FakeLuWithLocks({
232 e9a81214 Michael Hanselmann
        level: ["foo"],
233 e9a81214 Michael Hanselmann
        locking.LEVEL_NODE_ALLOC: locking.ALL_SET,
234 e9a81214 Michael Hanselmann
        }, {
235 e9a81214 Michael Hanselmann
        level: 1,
236 e9a81214 Michael Hanselmann
        locking.LEVEL_NODE_ALLOC: 1,
237 e9a81214 Michael Hanselmann
        })
238 e9a81214 Michael Hanselmann
      glm = _FakeGlm(True)
239 e9a81214 Michael Hanselmann
240 e9a81214 Michael Hanselmann
      try:
241 e9a81214 Michael Hanselmann
        mcpu._VerifyLocks(lu, glm, _mode_whitelist=[_FakeLuWithLocks],
242 e9a81214 Michael Hanselmann
                          _nal_whitelist=[])
243 e9a81214 Michael Hanselmann
      except AssertionError, err:
244 e9a81214 Michael Hanselmann
        self.assertTrue("whitelisted to use different modes" in str(err))
245 e9a81214 Michael Hanselmann
      else:
246 e9a81214 Michael Hanselmann
        self.fail("Exception not raised")
247 e9a81214 Michael Hanselmann
248 e9a81214 Michael Hanselmann
      # Once more without the whitelist
249 e9a81214 Michael Hanselmann
      mcpu._VerifyLocks(lu, glm, _mode_whitelist=[], _nal_whitelist=[])
250 e9a81214 Michael Hanselmann
251 e9a81214 Michael Hanselmann
  def testAllWithoutAllocLock(self):
252 e9a81214 Michael Hanselmann
    for level in [locking.LEVEL_NODE, locking.LEVEL_NODE_RES]:
253 e9a81214 Michael Hanselmann
      lu = _FakeLuWithLocks({
254 e9a81214 Michael Hanselmann
        level: locking.ALL_SET,
255 e9a81214 Michael Hanselmann
        }, {
256 e9a81214 Michael Hanselmann
        level: 0,
257 e9a81214 Michael Hanselmann
        locking.LEVEL_NODE_ALLOC: 0,
258 e9a81214 Michael Hanselmann
        })
259 e9a81214 Michael Hanselmann
      glm = _FakeGlm(False)
260 e9a81214 Michael Hanselmann
      try:
261 e9a81214 Michael Hanselmann
        mcpu._VerifyLocks(lu, glm, _mode_whitelist=[], _nal_whitelist=[])
262 e9a81214 Michael Hanselmann
      except AssertionError, err:
263 e9a81214 Michael Hanselmann
        self.assertTrue("allocation lock must be used if" in str(err))
264 e9a81214 Michael Hanselmann
      else:
265 e9a81214 Michael Hanselmann
        self.fail("Exception not raised")
266 e9a81214 Michael Hanselmann
267 e9a81214 Michael Hanselmann
      # Once more with the whitelist
268 e9a81214 Michael Hanselmann
      mcpu._VerifyLocks(lu, glm, _mode_whitelist=[],
269 e9a81214 Michael Hanselmann
                        _nal_whitelist=[_FakeLuWithLocks])
270 e9a81214 Michael Hanselmann
271 e9a81214 Michael Hanselmann
  def testAllWithAllocLock(self):
272 e9a81214 Michael Hanselmann
    for level in [locking.LEVEL_NODE, locking.LEVEL_NODE_RES]:
273 e9a81214 Michael Hanselmann
      lu = _FakeLuWithLocks({
274 e9a81214 Michael Hanselmann
        level: locking.ALL_SET,
275 e9a81214 Michael Hanselmann
        locking.LEVEL_NODE_ALLOC: locking.ALL_SET,
276 e9a81214 Michael Hanselmann
        }, {
277 e9a81214 Michael Hanselmann
        level: 0,
278 e9a81214 Michael Hanselmann
        locking.LEVEL_NODE_ALLOC: 0,
279 e9a81214 Michael Hanselmann
        })
280 e9a81214 Michael Hanselmann
      glm = _FakeGlm(True)
281 e9a81214 Michael Hanselmann
282 e9a81214 Michael Hanselmann
      try:
283 e9a81214 Michael Hanselmann
        mcpu._VerifyLocks(lu, glm, _mode_whitelist=[],
284 e9a81214 Michael Hanselmann
                          _nal_whitelist=[_FakeLuWithLocks])
285 e9a81214 Michael Hanselmann
      except AssertionError, err:
286 e9a81214 Michael Hanselmann
        self.assertTrue("whitelisted for not acquiring" in str(err))
287 e9a81214 Michael Hanselmann
      else:
288 e9a81214 Michael Hanselmann
        self.fail("Exception not raised")
289 e9a81214 Michael Hanselmann
290 e9a81214 Michael Hanselmann
      # Once more without the whitelist
291 e9a81214 Michael Hanselmann
      mcpu._VerifyLocks(lu, glm, _mode_whitelist=[], _nal_whitelist=[])
292 e9a81214 Michael Hanselmann
293 e9a81214 Michael Hanselmann
294 407339d0 Michael Hanselmann
if __name__ == "__main__":
295 25231ec5 Michael Hanselmann
  testutils.GanetiTestProgram()