#!/usr/bin/env python """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) """ __test__ = False # Do not collect 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 = [] 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) def __str__(self): return "ClientTest(%s)" % self.client id = __str__ 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, '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' ) 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] + setup['noseopts'], suite=LazySuite(run_tests)) if __name__ == "__main__": sys.exit(main())