def go(self) -> ReturnCode: options = self.context.options with open(options.input_path, 'rb') as fp: steps = pickle.load(fp) try: heuristic = Heuristic(self.context, steps) except HeuristicException as e: raise Error('could not apply heuristic: {}'.format(e)) self.context.o.auto('{}\n\n{}\n\n{}\n\n'.format( heuristic.summary_string, steps, heuristic.verbose_output)) return ReturnCode.OK
def _run_test(self, test_name): """Attempt to run test files specified in options.source_files. Store result internally in self._test_cases. """ try: builderIR = self._build_test_case() steps = self._get_steps(builderIR) self._record_steps(test_name, steps) heuristic_score = Heuristic(self.context, steps) self._record_score(test_name, heuristic_score) except (BuildScriptException, DebuggerException, HeuristicException) as e: self._record_failed_test(test_name, e) return self._record_successful_test(test_name, steps, heuristic_score) return
def _run_test(self, test_name): # noqa options = self.context.options per_pass_score = [] current_bisect_pass_summary = defaultdict(list) max_limits = self._get_bisect_limits() overall_limit = sum(max_limits) prev_score = 1.0 prev_steps_str = None for current_limit in range(overall_limit + 1): # Take the overall limit number and split it across buckets for # each source file. limit_remaining = current_limit file_limits = [0] * len(max_limits) for i, max_limit in enumerate(max_limits): if limit_remaining < max_limit: file_limits[i] += limit_remaining break else: file_limits[i] = max_limit limit_remaining -= file_limits[i] f = [l for l in file_limits if l] current_file_index = len(f) - 1 if f else 0 _, err, builderIR = self._clang_opt_bisect_build(file_limits) err_lines = err.splitlines() # Find the last line that specified a running pass. for l in err_lines[::-1]: match = Tool._re_running_pass.match(l) if match: pass_info = match.groups() break else: pass_info = (0, None, None) try: debugger_controller =self._init_debugger_controller() debugger_controller = run_debugger_subprocess( debugger_controller, self.context.working_directory.path) steps = debugger_controller.step_collection except DebuggerException: steps = DextIR( executable_path=self.context.options.executable, source_paths=self.context.options.source_files, dexter_version=self.context.version) steps.builder = builderIR try: heuristic = Heuristic(self.context, steps) except HeuristicException as e: raise Error(e) score_difference = heuristic.score - prev_score prev_score = heuristic.score isnan = heuristic.score != heuristic.score if isnan or score_difference < 0: color1 = 'r' color2 = 'r' elif score_difference > 0: color1 = 'g' color2 = 'g' else: color1 = 'y' color2 = 'd' summary = '<{}>running pass {}/{} on "{}"'.format( color2, pass_info[0], max_limits[current_file_index], test_name) if len(options.source_files) > 1: summary += ' [{}/{}]'.format(current_limit, overall_limit) pass_text = ''.join(p for p in pass_info[1:] if p) summary += ': {} <{}>{:+.4f}</> <{}>{}</></>\n'.format( heuristic.summary_string, color1, score_difference, color2, pass_text) self.context.o.auto(summary) heuristic_verbose_output = heuristic.verbose_output if options.verbose: self.context.o.auto(heuristic_verbose_output) steps_str = str(steps) steps_changed = steps_str != prev_steps_str prev_steps_str = steps_str # If a results directory has been specified and this is the first # pass or something has changed, write a text file containing # verbose information on the current status. if options.results_directory and (current_limit == 0 or score_difference or steps_changed): file_name = '-'.join( str(s) for s in [ 'status', test_name, '{{:0>{}}}'.format( len(str(overall_limit))).format(current_limit), '{:.4f}'.format(heuristic.score).replace( '.', '_'), pass_info[1] ] if s is not None) file_name = ''.join( c for c in file_name if c.isalnum() or c in '()-_./ ').strip().replace( ' ', '_').replace('/', '_') output_text_path = os.path.join(options.results_directory, '{}.txt'.format(file_name)) with open(output_text_path, 'w') as fp: self.context.o.auto(summary + '\n', stream=Stream(fp)) self.context.o.auto(str(steps) + '\n', stream=Stream(fp)) self.context.o.auto( heuristic_verbose_output + '\n', stream=Stream(fp)) output_dextIR_path = os.path.join(options.results_directory, '{}.dextIR'.format(file_name)) with open(output_dextIR_path, 'wb') as fp: pickle.dump(steps, fp, protocol=pickle.HIGHEST_PROTOCOL) per_pass_score.append((test_name, pass_text, heuristic.score)) if pass_info[1]: self._all_bisect_pass_summary[pass_info[1]].append( score_difference) current_bisect_pass_summary[pass_info[1]].append( score_difference) if options.results_directory: per_pass_score_path = os.path.join( options.results_directory, '{}-per_pass_score.csv'.format(test_name)) with open(per_pass_score_path, mode='w', newline='') as fp: writer = csv.writer(fp, delimiter=',') writer.writerow(['Source File', 'Pass', 'Score']) for path, pass_, score in per_pass_score: writer.writerow([path, pass_, score]) self.context.o.blue('wrote "{}"\n'.format(per_pass_score_path)) pass_summary_path = os.path.join( options.results_directory, '{}-pass-summary.csv'.format(test_name)) self._write_pass_summary(pass_summary_path, current_bisect_pass_summary)