Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.config_unittest.py @ 5b798711

History | View | Annotate | Download (26.4 kB)

1 e00fb268 Iustin Pop
#!/usr/bin/python
2 e00fb268 Iustin Pop
#
3 e00fb268 Iustin Pop
4 64760879 Bernardo Dal Seno
# Copyright (C) 2006, 2007, 2010, 2011, 2012, 2013 Google Inc.
5 e00fb268 Iustin Pop
#
6 e00fb268 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 e00fb268 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 e00fb268 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 e00fb268 Iustin Pop
# (at your option) any later version.
10 e00fb268 Iustin Pop
#
11 e00fb268 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 e00fb268 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 e00fb268 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 e00fb268 Iustin Pop
# General Public License for more details.
15 e00fb268 Iustin Pop
#
16 e00fb268 Iustin Pop
# You should have received a copy of the GNU General Public License
17 e00fb268 Iustin Pop
# along with this program; if not, write to the Free Software
18 e00fb268 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 e00fb268 Iustin Pop
# 02110-1301, USA.
20 e00fb268 Iustin Pop
21 e00fb268 Iustin Pop
22 e00fb268 Iustin Pop
"""Script for unittesting the config module"""
23 e00fb268 Iustin Pop
24 e00fb268 Iustin Pop
25 e00fb268 Iustin Pop
import unittest
26 e00fb268 Iustin Pop
import os
27 e00fb268 Iustin Pop
import tempfile
28 54c31fd3 Michael Hanselmann
import operator
29 e00fb268 Iustin Pop
30 c666722f Oleksiy Mishchenko
from ganeti import bootstrap
31 e00fb268 Iustin Pop
from ganeti import config
32 c666722f Oleksiy Mishchenko
from ganeti import constants
33 c666722f Oleksiy Mishchenko
from ganeti import errors
34 e00fb268 Iustin Pop
from ganeti import objects
35 6f1bebf9 Michael Hanselmann
from ganeti import utils
36 a744b676 Manuel Franceschini
from ganeti import netutils
37 54c31fd3 Michael Hanselmann
from ganeti import compat
38 a5efec93 Santi Raffa
from ganeti import serializer
39 22b7f6f8 Thomas Thrainer
from ganeti.cmdlib import instance
40 e00fb268 Iustin Pop
41 28a7318f Iustin Pop
from ganeti.config import TemporaryReservationManager
42 28a7318f Iustin Pop
43 25231ec5 Michael Hanselmann
import testutils
44 e60c73a1 René Nussbaumer
import mocks
45 def6577f Helga Velroyen
import mock
46 e60c73a1 René Nussbaumer
47 e60c73a1 René Nussbaumer
48 e60c73a1 René Nussbaumer
def _StubGetEntResolver():
49 e60c73a1 René Nussbaumer
  return mocks.FakeGetentResolver()
50 25231ec5 Michael Hanselmann
51 e00fb268 Iustin Pop
52 e00fb268 Iustin Pop
class TestConfigRunner(unittest.TestCase):
53 e00fb268 Iustin Pop
  """Testing case for HooksRunner"""
54 e00fb268 Iustin Pop
  def setUp(self):
55 e00fb268 Iustin Pop
    fd, self.cfg_file = tempfile.mkstemp()
56 e00fb268 Iustin Pop
    os.close(fd)
57 c666722f Oleksiy Mishchenko
    self._init_cluster(self.cfg_file)
58 e00fb268 Iustin Pop
59 e00fb268 Iustin Pop
  def tearDown(self):
60 e00fb268 Iustin Pop
    try:
61 e00fb268 Iustin Pop
      os.unlink(self.cfg_file)
62 e00fb268 Iustin Pop
    except OSError:
63 e00fb268 Iustin Pop
      pass
64 e00fb268 Iustin Pop
65 e00fb268 Iustin Pop
  def _get_object(self):
66 64760879 Bernardo Dal Seno
    """Returns an instance of ConfigWriter"""
67 e60c73a1 René Nussbaumer
    cfg = config.ConfigWriter(cfg_file=self.cfg_file, offline=True,
68 e60c73a1 René Nussbaumer
                              _getents=_StubGetEntResolver)
69 e00fb268 Iustin Pop
    return cfg
70 e00fb268 Iustin Pop
71 e00fb268 Iustin Pop
  def _init_cluster(self, cfg):
72 e00fb268 Iustin Pop
    """Initializes the cfg object"""
73 b705c7a6 Manuel Franceschini
    me = netutils.Hostname()
74 9769bb78 Manuel Franceschini
    ip = constants.IP4_ADDRESS_LOCALHOST
75 3697def0 Bernardo Dal Seno
    # master_ip must not conflict with the node ip address
76 3697def0 Bernardo Dal Seno
    master_ip = "127.0.0.2"
77 f6bd6e98 Michael Hanselmann
78 b9eeeb02 Michael Hanselmann
    cluster_config = objects.Cluster(
79 b9eeeb02 Michael Hanselmann
      serial_no=1,
80 b9eeeb02 Michael Hanselmann
      rsahostkeypub="",
81 a9542a4f Thomas Thrainer
      dsahostkeypub="",
82 b9eeeb02 Michael Hanselmann
      highest_used_port=(constants.FIRST_DRBD_PORT - 1),
83 b9eeeb02 Michael Hanselmann
      mac_prefix="aa:00:00",
84 b9eeeb02 Michael Hanselmann
      volume_group_name="xenvg",
85 9e33896b Luca Bigliardi
      drbd_usermode_helper="/bin/true",
86 c66f21a4 Guido Trotter
      nicparams={constants.PP_DEFAULT: constants.NICC_DEFAULTS},
87 5768e6a6 René Nussbaumer
      ndparams=constants.NDC_DEFAULTS,
88 b9eeeb02 Michael Hanselmann
      tcpudp_port_pool=set(),
89 066f465d Guido Trotter
      enabled_hypervisors=[constants.HT_FAKE],
90 f6bd6e98 Michael Hanselmann
      master_node=me.name,
91 3697def0 Bernardo Dal Seno
      master_ip=master_ip,
92 f6bd6e98 Michael Hanselmann
      master_netdev=constants.DEFAULT_BRIDGE,
93 f6bd6e98 Michael Hanselmann
      cluster_name="cluster.local",
94 f6bd6e98 Michael Hanselmann
      file_storage_dir="/tmp",
95 93be53da Balazs Lecz
      uid_pool=[],
96 b9eeeb02 Michael Hanselmann
      )
97 f6bd6e98 Michael Hanselmann
98 f6bd6e98 Michael Hanselmann
    master_node_config = objects.Node(name=me.name,
99 f6bd6e98 Michael Hanselmann
                                      primary_ip=me.ip,
100 36b8c2c1 Michael Hanselmann
                                      secondary_ip=ip,
101 4a89c54a Iustin Pop
                                      serial_no=1,
102 4a89c54a Iustin Pop
                                      master_candidate=True)
103 f6bd6e98 Michael Hanselmann
104 c666722f Oleksiy Mishchenko
    bootstrap.InitConfig(constants.CONFIG_VERSION,
105 c666722f Oleksiy Mishchenko
                         cluster_config, master_node_config, self.cfg_file)
106 e00fb268 Iustin Pop
107 8533cd2d Ilias Tsitsimpis
  def _create_instance(self, cfg):
108 e00fb268 Iustin Pop
    """Create and return an instance object"""
109 da4a52a3 Thomas Thrainer
    inst = objects.Instance(name="test.example.com",
110 da4a52a3 Thomas Thrainer
                            uuid="test-uuid",
111 da4a52a3 Thomas Thrainer
                            disks=[], nics=[],
112 4a89c54a Iustin Pop
                            disk_template=constants.DT_DISKLESS,
113 8533cd2d Ilias Tsitsimpis
                            primary_node=cfg.GetMasterNode(),
114 a5efec93 Santi Raffa
                            osparams_private=serializer.PrivateDict())
115 e00fb268 Iustin Pop
    return inst
116 e00fb268 Iustin Pop
117 e00fb268 Iustin Pop
  def testEmpty(self):
118 e00fb268 Iustin Pop
    """Test instantiate config object"""
119 e00fb268 Iustin Pop
    self._get_object()
120 e00fb268 Iustin Pop
121 e00fb268 Iustin Pop
  def testInit(self):
122 e00fb268 Iustin Pop
    """Test initialize the config file"""
123 e00fb268 Iustin Pop
    cfg = self._get_object()
124 e00fb268 Iustin Pop
    self.failUnlessEqual(1, len(cfg.GetNodeList()))
125 e00fb268 Iustin Pop
    self.failUnlessEqual(0, len(cfg.GetInstanceList()))
126 e00fb268 Iustin Pop
127 5b798711 Ilias Tsitsimpis
  def _GenericNodesCheck(self, inst, all_nodes, secondary_nodes):
128 5b798711 Ilias Tsitsimpis
    for i in [all_nodes, secondary_nodes]:
129 5b798711 Ilias Tsitsimpis
      self.assertTrue(isinstance(i, (list, tuple)),
130 5b798711 Ilias Tsitsimpis
                      msg="Data type doesn't guarantee order")
131 5b798711 Ilias Tsitsimpis
132 5b798711 Ilias Tsitsimpis
    self.assertTrue(inst.primary_node not in secondary_nodes)
133 5b798711 Ilias Tsitsimpis
    self.assertEqual(all_nodes[0], inst.primary_node,
134 5b798711 Ilias Tsitsimpis
                     msg="Primary node not first node in list")
135 5b798711 Ilias Tsitsimpis
136 5b798711 Ilias Tsitsimpis
  def testInstNodesNoDisks(self):
137 5b798711 Ilias Tsitsimpis
    """Test all_nodes/secondary_nodes when there are no disks"""
138 5b798711 Ilias Tsitsimpis
    # construct instance
139 5b798711 Ilias Tsitsimpis
    cfg = self._get_object()
140 5b798711 Ilias Tsitsimpis
    inst = self._create_instance(cfg)
141 5b798711 Ilias Tsitsimpis
    cfg.AddInstance(inst, "my-job")
142 5b798711 Ilias Tsitsimpis
143 5b798711 Ilias Tsitsimpis
    # No disks
144 5b798711 Ilias Tsitsimpis
    all_nodes = cfg.GetInstanceNodes(inst)
145 5b798711 Ilias Tsitsimpis
    secondary_nodes = cfg.GetInstanceSecondaryNodes(inst)
146 5b798711 Ilias Tsitsimpis
    self._GenericNodesCheck(inst, all_nodes, secondary_nodes)
147 5b798711 Ilias Tsitsimpis
    self.assertEqual(len(secondary_nodes), 0)
148 5b798711 Ilias Tsitsimpis
    self.assertEqual(set(all_nodes), set([inst.primary_node]))
149 5b798711 Ilias Tsitsimpis
    self.assertEqual(cfg.GetInstanceLVsByNode(inst), {
150 5b798711 Ilias Tsitsimpis
      inst.primary_node: [],
151 5b798711 Ilias Tsitsimpis
      })
152 5b798711 Ilias Tsitsimpis
153 5b798711 Ilias Tsitsimpis
  def testInstNodesPlainDisks(self):
154 5b798711 Ilias Tsitsimpis
    # construct instance
155 5b798711 Ilias Tsitsimpis
    cfg = self._get_object()
156 5b798711 Ilias Tsitsimpis
    inst = self._create_instance(cfg)
157 5b798711 Ilias Tsitsimpis
    disks = [
158 5b798711 Ilias Tsitsimpis
      objects.Disk(dev_type=constants.DT_PLAIN, size=128,
159 5b798711 Ilias Tsitsimpis
                   logical_id=("myxenvg", "disk25494")),
160 5b798711 Ilias Tsitsimpis
      objects.Disk(dev_type=constants.DT_PLAIN, size=512,
161 5b798711 Ilias Tsitsimpis
                   logical_id=("myxenvg", "disk29071")),
162 5b798711 Ilias Tsitsimpis
      ]
163 5b798711 Ilias Tsitsimpis
    inst.disks = disks
164 5b798711 Ilias Tsitsimpis
    cfg.AddInstance(inst, "my-job")
165 5b798711 Ilias Tsitsimpis
166 5b798711 Ilias Tsitsimpis
    # Plain disks
167 5b798711 Ilias Tsitsimpis
    all_nodes = cfg.GetInstanceNodes(inst)
168 5b798711 Ilias Tsitsimpis
    secondary_nodes = cfg.GetInstanceSecondaryNodes(inst)
169 5b798711 Ilias Tsitsimpis
    self._GenericNodesCheck(inst, all_nodes, secondary_nodes)
170 5b798711 Ilias Tsitsimpis
    self.assertEqual(len(secondary_nodes), 0)
171 5b798711 Ilias Tsitsimpis
    self.assertEqual(set(all_nodes), set([inst.primary_node]))
172 5b798711 Ilias Tsitsimpis
    self.assertEqual(cfg.GetInstanceLVsByNode(inst), {
173 5b798711 Ilias Tsitsimpis
      inst.primary_node: ["myxenvg/disk25494", "myxenvg/disk29071"],
174 5b798711 Ilias Tsitsimpis
      })
175 5b798711 Ilias Tsitsimpis
176 5b798711 Ilias Tsitsimpis
  def testInstNodesDrbdDisks(self):
177 5b798711 Ilias Tsitsimpis
    # construct a second node
178 5b798711 Ilias Tsitsimpis
    cfg = self._get_object()
179 5b798711 Ilias Tsitsimpis
    node_group = cfg.LookupNodeGroup(None)
180 5b798711 Ilias Tsitsimpis
    master_uuid = cfg.GetMasterNode()
181 5b798711 Ilias Tsitsimpis
    node2 = objects.Node(name="node2.example.com", group=node_group,
182 5b798711 Ilias Tsitsimpis
                         ndparams={}, uuid="node2-uuid")
183 5b798711 Ilias Tsitsimpis
    cfg.AddNode(node2, "my-job")
184 5b798711 Ilias Tsitsimpis
185 5b798711 Ilias Tsitsimpis
    # construct instance
186 5b798711 Ilias Tsitsimpis
    inst = self._create_instance(cfg)
187 5b798711 Ilias Tsitsimpis
    disks = [
188 5b798711 Ilias Tsitsimpis
      objects.Disk(dev_type=constants.DT_DRBD8, size=786432,
189 5b798711 Ilias Tsitsimpis
                   logical_id=(master_uuid, node2.uuid,
190 5b798711 Ilias Tsitsimpis
                               12300, 0, 0, "secret"),
191 5b798711 Ilias Tsitsimpis
                   children=[
192 5b798711 Ilias Tsitsimpis
                     objects.Disk(dev_type=constants.DT_PLAIN, size=786432,
193 5b798711 Ilias Tsitsimpis
                                  logical_id=("myxenvg", "disk0")),
194 5b798711 Ilias Tsitsimpis
                     objects.Disk(dev_type=constants.DT_PLAIN, size=128,
195 5b798711 Ilias Tsitsimpis
                                  logical_id=("myxenvg", "meta0"))
196 5b798711 Ilias Tsitsimpis
                   ],
197 5b798711 Ilias Tsitsimpis
                   iv_name="disk/0")
198 5b798711 Ilias Tsitsimpis
      ]
199 5b798711 Ilias Tsitsimpis
    inst.disks = disks
200 5b798711 Ilias Tsitsimpis
    cfg.AddInstance(inst, "my-job")
201 5b798711 Ilias Tsitsimpis
202 5b798711 Ilias Tsitsimpis
    # Drbd Disks
203 5b798711 Ilias Tsitsimpis
    all_nodes = cfg.GetInstanceNodes(inst)
204 5b798711 Ilias Tsitsimpis
    secondary_nodes = cfg.GetInstanceSecondaryNodes(inst)
205 5b798711 Ilias Tsitsimpis
    self._GenericNodesCheck(inst, all_nodes, secondary_nodes)
206 5b798711 Ilias Tsitsimpis
    self.assertEqual(set(secondary_nodes), set([node2.uuid]))
207 5b798711 Ilias Tsitsimpis
    self.assertEqual(set(all_nodes),
208 5b798711 Ilias Tsitsimpis
                     set([inst.primary_node, node2.uuid]))
209 5b798711 Ilias Tsitsimpis
    self.assertEqual(cfg.GetInstanceLVsByNode(inst), {
210 5b798711 Ilias Tsitsimpis
      master_uuid: ["myxenvg/disk0", "myxenvg/meta0"],
211 5b798711 Ilias Tsitsimpis
      node2.uuid: ["myxenvg/disk0", "myxenvg/meta0"],
212 5b798711 Ilias Tsitsimpis
      })
213 5b798711 Ilias Tsitsimpis
214 e00fb268 Iustin Pop
  def testUpdateCluster(self):
215 e00fb268 Iustin Pop
    """Test updates on the cluster object"""
216 e00fb268 Iustin Pop
    cfg = self._get_object()
217 e00fb268 Iustin Pop
    # construct a fake cluster object
218 e00fb268 Iustin Pop
    fake_cl = objects.Cluster()
219 e00fb268 Iustin Pop
    # fail if we didn't read the config
220 a4eae71f Michael Hanselmann
    self.failUnlessRaises(errors.ConfigurationError, cfg.Update, fake_cl, None)
221 e00fb268 Iustin Pop
222 e00fb268 Iustin Pop
    cl = cfg.GetClusterInfo()
223 e00fb268 Iustin Pop
    # first pass, must not fail
224 a4eae71f Michael Hanselmann
    cfg.Update(cl, None)
225 e00fb268 Iustin Pop
    # second pass, also must not fail (after the config has been written)
226 a4eae71f Michael Hanselmann
    cfg.Update(cl, None)
227 e00fb268 Iustin Pop
    # but the fake_cl update should still fail
228 a4eae71f Michael Hanselmann
    self.failUnlessRaises(errors.ConfigurationError, cfg.Update, fake_cl, None)
229 e00fb268 Iustin Pop
230 e00fb268 Iustin Pop
  def testUpdateNode(self):
231 e00fb268 Iustin Pop
    """Test updates on one node object"""
232 e00fb268 Iustin Pop
    cfg = self._get_object()
233 e00fb268 Iustin Pop
    # construct a fake node
234 e00fb268 Iustin Pop
    fake_node = objects.Node()
235 e00fb268 Iustin Pop
    # fail if we didn't read the config
236 a4eae71f Michael Hanselmann
    self.failUnlessRaises(errors.ConfigurationError, cfg.Update, fake_node,
237 a4eae71f Michael Hanselmann
                          None)
238 e00fb268 Iustin Pop
239 e00fb268 Iustin Pop
    node = cfg.GetNodeInfo(cfg.GetNodeList()[0])
240 e00fb268 Iustin Pop
    # first pass, must not fail
241 a4eae71f Michael Hanselmann
    cfg.Update(node, None)
242 e00fb268 Iustin Pop
    # second pass, also must not fail (after the config has been written)
243 a4eae71f Michael Hanselmann
    cfg.Update(node, None)
244 e00fb268 Iustin Pop
    # but the fake_node update should still fail
245 a4eae71f Michael Hanselmann
    self.failUnlessRaises(errors.ConfigurationError, cfg.Update, fake_node,
246 a4eae71f Michael Hanselmann
                          None)
247 e00fb268 Iustin Pop
248 e00fb268 Iustin Pop
  def testUpdateInstance(self):
249 e00fb268 Iustin Pop
    """Test updates on one instance object"""
250 e00fb268 Iustin Pop
    cfg = self._get_object()
251 e00fb268 Iustin Pop
    # construct a fake instance
252 8533cd2d Ilias Tsitsimpis
    inst = self._create_instance(cfg)
253 e00fb268 Iustin Pop
    fake_instance = objects.Instance()
254 e00fb268 Iustin Pop
    # fail if we didn't read the config
255 a4eae71f Michael Hanselmann
    self.failUnlessRaises(errors.ConfigurationError, cfg.Update, fake_instance,
256 a4eae71f Michael Hanselmann
                          None)
257 e00fb268 Iustin Pop
258 0debfb35 Guido Trotter
    cfg.AddInstance(inst, "my-job")
259 e00fb268 Iustin Pop
    instance = cfg.GetInstanceInfo(cfg.GetInstanceList()[0])
260 e00fb268 Iustin Pop
    # first pass, must not fail
261 a4eae71f Michael Hanselmann
    cfg.Update(instance, None)
262 e00fb268 Iustin Pop
    # second pass, also must not fail (after the config has been written)
263 a4eae71f Michael Hanselmann
    cfg.Update(instance, None)
264 e00fb268 Iustin Pop
    # but the fake_instance update should still fail
265 a4eae71f Michael Hanselmann
    self.failUnlessRaises(errors.ConfigurationError, cfg.Update, fake_instance,
266 a4eae71f Michael Hanselmann
                          None)
267 e00fb268 Iustin Pop
268 45f62156 Bernardo Dal Seno
  def testUpgradeSave(self):
269 45f62156 Bernardo Dal Seno
    """Test that any modification done during upgrading is saved back"""
270 45f62156 Bernardo Dal Seno
    cfg = self._get_object()
271 45f62156 Bernardo Dal Seno
272 45f62156 Bernardo Dal Seno
    # Remove an element, run upgrade, and check if the element is
273 45f62156 Bernardo Dal Seno
    # back and the file upgraded
274 45f62156 Bernardo Dal Seno
    node = cfg.GetNodeInfo(cfg.GetNodeList()[0])
275 45f62156 Bernardo Dal Seno
    # For a ConfigObject, None is the same as a missing field
276 45f62156 Bernardo Dal Seno
    node.ndparams = None
277 45f62156 Bernardo Dal Seno
    oldsaved = utils.ReadFile(self.cfg_file)
278 45f62156 Bernardo Dal Seno
    cfg._UpgradeConfig()
279 45f62156 Bernardo Dal Seno
    self.assertTrue(node.ndparams is not None)
280 45f62156 Bernardo Dal Seno
    newsaved = utils.ReadFile(self.cfg_file)
281 45f62156 Bernardo Dal Seno
    # We rely on the fact that at least the serial number changes
282 45f62156 Bernardo Dal Seno
    self.assertNotEqual(oldsaved, newsaved)
283 45f62156 Bernardo Dal Seno
284 45f62156 Bernardo Dal Seno
    # Add something that should not be there this time
285 45f62156 Bernardo Dal Seno
    key = list(constants.NDC_GLOBALS)[0]
286 45f62156 Bernardo Dal Seno
    node.ndparams[key] = constants.NDC_DEFAULTS[key]
287 45f62156 Bernardo Dal Seno
    cfg._WriteConfig(None)
288 45f62156 Bernardo Dal Seno
    oldsaved = utils.ReadFile(self.cfg_file)
289 45f62156 Bernardo Dal Seno
    cfg._UpgradeConfig()
290 45f62156 Bernardo Dal Seno
    self.assertTrue(node.ndparams.get(key) is None)
291 45f62156 Bernardo Dal Seno
    newsaved = utils.ReadFile(self.cfg_file)
292 45f62156 Bernardo Dal Seno
    self.assertNotEqual(oldsaved, newsaved)
293 45f62156 Bernardo Dal Seno
294 45f62156 Bernardo Dal Seno
    # Do the upgrade again, this time there should be no update
295 45f62156 Bernardo Dal Seno
    oldsaved = newsaved
296 45f62156 Bernardo Dal Seno
    cfg._UpgradeConfig()
297 45f62156 Bernardo Dal Seno
    newsaved = utils.ReadFile(self.cfg_file)
298 45f62156 Bernardo Dal Seno
    self.assertEqual(oldsaved, newsaved)
299 45f62156 Bernardo Dal Seno
300 45f62156 Bernardo Dal Seno
    # Reload the configuration again: it shouldn't change the file
301 45f62156 Bernardo Dal Seno
    oldsaved = newsaved
302 45f62156 Bernardo Dal Seno
    self._get_object()
303 45f62156 Bernardo Dal Seno
    newsaved = utils.ReadFile(self.cfg_file)
304 45f62156 Bernardo Dal Seno
    self.assertEqual(oldsaved, newsaved)
305 45f62156 Bernardo Dal Seno
306 255e19d4 Guido Trotter
  def testNICParameterSyntaxCheck(self):
307 255e19d4 Guido Trotter
    """Test the NIC's CheckParameterSyntax function"""
308 255e19d4 Guido Trotter
    mode = constants.NIC_MODE
309 255e19d4 Guido Trotter
    link = constants.NIC_LINK
310 255e19d4 Guido Trotter
    m_bridged = constants.NIC_MODE_BRIDGED
311 255e19d4 Guido Trotter
    m_routed = constants.NIC_MODE_ROUTED
312 255e19d4 Guido Trotter
    CheckSyntax = objects.NIC.CheckParameterSyntax
313 255e19d4 Guido Trotter
314 255e19d4 Guido Trotter
    CheckSyntax(constants.NICC_DEFAULTS)
315 8c114acd Michael Hanselmann
    CheckSyntax({mode: m_bridged, link: "br1"})
316 8c114acd Michael Hanselmann
    CheckSyntax({mode: m_routed, link: "default"})
317 255e19d4 Guido Trotter
    self.assertRaises(errors.ConfigurationError,
318 8c114acd Michael Hanselmann
                      CheckSyntax, {mode: "000invalid", link: "any"})
319 255e19d4 Guido Trotter
    self.assertRaises(errors.ConfigurationError,
320 255e19d4 Guido Trotter
                      CheckSyntax, {mode: m_bridged, link: None})
321 255e19d4 Guido Trotter
    self.assertRaises(errors.ConfigurationError,
322 8c114acd Michael Hanselmann
                      CheckSyntax, {mode: m_bridged, link: ""})
323 255e19d4 Guido Trotter
324 5768e6a6 René Nussbaumer
  def testGetNdParamsDefault(self):
325 5768e6a6 René Nussbaumer
    cfg = self._get_object()
326 5768e6a6 René Nussbaumer
    node = cfg.GetNodeInfo(cfg.GetNodeList()[0])
327 5768e6a6 René Nussbaumer
    self.assertEqual(cfg.GetNdParams(node), constants.NDC_DEFAULTS)
328 5768e6a6 René Nussbaumer
329 5768e6a6 René Nussbaumer
  def testGetNdParamsModifiedNode(self):
330 5768e6a6 René Nussbaumer
    my_ndparams = {
331 5768e6a6 René Nussbaumer
        constants.ND_OOB_PROGRAM: "/bin/node-oob",
332 432e8e2f Iustin Pop
        constants.ND_SPINDLE_COUNT: 1,
333 0ea11dcb Bernardo Dal Seno
        constants.ND_EXCLUSIVE_STORAGE: False,
334 807d8853 Sebastian Gebhard
        constants.ND_OVS: True,
335 807d8853 Sebastian Gebhard
        constants.ND_OVS_NAME: "openvswitch",
336 33ffda6c Petr Pudlak
        constants.ND_OVS_LINK: "eth1",
337 33ffda6c Petr Pudlak
        constants.ND_SSH_PORT: 22,
338 5768e6a6 René Nussbaumer
        }
339 5768e6a6 René Nussbaumer
340 5768e6a6 René Nussbaumer
    cfg = self._get_object()
341 5768e6a6 René Nussbaumer
    node = cfg.GetNodeInfo(cfg.GetNodeList()[0])
342 5768e6a6 René Nussbaumer
    node.ndparams = my_ndparams
343 5768e6a6 René Nussbaumer
    cfg.Update(node, None)
344 5768e6a6 René Nussbaumer
    self.assertEqual(cfg.GetNdParams(node), my_ndparams)
345 5768e6a6 René Nussbaumer
346 0ea11dcb Bernardo Dal Seno
  def testGetNdParamsInheritance(self):
347 0ea11dcb Bernardo Dal Seno
    node_ndparams = {
348 0ea11dcb Bernardo Dal Seno
      constants.ND_OOB_PROGRAM: "/bin/node-oob",
349 807d8853 Sebastian Gebhard
      constants.ND_OVS_LINK: "eth3"
350 0ea11dcb Bernardo Dal Seno
      }
351 0ea11dcb Bernardo Dal Seno
    group_ndparams = {
352 0ea11dcb Bernardo Dal Seno
      constants.ND_SPINDLE_COUNT: 10,
353 807d8853 Sebastian Gebhard
      constants.ND_OVS: True,
354 807d8853 Sebastian Gebhard
      constants.ND_OVS_NAME: "openvswitch",
355 33ffda6c Petr Pudlak
      constants.ND_SSH_PORT: 222,
356 0ea11dcb Bernardo Dal Seno
      }
357 0ea11dcb Bernardo Dal Seno
    expected_ndparams = {
358 0ea11dcb Bernardo Dal Seno
      constants.ND_OOB_PROGRAM: "/bin/node-oob",
359 0ea11dcb Bernardo Dal Seno
      constants.ND_SPINDLE_COUNT: 10,
360 0ea11dcb Bernardo Dal Seno
      constants.ND_EXCLUSIVE_STORAGE:
361 0ea11dcb Bernardo Dal Seno
        constants.NDC_DEFAULTS[constants.ND_EXCLUSIVE_STORAGE],
362 807d8853 Sebastian Gebhard
      constants.ND_OVS: True,
363 807d8853 Sebastian Gebhard
      constants.ND_OVS_NAME: "openvswitch",
364 33ffda6c Petr Pudlak
      constants.ND_OVS_LINK: "eth3",
365 33ffda6c Petr Pudlak
      constants.ND_SSH_PORT: 222,
366 0ea11dcb Bernardo Dal Seno
      }
367 0ea11dcb Bernardo Dal Seno
    cfg = self._get_object()
368 0ea11dcb Bernardo Dal Seno
    node = cfg.GetNodeInfo(cfg.GetNodeList()[0])
369 0ea11dcb Bernardo Dal Seno
    node.ndparams = node_ndparams
370 0ea11dcb Bernardo Dal Seno
    cfg.Update(node, None)
371 0ea11dcb Bernardo Dal Seno
    group = cfg.GetNodeGroup(node.group)
372 0ea11dcb Bernardo Dal Seno
    group.ndparams = group_ndparams
373 0ea11dcb Bernardo Dal Seno
    cfg.Update(group, None)
374 0ea11dcb Bernardo Dal Seno
    self.assertEqual(cfg.GetNdParams(node), expected_ndparams)
375 0ea11dcb Bernardo Dal Seno
376 2bac48c4 Adeodato Simo
  def testAddGroupFillsFieldsIfMissing(self):
377 2bac48c4 Adeodato Simo
    cfg = self._get_object()
378 2bac48c4 Adeodato Simo
    group = objects.NodeGroup(name="test", members=[])
379 2bac48c4 Adeodato Simo
    cfg.AddNodeGroup(group, "my-job")
380 2bac48c4 Adeodato Simo
    self.assert_(utils.UUID_RE.match(group.uuid))
381 2bac48c4 Adeodato Simo
    self.assertEqual(constants.ALLOC_POLICY_PREFERRED, group.alloc_policy)
382 2bac48c4 Adeodato Simo
383 2bac48c4 Adeodato Simo
  def testAddGroupPreservesFields(self):
384 2bac48c4 Adeodato Simo
    cfg = self._get_object()
385 2bac48c4 Adeodato Simo
    group = objects.NodeGroup(name="test", members=[],
386 2bac48c4 Adeodato Simo
                              alloc_policy=constants.ALLOC_POLICY_LAST_RESORT)
387 2bac48c4 Adeodato Simo
    cfg.AddNodeGroup(group, "my-job")
388 2bac48c4 Adeodato Simo
    self.assertEqual(constants.ALLOC_POLICY_LAST_RESORT, group.alloc_policy)
389 2bac48c4 Adeodato Simo
390 2bac48c4 Adeodato Simo
  def testAddGroupDoesNotPreserveFields(self):
391 2bac48c4 Adeodato Simo
    cfg = self._get_object()
392 2bac48c4 Adeodato Simo
    group = objects.NodeGroup(name="test", members=[],
393 2bac48c4 Adeodato Simo
                              serial_no=17, ctime=123, mtime=456)
394 2bac48c4 Adeodato Simo
    cfg.AddNodeGroup(group, "my-job")
395 2bac48c4 Adeodato Simo
    self.assertEqual(1, group.serial_no)
396 2bac48c4 Adeodato Simo
    self.assert_(group.ctime > 1200000000)
397 2bac48c4 Adeodato Simo
    self.assert_(group.mtime > 1200000000)
398 2bac48c4 Adeodato Simo
399 2bac48c4 Adeodato Simo
  def testAddGroupCanSkipUUIDCheck(self):
400 2bac48c4 Adeodato Simo
    cfg = self._get_object()
401 2bac48c4 Adeodato Simo
    uuid = cfg.GenerateUniqueID("my-job")
402 2bac48c4 Adeodato Simo
    group = objects.NodeGroup(name="test", members=[], uuid=uuid,
403 2bac48c4 Adeodato Simo
                              serial_no=17, ctime=123, mtime=456)
404 2bac48c4 Adeodato Simo
405 2bac48c4 Adeodato Simo
    self.assertRaises(errors.ConfigurationError,
406 2bac48c4 Adeodato Simo
                      cfg.AddNodeGroup, group, "my-job")
407 2bac48c4 Adeodato Simo
408 2bac48c4 Adeodato Simo
    cfg.AddNodeGroup(group, "my-job", check_uuid=False) # Does not raise.
409 2bac48c4 Adeodato Simo
    self.assertEqual(uuid, group.uuid)
410 2bac48c4 Adeodato Simo
411 54c31fd3 Michael Hanselmann
  def testAssignGroupNodes(self):
412 54c31fd3 Michael Hanselmann
    me = netutils.Hostname()
413 54c31fd3 Michael Hanselmann
    cfg = self._get_object()
414 54c31fd3 Michael Hanselmann
415 54c31fd3 Michael Hanselmann
    # Create two groups
416 54c31fd3 Michael Hanselmann
    grp1 = objects.NodeGroup(name="grp1", members=[],
417 54c31fd3 Michael Hanselmann
                             uuid="2f2fadf7-2a70-4a23-9ab5-2568c252032c")
418 54c31fd3 Michael Hanselmann
    grp1_serial = 1
419 54c31fd3 Michael Hanselmann
    cfg.AddNodeGroup(grp1, "job")
420 54c31fd3 Michael Hanselmann
421 54c31fd3 Michael Hanselmann
    grp2 = objects.NodeGroup(name="grp2", members=[],
422 54c31fd3 Michael Hanselmann
                             uuid="798d0de3-680f-4a0e-b29a-0f54f693b3f1")
423 54c31fd3 Michael Hanselmann
    grp2_serial = 1
424 54c31fd3 Michael Hanselmann
    cfg.AddNodeGroup(grp2, "job")
425 54c31fd3 Michael Hanselmann
    self.assertEqual(set(map(operator.attrgetter("name"),
426 54c31fd3 Michael Hanselmann
                             cfg.GetAllNodeGroupsInfo().values())),
427 54c31fd3 Michael Hanselmann
                     set(["grp1", "grp2", constants.INITIAL_NODE_GROUP_NAME]))
428 54c31fd3 Michael Hanselmann
429 54c31fd3 Michael Hanselmann
    # No-op
430 54c31fd3 Michael Hanselmann
    cluster_serial = cfg.GetClusterInfo().serial_no
431 54c31fd3 Michael Hanselmann
    cfg.AssignGroupNodes([])
432 54c31fd3 Michael Hanselmann
    cluster_serial += 1
433 54c31fd3 Michael Hanselmann
434 54c31fd3 Michael Hanselmann
    # Create two nodes
435 1c3231aa Thomas Thrainer
    node1 = objects.Node(name="node1", group=grp1.uuid, ndparams={},
436 1c3231aa Thomas Thrainer
                         uuid="node1-uuid")
437 54c31fd3 Michael Hanselmann
    node1_serial = 1
438 1c3231aa Thomas Thrainer
    node2 = objects.Node(name="node2", group=grp2.uuid, ndparams={},
439 1c3231aa Thomas Thrainer
                         uuid="node2-uuid")
440 54c31fd3 Michael Hanselmann
    node2_serial = 1
441 54c31fd3 Michael Hanselmann
    cfg.AddNode(node1, "job")
442 54c31fd3 Michael Hanselmann
    cfg.AddNode(node2, "job")
443 54c31fd3 Michael Hanselmann
    cluster_serial += 2
444 1c3231aa Thomas Thrainer
    self.assertEqual(set(cfg.GetNodeList()),
445 1c3231aa Thomas Thrainer
                     set(["node1-uuid", "node2-uuid",
446 1c3231aa Thomas Thrainer
                          cfg.GetNodeInfoByName(me.name).uuid]))
447 54c31fd3 Michael Hanselmann
448 54c31fd3 Michael Hanselmann
    def _VerifySerials():
449 54c31fd3 Michael Hanselmann
      self.assertEqual(cfg.GetClusterInfo().serial_no, cluster_serial)
450 54c31fd3 Michael Hanselmann
      self.assertEqual(node1.serial_no, node1_serial)
451 54c31fd3 Michael Hanselmann
      self.assertEqual(node2.serial_no, node2_serial)
452 54c31fd3 Michael Hanselmann
      self.assertEqual(grp1.serial_no, grp1_serial)
453 54c31fd3 Michael Hanselmann
      self.assertEqual(grp2.serial_no, grp2_serial)
454 54c31fd3 Michael Hanselmann
455 54c31fd3 Michael Hanselmann
    _VerifySerials()
456 54c31fd3 Michael Hanselmann
457 1c3231aa Thomas Thrainer
    self.assertEqual(set(grp1.members), set(["node1-uuid"]))
458 1c3231aa Thomas Thrainer
    self.assertEqual(set(grp2.members), set(["node2-uuid"]))
459 54c31fd3 Michael Hanselmann
460 54c31fd3 Michael Hanselmann
    # Check invalid nodes and groups
461 54c31fd3 Michael Hanselmann
    self.assertRaises(errors.ConfigurationError, cfg.AssignGroupNodes, [
462 54c31fd3 Michael Hanselmann
      ("unknown.node.example.com", grp2.uuid),
463 54c31fd3 Michael Hanselmann
      ])
464 54c31fd3 Michael Hanselmann
    self.assertRaises(errors.ConfigurationError, cfg.AssignGroupNodes, [
465 54c31fd3 Michael Hanselmann
      (node1.name, "unknown-uuid"),
466 54c31fd3 Michael Hanselmann
      ])
467 54c31fd3 Michael Hanselmann
468 54c31fd3 Michael Hanselmann
    self.assertEqual(node1.group, grp1.uuid)
469 54c31fd3 Michael Hanselmann
    self.assertEqual(node2.group, grp2.uuid)
470 1c3231aa Thomas Thrainer
    self.assertEqual(set(grp1.members), set(["node1-uuid"]))
471 1c3231aa Thomas Thrainer
    self.assertEqual(set(grp2.members), set(["node2-uuid"]))
472 54c31fd3 Michael Hanselmann
473 54c31fd3 Michael Hanselmann
    # Another no-op
474 54c31fd3 Michael Hanselmann
    cfg.AssignGroupNodes([])
475 54c31fd3 Michael Hanselmann
    cluster_serial += 1
476 54c31fd3 Michael Hanselmann
    _VerifySerials()
477 54c31fd3 Michael Hanselmann
478 54c31fd3 Michael Hanselmann
    # Assign to the same group (should be a no-op)
479 54c31fd3 Michael Hanselmann
    self.assertEqual(node2.group, grp2.uuid)
480 54c31fd3 Michael Hanselmann
    cfg.AssignGroupNodes([
481 1c3231aa Thomas Thrainer
      (node2.uuid, grp2.uuid),
482 54c31fd3 Michael Hanselmann
      ])
483 54c31fd3 Michael Hanselmann
    cluster_serial += 1
484 54c31fd3 Michael Hanselmann
    self.assertEqual(node2.group, grp2.uuid)
485 54c31fd3 Michael Hanselmann
    _VerifySerials()
486 1c3231aa Thomas Thrainer
    self.assertEqual(set(grp1.members), set(["node1-uuid"]))
487 1c3231aa Thomas Thrainer
    self.assertEqual(set(grp2.members), set(["node2-uuid"]))
488 54c31fd3 Michael Hanselmann
489 54c31fd3 Michael Hanselmann
    # Assign node 2 to group 1
490 54c31fd3 Michael Hanselmann
    self.assertEqual(node2.group, grp2.uuid)
491 54c31fd3 Michael Hanselmann
    cfg.AssignGroupNodes([
492 1c3231aa Thomas Thrainer
      (node2.uuid, grp1.uuid),
493 54c31fd3 Michael Hanselmann
      ])
494 54c31fd3 Michael Hanselmann
    cluster_serial += 1
495 54c31fd3 Michael Hanselmann
    node2_serial += 1
496 54c31fd3 Michael Hanselmann
    grp1_serial += 1
497 54c31fd3 Michael Hanselmann
    grp2_serial += 1
498 54c31fd3 Michael Hanselmann
    self.assertEqual(node2.group, grp1.uuid)
499 54c31fd3 Michael Hanselmann
    _VerifySerials()
500 1c3231aa Thomas Thrainer
    self.assertEqual(set(grp1.members), set(["node1-uuid", "node2-uuid"]))
501 54c31fd3 Michael Hanselmann
    self.assertFalse(grp2.members)
502 54c31fd3 Michael Hanselmann
503 54c31fd3 Michael Hanselmann
    # And assign both nodes to group 2
504 54c31fd3 Michael Hanselmann
    self.assertEqual(node1.group, grp1.uuid)
505 54c31fd3 Michael Hanselmann
    self.assertEqual(node2.group, grp1.uuid)
506 54c31fd3 Michael Hanselmann
    self.assertNotEqual(grp1.uuid, grp2.uuid)
507 54c31fd3 Michael Hanselmann
    cfg.AssignGroupNodes([
508 1c3231aa Thomas Thrainer
      (node1.uuid, grp2.uuid),
509 1c3231aa Thomas Thrainer
      (node2.uuid, grp2.uuid),
510 54c31fd3 Michael Hanselmann
      ])
511 54c31fd3 Michael Hanselmann
    cluster_serial += 1
512 54c31fd3 Michael Hanselmann
    node1_serial += 1
513 54c31fd3 Michael Hanselmann
    node2_serial += 1
514 54c31fd3 Michael Hanselmann
    grp1_serial += 1
515 54c31fd3 Michael Hanselmann
    grp2_serial += 1
516 54c31fd3 Michael Hanselmann
    self.assertEqual(node1.group, grp2.uuid)
517 54c31fd3 Michael Hanselmann
    self.assertEqual(node2.group, grp2.uuid)
518 54c31fd3 Michael Hanselmann
    _VerifySerials()
519 54c31fd3 Michael Hanselmann
    self.assertFalse(grp1.members)
520 1c3231aa Thomas Thrainer
    self.assertEqual(set(grp2.members), set(["node1-uuid", "node2-uuid"]))
521 54c31fd3 Michael Hanselmann
522 54c31fd3 Michael Hanselmann
    # Destructive tests
523 54c31fd3 Michael Hanselmann
    orig_group = node2.group
524 54c31fd3 Michael Hanselmann
    try:
525 54c31fd3 Michael Hanselmann
      other_uuid = "68b3d087-6ea5-491c-b81f-0a47d90228c5"
526 54c31fd3 Michael Hanselmann
      assert compat.all(node.group != other_uuid
527 54c31fd3 Michael Hanselmann
                        for node in cfg.GetAllNodesInfo().values())
528 54c31fd3 Michael Hanselmann
      node2.group = "68b3d087-6ea5-491c-b81f-0a47d90228c5"
529 54c31fd3 Michael Hanselmann
      self.assertRaises(errors.ConfigurationError, cfg.AssignGroupNodes, [
530 1c3231aa Thomas Thrainer
        (node2.uuid, grp2.uuid),
531 54c31fd3 Michael Hanselmann
        ])
532 54c31fd3 Michael Hanselmann
      _VerifySerials()
533 54c31fd3 Michael Hanselmann
    finally:
534 54c31fd3 Michael Hanselmann
      node2.group = orig_group
535 54c31fd3 Michael Hanselmann
536 64760879 Bernardo Dal Seno
  def _TestVerifyConfigIPolicy(self, ipolicy, ipowner, cfg, isgroup):
537 64760879 Bernardo Dal Seno
    INVALID_KEY = "this_key_cannot_exist"
538 64760879 Bernardo Dal Seno
539 64760879 Bernardo Dal Seno
    ipolicy[INVALID_KEY] = None
540 64760879 Bernardo Dal Seno
    # A call to cluster.SimpleFillIPolicy causes different kinds of error
541 64760879 Bernardo Dal Seno
    # depending on the owner (cluster or group)
542 64760879 Bernardo Dal Seno
    if isgroup:
543 64760879 Bernardo Dal Seno
      errs = cfg.VerifyConfig()
544 0f511c8a Bernardo Dal Seno
      self.assertTrue(len(errs) >= 1)
545 64760879 Bernardo Dal Seno
      errstr = "%s has invalid instance policy" % ipowner
546 0f511c8a Bernardo Dal Seno
      self.assertTrue(_IsErrorInList(errstr, errs))
547 64760879 Bernardo Dal Seno
    else:
548 64760879 Bernardo Dal Seno
      self.assertRaises(AssertionError, cfg.VerifyConfig)
549 64760879 Bernardo Dal Seno
    del ipolicy[INVALID_KEY]
550 64760879 Bernardo Dal Seno
    errs = cfg.VerifyConfig()
551 64760879 Bernardo Dal Seno
    self.assertFalse(errs)
552 64760879 Bernardo Dal Seno
553 64760879 Bernardo Dal Seno
    key = list(constants.IPOLICY_PARAMETERS)[0]
554 64760879 Bernardo Dal Seno
    hasoldv = (key in ipolicy)
555 64760879 Bernardo Dal Seno
    if hasoldv:
556 64760879 Bernardo Dal Seno
      oldv = ipolicy[key]
557 64760879 Bernardo Dal Seno
    ipolicy[key] = "blah"
558 64760879 Bernardo Dal Seno
    errs = cfg.VerifyConfig()
559 64760879 Bernardo Dal Seno
    self.assertTrue(len(errs) >= 1)
560 64760879 Bernardo Dal Seno
    self.assertTrue(_IsErrorInList("%s has invalid instance policy" % ipowner,
561 64760879 Bernardo Dal Seno
                                   errs))
562 64760879 Bernardo Dal Seno
    if hasoldv:
563 64760879 Bernardo Dal Seno
      ipolicy[key] = oldv
564 64760879 Bernardo Dal Seno
    else:
565 64760879 Bernardo Dal Seno
      del ipolicy[key]
566 64760879 Bernardo Dal Seno
567 0f511c8a Bernardo Dal Seno
    ispeclist = []
568 0f511c8a Bernardo Dal Seno
    if constants.ISPECS_MINMAX in ipolicy:
569 41044e04 Bernardo Dal Seno
      for k in range(len(ipolicy[constants.ISPECS_MINMAX])):
570 41044e04 Bernardo Dal Seno
        ispeclist.extend([
571 41044e04 Bernardo Dal Seno
            (ipolicy[constants.ISPECS_MINMAX][k][constants.ISPECS_MIN],
572 41044e04 Bernardo Dal Seno
             "%s[%s]/%s" % (constants.ISPECS_MINMAX, k, constants.ISPECS_MIN)),
573 41044e04 Bernardo Dal Seno
            (ipolicy[constants.ISPECS_MINMAX][k][constants.ISPECS_MAX],
574 41044e04 Bernardo Dal Seno
             "%s[%s]/%s" % (constants.ISPECS_MINMAX, k, constants.ISPECS_MAX)),
575 41044e04 Bernardo Dal Seno
            ])
576 0f511c8a Bernardo Dal Seno
    if constants.ISPECS_STD in ipolicy:
577 0f511c8a Bernardo Dal Seno
      ispeclist.append((ipolicy[constants.ISPECS_STD], constants.ISPECS_STD))
578 0f511c8a Bernardo Dal Seno
579 64760879 Bernardo Dal Seno
    for (ispec, ispecpath) in ispeclist:
580 64760879 Bernardo Dal Seno
      ispec[INVALID_KEY] = None
581 64760879 Bernardo Dal Seno
      errs = cfg.VerifyConfig()
582 64760879 Bernardo Dal Seno
      self.assertTrue(len(errs) >= 1)
583 64760879 Bernardo Dal Seno
      self.assertTrue(_IsErrorInList(("%s has invalid ipolicy/%s" %
584 64760879 Bernardo Dal Seno
                                      (ipowner, ispecpath)), errs))
585 64760879 Bernardo Dal Seno
      del ispec[INVALID_KEY]
586 64760879 Bernardo Dal Seno
      errs = cfg.VerifyConfig()
587 64760879 Bernardo Dal Seno
      self.assertFalse(errs)
588 64760879 Bernardo Dal Seno
589 64760879 Bernardo Dal Seno
      for par in constants.ISPECS_PARAMETERS:
590 64760879 Bernardo Dal Seno
        hasoldv = par in ispec
591 64760879 Bernardo Dal Seno
        if hasoldv:
592 64760879 Bernardo Dal Seno
          oldv = ispec[par]
593 64760879 Bernardo Dal Seno
        ispec[par] = "blah"
594 64760879 Bernardo Dal Seno
        errs = cfg.VerifyConfig()
595 64760879 Bernardo Dal Seno
        self.assertTrue(len(errs) >= 1)
596 64760879 Bernardo Dal Seno
        self.assertTrue(_IsErrorInList(("%s has invalid ipolicy/%s" %
597 64760879 Bernardo Dal Seno
                                        (ipowner, ispecpath)), errs))
598 64760879 Bernardo Dal Seno
        if hasoldv:
599 64760879 Bernardo Dal Seno
          ispec[par] = oldv
600 64760879 Bernardo Dal Seno
        else:
601 64760879 Bernardo Dal Seno
          del ispec[par]
602 64760879 Bernardo Dal Seno
        errs = cfg.VerifyConfig()
603 64760879 Bernardo Dal Seno
        self.assertFalse(errs)
604 64760879 Bernardo Dal Seno
605 0f511c8a Bernardo Dal Seno
    if constants.ISPECS_MINMAX in ipolicy:
606 0f511c8a Bernardo Dal Seno
      # Test partial minmax specs
607 41044e04 Bernardo Dal Seno
      for minmax in ipolicy[constants.ISPECS_MINMAX]:
608 41044e04 Bernardo Dal Seno
        for key in constants.ISPECS_MINMAX_KEYS:
609 41044e04 Bernardo Dal Seno
          self.assertTrue(key in minmax)
610 41044e04 Bernardo Dal Seno
          ispec = minmax[key]
611 41044e04 Bernardo Dal Seno
          del minmax[key]
612 0f511c8a Bernardo Dal Seno
          errs = cfg.VerifyConfig()
613 0f511c8a Bernardo Dal Seno
          self.assertTrue(len(errs) >= 1)
614 41044e04 Bernardo Dal Seno
          self.assertTrue(_IsErrorInList("Missing instance specification",
615 0f511c8a Bernardo Dal Seno
                                         errs))
616 41044e04 Bernardo Dal Seno
          minmax[key] = ispec
617 41044e04 Bernardo Dal Seno
          for par in constants.ISPECS_PARAMETERS:
618 41044e04 Bernardo Dal Seno
            oldv = ispec[par]
619 41044e04 Bernardo Dal Seno
            del ispec[par]
620 41044e04 Bernardo Dal Seno
            errs = cfg.VerifyConfig()
621 41044e04 Bernardo Dal Seno
            self.assertTrue(len(errs) >= 1)
622 41044e04 Bernardo Dal Seno
            self.assertTrue(_IsErrorInList("Missing instance specs parameters",
623 41044e04 Bernardo Dal Seno
                                           errs))
624 41044e04 Bernardo Dal Seno
            ispec[par] = oldv
625 0f511c8a Bernardo Dal Seno
      errs = cfg.VerifyConfig()
626 0f511c8a Bernardo Dal Seno
      self.assertFalse(errs)
627 0f511c8a Bernardo Dal Seno
628 64760879 Bernardo Dal Seno
  def _TestVerifyConfigGroupIPolicy(self, groupinfo, cfg):
629 64760879 Bernardo Dal Seno
    old_ipolicy = groupinfo.ipolicy
630 64760879 Bernardo Dal Seno
    ipolicy = cfg.GetClusterInfo().SimpleFillIPolicy({})
631 64760879 Bernardo Dal Seno
    groupinfo.ipolicy = ipolicy
632 64760879 Bernardo Dal Seno
    # Test partial policies
633 64760879 Bernardo Dal Seno
    for key in constants.IPOLICY_ALL_KEYS:
634 64760879 Bernardo Dal Seno
      self.assertTrue(key in ipolicy)
635 64760879 Bernardo Dal Seno
      oldv = ipolicy[key]
636 64760879 Bernardo Dal Seno
      del ipolicy[key]
637 64760879 Bernardo Dal Seno
      errs = cfg.VerifyConfig()
638 64760879 Bernardo Dal Seno
      self.assertFalse(errs)
639 64760879 Bernardo Dal Seno
      ipolicy[key] = oldv
640 64760879 Bernardo Dal Seno
    groupinfo.ipolicy = old_ipolicy
641 64760879 Bernardo Dal Seno
642 64760879 Bernardo Dal Seno
  def _TestVerifyConfigClusterIPolicy(self, ipolicy, cfg):
643 64760879 Bernardo Dal Seno
    # Test partial policies
644 64760879 Bernardo Dal Seno
    for key in constants.IPOLICY_ALL_KEYS:
645 64760879 Bernardo Dal Seno
      self.assertTrue(key in ipolicy)
646 64760879 Bernardo Dal Seno
      oldv = ipolicy[key]
647 64760879 Bernardo Dal Seno
      del ipolicy[key]
648 64760879 Bernardo Dal Seno
      self.assertRaises(AssertionError, cfg.VerifyConfig)
649 64760879 Bernardo Dal Seno
      ipolicy[key] = oldv
650 0f511c8a Bernardo Dal Seno
    errs = cfg.VerifyConfig()
651 0f511c8a Bernardo Dal Seno
    self.assertFalse(errs)
652 0f511c8a Bernardo Dal Seno
    # Partial standard specs
653 0f511c8a Bernardo Dal Seno
    ispec = ipolicy[constants.ISPECS_STD]
654 0f511c8a Bernardo Dal Seno
    for par in constants.ISPECS_PARAMETERS:
655 0f511c8a Bernardo Dal Seno
      oldv = ispec[par]
656 0f511c8a Bernardo Dal Seno
      del ispec[par]
657 0f511c8a Bernardo Dal Seno
      errs = cfg.VerifyConfig()
658 0f511c8a Bernardo Dal Seno
      self.assertTrue(len(errs) >= 1)
659 0f511c8a Bernardo Dal Seno
      self.assertTrue(_IsErrorInList("Missing instance specs parameters",
660 0f511c8a Bernardo Dal Seno
                                     errs))
661 0f511c8a Bernardo Dal Seno
      ispec[par] = oldv
662 64760879 Bernardo Dal Seno
    errs = cfg.VerifyConfig()
663 64760879 Bernardo Dal Seno
    self.assertFalse(errs)
664 64760879 Bernardo Dal Seno
665 3697def0 Bernardo Dal Seno
  def testVerifyConfig(self):
666 3697def0 Bernardo Dal Seno
    cfg = self._get_object()
667 3697def0 Bernardo Dal Seno
668 3697def0 Bernardo Dal Seno
    errs = cfg.VerifyConfig()
669 3697def0 Bernardo Dal Seno
    self.assertFalse(errs)
670 3697def0 Bernardo Dal Seno
671 3697def0 Bernardo Dal Seno
    node = cfg.GetNodeInfo(cfg.GetNodeList()[0])
672 3697def0 Bernardo Dal Seno
    key = list(constants.NDC_GLOBALS)[0]
673 3697def0 Bernardo Dal Seno
    node.ndparams[key] = constants.NDC_DEFAULTS[key]
674 3697def0 Bernardo Dal Seno
    errs = cfg.VerifyConfig()
675 3697def0 Bernardo Dal Seno
    self.assertTrue(len(errs) >= 1)
676 3697def0 Bernardo Dal Seno
    self.assertTrue(_IsErrorInList("has some global parameters set", errs))
677 3697def0 Bernardo Dal Seno
678 3697def0 Bernardo Dal Seno
    del node.ndparams[key]
679 3697def0 Bernardo Dal Seno
    errs = cfg.VerifyConfig()
680 3697def0 Bernardo Dal Seno
    self.assertFalse(errs)
681 3697def0 Bernardo Dal Seno
682 64760879 Bernardo Dal Seno
    cluster = cfg.GetClusterInfo()
683 64760879 Bernardo Dal Seno
    nodegroup = cfg.GetNodeGroup(cfg.GetNodeGroupList()[0])
684 64760879 Bernardo Dal Seno
    self._TestVerifyConfigIPolicy(cluster.ipolicy, "cluster", cfg, False)
685 64760879 Bernardo Dal Seno
    self._TestVerifyConfigClusterIPolicy(cluster.ipolicy, cfg)
686 64760879 Bernardo Dal Seno
    self._TestVerifyConfigIPolicy(nodegroup.ipolicy, nodegroup.name, cfg, True)
687 64760879 Bernardo Dal Seno
    self._TestVerifyConfigGroupIPolicy(nodegroup, cfg)
688 64760879 Bernardo Dal Seno
    nodegroup.ipolicy = cluster.SimpleFillIPolicy(nodegroup.ipolicy)
689 64760879 Bernardo Dal Seno
    self._TestVerifyConfigIPolicy(nodegroup.ipolicy, nodegroup.name, cfg, True)
690 64760879 Bernardo Dal Seno
691 def6577f Helga Velroyen
  # Tests for Ssconf helper functions
692 def6577f Helga Velroyen
  def testUnlockedGetHvparamsString(self):
693 def6577f Helga Velroyen
    hvparams = {"a": "A", "b": "B", "c": "C"}
694 def6577f Helga Velroyen
    hvname = "myhv"
695 def6577f Helga Velroyen
    cfg_writer = self._get_object()
696 def6577f Helga Velroyen
    cfg_writer._config_data = mock.Mock()
697 def6577f Helga Velroyen
    cfg_writer._config_data.cluster = mock.Mock()
698 def6577f Helga Velroyen
    cfg_writer._config_data.cluster.hvparams = {hvname: hvparams}
699 def6577f Helga Velroyen
700 def6577f Helga Velroyen
    result = cfg_writer._UnlockedGetHvparamsString(hvname)
701 def6577f Helga Velroyen
702 def6577f Helga Velroyen
    self.assertTrue("a=A" in result)
703 def6577f Helga Velroyen
    lines = [line for line in result.split('\n') if line != '']
704 def6577f Helga Velroyen
    self.assertEqual(len(hvparams.keys()), len(lines))
705 def6577f Helga Velroyen
706 def6577f Helga Velroyen
  def testExtendByAllHvparamsStrings(self):
707 def6577f Helga Velroyen
    all_hvparams = {constants.HT_XEN_PVM: "foo"}
708 def6577f Helga Velroyen
    ssconf_values = {}
709 def6577f Helga Velroyen
    cfg_writer = self._get_object()
710 def6577f Helga Velroyen
711 def6577f Helga Velroyen
    cfg_writer._ExtendByAllHvparamsStrings(ssconf_values, all_hvparams)
712 def6577f Helga Velroyen
713 def6577f Helga Velroyen
    expected_key = constants.SS_HVPARAMS_PREF + constants.HT_XEN_PVM
714 def6577f Helga Velroyen
    self.assertTrue(expected_key in ssconf_values)
715 def6577f Helga Velroyen
716 3697def0 Bernardo Dal Seno
717 3697def0 Bernardo Dal Seno
def _IsErrorInList(err_str, err_list):
718 3697def0 Bernardo Dal Seno
  return any(map(lambda e: err_str in e, err_list))
719 3697def0 Bernardo Dal Seno
720 e00fb268 Iustin Pop
721 28a7318f Iustin Pop
class TestTRM(unittest.TestCase):
722 28a7318f Iustin Pop
  EC_ID = 1
723 28a7318f Iustin Pop
724 28a7318f Iustin Pop
  def testEmpty(self):
725 28a7318f Iustin Pop
    t = TemporaryReservationManager()
726 28a7318f Iustin Pop
    t.Reserve(self.EC_ID, "a")
727 28a7318f Iustin Pop
    self.assertFalse(t.Reserved(self.EC_ID))
728 28a7318f Iustin Pop
    self.assertTrue(t.Reserved("a"))
729 28a7318f Iustin Pop
    self.assertEqual(len(t.GetReserved()), 1)
730 28a7318f Iustin Pop
731 28a7318f Iustin Pop
  def testDuplicate(self):
732 28a7318f Iustin Pop
    t = TemporaryReservationManager()
733 28a7318f Iustin Pop
    t.Reserve(self.EC_ID, "a")
734 28a7318f Iustin Pop
    self.assertRaises(errors.ReservationError, t.Reserve, 2, "a")
735 28a7318f Iustin Pop
    t.DropECReservations(self.EC_ID)
736 28a7318f Iustin Pop
    self.assertFalse(t.Reserved("a"))
737 28a7318f Iustin Pop
738 28a7318f Iustin Pop
739 82c54b5b Michael Hanselmann
class TestCheckInstanceDiskIvNames(unittest.TestCase):
740 82c54b5b Michael Hanselmann
  @staticmethod
741 82c54b5b Michael Hanselmann
  def _MakeDisks(names):
742 82c54b5b Michael Hanselmann
    return [objects.Disk(iv_name=name) for name in names]
743 82c54b5b Michael Hanselmann
744 82c54b5b Michael Hanselmann
  def testNoError(self):
745 82c54b5b Michael Hanselmann
    disks = self._MakeDisks(["disk/0", "disk/1"])
746 82c54b5b Michael Hanselmann
    self.assertEqual(config._CheckInstanceDiskIvNames(disks), [])
747 22b7f6f8 Thomas Thrainer
    instance._UpdateIvNames(0, disks)
748 82c54b5b Michael Hanselmann
    self.assertEqual(config._CheckInstanceDiskIvNames(disks), [])
749 82c54b5b Michael Hanselmann
750 82c54b5b Michael Hanselmann
  def testWrongNames(self):
751 82c54b5b Michael Hanselmann
    disks = self._MakeDisks(["disk/1", "disk/3", "disk/2"])
752 82c54b5b Michael Hanselmann
    self.assertEqual(config._CheckInstanceDiskIvNames(disks), [
753 82c54b5b Michael Hanselmann
      (0, "disk/0", "disk/1"),
754 82c54b5b Michael Hanselmann
      (1, "disk/1", "disk/3"),
755 82c54b5b Michael Hanselmann
      ])
756 82c54b5b Michael Hanselmann
757 82c54b5b Michael Hanselmann
    # Fix names
758 22b7f6f8 Thomas Thrainer
    instance._UpdateIvNames(0, disks)
759 82c54b5b Michael Hanselmann
    self.assertEqual(config._CheckInstanceDiskIvNames(disks), [])
760 82c54b5b Michael Hanselmann
761 82c54b5b Michael Hanselmann
762 2f96c43c Michael Hanselmann
if __name__ == "__main__":
763 25231ec5 Michael Hanselmann
  testutils.GanetiTestProgram()