From a0c3e7264aad583e956c1608bdc62a634b971f36 Mon Sep 17 00:00:00 2001 From: Michael Hanselmann <hansmi@google.com> Date: Thu, 26 Apr 2012 19:35:46 +0200 Subject: [PATCH] QA: Enable use of OR conditions in test checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Until now βTestRunIfβ and βTestEnabledβ could only handle AND. With this patch a new class named βEitherβ is added to βqa_configβ and allows OR. The name βEitherβ was chosen instead of βOrβ as the latter is very close to the reserved keyword βorβ. Examples: ["rapi", Either(["instance-rename", "instance-reboot"])] Either(["node-list", "instance-list", "job-list"]) Signed-off-by: Michael Hanselmann <hansmi@google.com> Reviewed-by: Iustin Pop <iustin@google.com> --- Makefile.am | 2 + autotools/run-in-tempdir | 2 +- qa/qa_config.py | 71 ++++++++++++++++-- test/qa.qa_config_unittest.py | 137 ++++++++++++++++++++++++++++++++++ 4 files changed, 204 insertions(+), 8 deletions(-) create mode 100755 test/qa.qa_config_unittest.py diff --git a/Makefile.am b/Makefile.am index 31cd8fa5c..4da1ae32e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -498,6 +498,7 @@ PYTHON_BOOTSTRAP = \ tools/ensure-dirs qa_scripts = \ + qa/__init__.py \ qa/ganeti-qa.py \ qa/qa_cluster.py \ qa/qa_config.py \ @@ -847,6 +848,7 @@ python_tests = \ test/ganeti.utils.x509_unittest.py \ test/ganeti.utils_unittest.py \ test/ganeti.workerpool_unittest.py \ + test/qa.qa_config_unittest.py \ test/cfgupgrade_unittest.py \ test/docs_unittest.py \ test/pycurl_reset_unittest.py \ diff --git a/autotools/run-in-tempdir b/autotools/run-in-tempdir index e656ffe73..316b54775 100755 --- a/autotools/run-in-tempdir +++ b/autotools/run-in-tempdir @@ -10,7 +10,7 @@ trap "rm -rf $tmpdir" EXIT mkdir $tmpdir/doc -cp -r autotools daemons scripts lib tools test $tmpdir +cp -r autotools daemons scripts lib tools test qa $tmpdir cp -r doc/examples $tmpdir/doc mv $tmpdir/lib $tmpdir/ganeti diff --git a/qa/qa_config.py b/qa/qa_config.py index e058a71d8..5e19c5eab 100644 --- a/qa/qa_config.py +++ b/qa/qa_config.py @@ -60,22 +60,79 @@ def get(name, default=None): return cfg.get(name, default) -def TestEnabled(tests): +class Either: + def __init__(self, tests): + """Initializes this class. + + @type tests: list or string + @param tests: List of test names + @see: L{TestEnabled} for details + + """ + self.tests = tests + + +def _MakeSequence(value): + """Make sequence of single argument. + + If the single argument is not already a list or tuple, a list with the + argument as a single item is returned. + + """ + if isinstance(value, (list, tuple)): + return value + else: + return [value] + + +def _TestEnabledInner(check_fn, names, fn): + """Evaluate test conditions. + + @type check_fn: callable + @param check_fn: Callback to check whether a test is enabled + @type names: sequence or string + @param names: Test name(s) + @type fn: callable + @param fn: Aggregation function + @rtype: bool + @return: Whether test is enabled + + """ + names = _MakeSequence(names) + + result = [] + + for name in names: + if isinstance(name, Either): + value = _TestEnabledInner(check_fn, name.tests, compat.any) + elif isinstance(name, (list, tuple)): + value = _TestEnabledInner(check_fn, name, compat.all) + else: + value = check_fn(name) + + result.append(value) + + return fn(result) + + +def TestEnabled(tests, _cfg=None): """Returns True if the given tests are enabled. - @param tests: a single test, or a list of tests to check + @param tests: A single test as a string, or a list of tests to check; can + contain L{Either} for OR conditions, AND is default """ - if isinstance(tests, basestring): - tests = [tests] + if _cfg is None: + _cfg = cfg # Get settings for all tests - all_tests = cfg.get("tests", {}) + cfg_tests = _cfg.get("tests", {}) # Get default setting - default = all_tests.get("default", True) + default = cfg_tests.get("default", True) - return compat.all(all_tests.get(name, default) for name in tests) + return _TestEnabledInner(lambda name: cfg_tests.get(name, default), + tests, compat.all) def GetMasterNode(): diff --git a/test/qa.qa_config_unittest.py b/test/qa.qa_config_unittest.py new file mode 100755 index 000000000..fd7332271 --- /dev/null +++ b/test/qa.qa_config_unittest.py @@ -0,0 +1,137 @@ +#!/usr/bin/python +# + +# Copyright (C) 2012 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 +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + + +"""Script for testing qa.qa_config""" + +import unittest + +from qa import qa_config + +import testutils + + +class TestTestEnabled(unittest.TestCase): + def testSimple(self): + for name in ["test", ["foobar"], ["a", "b"]]: + self.assertTrue(qa_config.TestEnabled(name, _cfg={})) + + for default in [False, True]: + self.assertFalse(qa_config.TestEnabled("foo", _cfg={ + "tests": { + "default": default, + "foo": False, + }, + })) + + self.assertTrue(qa_config.TestEnabled("bar", _cfg={ + "tests": { + "default": default, + "bar": True, + }, + })) + + def testEitherWithDefault(self): + names = qa_config.Either("one") + + self.assertTrue(qa_config.TestEnabled(names, _cfg={ + "tests": { + "default": True, + }, + })) + + self.assertFalse(qa_config.TestEnabled(names, _cfg={ + "tests": { + "default": False, + }, + })) + + def testEither(self): + names = [qa_config.Either(["one", "two"]), + qa_config.Either("foo"), + "hello", + ["bar", "baz"]] + + self.assertTrue(qa_config.TestEnabled(names, _cfg={ + "tests": { + "default": True, + }, + })) + + self.assertFalse(qa_config.TestEnabled(names, _cfg={ + "tests": { + "default": False, + }, + })) + + for name in ["foo", "bar", "baz", "hello"]: + self.assertFalse(qa_config.TestEnabled(names, _cfg={ + "tests": { + "default": True, + name: False, + }, + })) + + self.assertFalse(qa_config.TestEnabled(names, _cfg={ + "tests": { + "default": True, + "one": False, + "two": False, + }, + })) + + self.assertTrue(qa_config.TestEnabled(names, _cfg={ + "tests": { + "default": True, + "one": False, + "two": True, + }, + })) + + self.assertFalse(qa_config.TestEnabled(names, _cfg={ + "tests": { + "default": True, + "one": True, + "two": True, + "foo": False, + }, + })) + + def testEitherNestedWithAnd(self): + names = qa_config.Either([["one", "two"], "foo"]) + + self.assertTrue(qa_config.TestEnabled(names, _cfg={ + "tests": { + "default": True, + }, + })) + + for name in ["one", "two"]: + self.assertFalse(qa_config.TestEnabled(names, _cfg={ + "tests": { + "default": True, + "foo": False, + name: False, + }, + })) + + +if __name__ == "__main__": + testutils.GanetiTestProgram() -- GitLab