commit e969a81f7e08772f04ab2d7a9521774b4d5dd62d
Author: Thomas Thrainer <thomasth@google.com>
Date:   Mon Jul 22 17:14:13 2013 +0200

    Add unit test for LUTestAllocator
    
    Additionally to adding unit tests for LUTestAllocator, the test
    framework was adapted for its requirements.
    
    Signed-off-by: Thomas Thrainer <thomasth@google.com>
    Reviewed-by: Michele Tartara <mtartara@google.com>

diff --git a/test/py/cmdlib/test_unittest.py b/test/py/cmdlib/test_unittest.py
index 3658e5e..50de33b 100644
--- a/test/py/cmdlib/test_unittest.py
+++ b/test/py/cmdlib/test_unittest.py
@@ -21,9 +21,9 @@
 
 """Tests for LUTest*"""
 
+import mock
 
 from ganeti import constants
-from ganeti import errors
 from ganeti import opcodes
 
 from testsupport import *
@@ -47,7 +47,7 @@ class TestLUTestDelay(CmdlibTestCase):
   def testInvalidDuration(self):
     op = opcodes.OpTestDelay(duration=-1)
 
-    self.assertRaises(errors.OpExecError, self.ExecOpCode, op)
+    self.ExecOpCodeExpectOpExecError(op)
 
   def testOnNodeUuid(self):
     node_uuids = [self.cfg.GetMasterNode()]
@@ -87,7 +87,7 @@ class TestLUTestDelay(CmdlibTestCase):
         .AddFailedNode(self.cfg.GetMasterNode()) \
         .Build()
 
-    self.assertRaises(errors.OpExecError, self.ExecOpCode, op)
+    self.ExecOpCodeExpectOpExecError(op)
 
   def testMultipleNodes(self):
     node1 = self.cfg.AddNewNode()
@@ -107,5 +107,144 @@ class TestLUTestDelay(CmdlibTestCase):
                                                      DELAY_DURATION)
 
 
+class TestLUTestAllocator(CmdlibTestCase):
+  def setUp(self):
+    super(TestLUTestAllocator, self).setUp()
+
+    self.base_op = opcodes.OpTestAllocator(
+                      name="new-instance.example.com",
+                      nics=[],
+                      disks=[],
+                      disk_template=constants.DT_DISKLESS,
+                      direction=constants.IALLOCATOR_DIR_OUT,
+                      iallocator="test")
+
+    self.valid_alloc_op = \
+      self.CopyOpCode(self.base_op,
+                      mode=constants.IALLOCATOR_MODE_ALLOC,
+                      memory=0,
+                      disk_template=constants.DT_DISKLESS,
+                      os="mock_os",
+                      vcpus=1)
+    self.valid_multi_alloc_op = \
+      self.CopyOpCode(self.base_op,
+                      mode=constants.IALLOCATOR_MODE_MULTI_ALLOC,
+                      instances=["new-instance.example.com"],
+                      memory=0,
+                      disk_template=constants.DT_DISKLESS,
+                      os="mock_os",
+                      vcpus=1)
+    self.valid_reloc_op = \
+      self.CopyOpCode(self.base_op,
+                      mode=constants.IALLOCATOR_MODE_RELOC)
+    self.valid_chg_group_op = \
+      self.CopyOpCode(self.base_op,
+                      mode=constants.IALLOCATOR_MODE_CHG_GROUP,
+                      instances=["new-instance.example.com"],
+                      target_groups=["default"])
+    self.valid_node_evac_op = \
+      self.CopyOpCode(self.base_op,
+                      mode=constants.IALLOCATOR_MODE_NODE_EVAC,
+                      instances=["new-instance.example.com"],
+                      evac_mode=constants.IALLOCATOR_NEVAC_PRI)
+
+    self.iallocator_cls.return_value.in_text = "mock in text"
+    self.iallocator_cls.return_value.out_text = "mock out text"
+
+  def testMissingDirection(self):
+    op = self.CopyOpCode(self.base_op,
+                         direction=self.REMOVE)
+
+    self.ExecOpCodeExpectOpPrereqError(
+      op, "'OP_TEST_ALLOCATOR.direction' fails validation")
+
+  def testAllocWrongDisks(self):
+    op = self.CopyOpCode(self.valid_alloc_op,
+                         disks=[0, "test"])
+
+    self.ExecOpCodeExpectOpPrereqError(op, "Invalid contents")
+
+  def testAllocWithExistingInstance(self):
+    inst = self.cfg.AddNewInstance()
+    op = self.CopyOpCode(self.valid_alloc_op, name=inst.name)
+
+    self.ExecOpCodeExpectOpPrereqError(op, "already in the cluster")
+
+  def testAllocMultiAllocMissingIAllocator(self):
+    for mode in [constants.IALLOCATOR_MODE_ALLOC,
+                 constants.IALLOCATOR_MODE_MULTI_ALLOC]:
+      op = self.CopyOpCode(self.base_op,
+                           mode=mode,
+                           iallocator=None)
+
+      self.ResetMocks()
+      self.ExecOpCodeExpectOpPrereqError(op, "Missing allocator name")
+
+  def testChgGroupNodeEvacMissingInstances(self):
+    for mode in [constants.IALLOCATOR_MODE_CHG_GROUP,
+                 constants.IALLOCATOR_MODE_NODE_EVAC]:
+      op = self.CopyOpCode(self.base_op,
+                           mode=mode)
+
+      self.ResetMocks()
+      self.ExecOpCodeExpectOpPrereqError(op, "Missing instances")
+
+  def testAlloc(self):
+    op = self.valid_alloc_op
+
+    self.ExecOpCode(op)
+
+    assert self.iallocator_cls.call_count == 1
+    self.iallocator_cls.return_value.Run \
+      .assert_called_once_with("test", validate=False)
+
+  def testReloc(self):
+    op = self.valid_reloc_op
+    self.cfg.AddNewInstance(name=op.name)
+
+    self.ExecOpCode(op)
+
+    assert self.iallocator_cls.call_count == 1
+    self.iallocator_cls.return_value.Run \
+      .assert_called_once_with("test", validate=False)
+
+  def testChgGroup(self):
+    op = self.valid_chg_group_op
+    for inst_name in op.instances:
+      self.cfg.AddNewInstance(name=inst_name)
+
+    self.ExecOpCode(op)
+
+    assert self.iallocator_cls.call_count == 1
+    self.iallocator_cls.return_value.Run \
+      .assert_called_once_with("test", validate=False)
+
+  def testNodeEvac(self):
+    op = self.valid_node_evac_op
+    for inst_name in op.instances:
+      self.cfg.AddNewInstance(name=inst_name)
+
+    self.ExecOpCode(op)
+
+    assert self.iallocator_cls.call_count == 1
+    self.iallocator_cls.return_value.Run \
+      .assert_called_once_with("test", validate=False)
+
+  def testMultiAlloc(self):
+    op = self.valid_multi_alloc_op
+
+    self.ExecOpCode(op)
+
+    assert self.iallocator_cls.call_count == 1
+    self.iallocator_cls.return_value.Run \
+      .assert_called_once_with("test", validate=False)
+
+  def testAllocDirectionIn(self):
+    op = self.CopyOpCode(self.valid_alloc_op,
+                         direction=constants.IALLOCATOR_DIR_IN)
+
+    self.ExecOpCode(op)
+
+
 if __name__ == "__main__":
   testutils.GanetiTestProgram()
