4 # Copyright (C) 2012, 2013 Google Inc.
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 """Script for testing qa.qa_config"""
30 from ganeti import utils
31 from ganeti import serializer
32 from ganeti import constants
33 from ganeti import compat
35 from qa import qa_config
36 from qa import qa_error
41 class TestTestEnabled(unittest.TestCase):
43 for name in ["test", ["foobar"], ["a", "b"]]:
44 self.assertTrue(qa_config.TestEnabled(name, _cfg={}))
46 for default in [False, True]:
47 self.assertFalse(qa_config.TestEnabled("foo", _cfg={
54 self.assertTrue(qa_config.TestEnabled("bar", _cfg={
61 def testEitherWithDefault(self):
62 names = qa_config.Either("one")
64 self.assertTrue(qa_config.TestEnabled(names, _cfg={
70 self.assertFalse(qa_config.TestEnabled(names, _cfg={
77 names = [qa_config.Either(["one", "two"]),
78 qa_config.Either("foo"),
82 self.assertTrue(qa_config.TestEnabled(names, _cfg={
88 self.assertFalse(qa_config.TestEnabled(names, _cfg={
94 for name in ["foo", "bar", "baz", "hello"]:
95 self.assertFalse(qa_config.TestEnabled(names, _cfg={
102 self.assertFalse(qa_config.TestEnabled(names, _cfg={
110 self.assertTrue(qa_config.TestEnabled(names, _cfg={
118 self.assertFalse(qa_config.TestEnabled(names, _cfg={
127 def testEitherNestedWithAnd(self):
128 names = qa_config.Either([["one", "two"], "foo"])
130 self.assertTrue(qa_config.TestEnabled(names, _cfg={
136 for name in ["one", "two"]:
137 self.assertFalse(qa_config.TestEnabled(names, _cfg={
146 class TestQaConfigLoad(unittest.TestCase):
148 self.tmpdir = tempfile.mkdtemp()
151 shutil.rmtree(self.tmpdir)
153 def testLoadNonExistent(self):
154 filename = utils.PathJoin(self.tmpdir, "does.not.exist")
155 self.assertRaises(EnvironmentError, qa_config._QaConfig.Load, filename)
158 def _WriteConfig(filename, data):
159 utils.WriteFile(filename, data=serializer.DumpJson(data))
161 def _CheckLoadError(self, filename, data, expected):
162 self._WriteConfig(filename, data)
165 qa_config._QaConfig.Load(filename)
166 except qa_error.Error, err:
167 self.assertTrue(str(err).startswith(expected))
169 self.fail("Exception was not raised")
171 def testFailsValidation(self):
172 filename = utils.PathJoin(self.tmpdir, "qa.json")
175 check_fn = compat.partial(self._CheckLoadError, filename, testconfig)
178 check_fn("Need at least one node")
180 testconfig["nodes"] = [
182 "primary": "xen-test-0",
183 "secondary": "192.0.2.1",
188 check_fn("Need at least one instance")
190 testconfig["instances"] = [
192 "name": "xen-test-inst1",
196 # Missing "disk" and "disk-growth"
197 check_fn("Config options 'disk' and 'disk-growth' ")
199 testconfig["disk"] = []
200 testconfig["disk-growth"] = testconfig["disk"]
202 # Minimal accepted configuration
203 self._WriteConfig(filename, testconfig)
204 result = qa_config._QaConfig.Load(filename)
205 self.assertTrue(result.get("nodes"))
207 # Non-existent instance check script
208 testconfig[qa_config._INSTANCE_CHECK_KEY] = \
209 utils.PathJoin(self.tmpdir, "instcheck")
210 check_fn("Can't find instance check script")
211 del testconfig[qa_config._INSTANCE_CHECK_KEY]
213 # No enabled hypervisor
214 testconfig[qa_config._ENABLED_HV_KEY] = None
215 check_fn("No hypervisor is enabled")
218 testconfig[qa_config._ENABLED_HV_KEY] = ["#unknownhv#"]
219 check_fn("Unknown hypervisor(s) enabled:")
222 class TestQaConfigWithSampleConfig(unittest.TestCase):
223 """Tests using C{qa-sample.json}.
225 This test case serves two purposes:
227 - Ensure shipped C{qa-sample.json} file is considered a valid QA
229 - Test some functions of L{qa_config._QaConfig} without having to
230 mock a whole configuration file
234 filename = "%s/qa/qa-sample.json" % testutils.GetSourceDir()
236 self.config = qa_config._QaConfig.Load(filename)
238 def testGetEnabledHypervisors(self):
239 self.assertEqual(self.config.GetEnabledHypervisors(),
240 [constants.DEFAULT_ENABLED_HYPERVISOR])
242 def testGetDefaultHypervisor(self):
243 self.assertEqual(self.config.GetDefaultHypervisor(),
244 constants.DEFAULT_ENABLED_HYPERVISOR)
246 def testGetInstanceCheckScript(self):
247 self.assertTrue(self.config.GetInstanceCheckScript() is None)
249 def testGetAndGetItem(self):
250 self.assertEqual(self.config["nodes"], self.config.get("nodes"))
252 def testGetMasterNode(self):
253 self.assertEqual(self.config.GetMasterNode(), self.config["nodes"][0])
256 class TestQaConfig(unittest.TestCase):
259 testutils.TestDataFilename("qa-minimal-nodes-instances-only.json")
261 self.config = qa_config._QaConfig.Load(filename)
263 def testExclusiveStorage(self):
264 self.assertRaises(AssertionError, self.config.GetExclusiveStorage)
266 for value in [False, True, 0, 1, 30804, ""]:
267 self.config.SetExclusiveStorage(value)
268 self.assertEqual(self.config.GetExclusiveStorage(), bool(value))
270 for template in constants.DISK_TEMPLATES:
271 if value and template not in constants.DTS_EXCL_STORAGE:
272 self.assertFalse(self.config.IsTemplateSupported(template))
274 self.assertTrue(self.config.IsTemplateSupported(template))
276 def testInstanceConversion(self):
277 self.assertTrue(isinstance(self.config["instances"][0],
278 qa_config._QaInstance))
280 def testAcquireAndReleaseInstance(self):
281 self.assertFalse(compat.any(map(operator.attrgetter("used"),
282 self.config["instances"])))
284 inst = qa_config.AcquireInstance(_cfg=self.config)
285 self.assertTrue(inst.used)
286 self.assertTrue(inst.disk_template is None)
290 self.assertFalse(inst.used)
291 self.assertTrue(inst.disk_template is None)
293 self.assertFalse(compat.any(map(operator.attrgetter("used"),
294 self.config["instances"])))
296 def testAcquireInstanceTooMany(self):
297 # Acquire all instances
298 for _ in range(len(self.config["instances"])):
299 inst = qa_config.AcquireInstance(_cfg=self.config)
300 self.assertTrue(inst.used)
301 self.assertTrue(inst.disk_template is None)
303 # The next acquisition must fail
304 self.assertRaises(qa_error.OutOfInstancesError,
305 qa_config.AcquireInstance, _cfg=self.config)
308 if __name__ == "__main__":
309 testutils.GanetiTestProgram()