def testGetTryJobResultWhenTryJobCompleted(self): analysis = WfAnalysis.Create(self.master_name, self.builder_name, self.build_number) analysis.failure_result_map = {'compile': 'm/b/121'} analysis.put() try_job = WfTryJob.Create(self.master_name, self.builder_name, self.build_number) try_job.status = analysis_status.COMPLETED try_job.compile_results = [{ 'report': { 'result': { 'rev1': 'passed', 'rev2': 'failed' } }, 'try_job_id': 'm/b/121', 'url': ('http://build.chromium.org/p/tryserver.chromium.' 'linux/builders/linux_chromium_variable/builds/121'), 'culprit': { 'compile': { 'revision': 'rev2', 'commit_position': '2', 'review_url': 'url_2' } } }] try_job.put() result = handlers_util.GetAllTryJobResults(self.master_name, self.builder_name, self.build_number) expected_result = { 'compile': { 'try_jobs': [{ 'try_job_key': 'm/b/121', 'status': analysis_status.COMPLETED, 'try_job_build_number': 121, 'try_job_url': ('http://build.chromium.org/p/tryserver.chromium.' 'linux/builders/linux_chromium_variable/builds/121'), 'culprit': { 'revision': 'rev2', 'commit_position': '2', 'review_url': 'url_2' } }] } } self.assertEqual(expected_result, result)
def testGetTryJobResultReturnNoneIfNoFailureResultMap(self): analysis = WfAnalysis.Create(self.master_name, self.builder_name, self.build_number) analysis.put() result = handlers_util.GetAllTryJobResults(self.master_name, self.builder_name, self.build_number) self.assertEqual({}, result)
def _GetTimes(q, r): """Obtains times of interest from a WfAnalysis instance. This is meant to be run by a worker thread.""" while True: a = q.get() result = { 'wfa.build_start_time': a.build_start_time, 'wfa.request_time': a.request_time, 'wfa.start_time': a.start_time, 'wfa.end_time': a.end_time, 'wfa.updated_time': a.updated_time, 'wfa.result_status': a.result_status, 'wfa.build_failure_type': a.build_failure_type, } try: tryjobs_times = {} step_to_tryjobs = handlers_util.GetAllTryJobResults( a.master_name, a.builder_name, a.build_number, True) for step in step_to_tryjobs.keys(): this_tryjobs = step_to_tryjobs[step]['try_jobs'] for job in this_tryjobs: if job.get('try_job_url'): tryjobs_times.setdefault('try.' + step, {}) times = _GetTimesFromBuildbot(job['try_job_url']) tryjobs_times['try.' + step].update(times) if job.get('task_url'): tryjobs_times.setdefault('swarm.' + step, {}) times = _GetTimesFromSwarming(job['task_url']) tryjobs_times['swarm.' + step].update(times) result.update(tryjobs_times) if a.pipeline_status_path: pipeline_root = re.search(r'(?<=root\=)[^&]*', a.pipeline_status_path).group(0) result.update(_GetTimesFromPipeline(pipeline_root)) r.put((a.key, result)) except Exception, e: print 'Problem with ', a.key, e q.task_done()
def testGetAllTryJobResultsTestFailureNoTaskInfo(self): analysis = WfAnalysis.Create(self.master_name, self.builder_name, self.build_number) analysis.failure_result_map = {'step1': {'test1': 'm/b/118'}} analysis.put() result = handlers_util.GetAllTryJobResults(self.master_name, self.builder_name, self.build_number) expected_result = { 'step1': { 'try_jobs': [{ 'try_job_key': 'm/b/118', 'status': (result_status.NO_TRY_JOB_REASON_MAP.get( result_status.NO_SWARMING_TASK_FOUND)), 'tests': ['test1'] }] } } self.assertEqual(expected_result, result)
def testGetTryJobResultReturnNoneIfNoFailureResultMapWithResult(self): analysis = WfAnalysis.Create(self.master_name, self.builder_name, self.build_number) analysis.result = { 'failures': [{ 'step_name': 'a', 'first_failure': 121, 'last_pass': 120, 'supported': True, 'suspected_cls': [], 'tests': [{ 'test_name': 'Unittest1.Subtest1', 'first_failure': 121, 'last_pass': 120, 'suspected_cls': [] }] }] } analysis.put() result = handlers_util.GetAllTryJobResults(self.master_name, self.builder_name, self.build_number) expected_result = { 'a': { 'try_jobs': [{ 'status': result_status.NO_FAILURE_RESULT_MAP, 'tests': ['Unittest1.Subtest1'] }] } } self.assertEqual(expected_result, result)
def _GetAnalysisResultWithTryJobInfo(show_debug_info, organized_results, master_name, builder_name, build_number): """Reorganizes analysis result and try job result by step_name and culprit. Returns: update_result (dict): A dict of classified results. The format for those dicts are as below: { # A dict of results that contains both # heuristic analysis results and try job results. 'reliable_failures': { 'step1': { 'results': [ { 'try_job':{ 'ref_name': 'step1', 'try_job_key': 'm/b/119', 'status': analysis_status.COMPLETED, 'try_job_url': 'url/121', 'try_job_build_number': 121, }, 'heuristic_analysis': { 'suspected_cls': [ { 'build_number': 98, 'repo_name': 'chromium', 'revision': 'r98_1', 'commit_position': None, 'url': None, 'score': 5, 'hints': { 'added f98.cc (and it was in log)': 5, }, } ] } 'tests': ['test1', 'test2'], 'first_failure': 98, 'last_pass': 97, 'supported': True } ] } }, # A dict of result for flaky tests. 'flaky_failures': {...}, # A dict of results for all the other conditions, # such as non-swarming tests or swarming rerun failed. 'unclassified_failures': {...} } """ updated_results = defaultdict( lambda: defaultdict(lambda: defaultdict(list))) if not organized_results: return updated_results try_job_info = handlers_util.GetAllTryJobResults(master_name, builder_name, build_number, show_debug_info) if not try_job_info: return updated_results for step_name, try_jobs in try_job_info.iteritems(): try_jobs = try_jobs['try_jobs'] step_heuristic_results = organized_results[step_name] step_updated_results = updated_results[step_name]['results'] # Finds out try job result index and heuristic result index for each test. test_result_map = defaultdict(lambda: defaultdict(int)) for index, try_job in enumerate(try_jobs): if not try_job.get('tests'): # Compile or non-swarming. test_result_map[NON_SWARMING]['try_job_index'] = index continue for test_name in try_job['tests']: test_result_map[test_name]['try_job_index'] = index for index, heuristic_result in enumerate(step_heuristic_results): if not heuristic_result.get('tests'): # Compile or non-swarming. test_result_map[NON_SWARMING]['heuristic_index'] = index continue for test_name in heuristic_result['tests']: test_result_map[test_name]['heuristic_index'] = index # Group tests based on indices. indices_test_map = defaultdict(list) for test_name, indices in test_result_map.iteritems(): indices_test_map[(indices['try_job_index'], indices['heuristic_index'])].append(test_name) for (try_job_index, heuristic_index), tests in indices_test_map.iteritems(): try_job_result = try_jobs[try_job_index] heuristic_result = step_heuristic_results[heuristic_index] final_result = { 'try_job': try_job_result, 'heuristic_analysis': { 'suspected_cls': heuristic_result['suspected_cls'] }, 'tests': tests if tests != [NON_SWARMING] else [], 'first_failure': heuristic_result['first_failure'], 'last_pass': heuristic_result['last_pass'], 'supported': heuristic_result['supported'] } if (('status' not in try_job_result or try_job_result['status'] in NO_TRY_JOB_REASON_MAP.values()) or try_job_result.get('can_force')): # There is no try job info but only heuristic result. try_job_result['status'] = try_job_result.get( 'status', result_status.UNKNOWN) step_updated_results['unclassified_failures'].append( final_result) elif try_job_result['status'] == result_status.FLAKY: step_updated_results['flaky_failures'].append(final_result) else: step_updated_results['reliable_failures'].append(final_result) return updated_results
def testGetAllTryJobResultsNoAnalysis(self): data = handlers_util.GetAllTryJobResults(self.master_name, self.builder_name, self.build_number) self.assertEqual({}, data)