def run_batch(self, batch_name): if batch_name not in self.batches: raise RuntimeError("Can't find batch '%s' to run." % batch_name) batch = self.batches[batch_name].copy() batch.update(self.settings.BATCH_OVERRIDE) # A batch declared 'abstract' is not runnable if batch.get('abstract', False): logger.info(" Batch marked as abstract. Not running.") return False elif batch.get('disabled', False) or not batch.get('enabled', True): logger.info(" Batch disabled.") return False argsets = self.get_argsets(batch) pause = int(batch.get('pause', 0)) batch_time = None if self.settings.BATCH_RESUME is not None and \ os.path.isdir(self.settings.BATCH_RESUME): # We're resuming a batch run. Try to find a data file we can get the # original batch run time from. for dirpath, dirnames, filenames in os.walk( self.settings.BATCH_RESUME): datafiles = [ f for f in filenames if f.endswith(resultset.SUFFIX) ] if datafiles: f = datafiles[0] r = resultset.load(os.path.join(dirpath, f)) batch_time = r.meta("BATCH_TIME") try: self.settings.BATCH_UUID = r.meta("BATCH_UUID") logger.info(" Using previous UUID %s.\n", self.settings.BATCH_UUID) except KeyError: pass break if batch_time is None: raise RuntimeError( "No data files found in resume directory %s." % self.settings.BATCH_RESUME) elif self.settings.BATCH_RESUME: raise RuntimeError("Batch resume directory %s doesn't exist!\n" % self.settings.BATCH_RESUME) else: batch_time = self.settings.TIME filenames_seen = set() for b, settings in self.expand_argsets(batch, argsets, batch_time, batch_name): if 'output_path' in b: output_path = clean_path(b['output_path'], allow_dirs=True) else: output_path = settings.DATA_DIR if settings.BATCH_RESUME is not None: if os.path.commonprefix( [os.path.abspath(output_path), os.path.abspath(settings.BATCH_RESUME)]) \ != os.path.abspath(settings.BATCH_RESUME): raise RuntimeError("Batch-specified output path is not a " "subdirectory of resume path. Bailing.") if os.path.exists( os.path.join( output_path, "%s%s" % (settings.DATA_FILENAME, resultset.SUFFIX))): logger.info(" Previous result exists, skipping.") continue if settings.BATCH_DRY and settings.BATCH_VERBOSE: logger.info(" Would output to: %s.\n", output_path) elif not settings.BATCH_DRY and not os.path.exists(output_path): try: os.makedirs(output_path) except OSError as e: raise RuntimeError( "Unable to create output path '%s': %s." % (output_path, e)) commands = self.commands_for(b, settings) if not settings.BATCH_DRY: self.logfile = loggers.setup_logfile(os.path.join( output_path, "%s.log" % settings.DATA_FILENAME), level=loggers.INFO, replay=False) if b.get('debug_log', False): self.logfile_debug = loggers.setup_logfile( os.path.join(output_path, "%s.debug.log" % settings.DATA_FILENAME), level=loggers.DEBUG, maxlevel=loggers.DEBUG, replay=False) if settings.DATA_FILENAME in filenames_seen: logger.warning("Filename already seen in this run: %s", settings.DATA_FILENAME) filenames_seen.add(settings.DATA_FILENAME) self.run_commands(commands, 'pre') self.run_commands(commands, 'monitor') try: if settings.BATCH_VERBOSE: if settings.BATCH_DRY: logger.info(" Would run test '%s'.", settings.NAME) else: logger.info(" Running test '%s'.", settings.NAME) logger.info(" data_filename=%s", settings.DATA_FILENAME) for k in sorted(b.keys()): if k.upper() in SETTINGS_PARSER: logger.info(" %s=%s", k, b[k]) if settings.BATCH_DRY: self.tests_run += 1 else: # Load test again with informational=False to enable host # lookups and other actions that may fail settings.load_test(informational=False) self.run_test(settings, output_path) except KeyboardInterrupt: self.run_commands(commands, 'post', essential_only=True) raise except Exception as e: self.run_commands(commands, 'post', essential_only=True) logger.exception(" Error running test: %s", str(e)) else: try: self.run_commands(commands, 'post') except Exception as e: self.run_commands(commands, 'post', essential_only=True) logger.exception(" Error running post-commands: %s", str(e)) finally: self.kill_children() if self.logfile: loggers.remove_log_handler(self.logfile) self.logfile.close() self.logfile = None if self.logfile_debug: loggers.remove_log_handler(self.logfile_debug) self.logfile_debug.close() self.logfile_debug = None if settings.BATCH_DRY and settings.BATCH_VERBOSE: logger.info(" Would sleep for %d seconds.", pause) elif not settings.BATCH_DRY: time.sleep(pause)
def run_batch(self, batch_name): if batch_name not in self.batches: raise RuntimeError("Can't find batch '%s' to run." % batch_name) batch = self.batches[batch_name].copy() batch.update(self.settings.BATCH_OVERRIDE) # A batch declared 'abstract' is not runnable if batch.get('abstract', False): logger.info(" Batch marked as abstract. Not running.") return False elif batch.get('disabled', False) or not batch.get('enabled', True): logger.info(" Batch disabled.") return False argsets = self.get_argsets(batch) pause = int(batch.get('pause', 0)) batch_time = None if self.settings.BATCH_RESUME is not None and \ os.path.isdir(self.settings.BATCH_RESUME): # We're resuming a batch run. Try to find a data file we can get the # original batch run time from. for dirpath, dirnames, filenames in os.walk( self.settings.BATCH_RESUME): datafiles = [f for f in filenames if f.endswith(resultset.SUFFIX)] if datafiles: f = datafiles[0] r = resultset.load(os.path.join(dirpath, f)) batch_time = r.meta("BATCH_TIME") try: self.settings.BATCH_UUID = r.meta("BATCH_UUID") logger.info(" Using previous UUID %s.\n", self.settings.BATCH_UUID) except KeyError: pass break if batch_time is None: raise RuntimeError("No data files found in resume directory %s." % self.settings.BATCH_RESUME) elif self.settings.BATCH_RESUME: raise RuntimeError("Batch resume directory %s doesn't exist!\n" % self.settings.BATCH_RESUME) else: batch_time = self.settings.TIME filenames_seen = set() for b, settings in self.expand_argsets(batch, argsets, batch_time, batch_name): if 'output_path' in b: output_path = clean_path(b['output_path'], allow_dirs=True) else: output_path = settings.DATA_DIR if settings.BATCH_RESUME is not None: if os.path.commonprefix( [os.path.abspath(output_path), os.path.abspath(settings.BATCH_RESUME)]) \ != os.path.abspath(settings.BATCH_RESUME): raise RuntimeError("Batch-specified output path is not a " "subdirectory of resume path. Bailing.") if os.path.exists(os.path.join(output_path, "%s%s" % (settings.DATA_FILENAME, resultset.SUFFIX))): logger.info(" Previous result exists, skipping.") continue if settings.BATCH_DRY and settings.BATCH_VERBOSE: logger.info(" Would output to: %s.\n", output_path) elif not settings.BATCH_DRY and not os.path.exists(output_path): try: os.makedirs(output_path) except OSError as e: raise RuntimeError("Unable to create output path '%s': %s." % (output_path, e)) commands = self.commands_for(b, settings) if not settings.BATCH_DRY: self.logfile = loggers.setup_logfile( os.path.join(output_path, "%s.log" % settings.DATA_FILENAME), level=loggers.INFO, replay=False) if b.get('debug_log', False): self.logfile_debug = loggers.setup_logfile( os.path.join(output_path, "%s.debug.log" % settings.DATA_FILENAME), level=loggers.DEBUG, maxlevel=loggers.DEBUG, replay=False) if settings.DATA_FILENAME in filenames_seen: logger.warning("Filename already seen in this run: %s", settings.DATA_FILENAME) filenames_seen.add(settings.DATA_FILENAME) self.run_commands(commands, 'pre') self.run_commands(commands, 'monitor') try: if settings.BATCH_VERBOSE: if settings.BATCH_DRY: logger.info(" Would run test '%s'.", settings.NAME) else: logger.info(" Running test '%s'.", settings.NAME) logger.info(" data_filename=%s", settings.DATA_FILENAME) for k in sorted(b.keys()): if k.upper() in SETTINGS_PARSER: logger.info(" %s=%s", k, b[k]) if settings.BATCH_DRY: self.tests_run += 1 else: # Load test again with informational=False to enable host # lookups and other actions that may fail settings.load_test(informational=False) self.run_test(settings, output_path) except KeyboardInterrupt: self.run_commands(commands, 'post', essential_only=True) raise except Exception as e: self.run_commands(commands, 'post', essential_only=True) logger.exception(" Error running test: %s", str(e)) else: try: self.run_commands(commands, 'post') except Exception as e: self.run_commands(commands, 'post', essential_only=True) logger.exception(" Error running post-commands: %s", str(e)) finally: self.kill_children() if self.logfile: loggers.remove_log_handler(self.logfile) self.logfile.close() self.logfile = None if self.logfile_debug: loggers.remove_log_handler(self.logfile_debug) self.logfile_debug.close() self.logfile_debug = None if settings.BATCH_DRY and settings.BATCH_VERBOSE: logger.info(" Would sleep for %d seconds.", pause) elif not settings.BATCH_DRY: time.sleep(pause)