summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/Bcfg2/Options.py10
-rwxr-xr-xsrc/sbin/bcfg2-test104
2 files changed, 86 insertions, 28 deletions
diff --git a/src/lib/Bcfg2/Options.py b/src/lib/Bcfg2/Options.py
index 6a6b83d61..f6273924a 100644
--- a/src/lib/Bcfg2/Options.py
+++ b/src/lib/Bcfg2/Options.py
@@ -3,6 +3,7 @@
import getopt
import os
import sys
+import shlex
import Bcfg2.Client.Tools
# Compatibility imports
from Bcfg2.Bcfg2Py3k import ConfigParser
@@ -353,6 +354,15 @@ CLIENT_TIMEOUT = Option('Set the client XML-RPC timeout', default=90,
cmd='-t', cf=('communication', 'timeout'),
odesc='<timeout>')
+# bcfg2-test options
+TEST_NOSEOPTS = Option('Options to pass to nosetests', default=[],
+ cmd='--nose-options', cf=('bcfg2_test', 'nose_options'),
+ odesc='<opts>', long_arg=True, cook=shlex.split)
+TEST_IGNORE = Option('Ignore these entries if they fail to build.', default=[],
+ cmd='--ignore',
+ cf=('bcfg2_test', 'ignore_entries'), long_arg=True,
+ odesc='<Type>:<name>,<Type>:<name>', cook=list_split)
+
# APT client tool options
CLIENT_APT_TOOLS_INSTALL_PATH = Option('Apt tools install path',
cf=('APT', 'install_path'),
diff --git a/src/sbin/bcfg2-test b/src/sbin/bcfg2-test
index af2225245..01a2a4893 100755
--- a/src/sbin/bcfg2-test
+++ b/src/sbin/bcfg2-test
@@ -1,41 +1,60 @@
#!/usr/bin/env python
-"""This tool verifies that all clients known to the server build without failures"""
+"""This tool verifies that all clients known to the server build
+without failures"""
import sys
+import fnmatch
+import logging
+import Bcfg2.Logger
import Bcfg2.Server.Core
from nose.core import TestProgram
+from nose.suite import LazySuite
from unittest import TestCase
class ClientTest(TestCase):
"""
- A test case representing the build of all of the configuration for a single host.
- Checks that none of the build config entities has had a failure when it is building.
- Optionally ignores some config files that we know will cause errors (because they
- are private files we don't have access to, for instance)
+ A test case representing the build of all of the configuration for
+ a single host. Checks that none of the build config entities has
+ had a failure when it is building. Optionally ignores some config
+ files that we know will cause errors (because they are private
+ files we don't have access to, for instance)
"""
__test__ = False # Do not collect
- def __init__(self, bcfg2_core, client):
+ def __init__(self, bcfg2_core, client, ignore=None):
TestCase.__init__(self)
self.bcfg2_core = bcfg2_core
self.client = client
+ if ignore is None:
+ self.ignore = dict()
+ else:
+ self.ignore = ignore
+
+ def ignore_entry(self, tag, name):
+ if tag in self.ignore:
+ if name in self.ignore[tag]:
+ return True
+ else:
+ # try wildcard matching
+ for pattern in self.ignore[tag]:
+ if fnmatch.fnmatch(name, pattern):
+ return True
+ return False
def runTest(self):
config = self.bcfg2_core.BuildConfiguration(self.client)
- failures = config.xpath('//*[@failure]')
- def format_failure(failure):
- return "%s(%s): %s" % (
- failure.tag,
- failure.attrib.get('name'),
- failure.attrib.get('failure')
- )
+ failures = []
+ msg = ["Failures:"]
+ for failure in config.xpath('//*[@failure]'):
+ if not self.ignore_entry(failure.tag, failure.get('name')):
+ failures.append(failure)
+ msg.append("%s:%s: %s" % (failure.tag, failure.get("name"),
+ failure.get("failure")))
+
+ assert len(failures) == 0, "\n".join(msg)
- assert len(failures) == 0, "Failures:\n%s" % "\n".join(
- [format_failure(failure) for failure in failures]
- )
-
def __str__(self):
return "ClientTest(%s)" % self.client
@@ -43,26 +62,55 @@ class ClientTest(TestCase):
def main():
optinfo = {
- 'configfile': Bcfg2.Options.CFILE,
- 'help': Bcfg2.Options.HELP,
- 'encoding': Bcfg2.Options.ENCODING,
- 'repo': Bcfg2.Options.SERVER_REPOSITORY,
- 'plugins': Bcfg2.Options.SERVER_PLUGINS,
- 'password': Bcfg2.Options.SERVER_PASSWORD,
- }
+ 'configfile': Bcfg2.Options.CFILE,
+ 'help': Bcfg2.Options.HELP,
+ 'encoding': Bcfg2.Options.ENCODING,
+ 'repo': Bcfg2.Options.SERVER_REPOSITORY,
+ 'plugins': Bcfg2.Options.SERVER_PLUGINS,
+ 'password': Bcfg2.Options.SERVER_PASSWORD,
+ 'verbose': Bcfg2.Options.VERBOSE,
+ 'noseopts': Bcfg2.Options.TEST_NOSEOPTS,
+ 'ignore': Bcfg2.Options.TEST_IGNORE,
+ }
setup = Bcfg2.Options.OptionParser(optinfo)
+ setup.hm = \
+ "bcfg2-test [options] [client] [client] [...]\nOptions:\n %s" % \
+ setup.buildHelpMessage()
setup.parse(sys.argv[1:])
+
+ if setup['verbose']:
+ Bcfg2.Logger.setup_logging("bcfg2-test", to_syslog=False)
+
core = Bcfg2.Server.Core.Core(
setup['repo'],
setup['plugins'],
setup['password'],
setup['encoding'],
filemonitor='pseudo'
- )
- core.fam.handle_events_in_interval(0.1)
- suite = [ClientTest(core, client) for client in core.metadata.clients]
+ )
+
+ ignore = dict()
+ for entry in setup['ignore']:
+ tag, name = entry.split(":")
+ try:
+ ignore[tag].append(name)
+ except KeyError:
+ ignore[tag] = [name]
+
+ def run_tests():
+ core.fam.handle_events_in_interval(0.1)
+
+ if setup['args']:
+ clients = setup['args']
+ else:
+ clients = core.metadata.clients
+
+ for client in clients:
+ logging.info("Building %s" % client)
+ yield ClientTest(core, client, ignore)
- TestProgram(argv=sys.argv[0:1], suite = suite)
+ TestProgram(argv=sys.argv[0:1] + setup['noseopts'],
+ suite=LazySuite(run_tests))
if __name__ == "__main__":
sys.exit(main())