def testUpdateSuspectedCLPartially(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 }, self.build_key_2: { '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() triage_suspected_cl._UpdateSuspectedCL(self.repo_name, self.revision_1, self.build_key_1, suspected_cl_status.CORRECT) suspected_cl = WfSuspectedCL.Get(self.repo_name, self.revision_1) self.assertEqual(suspected_cl.builds[self.build_key_1]['status'], suspected_cl_status.CORRECT) self.assertEqual(suspected_cl.status, suspected_cl_status.PARTIALLY_TRIAGED) triage_suspected_cl._UpdateSuspectedCL(self.repo_name, self.revision_1, self.build_key_2, suspected_cl_status.INCORRECT) suspected_cl = WfSuspectedCL.Get(self.repo_name, self.revision_1) self.assertEqual(suspected_cl.builds[self.build_key_2]['status'], suspected_cl_status.INCORRECT) self.assertEqual(suspected_cl.status, suspected_cl_status.PARTIALLY_CORRECT)
def testShouldSendNotificationForSecondFailedBuild(self): culprit = WfSuspectedCL.Create('chromium', 'r3', 1) culprit.builds['m/b31/31'] = {} culprit.put() self.assertFalse( send_notification_for_culprit_pipeline._ShouldSendNotification( 'chromium', 'r3', 2, False)) culprit = WfSuspectedCL.Get('chromium', 'r3') culprit.builds['m/b32/32'] = {} culprit.put() self.assertTrue( send_notification_for_culprit_pipeline._ShouldSendNotification( 'chromium', 'r3', 2, False)) culprit = WfSuspectedCL.Get('chromium', 'r3') self.assertEqual(status.RUNNING, culprit.cr_notification_status)
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 _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 _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 testShouldSendNotificationForSecondFailedBuild(self): culprit = WfSuspectedCL.Create('chromium', 'r3', 1) culprit.builds['m/b31/31'] = {} culprit.put() self.assertFalse( culprit_action._ShouldSendNotification('chromium', 'r3', False, None, 2)) culprit = WfSuspectedCL.Get('chromium', 'r3') culprit.builds['m/b32/32'] = {} culprit.put() self.assertTrue( culprit_action._ShouldSendNotification('chromium', 'r3', False, None, 2)) culprit = WfSuspectedCL.Get('chromium', 'r3') self.assertEqual(analysis_status.RUNNING, culprit.cr_notification_status)
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 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 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 _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 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 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 GetWfSuspectedClKeysFromCLInfo(cl_info): """Get a dict of urlsafe keys object from result of GetCLInfo.""" cl_keys = DictOfBasestring() for revision, info in cl_info.iteritems(): culprit = WfSuspectedCL.Get(info['repo_name'], info['revision']) if not culprit: continue cl_keys[revision] = culprit.key.urlsafe() return cl_keys
def _LogUnexpectedAborting(self, was_aborted): if not was_aborted: # pragma: no cover return culprit = WfSuspectedCL.Get(self.repo_name, self.revision) if culprit.revert_status and culprit.revert_status != status.COMPLETED: culprit.revert_status = status.ERROR culprit.put()
def testCreateWfSuspectedCL(self): approach = analysis_approach_type.HEURISTIC master_name = 'm' builder_name = 'b' build_number = 123 compile_failure_type = failure_type.COMPILE repo_name = 'chromium' revision = 'r1' commit_position = 1 failures = {'compile': []} top_score = 5 mocked_utcnow = datetime.datetime(2016, 10, 4, 0, 0, 0) self.MockUTCNow(mocked_utcnow) self.assertIsNone(WfSuspectedCL.Get(repo_name, revision)) suspected_cl_util.UpdateSuspectedCL(repo_name, revision, commit_position, approach, master_name, builder_name, build_number, compile_failure_type, failures, top_score) expected_builds = { build_util.CreateBuildId(master_name, builder_name, build_number): { 'approaches': [approach], 'failure_type': compile_failure_type, 'failures': failures, 'status': None, 'top_score': top_score } } suspected_cl = WfSuspectedCL.Get(repo_name, revision) self.assertIsNotNone(suspected_cl) self.assertEqual([analysis_approach_type.HEURISTIC], suspected_cl.approaches) self.assertEqual([compile_failure_type], suspected_cl.failure_type) self.assertEqual(expected_builds, suspected_cl.builds) self.assertEqual(mocked_utcnow, suspected_cl.identified_time) self.assertEqual(mocked_utcnow, suspected_cl.updated_time)
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 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 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 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 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 GetHeuristicSuspectedCLs(master_name, builder_name, build_number): """Gets revisions of suspected cls found by heuristic approach.""" analysis = WfAnalysis.Get(master_name, builder_name, build_number) suspects = ListOfBasestring() if analysis and analysis.suspected_cls: for cl in analysis.suspected_cls: culprit = WfSuspectedCL.Get(cl['repo_name'], cl['revision']) if not culprit: # pragma: no cover logging.warning( 'No culprit found for repo_name %s and revision %s', cl['repo_name'], cl['revision']) continue suspects.append(culprit.key.urlsafe()) return suspects
def testCommit(self, *_): culprit = WfSuspectedCL.Create('chromium', 'rev1', 1) culprit.put() pipeline_input = SubmitRevertCLParameters( cl_key=culprit.key.urlsafe(), revert_status=constants.CREATED_BY_FINDIT, failure_type=failure_type.COMPILE) self.assertEqual( constants.COMMITTED, culprit_action.CommitRevert(pipeline_input, 'pipeline_id')) culprit = WfSuspectedCL.Get('chromium', 'rev1') self.assertEqual(analysis_status.COMPLETED, culprit.revert_submission_status)
def GetSampleFailedStepName(repo_name, revision, build_id): culprit = WfSuspectedCL.Get(repo_name, revision) if culprit and culprit.builds: if (culprit.builds.get(build_id) and culprit.builds[build_id].get('failures')): failures = culprit.builds[build_id]['failures'] else: logging.warning( '%s is not found in culprit %s/%s\'s build,' ' using another build to get a sample failed step.', build_id, repo_name, revision) failures = culprit.builds.values()[0]['failures'] return failures.keys()[0] logging.error('Cannot get a sample failed step for culprit %s/%s.', repo_name, revision) return ''
def _UpdateSuspectedCL(repo_name, revision, build_key, cl_status, updated_time=None): suspected_cl = WfSuspectedCL.Get(repo_name, revision) if (not suspected_cl or not suspected_cl.builds): return False if not suspected_cl.builds.get(build_key): # The failure is not a first time failure. # Will not update suspected_cl but will update analysis. return True suspected_cl.builds[build_key]['status'] = cl_status cl_correct = True cl_incorrect = True partial_triaged = False # Checks if all the builds have been triaged and checks the status of the cl # on each build. # If all the builds are correct, the cl is correct; # If all the builds are incorrect, the cl is incorrect; # If some builds are correct while others aren't, the cl is partially correct; # If not all the builds have been triaged, the cl is partially triaged. for build in suspected_cl.builds.values(): if build['status'] is None: partial_triaged = True elif build['status'] == suspected_cl_status.CORRECT: cl_incorrect = False else: cl_correct = False if partial_triaged: suspected_cl.status = suspected_cl_status.PARTIALLY_TRIAGED elif cl_correct: suspected_cl.status = suspected_cl_status.CORRECT elif cl_incorrect: suspected_cl.status = suspected_cl_status.INCORRECT else: suspected_cl.status = suspected_cl_status.PARTIALLY_CORRECT suspected_cl.updated_time = updated_time or time_util.GetUTCNow() suspected_cl.put() return True
def testLogUnexpectedAbortingPipelineIdNotMatch(self): repo_name = 'chromium' revision = 'rev1' culprit = WfSuspectedCL.Create(repo_name, revision, 123) culprit.submit_revert_pipeline_id = 'pipeline_id' 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) pipeline.start_test() pipeline.OnAbort(pipeline_input) culprit = WfSuspectedCL.Get(repo_name, revision) self.assertEqual(culprit.submit_revert_pipeline_id, 'pipeline_id')
def _ShouldSendNotification(repo_name, revision, force_notify, revert_status, build_num_threshold): """Returns True if a notification for the culprit should be sent. Send notification only when: 1. The culprit is not reverted. 2. It was not processed yet. 3. 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. force_notify (bool): If we should skip the fail number threshold check. revert_status (int): Status of revert if exists. build_num_threshold (int): Threshold for the number of builds the culprit is responsible for. A notification should be sent when number of builds exceeds the threshold. Returns: A boolean indicating whether we should send the notification. """ if revert_status == constants.CREATED_BY_FINDIT: # Already notified when revert, bail out. return False if revert_status == constants.CREATED_BY_SHERIFF: force_notify = True # 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 = analysis_status.RUNNING culprit.put() return True return False
def testLogUnexpectedAbortingPipelineIdNotMatch(self): repo_name = 'chromium' revision = 'rev1' build_key = 'm/b/123' culprit = WfSuspectedCL.Create(repo_name, revision, 123) culprit.revert_pipeline_id = 'pipeline_id' culprit.put() pipeline_input = CreateRevertCLParameters( cl_key=culprit.key.urlsafe(), build_key=build_key, failure_type=failure_type.COMPILE) pipeline = CreateRevertCLPipeline(pipeline_input) pipeline.start() pipeline.OnAbort(pipeline_input) culprit = WfSuspectedCL.Get(repo_name, revision) self.assertEqual(culprit.revert_pipeline_id, 'pipeline_id')
def _SetActionsForEvent(event): """Sets the actions for an analysis event. Args: (*AnalysisCompletionEventProto): Event proto to be written to. """ if event.analysis_info.culprit.host: # If there's a culprit.host, then the SuspectedCL exists. culprit_cl = WfSuspectedCL.Get(event.analysis_info.culprit.project, event.analysis_info.culprit.revision) assert culprit_cl if culprit_cl.revert_submission_status == analysis_status.COMPLETED: event.analysis_info.actions.append(findit_pb2.REVERT_SUBMITTED) if culprit_cl.revert_status == analysis_status.COMPLETED: event.analysis_info.actions.append(findit_pb2.REVERT_CREATED) if culprit_cl.cr_notification_status == analysis_status.COMPLETED: event.analysis_info.actions.append(findit_pb2.CL_COMMENTED)