def testLatestBuildSucceeded(self, mock_fn, *_): repo_name = 'chromium' revision = 'rev1' cl_info = ClInfo(self.review_server_host, self.review_change_id) cl_info.owner_email = '*****@*****.**' cl_info.commits.append( Commit('20001', 'rev1', datetime(2017, 2, 1, 0, 0, 0))) revert_cl = ClInfo('revert_review_host', '123V3127') revert_cl.url = 'https://codereview.chromium.org/54321' cl_info.reverts.append( Revert('20001', revert_cl, constants.DEFAULT_SERVICE_ACCOUNT, datetime(2017, 2, 1, 1, 0, 0))) mock_fn.return_value = cl_info culprit = WfSuspectedCL.Create(repo_name, revision, 123) culprit.revert_cl = RevertCL() culprit.revert_status = status.RUNNING culprit.put() pipeline = CreateRevertCLPipeline('m', 'b', 123, repo_name, revision) revert_status = pipeline.run('m', 'b', 123, repo_name, revision) self.assertEquals(revert_status, create_revert_cl_pipeline.SKIPPED) culprit = WfSuspectedCL.Get(repo_name, revision) self.assertEqual(culprit.revert_status, status.SKIPPED) self.assertIsNotNone(culprit.revert_cl) self.assertEqual(culprit.skip_revert_reason, create_revert_cl_pipeline.NEWEST_BUILD_GREEN)
def testSubmitRevertSucceed(self, mock_fn, mock_commit, *_): repo_name = 'chromium' revision = 'rev1' commit_position = 123 cl_info = ClInfo(self.review_server_host, self.review_change_id) cl_info.commits.append( Commit('20001', 'rev1', [], datetime(2017, 2, 1, 0, 0, 0))) mock_fn.return_value = cl_info mock_commit.return_value = True culprit = WfSuspectedCL.Create(repo_name, revision, commit_position) revert = RevertCL() revert_change_id = '54321' revert.revert_cl_url = 'https://%s/q/%s' % (self.review_server_host, revert_change_id) culprit.revert_cl = revert culprit.revert_status = status.COMPLETED culprit.put() revert_status = constants.CREATED_BY_FINDIT pipeline_input = SubmitRevertCLParameters( cl_key=culprit.key.urlsafe(), revert_status=revert_status, failure_type=failure_type.COMPILE) pipeline = SubmitRevertCLPipeline(pipeline_input) self.assertEqual(constants.COMMITTED, pipeline.run(pipeline_input)) culprit = WfSuspectedCL.Get(repo_name, revision) self.assertEqual(culprit.revert_submission_status, status.COMPLETED) mock_commit.assert_called_with(revert_change_id)
def UpdateSuspectedCL(repo_name, revision, commit_position, approach, master_name, builder_name, build_number, cl_failure_type, failures, top_score): suspected_cl = ( WfSuspectedCL.Get(repo_name, revision) or WfSuspectedCL.Create(repo_name, revision, commit_position)) if not suspected_cl.identified_time: # pragma: no cover. suspected_cl.identified_time = time_util.GetUTCNow() suspected_cl.updated_time = time_util.GetUTCNow() if approach not in suspected_cl.approaches: suspected_cl.approaches.append(approach) if cl_failure_type not in suspected_cl.failure_type: suspected_cl.failure_type.append(cl_failure_type) build_key = BaseBuildModel.CreateBuildKey(master_name, builder_name, build_number) if build_key not in suspected_cl.builds: suspected_cl.builds[build_key] = { 'approaches': [approach], 'failure_type': cl_failure_type, 'failures': failures, 'status': _GetsStatusFromSameFailure(suspected_cl.builds, failures), 'top_score': top_score } else: build = suspected_cl.builds[build_key] if approach not in build['approaches']: build['approaches'].append(approach) suspected_cl.put()
def testRevertCLNotSaved(self, mock_fn, *_): repo_name = 'chromium' revision = 'rev1' cl_info = ClInfo(self.review_server_host, self.review_change_id) cl_info.commits.append( Commit('20001', 'rev1', datetime(2017, 2, 1, 0, 0, 0))) cl_info.owner_email = '*****@*****.**' revert_cl = ClInfo('revert_review_host', '123V3127') revert_cl.url = 'https://codereview.chromium.org/54321' cl_info.reverts.append( Revert('20001', revert_cl, constants.DEFAULT_SERVICE_ACCOUNT, datetime(2017, 2, 1, 1, 0, 0))) mock_fn.return_value = cl_info WfSuspectedCL.Create(repo_name, revision, 123).put() pipeline = CreateRevertCLPipeline('m', 'b', 123, repo_name, revision) revert_status = pipeline.run('m', 'b', 123, repo_name, revision) self.assertEquals(revert_status, create_revert_cl_pipeline.CREATED_BY_FINDIT) culprit = WfSuspectedCL.Get(repo_name, revision) self.assertEqual(culprit.revert_status, status.COMPLETED) self.assertIsNotNone(culprit.revert_cl)
def testRevertCulprit(self, mock_revert, *_): repo_name = 'chromium' revision = 'rev1' build_key = 'm/b/123' revert_cl = RevertCL() revert_cl.revert_cl_url = 'url' revert_cl.created_time = datetime.datetime(2018, 6, 20, 0, 0, 0) mock_revert.return_value = (constants.CREATED_BY_FINDIT, revert_cl, None) culprit = WfSuspectedCL.Create(repo_name, revision, 1) culprit.put() pipeline_input = CreateRevertCLParameters( cl_key=culprit.key.urlsafe(), build_key=build_key, failure_type=failure_type.COMPILE) self.assertEqual( constants.CREATED_BY_FINDIT, culprit_action.RevertCulprit(pipeline_input, 'pipeline_id')) culprit = WfSuspectedCL.Get(repo_name, revision) self.assertEqual(revert_cl, culprit.revert_cl) self.assertEqual(analysis_status.COMPLETED, culprit.revert_status)
def testUpdateSuspectedCLCorrect(self): suspected_cl = WfSuspectedCL.Create( self.repo_name, self.revision_1, self.commit_position) suspected_cl.builds = { self.build_key_1: { 'failure_type': 'test', 'failures': { 's1': ['t1', 't2'] }, 'status': None, 'approaches': [analysis_approach_type.HEURISTIC, analysis_approach_type.TRY_JOB], 'top_score': None, 'Confidence': 80.0 } } suspected_cl.put() cl_status = suspected_cl_status.CORRECT triage_suspected_cl._UpdateSuspectedCL( self.repo_name, self.revision_1, self.build_key_1, cl_status) suspected_cl = WfSuspectedCL.Get(self.repo_name, self.revision_1) self.assertEqual( suspected_cl.builds[self.build_key_1]['status'], cl_status) self.assertEqual(suspected_cl.status, cl_status)
def testLogUnexpectedAbortingNoChange(self): repo_name = 'chromium' revision = 'rev1' culprit = WfSuspectedCL.Create(repo_name, revision, 123) culprit.put() CreateRevertCLPipeline('m', 'b', 123, repo_name, revision)._LogUnexpectedAborting(True) culprit = WfSuspectedCL.Get(repo_name, revision) self.assertIsNone(culprit.revert_status)
def testLogUnexpectedAborting(self): repo_name = 'chromium' revision = 'rev1' culprit = WfSuspectedCL.Create(repo_name, revision, 123) culprit.revert_status = status.RUNNING culprit.put() CreateRevertCLPipeline('m', 'b', 123, repo_name, revision)._LogUnexpectedAborting(True) culprit = WfSuspectedCL.Get(repo_name, revision) self.assertEquals(culprit.revert_status, status.ERROR)
def testShouldNotSendNotificationForSameFailedBuild(self): culprit = WfSuspectedCL.Create('chromium', 'r2', 1) culprit.builds['m/b2/2'] = {} culprit.put() self.assertTrue( send_notification_for_culprit_pipeline._ShouldSendNotification( 'chromium', 'r2', 2, True)) self.assertFalse( send_notification_for_culprit_pipeline._ShouldSendNotification( 'chromium', 'r2', 2, True)) culprit = WfSuspectedCL.Get('chromium', 'r2') self.assertEqual(status.RUNNING, culprit.cr_notification_status)
def testUpdateWfSuspectedCLAddSameBuild(self): approach = analysis_approach_type.HEURISTIC master_name = 'm' builder_name = 'b' build_number = 122 test_failure_type = failure_type.TEST repo_name = 'chromium' revision = 'r2' commit_position = 2 failures = {'step_1': ['test1', 'test2']} top_score = 4 suspected_cl = WfSuspectedCL.Create(repo_name, revision, commit_position) suspected_cl.approaches = [analysis_approach_type.HEURISTIC] suspected_cl.builds = { build_util.CreateBuildId(master_name, builder_name, build_number): { 'approaches': [analysis_approach_type.HEURISTIC], 'failure_type': test_failure_type, 'failures': failures, 'status': None, 'top_score': 4 } } suspected_cl.failure_type = [test_failure_type] suspected_cl.put() suspected_cl_util.UpdateSuspectedCL(repo_name, revision, commit_position, approach, master_name, builder_name, build_number, test_failure_type, failures, top_score) expected_builds = { build_util.CreateBuildId(master_name, builder_name, build_number): { 'approaches': [analysis_approach_type.HEURISTIC], 'failure_type': test_failure_type, 'failures': failures, 'status': None, 'top_score': 4 } } expected_approaches = [analysis_approach_type.HEURISTIC] suspected_cl = WfSuspectedCL.Get(repo_name, revision) self.assertIsNotNone(suspected_cl) self.assertEqual(expected_approaches, suspected_cl.approaches) self.assertEqual([test_failure_type], suspected_cl.failure_type) self.assertEqual(expected_builds, suspected_cl.builds)
def testShouldNotSendNotificationForSameFailedBuild(self): culprit = WfSuspectedCL.Create('chromium', 'r2', 1) culprit.builds['m/b2/2'] = {} culprit.put() self.assertTrue( culprit_action._ShouldSendNotification( 'chromium', 'r2', True, constants.CREATED_BY_SHERIFF, 2)) self.assertFalse( culprit_action._ShouldSendNotification( 'chromium', 'r2', True, constants.CREATED_BY_SHERIFF, 2)) culprit = WfSuspectedCL.Get('chromium', 'r2') self.assertEqual(analysis_status.RUNNING, culprit.cr_notification_status)
def testLogUnexpectedAborting(self): repo_name = 'chromium' revision = 'rev1' culprit = WfSuspectedCL.Create(repo_name, revision, 123) culprit.revert_submission_status = status.RUNNING culprit.put() revert_status = constants.CREATED_BY_FINDIT pipeline_input = SubmitRevertCLParameters( cl_key=culprit.key.urlsafe(), revert_status=revert_status, failure_type=failure_type.COMPILE) SubmitRevertCLPipeline(pipeline_input).OnAbort(pipeline_input) culprit = WfSuspectedCL.Get(repo_name, revision) self.assertEquals(culprit.revert_submission_status, status.ERROR)
def testLogUnexpectedAbortingNoChange(self): repo_name = 'chromium' revision = 'rev1' build_key = 'm/b/123' culprit = WfSuspectedCL.Create(repo_name, revision, 123) culprit.put() pipeline_input = CreateRevertCLParameters( cl_key=culprit.key.urlsafe(), build_key=build_key, failure_type=failure_type.COMPILE) CreateRevertCLPipeline(pipeline_input).OnAbort(pipeline_input) culprit = WfSuspectedCL.Get(repo_name, revision) self.assertIsNone(culprit.revert_status)
def testRevertCLSucceed(self, mock_fn, mock_revert, *_): repo_name = 'chromium' revision = 'rev1' commit_position = 123 build_key = 'm/b/123' cl_info = ClInfo(self.review_server_host, self.review_change_id) cl_info.commits.append( Commit('20001', 'rev1', ['rev0'], datetime(2017, 2, 1, 0, 0, 0))) cl_info.owner_email = '*****@*****.**' mock_fn.return_value = cl_info mock_revert.return_value = '54321' culprit = WfSuspectedCL.Create(repo_name, revision, commit_position) culprit.builds = { build_key: { 'status': None, 'failures': { 'step': ['test1'] } } } culprit.put() pipeline_input = CreateRevertCLParameters( cl_key=culprit.key.urlsafe(), build_key=build_key, failure_type=failure_type.COMPILE) pipeline = CreateRevertCLPipeline(pipeline_input) revert_status = pipeline.run(pipeline_input) self.assertEquals(revert_status, constants.CREATED_BY_FINDIT) culprit = WfSuspectedCL.Get(repo_name, revision) self.assertEqual(culprit.revert_status, status.COMPLETED) self.assertIsNotNone(culprit.revert_cl) reason = textwrap.dedent(""" Findit (https://goo.gl/kROfz5) identified CL at revision %s as the culprit for failures in the build cycles as shown on: https://analysis.chromium.org/waterfall/culprit?key=%s\n Sample Failed Build: %s\n Sample Failed Step: %s""") % (commit_position, culprit.key.urlsafe(), buildbot.CreateBuildUrl('m', 'b', '123'), 'step') mock_revert.assert_called_with(reason, self.review_change_id, '20001', bug_id=None)
def setUp(self): super(TestCulpritActionTest, self).setUp() repo_name = 'chromium' revision = 'rev1' self.culprit = WfSuspectedCL.Create(repo_name, revision, 100).put().urlsafe() culprit_dict = DictOfBasestring() culprit_dict[revision] = self.culprit heuristic_cls = ListOfBasestring() heuristic_cls.append(self.culprit) parameters_dict = { 'build_key': { 'master_name': 'm', 'builder_name': 'b', 'build_number': 123 }, 'culprits': { 'rev1': self.culprit }, 'heuristic_cls': heuristic_cls } self.parameters = CulpritActionParameters.FromSerializable( parameters_dict)
def testSendNotificationForCulprit(self, mock_post, _): repo_name = 'chromium' revision = 'rev1' revert_status = None culprit = WfSuspectedCL.Create(repo_name, revision, 123) culprit.put() culprit_link = culprit.GetCulpritLink() false_positive_bug_link = gerrit.CreateFinditWrongBugLink( gerrit.FINDIT_BUILD_FAILURE_COMPONENT, culprit_link, revision) parameters = SendNotificationForCulpritParameters( cl_key=culprit.key.urlsafe(), force_notify=False, revert_status=revert_status, failure_type=failure_type.COMPILE) self.assertTrue( gerrit.SendNotificationForCulprit(parameters, self.codereview_info)) message = textwrap.dedent(""" Findit (https://goo.gl/kROfz5) %s this CL at revision %s as the culprit for failures in the build cycles as shown on: https://analysis.chromium.org/waterfall/culprit?key=%s If it is a false positive, please report it at %s.""") % ( 'identified', self.culprit_commit_position, culprit.key.urlsafe(), false_positive_bug_link) mock_post.assert_called_once_with(self.review_change_id, message, True)
def testAddedReviewerFailedBefore(self, mock_fn, mock_send, *_): repo_name = 'chromium' revision = 'rev1' cl_info = ClInfo(self.review_server_host, self.review_change_id) cl_info.commits.append( Commit('20001', 'rev1', [], datetime(2017, 2, 1, 0, 0, 0))) cl_info.owner_email = '*****@*****.**' revert_cl = ClInfo('revert_review_host', '123V3127') revert_cl.url = 'https://chromium-review.googlesource.com/54321' cl_info.reverts.append( Revert('20001', revert_cl, constants.DEFAULT_SERVICE_ACCOUNT, datetime(2017, 2, 1, 1, 0, 0))) mock_fn.return_value = cl_info culprit = WfSuspectedCL.Create(repo_name, revision, 123) culprit.revert_cl = RevertCL() culprit.revert_status = status.RUNNING culprit.cr_notification_status = status.COMPLETED culprit.put() revert_status, _, _ = gerrit.RevertCulprit(culprit.key.urlsafe(), 'm/b/1', failure_type.COMPILE, 'compile', self.codereview_info) self.assertEquals(revert_status, services_constants.CREATED_BY_FINDIT)
def _AddDummyCLs(self): suspected_cls = [] for i in xrange(0, 10): cl = self._AddCL(i) suspected_cls.append(cl) # Adds a cl with no builds. cl10 = WfSuspectedCL.Create('chromium', '10', None) cl10.approaches = APPROACH_MAP[2] cl10.status = suspected_cl_status.CORRECT cl10.updated_time = self.start_date + datetime.timedelta(hours=10) cl10.put() suspected_cls.append(cl10) # Adds a build with the same failure for a heuristic result. new_value = copy.deepcopy(suspected_cls[3].builds['m/b/3']) suspected_cls[3].builds['new_key'] = new_value suspected_cls[3].put() # Adds a build with the same failure for a try job result. new_value = copy.deepcopy(suspected_cls[4].builds['m/b/4']) suspected_cls[4].builds['new_key'] = new_value suspected_cls[4].put() return suspected_cls
def _GetDailyNumberOfRevertedCulprits(limit): earliest_time = time_util.GetUTCNow() - timedelta(days=1) # TODO(chanli): improve the check for a rare case when two pipelines revert # at the same time. return WfSuspectedCL.query( ndb.AND(WfSuspectedCL.failure_type == failure_type.COMPILE, WfSuspectedCL.revert_created_time >= earliest_time)).count(limit)
def _SendNotificationForCulprit(repo_name, revision, commit_position, review_server_host, change_id, revert_status): code_review_settings = FinditConfig().Get().code_review_settings codereview = codereview_util.GetCodeReviewForReview( review_server_host, code_review_settings) sent = False if codereview and change_id: # Occasionally, a commit was not uploaded for code-review. culprit = WfSuspectedCL.Get(repo_name, revision) action = 'identified' if revert_status == create_revert_cl_pipeline.CREATED_BY_SHERIFF: action = 'confirmed' message = textwrap.dedent(""" Findit (https://goo.gl/kROfz5) %s this CL at revision %s as the culprit for failures in the build cycles as shown on: https://findit-for-me.appspot.com/waterfall/culprit?key=%s""") % ( action, commit_position or revision, culprit.key.urlsafe()) sent = codereview.PostMessage(change_id, message) else: logging.error('No code-review url for %s/%s', repo_name, revision) _UpdateNotificationStatus(repo_name, revision, status.COMPLETED if sent else status.ERROR) return sent
def _GetCLDataForTryJob(date_start, date_end): """Gets All triaged CLs which were found by try job approaches.""" suspected_cls_query = WfSuspectedCL.query( ndb.AND(WfSuspectedCL.status.IN(TRIAGED_STATUS), WfSuspectedCL.approaches == analysis_approach_type.TRY_JOB, WfSuspectedCL.updated_time >= date_start, WfSuspectedCL.updated_time < date_end)) suspected_cls = suspected_cls_query.fetch() try_job_cls_dict = defaultdict(lambda: defaultdict(int)) both_cls_dict = defaultdict(lambda: defaultdict(int)) for cl in suspected_cls: if not cl.builds: continue failures = [] for build in cl.builds.values(): # Deduplicate and ignore the builds which were not triaged. if (build['failures'] in failures or build['status'] is None): # pragma: no cover continue failures.append(build['failures']) try_job_cls_dict[build['failure_type']][build['status']] += 1 if analysis_approach_type.HEURISTIC in build['approaches']: # Both heuristic and try job found this CL on this build. both_cls_dict[build['failure_type']][build['status']] += 1 return try_job_cls_dict, both_cls_dict
def _GetAdditionalInformationForCL( self, repo_name, revision, confidences, build, reference_build_key): """Gets additional information for a cl. Currently additional information contains: confidence of the result; approaches that found this cl: HEURISTIC, TRY_JOB or both; revert_cl_url if the cl has been reverted by Findit. """ additional_info = {} cl = WfSuspectedCL.Get(repo_name, revision) if not cl: return additional_info master_name = buildbot.GetMasterNameFromUrl(build.master_url) builder_name = build.builder_name current_build = build.build_number # If the CL is found by a try job, only the first failure will be recorded. # So we might need to go to the first failure to get CL information. build_info = cl.GetBuildInfo(master_name, builder_name, current_build) first_build_info = None if not reference_build_key else cl.GetBuildInfo( *build_util.GetBuildInfoFromId(reference_build_key)) additional_info['confidence'], additional_info['cl_approach'] = ( suspected_cl_util.GetSuspectedCLConfidenceScoreAndApproach( confidences, build_info, first_build_info)) # Gets the revert_cl_url for the CL if there is one. if cl.revert_cl_url: additional_info['revert_cl_url'] = cl.revert_cl_url return additional_info
def testGetHeuristicSuspectedCLs(self): repo_name = 'chromium' revision = 'r123_2' culprit = WfSuspectedCL.Create(repo_name, revision, None) culprit.put() analysis = WfAnalysis.Create('m', 'b', 123) analysis.suspected_cls = [{ 'repo_name': repo_name, 'revision': revision, 'commit_position': None, 'url': None, 'failures': { 'b': ['Unittest2.Subtest1', 'Unittest3.Subtest2'] }, 'top_score': 4 }] analysis.put() suspected_cls = [culprit.key.urlsafe()] self.assertEqual( suspected_cls, build_failure_analysis.GetHeuristicSuspectedCLs( 'm', 'b', 123).ToSerializable())
def testGetWfSuspectedClKeysFromCLInfo(self): cl_info = { 'rev1': { 'revision': 'rev1', 'repo_name': 'chromium', 'commit_position': 100 }, 'rev2': { 'revision': 'rev2', 'repo_name': 'chromium', 'commit_position': 123, 'url': 'url' } } expected_cl_keys = {} for _, v in cl_info.iteritems(): cl = WfSuspectedCL.Create(v['repo_name'], v['revision'], v['commit_position']) cl.put() expected_cl_keys[v['revision']] = cl.key.urlsafe() self.assertEqual(expected_cl_keys, consistent_failure_culprits.GetWfSuspectedClKeysFromCLInfo( cl_info).ToSerializable())
def testUpdateSuspectedCLNonFirstTimeFailure(self): suspected_cl = WfSuspectedCL.Create(self.repo_name, self.revision_1, self.commit_position) suspected_cl.builds = { self.build_key_1: { 'failure_type': 'test', 'failures': { 's1': ['t1', 't2'] }, 'status': None, 'approaches': [ analysis_approach_type.HEURISTIC, analysis_approach_type.TRY_JOB ], 'top_score': None, 'Confidence': 80.0 } } suspected_cl.put() self.assertTrue( triage_suspected_cl._UpdateSuspectedCL(self.repo_name, self.revision_1, self.build_key_2, None))
def testCanAutoCreateRevert(self, _): repo_name = 'chromium' revision = 'rev1' culprit = WfSuspectedCL.Create(repo_name, revision, 123) culprit.failure_type.append(failure_type.TEST) culprit.revert_created_time = datetime(2018, 2, 14, 12, 0, 0) culprit.put() culprit_dict = DictOfBasestring() culprit_dict[revision] = culprit.key.urlsafe() heuristic_cls = ListOfBasestring() heuristic_cls.append(culprit.key.urlsafe()) parameters_dict = { 'build_key': { 'master_name': 'm', 'builder_name': 'b', 'build_number': 123 }, 'culprits': { 'rev1': culprit.key.urlsafe() }, 'heuristic_cls': heuristic_cls } parameters = CulpritActionParameters.FromSerializable(parameters_dict) self.assertTrue( test_culprit_action.CanAutoCreateRevert(culprit.key.urlsafe(), parameters))
def _ShouldSendNotification(repo_name, revision, build_num_threshold, force_notify): """Returns True if a notification for the culprit should be sent. Send notification only when: 1. It was not processed yet. 2. The culprit is for multiple failures in different builds to avoid false positive due to flakiness. Any new criteria for deciding when to notify should be implemented within this function. Args: repo_name, revision (str): Uniquely identify the revision to notify about. build_num_threshold (int): The number of builds the culprit needs to cause to fail before we notify. (To avoid false notifications for flake) force_notify (bool): If we should skip the fail number threshold check. Returns: A boolean indicating whether we should send the notification. """ # TODO (chanli): Add check for if confidence for the culprit is # over threshold. culprit = WfSuspectedCL.Get(repo_name, revision) assert culprit if culprit.cr_notification_processed: return False if force_notify or len(culprit.builds) >= build_num_threshold: culprit.cr_notification_status = status.RUNNING culprit.put() return True return False
def _GetCLDataForHeuristic(date_start, date_end): """Gets All triaged CLs which were found by heuristic approaches.""" suspected_cls_query = WfSuspectedCL.query( ndb.AND(WfSuspectedCL.status.IN(TRIAGED_STATUS), WfSuspectedCL.approaches == analysis_approach_type.HEURISTIC, WfSuspectedCL.updated_time >= date_start, WfSuspectedCL.updated_time < date_end)) suspected_cls = suspected_cls_query.fetch() cl_by_top_score_dict = defaultdict( lambda: defaultdict(lambda: defaultdict(int))) for cl in suspected_cls: if not cl.builds: continue failures = [] for build in cl.builds.values(): # Deduplicate and ignore the builds which were not found by heuristic # approach and ignore the builds which were not triaged. if (build['failures'] in failures or not build['top_score'] or build['status'] is None): # pragma: no cover continue failures.append(build['failures']) failure = build['failure_type'] top_score = build['top_score'] status = build['status'] cl_by_top_score_dict[failure][top_score][status] += 1 return cl_by_top_score_dict
def _GetAllSuspectedCLsAndCheckStatus(master_name, builder_name, build_number, analysis): build_key = build_util.CreateBuildId(master_name, builder_name, build_number) suspected_cls = copy.deepcopy(analysis.suspected_cls) if not suspected_cls: return [] confidences = SuspectedCLConfidence.Get() for cl in suspected_cls: cl['status'] = _ANALYSIS_CL_STATUS_MAP.get(analysis.result_status, None) cl['confidence'] = None suspected_cl = WfSuspectedCL.Get(cl['repo_name'], cl['revision']) if not suspected_cl: continue build = suspected_cl.builds.get(build_key) if build: cl['status'] = build['status'] cl['confidence'] = '%d%%' % ( suspected_cl_util.GetSuspectedCLConfidenceScore( confidences, build)) return suspected_cls
def testUpdateSuspectedCLBailOut(self): suspected_cl = WfSuspectedCL.Create('chromium', 'a1b2c3d4', 1) suspected_cl.sheriff_action_time = datetime(2017, 4, 6, 0, 0) check_reverted_cls._UpdateSuspectedCL(suspected_cl, datetime(2017, 4, 6, 0, 1)) self.assertEqual(datetime(2017, 4, 6, 0, 0), suspected_cl.sheriff_action_time)