Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.opcodes_unittest.py @ 44fbd23b

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 ff0d18e6 Iustin Pop
      self.assertEqual(cls.OP_ID, opcodes._NameToId(cls.__name__))
49 c32b908e Michael Hanselmann
50 c32b908e Michael Hanselmann
      self.assertRaises(TypeError, cls, unsupported_parameter="some value")
51 c32b908e Michael Hanselmann
52 c32b908e Michael Hanselmann
      args = [
53 c32b908e Michael Hanselmann
        # No variables
54 c32b908e Michael Hanselmann
        {},
55 c32b908e Michael Hanselmann
56 c32b908e Michael Hanselmann
        # Variables supported by all opcodes
57 c32b908e Michael Hanselmann
        {"dry_run": False, "debug_level": 0, },
58 c32b908e Michael Hanselmann
59 c32b908e Michael Hanselmann
        # All variables
60 c32b908e Michael Hanselmann
        dict([(name, False) for name in cls._all_slots()])
61 c32b908e Michael Hanselmann
        ]
62 c32b908e Michael Hanselmann
63 c32b908e Michael Hanselmann
      for i in args:
64 c32b908e Michael Hanselmann
        op = cls(**i)
65 c32b908e Michael Hanselmann
66 c32b908e Michael Hanselmann
        self.assertEqual(op.OP_ID, cls.OP_ID)
67 c32b908e Michael Hanselmann
        self._checkSummary(op)
68 c32b908e Michael Hanselmann
69 c32b908e Michael Hanselmann
        # Try a restore
70 c32b908e Michael Hanselmann
        state = op.__getstate__()
71 c32b908e Michael Hanselmann
        self.assert_(isinstance(state, dict))
72 c32b908e Michael Hanselmann
73 c32b908e Michael Hanselmann
        restored = opcodes.OpCode.LoadOpCode(state)
74 c32b908e Michael Hanselmann
        self.assert_(isinstance(restored, cls))
75 c32b908e Michael Hanselmann
        self._checkSummary(restored)
76 c32b908e Michael Hanselmann
77 65e183af Michael Hanselmann
        for name in ["x_y_z", "hello_world"]:
78 65e183af Michael Hanselmann
          assert name not in cls._all_slots()
79 65e183af Michael Hanselmann
          for value in [None, True, False, [], "Hello World"]:
80 65e183af Michael Hanselmann
            self.assertRaises(AttributeError, setattr, op, name, value)
81 65e183af Michael Hanselmann
82 c32b908e Michael Hanselmann
  def _checkSummary(self, op):
83 c32b908e Michael Hanselmann
    summary = op.Summary()
84 c32b908e Michael Hanselmann
85 c32b908e Michael Hanselmann
    if hasattr(op, "OP_DSC_FIELD"):
86 c32b908e Michael Hanselmann
      self.assert_(("OP_%s" % summary).startswith("%s(" % op.OP_ID))
87 c32b908e Michael Hanselmann
      self.assert_(summary.endswith(")"))
88 c32b908e Michael Hanselmann
    else:
89 c32b908e Michael Hanselmann
      self.assertEqual("OP_%s" % summary, op.OP_ID)
90 c32b908e Michael Hanselmann
91 65ffb373 Michael Hanselmann
  def testSummary(self):
92 ff0d18e6 Iustin Pop
    class OpTest(opcodes.OpCode):
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 ff0d18e6 Iustin Pop
    self.assertEqual(OpTest(data="").Summary(), "TEST()")
99 ff0d18e6 Iustin Pop
    self.assertEqual(OpTest(data="Hello World").Summary(),
100 65ffb373 Michael Hanselmann
                     "TEST(Hello World)")
101 ff0d18e6 Iustin Pop
    self.assertEqual(OpTest(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 ff0d18e6 Iustin Pop
    class OpTest(opcodes.OpCode):
106 65ffb373 Michael Hanselmann
      OP_DSC_FIELD = "data"
107 65ffb373 Michael Hanselmann
      OP_PARAMS = [
108 65ffb373 Michael Hanselmann
        ("data", ht.NoDefault, ht.TList),
109 65ffb373 Michael Hanselmann
        ]
110 65ffb373 Michael Hanselmann
111 ff0d18e6 Iustin Pop
    self.assertEqual(OpTest(data=["a", "b", "c"]).Summary(),
112 65ffb373 Michael Hanselmann
                     "TEST(a,b,c)")
113 ff0d18e6 Iustin Pop
    self.assertEqual(OpTest(data=["a", None, "c"]).Summary(),
114 65ffb373 Michael Hanselmann
                     "TEST(a,None,c)")
115 ff0d18e6 Iustin Pop
    self.assertEqual(OpTest(data=[1, 2, 3, 4]).Summary(), "TEST(1,2,3,4)")
116 65ffb373 Michael Hanselmann
117 dbc96028 Michael Hanselmann
  def testOpId(self):
118 dbc96028 Michael Hanselmann
    self.assertFalse(utils.FindDuplicates(cls.OP_ID
119 dbc96028 Michael Hanselmann
                                          for cls in opcodes._GetOpList()))
120 dbc96028 Michael Hanselmann
    self.assertEqual(len(opcodes._GetOpList()), len(opcodes.OP_MAPPING))
121 dbc96028 Michael Hanselmann
122 65e183af Michael Hanselmann
  def testParams(self):
123 65e183af Michael Hanselmann
    supported_by_all = set(["debug_level", "dry_run", "priority"])
124 65e183af Michael Hanselmann
125 687c10d9 Iustin Pop
    self.assertTrue(opcodes.BaseOpCode not in opcodes.OP_MAPPING.values())
126 687c10d9 Iustin Pop
    self.assertTrue(opcodes.OpCode not in opcodes.OP_MAPPING.values())
127 65e183af Michael Hanselmann
128 687c10d9 Iustin Pop
    for cls in opcodes.OP_MAPPING.values() + [opcodes.OpCode]:
129 65e183af Michael Hanselmann
      all_slots = cls._all_slots()
130 65e183af Michael Hanselmann
131 65e183af Michael Hanselmann
      self.assertEqual(len(set(all_slots) & supported_by_all), 3,
132 65e183af Michael Hanselmann
                       msg=("Opcode %s doesn't support all base"
133 65e183af Michael Hanselmann
                            " parameters (%r)" % (cls.OP_ID, supported_by_all)))
134 65e183af Michael Hanselmann
135 65e183af Michael Hanselmann
      # All opcodes must have OP_PARAMS
136 65e183af Michael Hanselmann
      self.assert_(hasattr(cls, "OP_PARAMS"),
137 65e183af Michael Hanselmann
                   msg="%s doesn't have OP_PARAMS" % cls.OP_ID)
138 65e183af Michael Hanselmann
139 65e183af Michael Hanselmann
      param_names = [name for (name, _, _) in cls.GetAllParams()]
140 65e183af Michael Hanselmann
141 65e183af Michael Hanselmann
      self.assertEqual(all_slots, param_names)
142 65e183af Michael Hanselmann
143 65e183af Michael Hanselmann
      # Without inheritance
144 65e183af Michael Hanselmann
      self.assertEqual(cls.__slots__, [name for (name, _, _) in cls.OP_PARAMS])
145 65e183af Michael Hanselmann
146 65e183af Michael Hanselmann
      # This won't work if parameters are converted to a dictionary
147 65e183af Michael Hanselmann
      duplicates = utils.FindDuplicates(param_names)
148 65e183af Michael Hanselmann
      self.assertFalse(duplicates,
149 65e183af Michael Hanselmann
                       msg=("Found duplicate parameters %r in %s" %
150 65e183af Michael Hanselmann
                            (duplicates, cls.OP_ID)))
151 65e183af Michael Hanselmann
152 65e183af Michael Hanselmann
      # Check parameter definitions
153 65e183af Michael Hanselmann
      for attr_name, aval, test in cls.GetAllParams():
154 65e183af Michael Hanselmann
        self.assert_(attr_name)
155 65e183af Michael Hanselmann
        self.assert_(test is None or test is ht.NoType or callable(test),
156 65e183af Michael Hanselmann
                     msg=("Invalid type check for %s.%s" %
157 65e183af Michael Hanselmann
                          (cls.OP_ID, attr_name)))
158 65e183af Michael Hanselmann
159 65e183af Michael Hanselmann
        if callable(aval):
160 65e183af Michael Hanselmann
          self.assertFalse(callable(aval()),
161 65e183af Michael Hanselmann
                           msg="Default value returned by function is callable")
162 65e183af Michael Hanselmann
163 1cbef6d8 Michael Hanselmann
  def testValidateNoModification(self):
164 ff0d18e6 Iustin Pop
    class OpTest(opcodes.OpCode):
165 1cbef6d8 Michael Hanselmann
      OP_PARAMS = [
166 1cbef6d8 Michael Hanselmann
        ("nodef", ht.NoDefault, ht.TMaybeString),
167 1cbef6d8 Michael Hanselmann
        ("wdef", "default", ht.TMaybeString),
168 1cbef6d8 Michael Hanselmann
        ("number", 0, ht.TInt),
169 1cbef6d8 Michael Hanselmann
        ("notype", None, ht.NoType),
170 1cbef6d8 Michael Hanselmann
        ]
171 1cbef6d8 Michael Hanselmann
172 1cbef6d8 Michael Hanselmann
    # Missing required parameter "nodef"
173 ff0d18e6 Iustin Pop
    op = OpTest()
174 1cbef6d8 Michael Hanselmann
    before = op.__getstate__()
175 1cbef6d8 Michael Hanselmann
    self.assertRaises(errors.OpPrereqError, op.Validate, False)
176 1cbef6d8 Michael Hanselmann
    self.assertFalse(hasattr(op, "nodef"))
177 1cbef6d8 Michael Hanselmann
    self.assertFalse(hasattr(op, "wdef"))
178 1cbef6d8 Michael Hanselmann
    self.assertFalse(hasattr(op, "number"))
179 1cbef6d8 Michael Hanselmann
    self.assertFalse(hasattr(op, "notype"))
180 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.__getstate__(), before, msg="Opcode was modified")
181 1cbef6d8 Michael Hanselmann
182 1cbef6d8 Michael Hanselmann
    # Required parameter "nodef" is provided
183 ff0d18e6 Iustin Pop
    op = OpTest(nodef="foo")
184 1cbef6d8 Michael Hanselmann
    before = op.__getstate__()
185 1cbef6d8 Michael Hanselmann
    op.Validate(False)
186 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.__getstate__(), before, msg="Opcode was modified")
187 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.nodef, "foo")
188 1cbef6d8 Michael Hanselmann
    self.assertFalse(hasattr(op, "wdef"))
189 1cbef6d8 Michael Hanselmann
    self.assertFalse(hasattr(op, "number"))
190 1cbef6d8 Michael Hanselmann
    self.assertFalse(hasattr(op, "notype"))
191 1cbef6d8 Michael Hanselmann
192 1cbef6d8 Michael Hanselmann
    # Missing required parameter "nodef"
193 ff0d18e6 Iustin Pop
    op = OpTest(wdef="hello", number=999)
194 1cbef6d8 Michael Hanselmann
    before = op.__getstate__()
195 1cbef6d8 Michael Hanselmann
    self.assertRaises(errors.OpPrereqError, op.Validate, False)
196 1cbef6d8 Michael Hanselmann
    self.assertFalse(hasattr(op, "nodef"))
197 1cbef6d8 Michael Hanselmann
    self.assertFalse(hasattr(op, "notype"))
198 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.__getstate__(), before, msg="Opcode was modified")
199 1cbef6d8 Michael Hanselmann
200 1cbef6d8 Michael Hanselmann
    # Wrong type for "nodef"
201 ff0d18e6 Iustin Pop
    op = OpTest(nodef=987)
202 1cbef6d8 Michael Hanselmann
    before = op.__getstate__()
203 1cbef6d8 Michael Hanselmann
    self.assertRaises(errors.OpPrereqError, op.Validate, False)
204 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.nodef, 987)
205 1cbef6d8 Michael Hanselmann
    self.assertFalse(hasattr(op, "notype"))
206 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.__getstate__(), before, msg="Opcode was modified")
207 1cbef6d8 Michael Hanselmann
208 1cbef6d8 Michael Hanselmann
    # Testing different types for "notype"
209 ff0d18e6 Iustin Pop
    op = OpTest(nodef="foo", notype=[1, 2, 3])
210 1cbef6d8 Michael Hanselmann
    before = op.__getstate__()
211 1cbef6d8 Michael Hanselmann
    op.Validate(False)
212 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.nodef, "foo")
213 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.notype, [1, 2, 3])
214 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.__getstate__(), before, msg="Opcode was modified")
215 1cbef6d8 Michael Hanselmann
216 ff0d18e6 Iustin Pop
    op = OpTest(nodef="foo", notype="Hello World")
217 1cbef6d8 Michael Hanselmann
    before = op.__getstate__()
218 1cbef6d8 Michael Hanselmann
    op.Validate(False)
219 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.nodef, "foo")
220 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.notype, "Hello World")
221 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.__getstate__(), before, msg="Opcode was modified")
222 1cbef6d8 Michael Hanselmann
223 1cbef6d8 Michael Hanselmann
  def testValidateSetDefaults(self):
224 ff0d18e6 Iustin Pop
    class OpTest(opcodes.OpCode):
225 1cbef6d8 Michael Hanselmann
      OP_PARAMS = [
226 1cbef6d8 Michael Hanselmann
        # Static default value
227 1cbef6d8 Michael Hanselmann
        ("value1", "default", ht.TMaybeString),
228 1cbef6d8 Michael Hanselmann
229 1cbef6d8 Michael Hanselmann
        # Default value callback
230 1cbef6d8 Michael Hanselmann
        ("value2", lambda: "result", ht.TMaybeString),
231 1cbef6d8 Michael Hanselmann
        ]
232 1cbef6d8 Michael Hanselmann
233 ff0d18e6 Iustin Pop
    op = OpTest()
234 1cbef6d8 Michael Hanselmann
    before = op.__getstate__()
235 1cbef6d8 Michael Hanselmann
    op.Validate(True)
236 1cbef6d8 Michael Hanselmann
    self.assertNotEqual(op.__getstate__(), before,
237 1cbef6d8 Michael Hanselmann
                        msg="Opcode was not modified")
238 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.value1, "default")
239 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.value2, "result")
240 1cbef6d8 Michael Hanselmann
    self.assert_(op.dry_run is None)
241 1cbef6d8 Michael Hanselmann
    self.assert_(op.debug_level is None)
242 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.priority, constants.OP_PRIO_DEFAULT)
243 1cbef6d8 Michael Hanselmann
244 ff0d18e6 Iustin Pop
    op = OpTest(value1="hello", value2="world", debug_level=123)
245 1cbef6d8 Michael Hanselmann
    before = op.__getstate__()
246 1cbef6d8 Michael Hanselmann
    op.Validate(True)
247 1cbef6d8 Michael Hanselmann
    self.assertNotEqual(op.__getstate__(), before,
248 1cbef6d8 Michael Hanselmann
                        msg="Opcode was not modified")
249 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.value1, "hello")
250 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.value2, "world")
251 1cbef6d8 Michael Hanselmann
    self.assertEqual(op.debug_level, 123)
252 1cbef6d8 Michael Hanselmann
253 c32b908e Michael Hanselmann
254 c32b908e Michael Hanselmann
if __name__ == "__main__":
255 c32b908e Michael Hanselmann
  testutils.GanetiTestProgram()