def testCreateAndSubmitRevert(self, under_limit, can_revert, revert_fn, commit_fn): build_key = 'mock_build_key' repo = 'chromium' rev = 'rev1' commit_position = 100 pipeline_id = 'foo' culprit = FlakeCulprit.Create(repo, rev, commit_position) culprit.put() analysis = MasterFlakeAnalysis.Create('m', 'b', 123, 's', 't') analysis.culprit_urlsafe_key = culprit.key.urlsafe() analysis.put() revert_expected = CreateRevertCLParameters( cl_key=culprit.key.urlsafe(), build_key=build_key, failure_type=failure_type.FLAKY_TEST) submit_expected = SubmitRevertCLParameters( cl_key=culprit.key.urlsafe(), revert_status=constants.CREATED_BY_FINDIT, failure_type=failure_type.FLAKY_TEST) pipeline_input = CreateAndSubmitRevertInput( analysis_urlsafe_key=analysis.key.urlsafe(), build_key=build_key) culprit_util.CreateAndSubmitRevert(pipeline_input, pipeline_id) under_limit.assert_called_once() can_revert.assert_called_once_with(analysis) revert_fn.assert_called_once_with(revert_expected, pipeline_id) commit_fn.assert_called_once_with(submit_expected, pipeline_id) self.assertTrue(analysis.has_created_autorevert) self.assertTrue(analysis.has_submitted_autorevert)
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 testCannotCommitRevertIfNotRevertByFindit(self): parameters = SubmitRevertCLParameters( cl_key='mockurlsafekey', revert_status=constants.CREATED_BY_SHERIFF) pipeline_id = 'pipeline_id' self.assertFalse( culprit_action._CanCommitRevert(parameters, pipeline_id, 'codereview_info'))
def CreateAndSubmitRevert(parameters, runner_id): """Wraps the creation and submission of autoreverts for flaky tests.""" analysis = ndb.Key(urlsafe=parameters.analysis_urlsafe_key).get() assert analysis culprit = ndb.Key(urlsafe=analysis.culprit_urlsafe_key).get() assert culprit # TODO(crbug.com/907675): Create, but not auto commit reverts for some # culprits. if not IsAutorevertEnabled(): analysis.LogInfo('Autorevert is disabled.') return False if not UnderLimitForAutorevert(): analysis.LogInfo('Not autoreverting since limit has been reached.') return False # Verify the conditions for revert are satisfied. if not CanRevertForAnalysis(analysis): analysis.LogInfo('Not reverting: CanRevertForAnalysis returned false.') return False # Create the revert, and check if it succeeded. If it succeeded, then # continue on and submit it. revert_culprit_parameters = CreateRevertCLParameters( cl_key=culprit.key.urlsafe(), build_key=parameters.build_key, failure_type=failure_type.FLAKY_TEST) revert_status = culprit_action.RevertCulprit(revert_culprit_parameters, runner_id) if revert_status != constants.CREATED_BY_FINDIT: analysis.LogInfo( 'Not reverting: RevertCulprit wasn\'t able to create a revert.') return False submit_revert_paramters = SubmitRevertCLParameters( cl_key=culprit.key.urlsafe(), revert_status=revert_status, failure_type=failure_type.FLAKY_TEST) submit_revert_status = culprit_action.CommitRevert(submit_revert_paramters, runner_id) if submit_revert_status != constants.COMMITTED: analysis.LogInfo( 'Not reverting: CommitRevert wasn\'t able to submit the revert') analysis.Update(has_created_autorevert=True) return False analysis.Update(has_created_autorevert=True, has_submitted_autorevert=True, autorevert_submission_time=time_util.GetUTCNow()) return True
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 testSendNotificationToConfirmRevert(self, *_): master_name = 'm' builder_name = 'b' build_number = 124 build_key = 'm/b/124' cl_key = 'mockurlsafekey' culprits = DictOfBasestring() culprits['r1'] = cl_key heuristic_cls = ListOfBasestring() heuristic_cls.append(cl_key) self.MockSynchronousPipeline( CreateRevertCLPipeline, CreateRevertCLParameters(cl_key=cl_key, build_key=build_key, failure_type=failure_type.COMPILE), services_constants.CREATED_BY_FINDIT) self.MockSynchronousPipeline( SubmitRevertCLPipeline, SubmitRevertCLParameters( cl_key=cl_key, revert_status=services_constants.CREATED_BY_FINDIT, failure_type=failure_type.COMPILE), services_constants.COMMITTED) self.MockSynchronousPipeline( SendNotificationToIrcPipeline, SendNotificationToIrcParameters( cl_key=cl_key, revert_status=services_constants.CREATED_BY_FINDIT, commit_status=services_constants.COMMITTED, failure_type=failure_type.COMPILE), True) self.MockSynchronousPipeline( SendNotificationForCulpritPipeline, SendNotificationForCulpritParameters( cl_key=cl_key, force_notify=True, revert_status=services_constants.CREATED_BY_FINDIT, failure_type=failure_type.COMPILE), True) pipeline = wrapper_pipeline.RevertAndNotifyCompileCulpritPipeline( CulpritActionParameters(build_key=BuildKey( master_name=master_name, builder_name=builder_name, build_number=build_number), culprits=culprits, heuristic_cls=heuristic_cls, failure_to_culprit_map=None)) pipeline.start(queue_name=constants.DEFAULT_QUEUE) self.execute_queued_tasks()
def testCommitSkipped(self, *_): repo_name = 'chromium' revision = 'rev1' culprit = WfSuspectedCL.Create(repo_name, revision, 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.SKIPPED, culprit_action.CommitRevert(pipeline_input, 'pipeline_id'))
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 testSubmitRevertSucceed(self, mock_fn, mock_commit, mock_add, *_): 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_for_culprit = RevertCL() revert_change_id = '54321' revert_for_culprit.revert_cl_url = 'https://%s/q/%s' % ( self.review_server_host, revert_change_id) culprit.revert_cl = revert_for_culprit culprit.revert_status = status.COMPLETED culprit.put() revert_status = services_constants.CREATED_BY_FINDIT commit_status = gerrit.CommitRevert( SubmitRevertCLParameters(cl_key=culprit.key.urlsafe(), revert_status=revert_status), self.codereview_info) self.assertEqual(services_constants.COMMITTED, commit_status) mock_commit.assert_called_once_with(revert_change_id) culprit_link = ( 'https://analysis.chromium.org/waterfall/culprit?key=%s' % (culprit.key.urlsafe())) false_positive_bug_link = gerrit.CreateFinditWrongBugLink( gerrit.FINDIT_BUILD_FAILURE_COMPONENT, culprit_link, revision) message = textwrap.dedent(""" Sheriffs, CL owner or CL reviewers: Please confirm this revert if it is correct. If it is a false positive, please reland the original CL and report this false positive at %s. For more information about Findit auto-revert: %s. Sheriffs, it'll be much appreciated if you could take a couple minutes to fill out this survey: %s.""") % ( false_positive_bug_link, gerrit._MANUAL_LINK, gerrit._SURVEY_LINK) mock_add.assert_called_once_with(revert_change_id, ['*****@*****.**'], message)
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 testCanCommitRevert(self, *_): repo_name = 'chromium' revision = 'rev1' culprit = WfSuspectedCL.Create(repo_name, revision, 123) culprit.revert_cl = RevertCL() culprit.revert_status = analysis_status.COMPLETED culprit.put() parameters = SubmitRevertCLParameters( cl_key=culprit.key.urlsafe(), revert_status=constants.CREATED_BY_FINDIT) pipeline_id = 'pipeline_id' self.assertTrue( culprit_action._CanCommitRevert(parameters, pipeline_id, 'codereview_info'))
def testCannotCommitRevertByAnotherAnalysis(self): repo_name = 'chromium' revision = 'rev1' culprit = WfSuspectedCL.Create(repo_name, revision, 123) culprit.revert_cl = RevertCL() culprit.revert_status = analysis_status.COMPLETED culprit.revert_submission_status = analysis_status.RUNNING culprit.submit_revert_pipeline_id = 'pipeline_id' culprit.put() parameters = SubmitRevertCLParameters( cl_key=culprit.key.urlsafe(), revert_status=constants.CREATED_BY_FINDIT) pipeline_id = 'another_pipeline' self.assertFalse( culprit_action._CanCommitRevert(parameters, pipeline_id, 'codereview_info'))
def testCommitRevertNoCodeReview(self, _): 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))) culprit = WfSuspectedCL.Create(repo_name, revision, commit_position) revert_for_culprit = RevertCL() revert_change_id = '54321' revert_for_culprit.revert_cl_url = 'https://%s/q/%s' % ( self.review_server_host, revert_change_id) culprit.revert_cl = revert_for_culprit culprit.revert_status = status.COMPLETED culprit.put() revert_status = services_constants.CREATED_BY_FINDIT self.assertEquals( services_constants.ERROR, gerrit.CommitRevert( SubmitRevertCLParameters(cl_key=culprit.key.urlsafe(), revert_status=revert_status), None))
def testSubmitRevertFailed(self, mock_fn, mock_commit, mock_add, *_): 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 = False culprit = WfSuspectedCL.Create(repo_name, revision, commit_position) revert_for_culprit = RevertCL() revert_change_id = '54321' revert_for_culprit.revert_cl_url = 'https://%s/q/%s' % ( self.review_server_host, revert_change_id) culprit.revert_cl = revert_for_culprit culprit.revert_status = status.COMPLETED culprit.put() revert_status = services_constants.CREATED_BY_FINDIT commit_status = gerrit.CommitRevert( SubmitRevertCLParameters(cl_key=culprit.key.urlsafe(), revert_status=revert_status), self.codereview_info) self.assertEqual(services_constants.ERROR, commit_status) mock_commit.assert_called_once_with(revert_change_id) culprit_link = ( 'https://analysis.chromium.org/waterfall/culprit?key=%s' % culprit.key.urlsafe()) false_positive_bug_link = gerrit.CreateFinditWrongBugLink( gerrit.FINDIT_BUILD_FAILURE_COMPONENT, culprit_link, revision) auto_revert_bug_query = urllib.urlencode({ 'status': 'Available', 'components': 'Tools>Test>FindIt>Autorevert', 'summary': 'Auto Revert failed on %s' % revision, 'comment': 'Detail is %s' % culprit_link }) auto_revert_bug_link = ( 'https://bugs.chromium.org/p/chromium/issues/entry?%s') % ( auto_revert_bug_query) message = textwrap.dedent(""" Sheriffs, CL owner or CL reviewers: Please submit this revert if it is correct. If it is a false positive, please abandon and report it at %s. If failed to submit the revert, please abandon it and report the failure at %s. For more information about Findit auto-revert: %s. Sheriffs, it'll be much appreciated if you could take a couple minutes to fill out this survey: %s.""") % ( false_positive_bug_link, auto_revert_bug_link, gerrit._MANUAL_LINK, gerrit._SURVEY_LINK) mock_add.assert_called_once_with('54321', ['*****@*****.**'], message)