def run_suite(self, test_suite, mux): """ Run one or more tests and report with test result. :param test_suite: a list of tests to run. :return: a list of test failures. """ failures = [] if self.job.sysinfo is not None: self.job.sysinfo.start_job_hook() self.result.start_tests() q = queues.SimpleQueue() ctrl_c = False for test_template in test_suite: for test_factory in mux.itertests(test_template): if not self._run_test(test_factory, q, failures): ctrl_c = True break if ctrl_c: break runtime.CURRENT_TEST = None self.result.end_tests() if self.job.sysinfo is not None: self.job.sysinfo.end_job_hook() return failures
def run_suite(self, test_suite, mux, timeout=0, replay_map=None): """ Run one or more tests and report with test result. :param test_suite: a list of tests to run. :param mux: the multiplexer. :param timeout: maximum amount of time (in seconds) to execute. :return: a list of test failures. """ failures = [] if self.job.sysinfo is not None: self.job.sysinfo.start_job_hook() self.result.start_tests() queue = queues.SimpleQueue() if timeout > 0: deadline = time.time() + timeout else: deadline = None index = -1 for test_template in test_suite: test_template[1]['base_logdir'] = self.job.logdir test_template[1]['job'] = self.job break_loop = False for test_factory in mux.itertests(test_template): index += 1 test_parameters = test_factory[1] if deadline is not None and time.time() > deadline: if 'methodName' in test_parameters: del test_parameters['methodName'] test_factory = (test.TimeOutSkipTest, test_parameters) break_loop = not self.run_test(test_factory, queue, failures) if break_loop: break else: if (replay_map is not None and replay_map[index] is not None): test_parameters["methodName"] = "test" test_factory = (replay_map[index], test_parameters) break_loop = not self.run_test(test_factory, queue, failures, deadline) if break_loop: break runtime.CURRENT_TEST = None if break_loop: break self.result.end_tests() self.job.funcatexit.run() if self.job.sysinfo is not None: self.job.sysinfo.end_job_hook() signal.signal(signal.SIGTSTP, signal.SIG_IGN) return failures
def run_suite(self, test_suite, mux, timeout=0): """ Run one or more tests and report with test result. :param test_suite: a list of tests to run. :param mux: the multiplexer. :param timeout: maximum amount of time (in seconds) to execute. :return: a list of test failures. """ failures = [] if self.job.sysinfo is not None: self.job.sysinfo.start_job_hook() self.result.start_tests() queue = queues.SimpleQueue() if timeout > 0: deadline = time.time() + timeout else: deadline = None for test_template in test_suite: for test_factory in mux.itertests(test_template): if deadline is not None and time.time() > deadline: test_parameters = test_factory[1] if 'methodName' in test_parameters: del test_parameters['methodName'] test_factory = (test.TimeOutSkipTest, test_parameters) self.run_test(test_factory, queue, failures) else: if not self.run_test(test_factory, queue, failures, deadline): break runtime.CURRENT_TEST = None self.result.end_tests() if self.job.sysinfo is not None: self.job.sysinfo.end_job_hook() return failures
def run_suite(self, test_suite, mux, timeout=0, replay_map=None, test_result_total=0): """ Run one or more tests and report with test result. :param test_suite: a list of tests to run. :param mux: the multiplexer. :param timeout: maximum amount of time (in seconds) to execute. :return: a set with types of test failures. """ summary = set() if self.job.sysinfo is not None: self.job.sysinfo.start_job_hook() self.result.start_tests() queue = queues.SimpleQueue() if timeout > 0: deadline = time.time() + timeout else: deadline = None no_digits = len(str(test_result_total)) index = -1 try: for test_template in test_suite: test_template[1]['base_logdir'] = self.job.logdir test_template[1]['job'] = self.job break_loop = False for test_factory, variant in mux.itertests(test_template): index += 1 test_parameters = test_factory[1] name = test_parameters.get("name") test_parameters["name"] = test.TestName(index + 1, name, variant, no_digits) if deadline is not None and time.time() > deadline: summary.add('INTERRUPTED') if 'methodName' in test_parameters: del test_parameters['methodName'] test_factory = (test.TimeOutSkipTest, test_parameters) break_loop = not self.run_test(test_factory, queue, summary) if break_loop: break else: if (replay_map is not None and replay_map[index] is not None): test_parameters["methodName"] = "test" test_factory = (replay_map[index], test_parameters) break_loop = not self.run_test(test_factory, queue, summary, deadline) if break_loop: break runtime.CURRENT_TEST = None if break_loop: break except KeyboardInterrupt: TEST_LOG.error('Job interrupted by ctrl+c.') summary.add('INTERRUPTED') if self.job.sysinfo is not None: self.job.sysinfo.end_job_hook() self.result.end_tests() self.job.funcatexit.run() signal.signal(signal.SIGTSTP, signal.SIG_IGN) return summary
def restore(self, hostname_backup_name, restore_resource, overwrite, recent_to_date, backup_media=None): """ :param hostname_backup_name: :param restore_path: :param overwrite: :param recent_to_date: """ if backup_media == 'fs': LOG.info("Creating restore path: {0}".format(restore_resource)) # if restore path can't be created this function will raise # exception utils.create_dir_tree(restore_resource) if not overwrite and not utils.is_empty_dir(restore_resource): raise Exception( "Restore dir is not empty. " "Please use --overwrite or provide different path " "or remove the content of {}".format(restore_resource)) LOG.info("Restore path creation completed") backups = self.storage.get_latest_level_zero_increments( engine=self, hostname_backup_name=hostname_backup_name, recent_to_date=recent_to_date) max_level = max(backups.keys()) # Use SimpleQueue because Queue does not work on Mac OS X. read_except_queue = queues.SimpleQueue() LOG.info("Restoring backup {0}".format(hostname_backup_name)) for level in range(0, max_level + 1): LOG.info("Restoring from level {0}".format(level)) backup = backups[level] read_pipe, write_pipe = multiprocessing.Pipe() process_stream = multiprocessing.Process( target=self.read_blocks, args=(backup, write_pipe, read_pipe, read_except_queue)) process_stream.daemon = True process_stream.start() write_pipe.close() # Start the tar pipe consumer process # Use SimpleQueue because Queue does not work on Mac OS X. write_except_queue = queues.SimpleQueue() engine_stream = multiprocessing.Process( target=self.restore_level, args=(restore_resource, read_pipe, backup, write_except_queue)) engine_stream.daemon = True engine_stream.start() read_pipe.close() write_pipe.close() process_stream.join() engine_stream.join() # SimpleQueue handling is different from queue handling. def handle_except_SimpleQueue(except_queue): if not except_queue.empty(): while not except_queue.empty(): e = except_queue.get() LOG.exception('Engine error: {0}'.format(e)) return True else: return False got_exception = None got_exception = (handle_except_SimpleQueue(read_except_queue) or got_exception) got_exception = (handle_except_SimpleQueue(write_except_queue) or got_exception) if engine_stream.exitcode or got_exception: raise engine_exceptions.EngineException( "Engine error. Failed to restore.") LOG.info( 'Restore completed successfully for backup name ' '{0}'.format(hostname_backup_name))
def run_suite(self, test_suite, variants, timeout=0, replay_map=None, execution_order=None): """ Run one or more tests and report with test result. :param test_suite: a list of tests to run. :param variants: A varianter iterator to produce test params. :param timeout: maximum amount of time (in seconds) to execute. :param replay_map: optional list to override test class based on test index. :param execution_order: Mode in which we should iterate through tests and variants. If not provided, will default to :attr:`DEFAULT_EXECUTION_ORDER`. :return: a set with types of test failures. """ summary = set() if self.job.sysinfo is not None: self.job.sysinfo.start_job_hook() # Python 3 requires a context for a queue if hasattr(multiprocessing, 'get_context'): ctx = multiprocessing.get_context('spawn') queue = queues.SimpleQueue(ctx=ctx) # pylint: disable=E1123 else: queue = queues.SimpleQueue() # pylint: disable=E1125 if timeout > 0: deadline = time.time() + timeout else: deadline = None test_result_total = variants.get_number_of_tests(test_suite) no_digits = len(str(test_result_total)) self.result.tests_total = test_result_total index = -1 try: for test_template in test_suite: test_template[1]["base_logdir"] = self.job.logdir test_template[1]["job"] = self.job if execution_order is None: execution_order = self.DEFAULT_EXECUTION_ORDER for test_factory, variant in self._iter_suite( test_suite, variants, execution_order): index += 1 test_parameters = test_factory[1] name = test_parameters.get("name") test_parameters["name"] = test.TestID(index + 1, name, variant, no_digits) if deadline is not None and time.time() > deadline: summary.add('INTERRUPTED') if 'methodName' in test_parameters: del test_parameters['methodName'] test_factory = (test.TimeOutSkipTest, test_parameters) if not self.run_test(test_factory, queue, summary): break else: if (replay_map is not None and replay_map[index] is not None): test_parameters["methodName"] = "test" test_factory = (replay_map[index], test_parameters) if not self.run_test(test_factory, queue, summary, deadline): break runtime.CURRENT_TEST = None except KeyboardInterrupt: TEST_LOG.error('Job interrupted by ctrl+c.') summary.add('INTERRUPTED') if self.job.sysinfo is not None: self.job.sysinfo.end_job_hook() self.result.end_tests() self.job.funcatexit.run() signal.signal(signal.SIGTSTP, signal.SIG_IGN) return summary
def scan_all_mca_files(world_obj, options): """ This function scans all te region files from a world_object printing status info in the process. Takes a world object and the options object from region-fixer.py and fills up the mcr_problems dict. The process always uses a multiprocessing pool but the single thread code is still stored just in case is needed. """ w = world_obj total_regions = len(w.all_mca_files) total_chunks = 0 corrupted_total = 0 wrong_total = 0 entities_total = 0 # init progress bar if not options.verbose: pbar = progressbar.ProgressBar(widgets=[ 'Scanning: ', FractionWidget(), ' ', progressbar.Percentage(), ' ', progressbar.Bar(left='[', right=']'), ' ', progressbar.ETA() ], maxval=total_regions) if True: #~ if abs(options.processes) >= 1: # queue used by processes to pass finished stuff q = queues.SimpleQueue() pool = multiprocessing.Pool(processes=options.processes, initializer=_mp_pool_init, initargs=(w, options, q)) if not options.verbose: pbar.start() # start the pool result = pool.map_async(scan_mcr_file, w.all_mca_files, max(1, total_regions // options.processes)) # printing status counter = 0 while not result.ready() or not q.empty(): time.sleep(0.01) if not q.empty(): filename, corrupted, wrong, entities_prob, num_chunks = q.get() corrupted_total += corrupted wrong_total += wrong total_chunks += num_chunks entities_total += entities_prob counter += 1 if options.verbose: stats = "(c: {0}, w: {1}, t: {2})".format( corrupted, wrong, num_chunks) print "Scanned {0: <15} {1:.<40} {2}/{3}".format( filename, stats, counter, total_regions) else: pbar.update(counter) if not options.verbose: pbar.finish() # extract results and fill in the world class w.num_chunks = total_chunks for region_problems in result.get(): for prob in region_problems: filename, chunk, problem = prob add_problem(w, filename, chunk, problem) else: # single thread version, non used anymore, left here because # just-in-case ################## not used >>>>>>>>>>>>>>>>>>> counter = 0 # init the progress bar if not options.verbose: pbar.start() for region_path in w.all_mca_files: # scan for errors filename, corrupted, wrong, total = scan_mcr_file( region_path, options.delete_entities, options.entity_limit) counter += 1 # print status if options.verbose: stats = "(corrupted: {0}, wrong located: {1}, chunks: {2})".format( len(corrupted), len(wrong), total) print "Scanned {0: <15} {1:.<60} {2}/{3}".format( filename, stats, counter, total_regions) else: pbar.update(counter) total_chunks += total if not options.verbose: pbar.finish()
def run_suite(self, test_suite): """ Run one or more tests and report with test result. :param test_suite: a list of tests to run. :return: a list of test failures. """ failures = [] if self.job.sysinfo is not None: self.job.sysinfo.start_job_hook() self.result.start_tests() q = queues.SimpleQueue() for test_factory in test_suite: p = multiprocessing.Process(target=self.run_test, args=( test_factory, q, )) cycle_timeout = 1 time_started = time.time() test_state = None p.start() early_state = q.get() if 'load_exception' in early_state: self.job.view.notify(event='error', msg='Avocado crashed during test load. ' 'Some reports might have not been ' 'generated. Aborting...') sys.exit(exit_codes.AVOCADO_FAIL) # At this point, the test is already initialized and we know # for sure if there's a timeout set. if 'timeout' in early_state['params'].keys(): timeout = float(early_state['params']['timeout']) else: timeout = self.DEFAULT_TIMEOUT time_deadline = time_started + timeout ctrl_c_count = 0 ignore_window = 2.0 ignore_time_started = time.time() stage_1_msg_displayed = False stage_2_msg_displayed = False while True: try: if time.time() >= time_deadline: os.kill(p.pid, signal.SIGUSR1) break wait.wait_for(lambda: not q.empty() or not p.is_alive(), cycle_timeout, first=0.01, step=0.1) if not q.empty(): test_state = q.get() if not test_state['running']: break else: self.job.result_proxy.notify_progress(True) if test_state['paused']: msg = test_state['paused_msg'] if msg: self.job.view.notify(event='partial', msg=msg) elif p.is_alive(): if ctrl_c_count == 0: self.job.result_proxy.notify_progress() else: break except KeyboardInterrupt: time_elapsed = time.time() - ignore_time_started ctrl_c_count += 1 if ctrl_c_count == 2: if not stage_1_msg_displayed: k_msg_1 = ( "SIGINT sent to tests, waiting for their " "reaction") k_msg_2 = ("Ignoring Ctrl+C during the next " "%d seconds so they can try to finish" % ignore_window) k_msg_3 = ( "A new Ctrl+C sent after that will send a " "SIGKILL to them") self.job.view.notify(event='message', msg=k_msg_1) self.job.view.notify(event='message', msg=k_msg_2) self.job.view.notify(event='message', msg=k_msg_3) stage_1_msg_displayed = True ignore_time_started = time.time() if (ctrl_c_count > 2) and (time_elapsed > ignore_window): if not stage_2_msg_displayed: k_msg_3 = ( "Ctrl+C received after the ignore window. " "Killing all active tests") self.job.view.notify(event='message', msg=k_msg_3) stage_2_msg_displayed = True os.kill(p.pid, signal.SIGKILL) # If test_state is None, the test was aborted before it ended. if test_state is None: if p.is_alive() and wait.wait_for( lambda: not q.empty(), cycle_timeout, first=0.01, step=0.1): test_state = q.get() else: early_state['time_elapsed'] = time.time() - time_started test_state = self._fill_aborted_test_state(early_state) test_log = logging.getLogger('avocado.test') test_log.error( 'ERROR %s -> TestAbortedError: ' 'Test aborted unexpectedly', test_state['name']) # don't process other tests from the list if ctrl_c_count > 0: self.job.view.notify(event='minor', msg='') break self.result.check_test(test_state) if not status.mapping[test_state['status']]: failures.append(test_state['name']) runtime.CURRENT_TEST = None self.result.end_tests() if self.job.sysinfo is not None: self.job.sysinfo.end_job_hook() return failures
def scan_regionset(regionset, options): """ This function scans all te region files in a regionset object and fills the ScannedRegionFile obj with the results """ total_regions = len(regionset.regions) total_chunks = 0 corrupted_total = 0 wrong_total = 0 entities_total = 0 too_small_total = 0 unreadable = 0 # init progress bar if not options.verbose: pbar = progressbar.ProgressBar(widgets=[ 'Scanning: ', FractionWidget(), ' ', progressbar.Percentage(), ' ', progressbar.Bar(left='[', right=']'), ' ', progressbar.ETA() ], maxval=total_regions) # queue used by processes to pass finished stuff q = queues.SimpleQueue() pool = multiprocessing.Pool(processes=options.processes, initializer=_mp_pool_init, initargs=(regionset, options, q)) if not options.verbose: pbar.start() # start the pool # Note to self: every child process has his own memory space, # that means every obj recived by them will be a copy of the # main obj result = pool.map_async(multithread_scan_regionfile, regionset.list_regions(None), max(1, total_regions // options.processes)) # printing status region_counter = 0 while not result.ready() or not q.empty(): time.sleep(0.01) if not q.empty(): r = q.get() if r == None: # something went wrong scanning this region file # probably a bug... don't know if it's a good # idea to skip it continue if not isinstance(r, world.ScannedRegionFile): raise ChildProcessException(r) else: corrupted, wrong, entities_prob, shared_offset, num_chunks = r.get_counters( ) filename = r.filename # the obj returned is a copy, overwrite it in regionset regionset[r.get_coords()] = r corrupted_total += corrupted wrong_total += wrong total_chunks += num_chunks entities_total += entities_prob if r.status == world.REGION_TOO_SMALL: too_small_total += 1 elif r.status == world.REGION_UNREADABLE: unreadable += 1 region_counter += 1 if options.verbose: if r.status == world.REGION_OK: stats = "(c: {0}, w: {1}, tme: {2}, so: {3}, t: {4})".format( corrupted, wrong, entities_prob, shared_offset, num_chunks) elif r.status == world.REGION_TOO_SMALL: stats = "(Error: not a region file)" elif r.status == world.REGION_UNREADABLE: stats = "(Error: unreadable region file)" print "Scanned {0: <12} {1:.<43} {2}/{3}".format( filename, stats, region_counter, total_regions) else: pbar.update(region_counter) if not options.verbose: pbar.finish() regionset.scanned = True