Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.opcodes_unittest.py @ 8572f1fe

History | View | Annotate | Download (8.7 kB)

1 c32b908e Michael Hanselmann
#!/usr/bin/python
2 c32b908e Michael Hanselmann
#
3 c32b908e Michael Hanselmann
4 687c10d9 Iustin Pop
# Copyright (C) 2010, 2011 Google Inc.
5 c32b908e Michael Hanselmann
#
6 c32b908e Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 c32b908e Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 c32b908e Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 c32b908e Michael Hanselmann
# (at your option) any later version.
10 c32b908e Michael Hanselmann
#
11 c32b908e Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 c32b908e Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 c32b908e Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 c32b908e Michael Hanselmann
# General Public License for more details.
15 c32b908e Michael Hanselmann
#
16 c32b908e Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 c32b908e Michael Hanselmann
# along with this program; if not, write to the Free Software
18 c32b908e Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 c32b908e Michael Hanselmann
# 02110-1301, USA.
20 c32b908e Michael Hanselmann
21 c32b908e Michael Hanselmann
22 c32b908e Michael Hanselmann
"""Script for testing ganeti.backend"""
23 c32b908e Michael Hanselmann
24 c32b908e Michael Hanselmann
import os
25 c32b908e Michael Hanselmann
import sys
26 c32b908e Michael Hanselmann
import unittest
27 c32b908e Michael Hanselmann
28 c32b908e Michael Hanselmann
from ganeti import utils
29 c32b908e Michael Hanselmann
from ganeti import opcodes
30 65e183af Michael Hanselmann
from ganeti import ht
31 1cbef6d8 Michael Hanselmann
from ganeti import constants
32 1cbef6d8 Michael Hanselmann
from ganeti import errors
33 c32b908e Michael Hanselmann
34 c32b908e Michael Hanselmann
import testutils
35 c32b908e Michael Hanselmann
36 c32b908e Michael Hanselmann
37 c32b908e Michael Hanselmann
class TestOpcodes(unittest.TestCase):
38 c32b908e Michael Hanselmann
  def test(self):
39 c32b908e Michael Hanselmann
    self.assertRaises(ValueError, opcodes.OpCode.LoadOpCode, None)
40 c32b908e Michael Hanselmann
    self.assertRaises(ValueError, opcodes.OpCode.LoadOpCode, "")
41 c32b908e Michael Hanselmann
    self.assertRaises(ValueError, opcodes.OpCode.LoadOpCode, {})
42 c32b908e Michael Hanselmann
    self.assertRaises(ValueError, opcodes.OpCode.LoadOpCode, {"OP_ID": ""})
43 c32b908e Michael Hanselmann
44 c32b908e Michael Hanselmann
    for cls in opcodes.OP_MAPPING.values():
45 c32b908e Michael Hanselmann
      self.assert_(cls.OP_ID.startswith("OP_"))
46 dbc96028 Michael Hanselmann
      self.assert_(len(cls.OP_ID) > 3)
47 c32b908e Michael Hanselmann
      self.assertEqual(cls.OP_ID, cls.OP_ID.upper())
48 c32b908e Michael Hanselmann
49 c32b908e Michael Hanselmann
      self.assertRaises(TypeError, cls, unsupported_parameter="some value")
50 c32b908e Michael Hanselmann
51 c32b908e Michael Hanselmann
      args = [
52 c32b908e Michael Hanselmann
        # No variables
53 c32b908e Michael Hanselmann
        {},
54 c32b908e Michael Hanselmann
55 c32b908e Michael Hanselmann
        # Variables supported by all opcodes
56 c32b908e Michael Hanselmann
        {"dry_run": False, "debug_level": 0, },
57 c32b908e Michael Hanselmann
58 c32b908e Michael Hanselmann
        # All variables
59 c32b908e Michael Hanselmann
        dict([(name, False) for name in cls._all_slots()])
60 c32b908e Michael Hanselmann
        ]
61 c32b908e Michael Hanselmann
62 c32b908e Michael Hanselmann
      for i in args:
63 c32b908e Michael Hanselmann
        op = cls(**i)
64 c32b908e Michael Hanselmann
65 c32b908e Michael Hanselmann
        self.assertEqual(op.OP_ID, cls.OP_ID)
66 c32b908e Michael Hanselmann
        self._checkSummary(op)
67 c32b908e Michael Hanselmann
68 c32b908e Michael Hanselmann
        # Try a restore
69 c32b908e Michael Hanselmann
        state = op.__getstate__()
70 c32b908e Michael Hanselmann
        self.assert_(isinstance(state, dict))
71 c32b908e Michael Hanselmann
72 c32b908e Michael Hanselmann
        restored = opcodes.OpCode.LoadOpCode(state)
73 c32b908e Michael Hanselmann
        self.assert_(isinstance(restored, cls))
74 c32b908e Michael Hanselmann
        self._checkSummary(restored)
75 c32b908e Michael Hanselmann
76 65e183af Michael Hanselmann
        for name in ["x_y_z", "hello_world"]:
77 65e183af Michael Hanselmann
          assert name not in cls._all_slots()
78 65e183af Michael Hanselmann
          for value in [None, True, False, [], "Hello World"]:
79 65e183af Michael Hanselmann
            self.assertRaises(AttributeError, setattr, op, name, value)
80 65e183af Michael Hanselmann
81 c32b908e Michael Hanselmann
  def _checkSummary(self, op):
82 c32b908e Michael Hanselmann
    summary = op.Summary()
83 c32b908e Michael Hanselmann
84 c32b908e Michael Hanselmann
    if hasattr(op, "OP_DSC_FIELD"):
85 c32b908e Michael Hanselmann
      self.assert_(("OP_%s" % summary).startswith("%s(" % op.OP_ID))
86 c32b908e Michael Hanselmann
      self.assert_(summary.endswith(")"))
87 c32b908e Michael Hanselmann
    else:
88 c32b908e Michael Hanselmann
      self.assertEqual("OP_%s" % summary, op.OP_ID)
89 c32b908e Michael Hanselmann
90 65ffb373 Michael Hanselmann
  def testSummary(self):
91 65ffb373 Michael Hanselmann
    class _TestOp(opcodes.OpCode):
92 65ffb373 Michael Hanselmann
      OP_ID = "OP_TEST"
93 65ffb373 Michael Hanselmann
      OP_DSC_FIELD = "data"
94 65ffb373 Michael Hanselmann
      OP_PARAMS = [
95 65ffb373 Michael Hanselmann
        ("data", ht.NoDefault, ht.TString),
96 65ffb373 Michael Hanselmann
        ]
97 65ffb373 Michael Hanselmann
98 65ffb373 Michael Hanselmann
    self.assertEqual(_TestOp(data="").Summary(), "TEST()")
99 65ffb373 Michael Hanselmann
    self.assertEqual(_TestOp(data="Hello World").Summary(),
100 65ffb373 Michael Hanselmann
                     "TEST(Hello World)")
101 65ffb373 Michael Hanselmann
    self.assertEqual(_TestOp(data="node1.example.com").Summary(),
102 65ffb373 Michael Hanselmann
                     "TEST(node1.example.com)")
103 65ffb373 Michael Hanselmann
104 65ffb373 Michael Hanselmann
  def testListSummary(self):
105 65ffb373 Michael Hanselmann
    class _TestOp(opcodes.OpCode):
106 65ffb373 Michael Hanselmann
      OP_ID = "OP_TEST"
107 65ffb373 Michael Hanselmann
      OP_DSC_FIELD = "data"
108 65ffb373 Michael Hanselmann
      OP_PARAMS = [
109 65ffb373 Michael Hanselmann
        ("data", ht.NoDefault, ht.TList),
110 65ffb373 Michael Hanselmann
        ]
111 65ffb373 Michael Hanselmann
112 65ffb373 Michael Hanselmann
    self.assertEqual(_TestOp(data=["a", "b", "c"]).Summary(),
113 65ffb373 Michael Hanselmann
                     "TEST(a,b,c)")
114 65ffb373 Michael Hanselmann
    self.assertEqual(_TestOp(data=["a", None, "c"]).Summary(),
115 65ffb373 Michael Hanselmann
                     "TEST(a,None,c)")
116 65ffb373 Michael Hanselmann
    self.assertEqual(_TestOp(data=[1, 2, 3, 4]).Summary(), "TEST(1,2,3,4)")
117 65ffb373 Michael Hanselmann
118 dbc96028 Michael Hanselmann
  def testOpId(self):
119 dbc96028 Michael Hanselmann
    self.assertFalse(utils.FindDuplicates(cls.OP_ID
120 dbc96028 Michael Hanselmann
                                          for cls in opcodes._GetOpList()))
121 dbc96028 Michael Hanselmann
    self.assertEqual(len(opcodes._GetOpList()), len(opcodes.OP_MAPPING))
122 dbc96028 Michael Hanselmann
123 65e183af Michael Hanselmann
  def testParams(self):
124 65e183af Michael Hanselmann
    supported_by_all = set(["debug_level", "dry_run", "priority"])
125 65e183af Michael Hanselmann
126 687c10d9 Iustin Pop
    self.assertTrue(opcodes.BaseOpCode not in opcodes.OP_MAPPING.values())
127 687c10d9 Iustin Pop
    self.assertTrue(opcodes.OpCode not in opcodes.OP_MAPPING.values())
128 65e183af Michael Hanselmann
129 687c10d9 Iustin Pop
    for cls in opcodes.OP_MAPPING.values() + [opcodes.OpCode]:
130 65e183af Michael Hanselmann
      all_slots = cls._all_slots()
131 65e183af Michael Hanselmann
132 65e183af Michael Hanselmann
      self.assertEqual(len(set(all_slots) & supported_by_all), 3,
133 65e183af Michael Hanselmann
                       msg=("Opcode %s doesn't support all base"
134 65e183af Michael Hanselmann
                            " parameters (%r)" % (cls.OP_ID, supported_by_all)))
135 65e183af Michael Hanselmann
136 65e183af Michael Hanselmann
      # All opcodes must have OP_PARAMS
137 65e183af Michael Hanselmann
      self.assert_(hasattr(cls, "OP_PARAMS"),
138 65e183af Michael Hanselmann
                   msg="%s doesn't have OP_PARAMS" % cls.OP_ID)
139 65e183af Michael Hanselmann
140 65e183af Michael Hanselmann
      param_names = [name for (name, _, _) in cls.GetAllParams()]
141 65e183af Michael Hanselmann
142 65e183af Michael Hanselmann
      self.assertEqual(all_slots, param_names)
143 65e183af Michael Hanselmann
144 65e183af Michael Hanselmann
      # Without inheritance
145 65e183af Michael Hanselmann
      self.assertEqual(cls.__slots__, [name for (name, _, _) in cls.OP_PARAMS])
146 65e183af Michael Hanselmann
147 65e183af Michael Hanselmann
      # This won't work if parameters are converted to a dictionary
148 65e183af Michael Hanselmann
      duplicates = utils.FindDuplicates(param_names)
149 65e183af Michael Hanselmann
      self.assertFalse(duplicates,
150 65e183af Michael Hanselmann
                       msg=("Found duplicate parameters %r in %s" %
151 65e183af Michael Hanselmann
                            (duplicates, cls.OP_ID)))
152 65e183af Michael Hanselmann
153 65e183af Michael Hanselmann
      # Check parameter definitions
154 65e183af Michael Hanselmann
      for attr_name, aval, test in cls.GetAllParams():
155 65e183af Michael Hanselmann
        self.assert_(attr_name)
156 65e183af Michael Hanselmann
        self.assert_(test is None or test is ht.NoType or callable(test),
157 65e183af Michael Hanselmann
                     msg=("Invalid type check for %s.%s" %
158 65e183af Michael Hanselmann
                          (cls.OP_ID, attr_name)))
159 65e183af Michael Hanselmann
160 65e183af Michael Hanselmann
        if callable(aval):
161 65e183af Michael Hanselmann
          self.assertFalse(callable(aval()),
162 65e183af Michael Hanselmann
                           msg="Default value returned by function is callable")
163 65e183af Michael Hanselmann
164 1cbef6d8 Michael Hanselmann
  def testValidateNoModification(self):
165 1cbef6d8 Michael Hanselmann
    class _TestOp(opcodes.OpCode):
166 1cbef6d8 Michael Hanselmann
      OP_ID = "OP_TEST"
167 1cbef6d8 Michael Hanselmann
      OP_PARAMS = [
168 1cbef6d8 Michael Hanselmann
        ("nodef", ht.NoDefault, ht.TMaybeString),
169 1cbef6d8 Michael Hanselmann
        ("wdef", "default", ht.TMaybeString),
170 1cbef6d8 Michael Hanselmann
        ("number", 0, ht.TInt),
171 1cbef6d8 Michael Hanselmann
        ("notype", None, ht.NoType),
172 1cbef6d8 Michael Hanselmann
        ]
173 1cbef6d8 Michael Hanselmann
174 1cbef6d8 Michael Hanselmann
    # Missing required parameter "nodef"
175 1cbef6d8 Michael Hanselmann
    op = _TestOp()
176 1cbef6d8 Michael Hanselmann
    before = op.__getstate__()
177 1cbef6d8 Michael Hanselmann
    self.assertRaises(errors.OpPrereqError, op.Validate, False)
178 1cbef6d8 Michael Hanselmann
    self.assertFalse(hasattr(op, "nodef"))
179 1cbef6d8 Michael Hanselmann
    self.assertFalse(hasattr(op, "wdef"))
180 1cbef6d8 Michael Hanselmann
    self.assertFalse(hasattr(op, "number"))
181 1cbef6d8 Michael Hanselmann
    self.assertFalse(hasattr(op, "notype"))
182 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.__getstate__(), before, msg="Opcode was modified")
183 1cbef6d8 Michael Hanselmann
184 1cbef6d8 Michael Hanselmann
    # Required parameter "nodef" is provided
185 1cbef6d8 Michael Hanselmann
    op = _TestOp(nodef="foo")
186 1cbef6d8 Michael Hanselmann
    before = op.__getstate__()
187 1cbef6d8 Michael Hanselmann
    op.Validate(False)
188 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.__getstate__(), before, msg="Opcode was modified")
189 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.nodef, "foo")
190 1cbef6d8 Michael Hanselmann
    self.assertFalse(hasattr(op, "wdef"))
191 1cbef6d8 Michael Hanselmann
    self.assertFalse(hasattr(op, "number"))
192 1cbef6d8 Michael Hanselmann
    self.assertFalse(hasattr(op, "notype"))
193 1cbef6d8 Michael Hanselmann
194 1cbef6d8 Michael Hanselmann
    # Missing required parameter "nodef"
195 1cbef6d8 Michael Hanselmann
    op = _TestOp(wdef="hello", number=999)
196 1cbef6d8 Michael Hanselmann
    before = op.__getstate__()
197 1cbef6d8 Michael Hanselmann
    self.assertRaises(errors.OpPrereqError, op.Validate, False)
198 1cbef6d8 Michael Hanselmann
    self.assertFalse(hasattr(op, "nodef"))
199 1cbef6d8 Michael Hanselmann
    self.assertFalse(hasattr(op, "notype"))
200 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.__getstate__(), before, msg="Opcode was modified")
201 1cbef6d8 Michael Hanselmann
202 1cbef6d8 Michael Hanselmann
    # Wrong type for "nodef"
203 1cbef6d8 Michael Hanselmann
    op = _TestOp(nodef=987)
204 1cbef6d8 Michael Hanselmann
    before = op.__getstate__()
205 1cbef6d8 Michael Hanselmann
    self.assertRaises(errors.OpPrereqError, op.Validate, False)
206 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.nodef, 987)
207 1cbef6d8 Michael Hanselmann
    self.assertFalse(hasattr(op, "notype"))
208 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.__getstate__(), before, msg="Opcode was modified")
209 1cbef6d8 Michael Hanselmann
210 1cbef6d8 Michael Hanselmann
    # Testing different types for "notype"
211 1cbef6d8 Michael Hanselmann
    op = _TestOp(nodef="foo", notype=[1, 2, 3])
212 1cbef6d8 Michael Hanselmann
    before = op.__getstate__()
213 1cbef6d8 Michael Hanselmann
    op.Validate(False)
214 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.nodef, "foo")
215 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.notype, [1, 2, 3])
216 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.__getstate__(), before, msg="Opcode was modified")
217 1cbef6d8 Michael Hanselmann
218 1cbef6d8 Michael Hanselmann
    op = _TestOp(nodef="foo", notype="Hello World")
219 1cbef6d8 Michael Hanselmann
    before = op.__getstate__()
220 1cbef6d8 Michael Hanselmann
    op.Validate(False)
221 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.nodef, "foo")
222 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.notype, "Hello World")
223 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.__getstate__(), before, msg="Opcode was modified")
224 1cbef6d8 Michael Hanselmann
225 1cbef6d8 Michael Hanselmann
  def testValidateSetDefaults(self):
226 1cbef6d8 Michael Hanselmann
    class _TestOp(opcodes.OpCode):
227 1cbef6d8 Michael Hanselmann
      OP_ID = "OP_TEST"
228 1cbef6d8 Michael Hanselmann
      OP_PARAMS = [
229 1cbef6d8 Michael Hanselmann
        # Static default value
230 1cbef6d8 Michael Hanselmann
        ("value1", "default", ht.TMaybeString),
231 1cbef6d8 Michael Hanselmann
232 1cbef6d8 Michael Hanselmann
        # Default value callback
233 1cbef6d8 Michael Hanselmann
        ("value2", lambda: "result", ht.TMaybeString),
234 1cbef6d8 Michael Hanselmann
        ]
235 1cbef6d8 Michael Hanselmann
236 1cbef6d8 Michael Hanselmann
    op = _TestOp()
237 1cbef6d8 Michael Hanselmann
    before = op.__getstate__()
238 1cbef6d8 Michael Hanselmann
    op.Validate(True)
239 1cbef6d8 Michael Hanselmann
    self.assertNotEqual(op.__getstate__(), before,
240 1cbef6d8 Michael Hanselmann
                        msg="Opcode was not modified")
241 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.value1, "default")
242 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.value2, "result")
243 1cbef6d8 Michael Hanselmann
    self.assert_(op.dry_run is None)
244 1cbef6d8 Michael Hanselmann
    self.assert_(op.debug_level is None)
245 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.priority, constants.OP_PRIO_DEFAULT)
246 1cbef6d8 Michael Hanselmann
247 1cbef6d8 Michael Hanselmann
    op = _TestOp(value1="hello", value2="world", debug_level=123)
248 1cbef6d8 Michael Hanselmann
    before = op.__getstate__()
249 1cbef6d8 Michael Hanselmann
    op.Validate(True)
250 1cbef6d8 Michael Hanselmann
    self.assertNotEqual(op.__getstate__(), before,
251 1cbef6d8 Michael Hanselmann
                        msg="Opcode was not modified")
252 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.value1, "hello")
253 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.value2, "world")
254 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.debug_level, 123)
255 1cbef6d8 Michael Hanselmann
256 c32b908e Michael Hanselmann
257 c32b908e Michael Hanselmann
if __name__ == "__main__":
258 c32b908e Michael Hanselmann
  testutils.GanetiTestProgram()