def _run(self): # start executor self.executor.start() wait_for(self.executor, 'process') if self.executor.broken: printf.error('Could not start command "{}": {}', Command.to_string(self.executor.command), self.executor.exception) self.returncode = RC(self.executor.returncode) # if process is not broken, propagate start event self.on_process_start(self) while self.executor.is_running(): self.on_process_update(self) if self._short_sleep: time.sleep(0.01) else: self.sleeper.sleep() # get return code rc = getattr(self.executor, 'returncode', None) self.returncode = RC(rc if self.custom_error is None or str(rc) == "0" else self.custom_error) # reverse return code if death test is set if self.case and self.case.death_test is not None: self.returncode = RC( self.case.death_test.reverse_return_code(self.returncode)) self.returncode.reversed = self.case.death_test.value != self.case.death_test.FALSE # propagate on_complete event self.on_process_complete(self)
def test_paths(cls, *paths): status = True for path in paths: filename = getattr(cls, path)() if not cls.exists(filename): printf.error('Error: file {:10s} ({}) does not exists!', path, filename) status = False return status
def create_comparisons(self): comparisons = ComparisonMultiThread( self.case.fs.ndiff_log, progress=printf.verbosity() is printf.OutputVerbosity.FULL) for check_rule in self.case.check_rules: method = str(list(check_rule.keys())[0]) module = self.get_module(method) comp_data = check_rule[method] if not module: printf.error('Warning! No module for check_rule method "{}"', method) continue pairs = self._get_ref_output_files(comp_data) if pairs: for pair in pairs: # load module and determine whether we are dealing with # exec comparison or inplace comparison if issubclass(module.__class__, modules.ExecComparison): command = module.get_command(*pair, **comp_data) pm = PyPy(BinExecutor(command)) pm.executor.output = OutputMode.variable_output() else: module = self.get_module(method) module.prepare(*pair, **comp_data) pm = PyPy(module) pm.executor.output = OutputMode.dummy_output() # pm.error_monitor.deactivate() # if we fail, set error to 13 pm.custom_error = 13 # TODO: maybe some time limit would be useful pm.full_output = self.case.fs.ndiff_log path = Paths.path_end_until(pair[0], REF_OUTPUT_DIR) test_name = Paths.basename( Paths.dirname(Paths.dirname(self.case.fs.ref_output))) size = Paths.filesize(pair[0], True) pm.name = '{}: {} ({})'.format(test_name, path, size) if printf.verbosity() is printf.OutputVerbosity.FULL: pm.monitor.color_complete_format = '{}: {} ({})'.format( test_name, path, size) else: pm.monitor.error_complete_format = '{}: {} ({})'.format( test_name, path, size) comparisons.add(pm) return comparisons
def on_complete(self, pypy=None): if self.log_file: IO.write(self.log_file, self.content) # finish after update if self.update_format and (not self.complete_format and not self.color_complete_format): printf.finish_rewrite() # print regular messages for fmt in ensure_iterable(self.complete_format): printf.out(fmt, monitor=self) # print messages if error if self.pypy.with_error(): for fmt in ensure_iterable(self.error_complete_format): printf.error(fmt, monitor=self) # print regular color messages based on result for fmt in ensure_iterable(self.color_complete_format): if self.pypy.returncode() == 0: printf.success(fmt, monitor=self) elif self.pypy.returncode() is None: printf.warning(fmt, monitor=self) else: printf.error(fmt, monitor=self) with printf: if printf.verbosity() is printf.OutputVerbosity.FULL: printf.sep() printf.out('Output from file {self.pypy.full_output}'.format( **locals())) printf.opt(raw=True).stream( format_n_lines(self.content, pypy.was_successful())) elif printf.verbosity( ) is printf.OutputVerbosity.SMART and pypy.with_error(): printf.sep() printf.out( 'Last 50 lines from file {self.pypy.full_output}'.format( **locals())) printf.opt(raw=True).stream( format_n_lines(self.content, success=False, n_lines=-50)) elif printf.verbosity( ) is printf.OutputVerbosity.MINIMAL and pypy.with_error(): printf.sep() printf.out( 'Last 50 lines from file {self.pypy.full_output}'.format( **locals())) printf.opt(raw=True).stream( format_n_lines(self.content, success=False, n_lines=-50))
def print_runner_stat(cls, runner, formatter=RunnerFormatter): """ :type runner: scripts.core.threads.ParallelThreads :type formatter: RunnerFormatter """ returncodes = [t.returncode for t in runner.threads] skipped = returncodes.count(None) + returncodes.count(-1) passed = returncodes.count(0) failed = len(returncodes) - (skipped + passed) result = 0 if len(returncodes) == passed else 1 status_name = '[ {} ]'.format(TestPrinterStatus.get( str(result))).upper() if result == 0: printf.success(formatter.template.format(**locals())) else: printf.error(formatter.template.format(**locals()))
def do_work(arg_options=None, debug=False): """ Main method which invokes ModuleRuntest :rtype: ParallelThreads :type debug: bool :type arg_options: utils.argparser.RuntestArgs """ module = ModuleRuntest(arg_options) result = module.run(debug) # type: ParallelThreads if not arg_options.queue: printf.sep() if arg_options.save_to_db: from scripts.artifacts.collect.loader import load_data, save_to_database from scripts.artifacts.collect.modules.flow123d_profiler import Flow123dProfiler for t in result.threads: thread = t # type: RuntestMultiThread with printf: printf.out('Processing %s' % thread.pypy.case.fs.output) data = load_data(thread.pypy.case.fs.output, Flow123dProfiler()) if data: with printf: printf.out(' - found %d file(s)' % len(data)) with printf: for item in data: printf.out(' %d element(s)' % len(item.items)) else: printf.error('No profiler data found') save_to_database(data) # pickle out result on demand if arg_options.dump: try: import pickle pickle.dump(result.dump(), open(arg_options.dump, 'wb')) except: pass return result.returncode, result
def _walk_files(self): # switching processing logic self.dir_mode = False # in this loop we are processing all given files/folders all_yamls = list() for path in self.arg_options.args: if not Paths.exists(path): printf.error('given path does not exists, path "{}"', path) sys.exit(3) # append files to all_yamls if Paths.is_dir(path): self.dir_mode = True all_yamls.extend(Paths.walk(path, ConfigPool.yaml_filters)) else: all_yamls.append(path) return all_yamls
def print_test_result(cls, thread, formatter=TestPrinterStatus): """ :type formatter: TestPrinterStatus :type thread: scripts.core.threads.RuntestMultiThread """ status_name = '[ {} ]'.format(formatter.get(str( thread.returncode))).upper() case_name = thread.pypy.case.as_string detail = '' thread_names = ['clean', 'pypy', 'comp'] thread_rcs = dict() thread_msg = dict() for ti in thread_names: subthread = getattr(thread, ti) thread_rcs[ti] = subthread.returncode thread_msg[ti] = getattr(formatter, 'detail_{}'.format(ti))(thread) # first non zero rc will be formatted # otherwise first non empty detail for ti in thread_names: subthread = getattr(thread, ti) if subthread.returncode.failed: sub_detail = thread_msg[ti] detail = formatter.errors[ti].format(**locals()) printf.error(formatter.template.format(**locals())) return # first non empty detail for ti in thread_names: subthread = getattr(thread, ti) sub_detail = thread_msg[ti] if sub_detail: detail = formatter.errors[ti].format(**locals()) printf.out(formatter.template.format(**locals())) return if str(thread.returncode).upper() == 'NONE': printf.warning(formatter.template.format(**locals())) else: printf.success(formatter.template.format(**locals()))
def _check_limits(self): if self.terminated: return if self.time_limit: try: self.runtime = self.process_runtime() if self.runtime > self.time_limit: printf.finish_rewrite() printf.error( 'Time limit exceeded! {:1.2f}s of runtime, {:1.2f}s allowed', self.runtime, self.time_limit) printf.error('Process will now be terminated...') self.terminated_cause = self.CAUSE_TIME_LIMIT self.terminated = True self.process.secure_kill() self.pypy.wakeup() return except AttributeError as e2: pass if self.memory_limit: try: self.memory_usage = self.process_memory_usage() self.memory_used = max(self.memory_used, self.memory_usage) if self.memory_usage > self.memory_limit: printf.finish_rewrite() printf.error( 'Memory limit exceeded! {:1.2f}MB used, {:1.2f}MB allowed ({:1.2f}MB per cpu)', self.memory_usage, self.memory_limit, self.memory_limit / self.proc) printf.error('Process will now be terminated...') self.terminated_cause = self.CAUSE_MEMORY_LIMIT self.terminated = True self.process.secure_kill() self.pypy.wakeup() return # except NoSuchProcess as e1: # pass except AttributeError as e2: pass
or export them to database. """) argparser.Parser.add(group, '--status-file', action=argparser.Parser.STORE_TRUE, help="""R| If set, will also generate status file in test_results directory. Status file will have name "runtest.status.json" and will contain additional information which cannot be obtained from profiler file """) return parser if __name__ == '__main__': parser = create_parser() arg_options = argparser.Parser.parse_runtest(parser) printf.init_logger(verbosity=arg_options.verbosity, logfile=arg_options.log) # run work with Timer.app_timer: BinExecutor.register_sigint() returncode, debug = do_work(arg_options) # run work if arg_options.death: if returncode == 0: printf.error('Command did exit with 0 but should not (--death flag was set)!') sys.exit(1) else: printf.success('Command did not with 0 (--death flag was set)') sys.exit(0) else: sys.exit(returncode())