def main(): """Entry point into the SLASH2 Test Suite. Deals with argument parsing and main configuration.""" #Reset colorama after prints # init(autoreset=True) parser = ArgumentParser(description="SLASH2 Test Suite") parser.add_argument("-v", "--verbose", action="count", help="increase verbosity", default=0) parser.add_argument("-l", "--log-file", help="log output to a file", default=None) parser.add_argument("-c", "--config-file", help="path to slash2 test suite config", default="tsuite.conf") parser.add_argument("-s", "--source", choices=["src", "svn"], help="build from src or svn", default="src") parser.add_argument("-x", "--ignore-tests", help="ignore a test set, folder name", default=[], nargs="*") parser.add_argument("-i", "--ignore", help="list of processes to ignore. Defaults to none.", default=[], nargs="*") parser.add_argument("-a", "--only", help="list of processes to perform. Defaults to all.", default=[], nargs="*") parser.add_argument("-o", "--overrides", help="Override value in config. -s section:value=something ...", nargs="+") args = parser.parse_args() #Get log level level = [logging.WARNING, logging.INFO, logging.DEBUG]\ [2 if args.verbose > 2 else args.verbose] log.setLevel(level) fmtstr = '%(asctime)s %(name)-8s %(levelname)-8s %(message)s' #Pretty output if colorama is installed try: from colorama import init, Fore, Style fmtstr = '{0}%(asctime)s{1} {2}%(name)-8s{1} {4}{3}%(levelname)-8s{1}{5} {0}%(message)s{1}'.format( Fore.WHITE, Fore.RESET, Fore.BLUE, Fore.CYAN, Style.BRIGHT, Style.RESET_ALL ) class ColorFormatter(logging.Formatter): colors = { logging.INFO : (Fore.GREEN, Fore.WHITE), logging.DEBUG : (Fore.MAGENTA, Fore.WHITE), logging.ERROR : (Fore.RED, Fore.YELLOW), logging.CRITICAL : (Fore.RED, Fore.RED) } def __init__(self, fmt="%(levelno)s: %(msg)s"): logging.Formatter.__init__(self, fmt, "%H:%M") def format(self, record): format_orig = self._fmt color, text = self.colors[logging.DEBUG] if record.levelno in self.colors: color, text = self.colors[record.levelno] self._fmt = '%(asctime)s %(name)-8s {4}{3}%(levelname)-8s{1}{5} {6}%(message)s{1}'.format( Fore.WHITE, Fore.RESET, Fore.WHITE, color, Style.NORMAL, Style.RESET_ALL, text ) result = logging.Formatter.format(self, record) self._fmt = format_orig return result fmt = ColorFormatter() hdlr = logging.StreamHandler(sys.stdout) hdlr.setFormatter(fmt) logging.root.addHandler(hdlr) logging.root.setLevel(level) except ImportError: logging.basicConfig(level=level, format=fmtstr, datefmt='%H:%M' ) #Setup file log if args.log_file: fch = logging.FileHandler(args.log_file) fch.setLevel(level) fch.setFormatter( logging.Formatter("%(asctime)s [%(levelname)s] %(message)s") ) log.addHandler(fch) #Check for config file conf = ConfigParser() if len(conf.read(args.config_file)) == 0: log.fatal("Unable to read configuration file!") sys.exit(1) #Required sections; check for their existence sections = { "tsuite": [ "rootdir", "logbase" ], "slash2": [ "conf", "mds_gdb", "ion_gdb", "mnt_gdb" ], "tests": [ "tsetdir", "excluded" ], "mongo": [ "host" ] } #Building from source or svn if args.source == "svn": sections["svn"] = [ "svnroot" ] else: sections["source"] = [ "srcroot" ] #Apply configuration overrides if args.overrides: overreg = re.compile(r"^(\w+):(\w+)=(.+?)$") for override in args.overrides: match = overreg.match(override) if match: section, key, value = match.groups() if section not in conf._sections or key not in conf._sections[section]: print "Override {0} does not override an existing config value!".format(override) sys.exit(1) conf._sections[section][key] = value #Check that the required sections exist missing = check_subset(list(sections), list(conf._sections)) if len(missing) != 0: log.fatal("Configuration file is missing sections!") log.fatal("Missing: {}".format(", ".join(missing))) sys.exit(1) #Check that all the fields listed are present #in each section for section in sections: missing = check_subset( sections[section], conf._sections[section] ) if len(missing) != 0: log.fatal("Missing fields in {} section!".format(section)) log.fatal("Missing: {}".format(", ".join(missing))) sys.exit(1) if "timeout" not in conf._sections["slash2"]: conf._sections["slash2"]["timeout"] = None log.info("Configuration file loaded successfully!") tsetdir = conf._sections["tests"]["tsetdir"] tsets = [] try: #Consider all directories in tset_dir to have tsets to be ran tsets = [tset for tset in os.listdir(tsetdir) \ if os.path.isdir(os.path.join(tsetdir, tset)) and not tset.startswith(".")] except OSError, e: log.critical("Unable to gather tset sets from the tseting directory!") sys.exit(1)