Remove restrictive hook node list check
[ganeti-local] / test / ganeti.config_unittest.py
index 9287fc3..a21bfa6 100755 (executable)
@@ -1,7 +1,7 @@
 #!/usr/bin/python
 #
 
-# Copyright (C) 2006, 2007 Google Inc.
+# Copyright (C) 2006, 2007, 2010 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -35,6 +35,16 @@ from ganeti import constants
 from ganeti import errors
 from ganeti import objects
 from ganeti import utils
+from ganeti import netutils
+
+from ganeti.config import TemporaryReservationManager
+
+import testutils
+import mocks
+
+
+def _StubGetEntResolver():
+  return mocks.FakeGetentResolver()
 
 
 class TestConfigRunner(unittest.TestCase):
@@ -52,13 +62,14 @@ class TestConfigRunner(unittest.TestCase):
 
   def _get_object(self):
     """Returns a instance of ConfigWriter"""
-    cfg = config.ConfigWriter(cfg_file=self.cfg_file, offline=True)
+    cfg = config.ConfigWriter(cfg_file=self.cfg_file, offline=True,
+                              _getents=_StubGetEntResolver)
     return cfg
 
   def _init_cluster(self, cfg):
     """Initializes the cfg object"""
-    me = utils.HostInfo()
-    ip = constants.LOCALHOST_IP_ADDRESS
+    me = netutils.Hostname()
+    ip = constants.IP4_ADDRESS_LOCALHOST
 
     cluster_config = objects.Cluster(
       serial_no=1,
@@ -66,14 +77,17 @@ class TestConfigRunner(unittest.TestCase):
       highest_used_port=(constants.FIRST_DRBD_PORT - 1),
       mac_prefix="aa:00:00",
       volume_group_name="xenvg",
+      drbd_usermode_helper="/bin/true",
       nicparams={constants.PP_DEFAULT: constants.NICC_DEFAULTS},
+      ndparams=constants.NDC_DEFAULTS,
       tcpudp_port_pool=set(),
-      default_hypervisor=constants.HT_FAKE,
+      enabled_hypervisors=[constants.HT_FAKE],
       master_node=me.name,
       master_ip="127.0.0.1",
       master_netdev=constants.DEFAULT_BRIDGE,
       cluster_name="cluster.local",
       file_storage_dir="/tmp",
+      uid_pool=[],
       )
 
     master_node_config = objects.Node(name=me.name,
@@ -108,15 +122,15 @@ class TestConfigRunner(unittest.TestCase):
     # construct a fake cluster object
     fake_cl = objects.Cluster()
     # fail if we didn't read the config
-    self.failUnlessRaises(errors.ConfigurationError, cfg.Update, fake_cl)
+    self.failUnlessRaises(errors.ConfigurationError, cfg.Update, fake_cl, None)
 
     cl = cfg.GetClusterInfo()
     # first pass, must not fail
-    cfg.Update(cl)
+    cfg.Update(cl, None)
     # second pass, also must not fail (after the config has been written)
-    cfg.Update(cl)
+    cfg.Update(cl, None)
     # but the fake_cl update should still fail
-    self.failUnlessRaises(errors.ConfigurationError, cfg.Update, fake_cl)
+    self.failUnlessRaises(errors.ConfigurationError, cfg.Update, fake_cl, None)
 
   def testUpdateNode(self):
     """Test updates on one node object"""
@@ -124,15 +138,17 @@ class TestConfigRunner(unittest.TestCase):
     # construct a fake node
     fake_node = objects.Node()
     # fail if we didn't read the config
-    self.failUnlessRaises(errors.ConfigurationError, cfg.Update, fake_node)
+    self.failUnlessRaises(errors.ConfigurationError, cfg.Update, fake_node,
+                          None)
 
     node = cfg.GetNodeInfo(cfg.GetNodeList()[0])
     # first pass, must not fail
-    cfg.Update(node)
+    cfg.Update(node, None)
     # second pass, also must not fail (after the config has been written)
-    cfg.Update(node)
+    cfg.Update(node, None)
     # but the fake_node update should still fail
-    self.failUnlessRaises(errors.ConfigurationError, cfg.Update, fake_node)
+    self.failUnlessRaises(errors.ConfigurationError, cfg.Update, fake_node,
+                          None)
 
   def testUpdateInstance(self):
     """Test updates on one instance object"""
@@ -141,16 +157,18 @@ class TestConfigRunner(unittest.TestCase):
     inst = self._create_instance()
     fake_instance = objects.Instance()
     # fail if we didn't read the config
-    self.failUnlessRaises(errors.ConfigurationError, cfg.Update, fake_instance)
+    self.failUnlessRaises(errors.ConfigurationError, cfg.Update, fake_instance,
+                          None)
 
-    cfg.AddInstance(inst)
+    cfg.AddInstance(inst, "my-job")
     instance = cfg.GetInstanceInfo(cfg.GetInstanceList()[0])
     # first pass, must not fail
-    cfg.Update(instance)
+    cfg.Update(instance, None)
     # second pass, also must not fail (after the config has been written)
-    cfg.Update(instance)
+    cfg.Update(instance, None)
     # but the fake_instance update should still fail
-    self.failUnlessRaises(errors.ConfigurationError, cfg.Update, fake_instance)
+    self.failUnlessRaises(errors.ConfigurationError, cfg.Update, fake_instance,
+                          None)
 
   def testNICParameterSyntaxCheck(self):
     """Test the NIC's CheckParameterSyntax function"""
@@ -170,6 +188,75 @@ class TestConfigRunner(unittest.TestCase):
     self.assertRaises(errors.ConfigurationError,
                       CheckSyntax, {mode: m_bridged, link: ''})
 
+  def testGetNdParamsDefault(self):
+    cfg = self._get_object()
+    node = cfg.GetNodeInfo(cfg.GetNodeList()[0])
+    self.assertEqual(cfg.GetNdParams(node), constants.NDC_DEFAULTS)
+
+  def testGetNdParamsModifiedNode(self):
+    my_ndparams = {
+        constants.ND_OOB_PROGRAM: "/bin/node-oob",
+        }
+
+    cfg = self._get_object()
+    node = cfg.GetNodeInfo(cfg.GetNodeList()[0])
+    node.ndparams = my_ndparams
+    cfg.Update(node, None)
+    self.assertEqual(cfg.GetNdParams(node), my_ndparams)
+
+  def testAddGroupFillsFieldsIfMissing(self):
+    cfg = self._get_object()
+    group = objects.NodeGroup(name="test", members=[])
+    cfg.AddNodeGroup(group, "my-job")
+    self.assert_(utils.UUID_RE.match(group.uuid))
+    self.assertEqual(constants.ALLOC_POLICY_PREFERRED, group.alloc_policy)
+
+  def testAddGroupPreservesFields(self):
+    cfg = self._get_object()
+    group = objects.NodeGroup(name="test", members=[],
+                              alloc_policy=constants.ALLOC_POLICY_LAST_RESORT)
+    cfg.AddNodeGroup(group, "my-job")
+    self.assertEqual(constants.ALLOC_POLICY_LAST_RESORT, group.alloc_policy)
+
+  def testAddGroupDoesNotPreserveFields(self):
+    cfg = self._get_object()
+    group = objects.NodeGroup(name="test", members=[],
+                              serial_no=17, ctime=123, mtime=456)
+    cfg.AddNodeGroup(group, "my-job")
+    self.assertEqual(1, group.serial_no)
+    self.assert_(group.ctime > 1200000000)
+    self.assert_(group.mtime > 1200000000)
+
+  def testAddGroupCanSkipUUIDCheck(self):
+    cfg = self._get_object()
+    uuid = cfg.GenerateUniqueID("my-job")
+    group = objects.NodeGroup(name="test", members=[], uuid=uuid,
+                              serial_no=17, ctime=123, mtime=456)
+
+    self.assertRaises(errors.ConfigurationError,
+                      cfg.AddNodeGroup, group, "my-job")
+
+    cfg.AddNodeGroup(group, "my-job", check_uuid=False) # Does not raise.
+    self.assertEqual(uuid, group.uuid)
+
+
+class TestTRM(unittest.TestCase):
+  EC_ID = 1
+
+  def testEmpty(self):
+    t = TemporaryReservationManager()
+    t.Reserve(self.EC_ID, "a")
+    self.assertFalse(t.Reserved(self.EC_ID))
+    self.assertTrue(t.Reserved("a"))
+    self.assertEqual(len(t.GetReserved()), 1)
+
+  def testDuplicate(self):
+    t = TemporaryReservationManager()
+    t.Reserve(self.EC_ID, "a")
+    self.assertRaises(errors.ReservationError, t.Reserve, 2, "a")
+    t.DropECReservations(self.EC_ID)
+    self.assertFalse(t.Reserved("a"))
+
 
 if __name__ == '__main__':
-  unittest.main()
+  testutils.GanetiTestProgram()