Merge branch 'stable-2.6'
[ganeti-local] / test / ganeti.rapi.baserlib_unittest.py
index 570636f..0582cb7 100755 (executable)
 """Script for testing ganeti.rapi.baserlib"""
 
 import unittest
+import itertools
 
 from ganeti import errors
 from ganeti import opcodes
 from ganeti import ht
 from ganeti import http
+from ganeti import compat
 from ganeti.rapi import baserlib
 
 import testutils
 
 
 class TestFillOpcode(unittest.TestCase):
-  class _TestOp(opcodes.OpCode):
-    OP_ID = "RAPI_TEST_OP"
+  class OpTest(opcodes.OpCode):
     OP_PARAMS = [
-      ("test", None, ht.TMaybeString),
+      ("test", None, ht.TMaybeString, None),
       ]
 
   def test(self):
     for static in [None, {}]:
-      op = baserlib.FillOpcode(self._TestOp, {}, static)
-      self.assertTrue(isinstance(op, self._TestOp))
+      op = baserlib.FillOpcode(self.OpTest, {}, static)
+      self.assertTrue(isinstance(op, self.OpTest))
       self.assertFalse(hasattr(op, "test"))
 
   def testStatic(self):
-    op = baserlib.FillOpcode(self._TestOp, {}, {"test": "abc"})
-    self.assertTrue(isinstance(op, self._TestOp))
+    op = baserlib.FillOpcode(self.OpTest, {}, {"test": "abc"})
+    self.assertTrue(isinstance(op, self.OpTest))
     self.assertEqual(op.test, "abc")
 
     # Overwrite static parameter
     self.assertRaises(http.HttpBadRequest, baserlib.FillOpcode,
-                      self._TestOp, {"test": 123}, {"test": "abc"})
+                      self.OpTest, {"test": 123}, {"test": "abc"})
 
   def testType(self):
     self.assertRaises(http.HttpBadRequest, baserlib.FillOpcode,
-                      self._TestOp, {"test": [1, 2, 3]}, {})
+                      self.OpTest, {"test": [1, 2, 3]}, {})
 
   def testStaticType(self):
     self.assertRaises(http.HttpBadRequest, baserlib.FillOpcode,
-                      self._TestOp, {}, {"test": [1, 2, 3]})
+                      self.OpTest, {}, {"test": [1, 2, 3]})
 
   def testUnicode(self):
-    op = baserlib.FillOpcode(self._TestOp, {u"test": "abc"}, {})
-    self.assertTrue(isinstance(op, self._TestOp))
+    op = baserlib.FillOpcode(self.OpTest, {u"test": "abc"}, {})
+    self.assertTrue(isinstance(op, self.OpTest))
     self.assertEqual(op.test, "abc")
 
-    op = baserlib.FillOpcode(self._TestOp, {}, {u"test": "abc"})
-    self.assertTrue(isinstance(op, self._TestOp))
+    op = baserlib.FillOpcode(self.OpTest, {}, {u"test": "abc"})
+    self.assertTrue(isinstance(op, self.OpTest))
     self.assertEqual(op.test, "abc")
 
   def testUnknownParameter(self):
     self.assertRaises(http.HttpBadRequest, baserlib.FillOpcode,
-                      self._TestOp, {"othervalue": 123}, None)
+                      self.OpTest, {"othervalue": 123}, None)
 
   def testInvalidBody(self):
     self.assertRaises(http.HttpBadRequest, baserlib.FillOpcode,
-                      self._TestOp, "", None)
+                      self.OpTest, "", None)
     self.assertRaises(http.HttpBadRequest, baserlib.FillOpcode,
-                      self._TestOp, range(10), None)
+                      self.OpTest, range(10), None)
+
+  def testRenameBothSpecified(self):
+    self.assertRaises(http.HttpBadRequest, baserlib.FillOpcode,
+                      self.OpTest, { "old": 123, "new": 999, }, None,
+                      rename={ "old": "new", })
+
+  def testRename(self):
+    value = "Hello World"
+    op = baserlib.FillOpcode(self.OpTest, { "data": value, }, None,
+                             rename={ "data": "test", })
+    self.assertEqual(op.test, value)
+
+  def testRenameStatic(self):
+    self.assertRaises(http.HttpBadRequest, baserlib.FillOpcode,
+                      self.OpTest, { "data": 0, }, { "test": None, },
+                      rename={ "data": "test", })
+
+
+class TestOpcodeResource(unittest.TestCase):
+  @staticmethod
+  def _MakeClass(method, attrs):
+    return type("Test%s" % method, (baserlib.OpcodeResource, ), attrs)
+
+  @staticmethod
+  def _GetMethodAttributes(method):
+    attrs = ["%s_OPCODE" % method, "%s_RENAME" % method,
+             "Get%sOpInput" % method.capitalize()]
+    assert attrs == dict((opattrs[0], list(opattrs[1:]))
+                         for opattrs in baserlib._OPCODE_ATTRS)[method]
+    return attrs
+
+  def test(self):
+    for method in baserlib._SUPPORTED_METHODS:
+      # Empty handler
+      obj = self._MakeClass(method, {})(None, None, None)
+      for attr in itertools.chain(*baserlib._OPCODE_ATTRS):
+        self.assertFalse(hasattr(obj, attr))
+
+      # Direct handler function
+      obj = self._MakeClass(method, {
+        method: lambda _: None,
+        })(None, None, None)
+      self.assertFalse(compat.all(hasattr(obj, attr)
+                                  for i in baserlib._SUPPORTED_METHODS
+                                  for attr in self._GetMethodAttributes(i)))
+
+      # Let metaclass define handler function
+      for opcls in [None, object()]:
+        obj = self._MakeClass(method, {
+          "%s_OPCODE" % method: opcls,
+          })(None, None, None)
+        self.assertTrue(callable(getattr(obj, method)))
+        self.assertEqual(getattr(obj, "%s_OPCODE" % method), opcls)
+        self.assertFalse(hasattr(obj, "%s_RENAME" % method))
+        self.assertFalse(compat.any(hasattr(obj, attr)
+                                    for i in baserlib._SUPPORTED_METHODS
+                                      if i != method
+                                    for attr in self._GetMethodAttributes(i)))
+
+  def testIllegalRename(self):
+    class _TClass(baserlib.OpcodeResource):
+      PUT_RENAME = None
+      def PUT(self): pass
+
+    self.assertRaises(AssertionError, _TClass, None, None, None)
+
+  def testEmpty(self):
+    class _Empty(baserlib.OpcodeResource):
+      pass
+
+    obj = _Empty(None, None, None)
+
+    for attr in itertools.chain(*baserlib._OPCODE_ATTRS):
+      self.assertFalse(hasattr(obj, attr))
 
 
 if __name__ == "__main__":