def testCorpUserCanViewAnalysisOfFailureOnUnsupportedMaster( self, mocked_ValidateAuthToken): mocked_ValidateAuthToken.side_effect = [(True, False)] master_name = 'm2' builder_name = 'b 1' build_number = 123 build_url = buildbot.CreateBuildUrl(master_name, builder_name, build_number) analysis = WfAnalysis.Create(master_name, builder_name, build_number) analysis.status = analysis_status.COMPLETED analysis.put() self.mock_current_user(user_email='*****@*****.**', is_admin=False) response = self.test_app.post('/failure', params={ 'url': build_url, 'xsrf_token': 'ab' }, status=302) redirect_url = '/waterfall/failure?redirect=1&url=%s' % build_url self.assertTrue( response.headers.get('Location', '').endswith(redirect_url)) self.assertEqual(0, len(self.taskqueue_stub.get_filtered_tasks()))
def testNotEveryoneCanRequestNewAnalysisOfFailureOnSupportedMaster( self, mock_fn, mocked_ValidateAuthToken): mocked_ValidateAuthToken.side_effect = [(True, False)] master_name = 'm' builder_name = 'b 1' build_number = 123 build_url = buildbot.CreateBuildUrl(master_name, builder_name, build_number) build_info = BuildInfo(master_name, builder_name, build_number) build_info.completed = False mock_fn.return_value = build_info self.mock_current_user(user_email='*****@*****.**', is_admin=False) response = self.test_app.post('/failure', params={ 'url': build_url, 'xsrf_token': 'abc' }, status=302) redirect_url = '/waterfall/failure?redirect=1&url=%s' % build_url self.assertTrue( response.headers.get('Location', '').endswith(redirect_url)) self.assertEqual(0, len(self.taskqueue_stub.get_filtered_tasks()))
def testCannotRerunIncompleteBuild(self, mock_fn, mocked_ValidateAuthToken): mocked_ValidateAuthToken.side_effect = [(True, False)] master_name = 'm' builder_name = 'b 1' build_number = 123 build_url = buildbot.CreateBuildUrl(master_name, builder_name, build_number) build_info = BuildInfo(master_name, builder_name, build_number) build_info.completed = False mock_fn.return_value = build_info self.mock_current_user(user_email='*****@*****.**', is_admin=True) self.assertRaisesRegexp( webtest.app.AppError, re.compile( '.*501 Not Implemented.*Can't force a rerun for an ' 'incomplete build "%s/%s/%s".*' % (master_name, builder_name, build_number), re.MULTILINE | re.DOTALL), self.test_app.post, '/failure', params={ 'url': build_url, 'force': '1', 'xsrf_token': 'abc' })
def _MockUrlfetchWithBuildData(self, master_name, builder_name, build_number, build_data=None, archive=False): """If build data is None, use json file in waterfall/test/data.""" if build_data is None: build_data = self._GetBuildData(master_name, builder_name, build_number) if archive: if build_data == 'Test get build data': build_data = build_data + ' from archive' archived_build_url = buildbot.CreateArchivedBuildUrl( master_name, builder_name, build_number) self.mocked_urlfetch.register_handler(archived_build_url, build_data) if build_data == 'Test get build data': build_data = build_data + ' from build master' build_url = buildbot.CreateBuildUrl(master_name, builder_name, build_number, json_api=True) self.mocked_urlfetch.register_handler(build_url, build_data)
def testGetTriageHistory(self, *_): master_name = 'm' builder_name = 'b' build_number = '123' step_name = 's' test_name = 't' suspected_flake_build_number = 123 triage_result = 2 user_name = 'test' analysis = MasterFlakeAnalysis.Create( master_name, builder_name, build_number, step_name, test_name) analysis.status = analysis_status.COMPLETED analysis.suspected_flake_build_number = 100 analysis.Save() analysis.UpdateTriageResult( triage_result, {'build_number': suspected_flake_build_number}, 'test') response = self.test_app.get('/waterfall/flake', params={ 'url': buildbot.CreateBuildUrl(master_name, builder_name, build_number), 'step_name': step_name, 'test_name': test_name, 'format': 'json'}) # Because TriagedResult uses auto_now=True, a direct dict comparison will # always fail. Instead only compare the relevant fields for trige_history. triage_history = response.json_body.get('triage_history') self.assertEqual(len(triage_history), 1) self.assertEqual(triage_history[0].get('triage_result'), 'Correct') self.assertEqual(triage_history[0].get('user_name'), user_name) self.assertEqual( triage_history[0].get('suspect_info', {}).get('build_number'), suspected_flake_build_number)
def testCannotRerunIncompleteBuild(self, mock_fn): master_name = 'm2' builder_name = 'b 1' build_number = 123 build_url = buildbot.CreateBuildUrl(master_name, builder_name, build_number) build_info = BuildInfo(master_name, builder_name, build_number) build_info.completed = False mock_fn.return_value = build_info self.mock_current_user(user_email='*****@*****.**', is_admin=True) self.assertRaisesRegexp( webtest.app.AppError, re.compile( '.*501 Not Implemented.*Can't rerun an incomplete' ' build "%s/%s/%s".*' % (master_name, builder_name, build_number), re.MULTILINE | re.DOTALL), self.test_app.get, '/failure', params={ 'url': build_url, 'force': '1' })
def testCreateBuildUrl(self): master_name = 'a' builder_name = 'Win7 Tests (1)' build_number = 123 expected_url = ('https://build.chromium.org/p/a/builders/' 'Win7%20Tests%20%281%29/builds/123') expected_url_json = ('https://build.chromium.org/p/a/json/builders/' 'Win7%20Tests%20%281%29/builds/123') self.assertEqual( expected_url, buildbot.CreateBuildUrl(master_name, builder_name, build_number)) self.assertEqual( expected_url_json, buildbot.CreateBuildUrl(master_name, builder_name, build_number, True))
def testCreateBuildUrl(self): master_name = 'a' builder_name = 'Win7 Tests (1)' build_number = 123 expected_url = ('https://ci.chromium.org/buildbot/a/' 'Win7%20Tests%20%281%29/123') self.assertEqual( expected_url, buildbot.CreateBuildUrl(master_name, builder_name, build_number))
def testCreateBuildUrl(self): master_name = 'a' builder_name = 'Win7 Tests (1)' build_number = 123 expected_url = ('https://luci-milo.appspot.com/buildbot/a/' 'Win7%20Tests%20%281%29/123') self.assertEqual( expected_url, buildbot.CreateBuildUrl(master_name, builder_name, build_number))
def testSuccessfulTriage(self): build_url = buildbot.CreateBuildUrl(self.master_name, self.builder_name, self.build_number_found) response = self.test_app.get('/triage-analysis', params={ 'url': build_url, 'correct': True, 'format': 'json' }) self.assertEquals(200, response.status_int) self.assertEquals({'success': True}, response.json_body)
def testHelpTriageHandlerReturnNoneForGreenBuild(self): build_url = buildbot.CreateBuildUrl(self.master_name, self.builder_name, 123) build = WfBuild.Create(self.master_name, self.builder_name, 123) build.data = self._GetBuildInfo(self.master_name, self.builder_name, 123) build.put() response = self.test_app.get('/help-triage', params={'url': build_url}) expected_results = {} self.assertEqual(200, response.status_int) self.assertEqual(expected_results, response.json_body)
def testAnalysisNotFound(self): master_name = 'm' builder_name = 'b 1' build_number = 123 build_url = buildbot.CreateBuildUrl(master_name, builder_name, build_number) response = self.test_app.get('/failure', params={ 'format': 'json', 'url': build_url }, status=400) self.assertEqual('Please schedule analyses on home page instead.', response.json_body.get('error_message'))
def testTriageFailed(self, *_): build_url = buildbot.CreateBuildUrl(self.master_name, self.builder_name, self.build_number_1) response = self.test_app.post( '/triage-suspected-cl', params={ 'url': build_url, 'status': '0', 'cl_info': 'chromium/rev1', 'xsrf_token': 'abc', 'format': 'json', }) self.assertEquals(200, response.status_int) self.assertEquals({'success': False}, response.json_body)
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 testAnalysisNotFoundAfterRedirect(self): master_name = 'm' builder_name = 'b 1' build_number = 123 build_url = buildbot.CreateBuildUrl(master_name, builder_name, build_number) response = self.test_app.get('/failure', params={ 'format': 'json', 'url': build_url, 'redirect': '1' }, status=401) self.assertEqual('No permission to schedule a new analysis.', response.json_body.get('error_message'))
def testAnyoneCanRequestAnalysisOfFailureOnSupportedMaster(self, mock_fn): master_name = 'm' builder_name = 'b 1' build_number = 123 build_url = buildbot.CreateBuildUrl(master_name, builder_name, build_number) build_info = BuildInfo(master_name, builder_name, build_number) build_info.completed = False mock_fn.return_value = build_info response = self.test_app.get('/failure', params={'url': build_url}) self.assertEquals(200, response.status_int) self.assertEqual(1, len(self.taskqueue_stub.get_filtered_tasks()))
def GenerateRevertReason(self, build_id, commit_position, revision, sample_step_name=None): sample_build = build_id.split('/') sample_build_url = buildbot.CreateBuildUrl(*sample_build) return 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 or revision, self.key.urlsafe(), sample_build_url, sample_step_name)
def testNonAdminCannotRequestAnalysisOfFailureOnUnsupportedMaster(self): master_name = 'm2' builder_name = 'b 1' build_number = 123 build_url = buildbot.CreateBuildUrl(master_name, builder_name, build_number) self.assertRaisesRegexp( webtest.app.AppError, re.compile( '.*501 Not Implemented.*Master "%s" ' 'is not supported yet.*' % master_name, re.MULTILINE | re.DOTALL), self.test_app.get, '/failure', params={'url': build_url})
def testSuccessfulTriage(self): build_url = buildbot.CreateBuildUrl( self.master_name, self.builder_name, self.build_number_1) response = self.test_app.get( '/triage-suspected-cl', params={ 'url': build_url, 'status': '0', 'cl_info': 'chromium/rev1', 'format': 'json' }) self.assertEquals(200, response.status_int) self.assertEquals( { 'success': False }, response.json_body)
def testAdminCanRequestAnalysisOfFailureOnUnsupportedMaster(self, mock_fn): master_name = 'm2' builder_name = 'b' build_number = 123 build_url = buildbot.CreateBuildUrl(master_name, builder_name, build_number) build_info = BuildInfo(master_name, builder_name, build_number) build_info.completed = False mock_fn.return_value = build_info self.mock_current_user(user_email='*****@*****.**', is_admin=True) response = self.test_app.get('/failure', params={'url': build_url}) self.assertEquals(200, response.status_int) self.assertEqual(1, len(self.taskqueue_stub.get_filtered_tasks()))
def testBuildFailureAnalysisScheduled(self): master_name = 'm' builder_name = 'b 1' build_number = 123 build_url = buildbot.CreateBuildUrl(master_name, builder_name, build_number) def MockMasterIsSupported(*_): return True self.mock(masters, 'MasterIsSupported', MockMasterIsSupported) response = self.test_app.get('/build-failure', params={'url': build_url}) self.assertEquals(200, response.status_int) self.assertEqual(1, len(self.taskqueue_stub.get_filtered_tasks()))
def testUnauthorizedUserCannotScheduleNewAnalysis(self): master_name = 'm' builder_name = 'b' build_number = 123 step_name = 's' test_name = 't' self.assertRaisesRegexp( webtest.app.AppError, re.compile('.*401 Unauthorized.*', re.MULTILINE | re.DOTALL), self.test_app.get, '/waterfall/flake', params={ 'url': buildbot.CreateBuildUrl( master_name, builder_name, build_number), 'step_name': step_name, 'test_name': test_name, 'format': 'json'})
def testHelpTriageHandler(self): build_url = buildbot.CreateBuildUrl(self.master_name, self.builder_name, 121) analysis = WfAnalysis.Create(self.master_name, self.builder_name, 121) analysis.result = { 'failures': [{ 'last_pass': None, 'first_failure': 120, 'suspected_cls': [], 'step_name': 'gn_check' }] } analysis.put() response = self.test_app.get('/help-triage', params={'url': build_url}) self.assertEqual(200, response.status_int) self.assertEqual(EXPECTED_RESULTS_121, response.json_body)
def testCannotGetBuildInfo(self, _): master_name = 'm2' builder_name = 'b 1' build_number = 123 build_url = buildbot.CreateBuildUrl(master_name, builder_name, build_number) self.mock_current_user(user_email='*****@*****.**', is_admin=True) self.assertRaisesRegexp( webtest.app.AppError, re.compile( '.*501 Not Implemented.*Can't get information about' ' build "%s/%s/%s".*' % (master_name, builder_name, build_number), re.MULTILINE | re.DOTALL), self.test_app.get, '/failure', params={'url': build_url})
def testCorpUserCanScheduleANewAnalysis(self, _): master_name = 'm' builder_name = 'b' build_number = '123' step_name = 's' test_name = 't' analysis = MasterFlakeAnalysis.Create( master_name, builder_name, build_number, step_name, test_name) analysis.Save() self.mock_current_user(user_email='*****@*****.**') response = self.test_app.get('/waterfall/flake', params={ 'url': buildbot.CreateBuildUrl(master_name, builder_name, build_number), 'step_name': step_name, 'test_name': test_name}) self.assertEquals(200, response.status_int)
def testNonAdminCanViewAnalysisOfFailureOnUnsupportedMaster(self): master_name = 'm2' builder_name = 'b 1' build_number = 123 build_url = buildbot.CreateBuildUrl(master_name, builder_name, build_number) analysis = WfAnalysis.Create(master_name, builder_name, build_number) analysis.status = analysis_status.COMPLETED analysis.suspected_cls = [{ 'repo_name': 'chromium', 'revision': 'r99_2', 'commit_position': None, 'url': None, }] analysis.put() response = self.test_app.get('/failure', params={'url': build_url}) self.assertEquals(200, response.status_int) self.assertEqual(0, len(self.taskqueue_stub.get_filtered_tasks()))
def GetBuildProperties(pipeline_input, try_job_type): master_name, builder_name, build_number = pipeline_input.build_key.GetParts( ) properties = { 'recipe': 'findit/chromium/%s' % (failure_type.GetDescriptionForFailureType(try_job_type)), 'good_revision': pipeline_input.good_revision, 'bad_revision': pipeline_input.bad_revision, 'target_mastername': master_name, 'referenced_build_url': buildbot.CreateBuildUrl(master_name, builder_name, build_number), 'suspected_revisions': pipeline_input.suspected_revisions or [], } return properties
def _Setup(self, master_name, builder_name, build_number): analysis = WfAnalysis.Create(master_name, builder_name, build_number) analysis.status = wf_analysis_status.ANALYZING analysis.put() def MockWaitUntilDownloadAllowed(*_): return True self.mock(lock_util, 'WaitUntilDownloadAllowed', MockWaitUntilDownloadAllowed) with self.mock_urlfetch() as urlfetch: # Mock build data. for i in range(2): build_url = buildbot.CreateBuildUrl(master_name, builder_name, build_number - i, json_api=True) file_name = os.path.join(os.path.dirname(__file__), 'data', 'm_b_%s.json' % (build_number - i)) with open(file_name, 'r') as f: urlfetch.register_handler(build_url, f.read()) # Mock step log. step_log_url = buildbot.CreateStdioLogUrl(master_name, builder_name, build_number, 'a') urlfetch.register_handler(step_log_url, 'error in file a/b/x.cc:89 ...') # Mock change logs. self._MockChangeLog(urlfetch, 'user1', 'some_git_hash', 8888, 'a/b/x.cc') self._MockChangeLog(urlfetch, 'user1', '64c72819e898e952103b63eabc12772f9640af07', 8887, 'd/e/y.cc') def MockGetChromeDependency(*_): return {} self.mock(chromium_deps, 'GetChromeDependency', MockGetChromeDependency)
def testAnyoneCanViewExistingAnalysis(self): master_name = 'm2' builder_name = 'b 1' build_number = 123 build_url = buildbot.CreateBuildUrl(master_name, builder_name, build_number) analysis = WfAnalysis.Create(master_name, builder_name, build_number) analysis.status = analysis_status.COMPLETED analysis.suspected_cls = [{ 'repo_name': 'chromium', 'revision': 'r99_2', 'commit_position': None, 'url': None, }] analysis.put() self.mock_current_user(user_email='*****@*****.**', is_admin=False) response = self.test_app.get('/failure', params={'url': build_url}) self.assertEquals(200, response.status_int)
def _GetBuildProperties(self, master_name, builder_name, build_number, good_revision, bad_revision, try_job_type, suspected_revisions): properties = { 'recipe': 'findit/chromium/%s' % (failure_type.GetDescriptionForFailureType(try_job_type)), 'good_revision': good_revision, 'bad_revision': bad_revision, 'target_mastername': master_name, 'referenced_build_url': buildbot.CreateBuildUrl(master_name, builder_name, build_number) } if suspected_revisions: properties['suspected_revisions'] = suspected_revisions return properties