def testOnBuildFailureAnalysisResultRequestedNotSupport( self, mock_compile_analysis): build_id = 80004567 build = LuciFailedBuild.Create( luci_project='chromium', luci_bucket='ci', luci_builder='Linux Builder', build_id=80004567, legacy_build_number=4567, gitiles_host='chromium.googlesource.com', gitiles_project='chromium/src', gitiles_ref='refs/heads/master', gitiles_id='git_hash', commit_position=65450, status=20, create_time=datetime(2019, 3, 28), start_time=datetime(2019, 3, 28, 0, 1), end_time=datetime(2019, 3, 28, 1), build_failure_type=StepTypeEnum.INFRA) build.put() request = findit_result.BuildFailureAnalysisRequest( build_id=build_id, failed_steps=['browser_tests']) self.assertEqual([], api.OnBuildFailureAnalysisResultRequested(request)) self.assertFalse(mock_compile_analysis.called)
def testOnBuildFailureAnalysisResultRequestedTest(self, mock_test_analysis): luci_project = 'chromium' luci_bucket = 'ci' luci_builder = 'Linux Builder' build_number = 4567 build = LuciFailedBuild.Create( luci_project=luci_project, luci_bucket=luci_bucket, luci_builder=luci_builder, build_id=80004567, legacy_build_number=build_number, gitiles_host='chromium.googlesource.com', gitiles_project='chromium/src', gitiles_ref='refs/heads/master', gitiles_id='git_hash', commit_position=65450, status=20, create_time=datetime(2019, 3, 28), start_time=datetime(2019, 3, 28, 0, 1), end_time=datetime(2019, 3, 28, 1), build_failure_type=StepTypeEnum.TEST) build.put() request = findit_result.BuildFailureAnalysisRequest( build_id=80004567, failed_steps=['test step']) self.assertEqual(['responses'], api.OnBuildFailureAnalysisResultRequested(request)) mock_test_analysis.assert_called_once_with(request, build)
def setUp(self): super(ChromeOSProjectAPITest, self).setUp() self.first_failed_commit_id = 'git_sha' self.first_failed_commit_position = 65450 self.context = Context(luci_project_name='chromeos', gitiles_host='gitiles.host.com', gitiles_project='project/name', gitiles_ref='ref/heads/master', gitiles_id='git_sha') self.builder = BuilderID(project='chromeos', bucket='postsubmit', builder='builder-postsubmit') self.group_build_id = 8000000000189 self.group_build = LuciFailedBuild.Create( luci_project=self.context.luci_project_name, luci_bucket=self.builder.bucket, luci_builder='builder2-postsubmit', build_id=self.group_build_id, legacy_build_number=12345, gitiles_host=self.context.gitiles_host, gitiles_project=self.context.gitiles_project, gitiles_ref=self.context.gitiles_ref, gitiles_id=self.context.gitiles_id, commit_position=self.first_failed_commit_position, status=20, create_time=datetime(2019, 3, 28), start_time=datetime(2019, 3, 28, 0, 1), end_time=datetime(2019, 3, 28, 1), build_failure_type=StepTypeEnum.COMPILE) self.group_build.put()
def setUp(self): super(CompileFailureTest, self).setUp() self.build_id = 9876543210 self.edges = [ (['target1.o'], 'CXX'), (['target2.o'], 'ACTION'), ] build = LuciFailedBuild.Create( luci_project='chromium', luci_bucket='ci', luci_builder='Linux Builder', build_id=self.build_id, legacy_build_number=12345, gitiles_host='chromium.googlesource.com', gitiles_project='chromium/src', gitiles_ref='refs/heads/master', gitiles_id='git_hash', commit_position=65450, status=20, create_time=datetime(2019, 3, 28), start_time=datetime(2019, 3, 28, 0, 1), end_time=datetime(2019, 3, 28, 1), build_failure_type=StepTypeEnum.COMPILE) build.put() self.target_entities = [] for output_targets, rule in self.edges: target = CompileFailure.Create(build.key, 'compile', output_targets, rule) target.put() self.target_entities.append(target)
def OnBuildFailureAnalysisResultRequested(request): """Returns the findings of an analysis for a failed build. Since Findit v2 only supports compile failure on cros builds, this api will simply respond an empty response on other failures. This is to prevent Findit spending too many pixels to tell users many failures are not supported. Args: request(findit_result.BuildFailureAnalysisRequest): request for a build failure. Returns: (findit_result.BuildFailureAnalysisResponseCollection): Analysis results for the requested build. """ build_id = request.build_id build_alternative_id = request.build_alternative_id if build_id: build_entity = LuciFailedBuild.get_by_id(build_id) if not build_entity: logging.debug('No LuciFailedBuild entity for build %d.', request.build_id) return [] else: build_entity = LuciFailedBuild.GetBuildByNumber( build_alternative_id.project, build_alternative_id.bucket, build_alternative_id.builder, build_alternative_id.number) if not build_entity: logging.debug('No LuciFailedBuild entity for build %s/%s/%s/%d.', build_alternative_id.project, build_alternative_id.bucket, build_alternative_id.builder, build_alternative_id.number) return [] if build_entity.build_failure_type == StepTypeEnum.COMPILE: return compile_analysis.OnCompileFailureAnalysisResultRequested( request, build_entity) if build_entity.build_failure_type == StepTypeEnum.TEST: return test_analysis.OnTestFailureAnalysisResultRequested( request, build_entity) logging.debug( 'Findit v2 only supports compile or test failure analysis, ' 'so no results for %d with %s failures.', build_id, build_entity.build_failure_type) return []
def testCreateLuciFailedBuildForCompileFailure(self): build_id = 87654321 commit_position = 65432 legacy_build_number = 12345 build = LuciFailedBuild.Create( luci_project='chromium', luci_bucket='ci', luci_builder='Linux Builder', build_id=build_id, legacy_build_number=legacy_build_number, gitiles_host='chromium.googlesource.com', gitiles_project='chromium/src', gitiles_ref='refs/heads/master', gitiles_id='git_hash', commit_position=commit_position, status=20, create_time=datetime(2019, 3, 28), start_time=datetime(2019, 3, 28, 0, 1), end_time=datetime(2019, 3, 28, 1), build_failure_type=StepTypeEnum.COMPILE) build.put() # Get entity by build_id. build = LuciFailedBuild.get_by_id(build_id) self.assertIsNotNone(build) self.assertEqual(StepTypeEnum.COMPILE, build.build_failure_type) self.assertEqual(commit_position, build.gitiles_commit.commit_position) self.assertEqual('chromium/ci', build.bucket_id) self.assertEqual('chromium/ci/Linux Builder', build.builder_id) # Get entity by build number. res1 = LuciFailedBuild.GetBuildByNumber('chromium', 'ci', 'Linux Builder', legacy_build_number) self.assertEqual(build_id, res1.build_id) # Get entity by commit_position. res2 = LuciFailedBuild.query( ndb.AND( LuciFailedBuild.builder_id == 'chromium/ci/Linux Builder', LuciFailedBuild.gitiles_commit.commit_position == commit_position)).fetch() self.assertEqual(1, len(res2)) self.assertEqual(build_id, res2[0].build_id)
def testOnCompileFailureAnalysisResultRequestedAnalysisRunning(self): build_id = 800000000123 request = findit_result.BuildFailureAnalysisRequest( build_id=build_id, failed_steps=[self.compile_step_name]) build = LuciFailedBuild.Create( luci_project='chromium', luci_bucket='ci', luci_builder='Linux Builder', build_id=build_id, legacy_build_number=12345, gitiles_host='chromium.googlesource.com', gitiles_project='chromium/src', gitiles_ref='refs/heads/master', gitiles_id='git_hash', commit_position=65450, status=20, create_time=datetime(2019, 3, 28), start_time=datetime(2019, 3, 28, 0, 1), end_time=datetime(2019, 3, 28, 1), build_failure_type=StepTypeEnum.COMPILE) build.put() compile_failure = CompileFailure.Create(build.key, self.compile_step_name, ['target1'], 'CXX') compile_failure.first_failed_build_id = build.build_id compile_failure.failure_group_build_id = build.build_id compile_failure.put() analysis = CompileFailureAnalysis.Create( luci_project=self.context.luci_project_name, luci_bucket='postsubmit', luci_builder='Linux Builder', build_id=build_id, gitiles_host=self.context.gitiles_host, gitiles_project=self.context.gitiles_project, gitiles_ref=self.context.gitiles_ref, last_passed_gitiles_id='last_passed_git_hash', last_passed_commit_position=65430, first_failed_gitiles_id='git_hash', first_failed_commit_position=65450, rerun_builder_id='chromeos/postsubmit/builder-bisect', compile_failure_keys=[]) analysis.status = analysis_status.RUNNING analysis.Save() responses = compile_api.OnCompileFailureAnalysisResultRequested( request, build) self.assertEqual(1, len(responses)) self.assertEqual(0, len(responses[0].culprits)) self.assertFalse(responses[0].is_finished) self.assertTrue(responses[0].is_supported)
def _CreateLuciBuild(self, build_id): build = LuciFailedBuild.Create( luci_project='chromium', luci_bucket='ci', luci_builder='Linux Builder', build_id=build_id, legacy_build_number=12345, gitiles_host='chromium.googlesource.com', gitiles_project='chromium/src', gitiles_ref='refs/heads/master', gitiles_id='git_hash', commit_position=65450, status=20, create_time=datetime(2019, 3, 28), start_time=datetime(2019, 3, 28, 0, 1), end_time=datetime(2019, 3, 28, 1), build_failure_type=StepTypeEnum.TEST) build.put() return build
def setUp(self): super(CompileAnalysisAPITest, self).setUp() self.build_id = 8000000000123 self.build_number = 123 self.builder = BuilderID(project='chromium', bucket='ci', builder='Linux Tests') self.build = self._MockBuild(self.build_id, self.build_number, 'git_sha_123') self.rerun_builder = BuilderID(project='chromium', bucket='try', builder='findit_variables') self.context = Context(luci_project_name='chromium', gitiles_host='gitiles.host.com', gitiles_project='project/name', gitiles_ref='ref/heads/master', gitiles_id='git_sha_123') self.build_entity = LuciFailedBuild.Create( luci_project=self.build.builder.project, luci_bucket=self.build.builder.bucket, luci_builder=self.build.builder.builder, build_id=self.build.id, legacy_build_number=self.build.number, gitiles_host=self.context.gitiles_host, gitiles_project=self.context.gitiles_project, gitiles_ref=self.context.gitiles_ref, gitiles_id=self.context.gitiles_id, commit_position=123, status=self.build.status, create_time=self.build.create_time.ToDatetime(), start_time=self.build.start_time.ToDatetime(), end_time=self.build.end_time.ToDatetime(), build_failure_type=StepTypeEnum.COMPILE) self.build_entity.put() self.analysis_api = CompileAnalysisAPI() self.compile_failure = self.analysis_api._CreateFailure( self.build_entity.key, 'compile', self.build_id, 8000000000122, None, frozenset(['a.o']), None) self.compile_failure.put()
def testSaveCompileFailuresOnlyStepLevelFailures(self, _): detailed_compile_failures = { 'compile': { 'failures': {}, 'first_failed_build': { 'id': 8000000000121, 'number': 121, 'commit_id': 'git_sha' }, 'last_passed_build': { 'id': 8000000000120, 'number': 120, 'commit_id': 'git_sha' }, }, } # Prepares data for first failed build. first_failed_build = self._MockBuild(8000000000121, 121, 'git_sha_121') first_failed_build_entity = luci_build.SaveFailedBuild( self.context, first_failed_build, StepTypeEnum.COMPILE) first_failure = CompileFailure.Create(first_failed_build_entity.key, 'compile', None, 'CXX') first_failure.put() pre_compile_analysis.SaveCompileFailures(self.context, self.build, detailed_compile_failures) build_entity = LuciFailedBuild.get_by_id(self.build_id) self.assertIsNotNone(build_entity) compile_failures = CompileFailure.query( ancestor=build_entity.key).fetch() self.assertEqual(1, len(compile_failures)) self.assertEqual(8000000000121, compile_failures[0].first_failed_build_id) self.assertEqual([], compile_failures[0].output_targets) self.assertEqual(first_failure.key, compile_failures[0].merged_failure_key)
def setUp(self): super(AnalysisUtilTest, self).setUp() self.gitiles_host = 'gitiles.host.com' self.gitiles_project = 'project/name' self.gitiles_ref = 'ref/heads/master' self.build = LuciFailedBuild.Create( luci_project='chromium', luci_bucket='ci', luci_builder='Linux Builder', build_id=9876543210, legacy_build_number=12345, gitiles_host='chromium.googlesource.com', gitiles_project='chromium/src', gitiles_ref='refs/heads/master', gitiles_id='git_hash', commit_position=65450, status=20, create_time=datetime(2019, 3, 28), start_time=datetime(2019, 3, 28, 0, 1), end_time=datetime(2019, 3, 28, 1), build_failure_type=StepTypeEnum.COMPILE) self.build.put() self.compile_failure_1 = CompileFailure.Create(self.build.key, 'compile', ['a.o'], 'CC') self.compile_failure_1.put() self.compile_failure_2 = CompileFailure.Create(self.build.key, 'compile', ['b.o'], 'CC') self.compile_failure_2.put() self.commits = [] for i in xrange(0, 11): self.commits.append(self._CreateGitilesCommit('r%d' % i, 100 + i))
def setUp(self): super(CompileFailureRerunAnalysisTest, self).setUp() self.build_id = 8000000000123 self.build_number = 123 self.builder = BuilderID(project='chromium', bucket='ci', builder='linux-rel') self.build = Build(id=self.build_id, builder=self.builder, number=self.build_number, status=common_pb2.FAILURE) self.build.input.gitiles_commit.host = 'gitiles.host.com' self.build.input.gitiles_commit.project = 'project/name' self.build.input.gitiles_commit.ref = 'ref/heads/master' self.build.input.gitiles_commit.id = 'git_sha_123' self.build.create_time.FromDatetime(datetime(2019, 4, 9)) self.build.start_time.FromDatetime(datetime(2019, 4, 9, 0, 1)) self.build.end_time.FromDatetime(datetime(2019, 4, 9, 1)) self.context = Context(luci_project_name='chromium', gitiles_host='gitiles.host.com', gitiles_project='project/name', gitiles_ref='ref/heads/master', gitiles_id='git_sha') build_entity = LuciFailedBuild.Create( luci_project=self.context.luci_project_name, luci_bucket=self.build.builder.bucket, luci_builder=self.build.builder.builder, build_id=self.build_id, legacy_build_number=self.build_number, gitiles_host=self.context.gitiles_host, gitiles_project=self.context.gitiles_project, gitiles_ref=self.context.gitiles_ref, gitiles_id=self.context.gitiles_id, commit_position=6000005, status=20, create_time=datetime(2019, 3, 28), start_time=datetime(2019, 3, 28, 0, 1), end_time=datetime(2019, 3, 28, 1), build_failure_type=StepTypeEnum.COMPILE) build_entity.put() self.compile_failure = CompileFailure.Create( failed_build_key=build_entity.key, step_ui_name='compile', output_targets=['a.o'], first_failed_build_id=self.build_id, failure_group_build_id=None) self.compile_failure.put() self.analysis = CompileFailureAnalysis.Create( luci_project=self.context.luci_project_name, luci_bucket=self.build.builder.bucket, luci_builder=self.build.builder.builder, build_id=self.build_id, gitiles_host=self.context.gitiles_host, gitiles_project=self.context.gitiles_project, gitiles_ref=self.context.gitiles_ref, last_passed_gitiles_id='left_sha', last_passed_commit_position=6000000, first_failed_gitiles_id=self.context.gitiles_id, first_failed_commit_position=6000005, rerun_builder_id='chromium/findit/findit-variables', compile_failure_keys=[self.compile_failure.key]) self.analysis.Save()
def testGetFirstFailuresInCurrentBuildWithoutGroup(self, *_): build_121_info = { 'id': 8000000000121, 'number': self.build_number - 2, 'commit_id': 'git_sha_121' } first_failures_in_current_build = { 'failures': { 'compile': { 'output_targets': [frozenset(['target1']), frozenset(['target2'])], 'last_passed_build': build_121_info, }, }, 'last_passed_build': build_121_info } # Creates and saves entities of the existing group. detailed_compile_failures = { 'compile': { 'failures': { frozenset(['target1']): { 'rule': 'CXX', 'first_failed_build': self.build_info, 'last_passed_build': build_121_info, }, frozenset(['target2']): { 'rule': 'ACTION', 'first_failed_build': self.build_info, 'last_passed_build': build_121_info, }, }, 'first_failed_build': self.build_info, 'last_passed_build': build_121_info, }, } pre_compile_analysis.SaveCompileFailures(self.context, self.build, detailed_compile_failures) # Prepares data for existing failure group. group_build = self._MockBuild(8000000000134, 12134, 'git_sha_134', builder_name='Mac') group_build_entity = luci_build.SaveFailedBuild( self.context, group_build, StepTypeEnum.COMPILE) group_failure1 = CompileFailure.Create(group_build_entity.key, 'compile', ['target1'], 'CXX') group_failure1.put() group_failure2 = CompileFailure.Create(group_build_entity.key, 'compile', ['target2'], 'ACTION') group_failure2.put() self.assertEqual( { 'failures': {}, 'last_passed_build': None }, pre_compile_analysis.GetFirstFailuresInCurrentBuildWithoutGroup( self.context, self.build, first_failures_in_current_build)) build = LuciFailedBuild.get_by_id(self.build_id) compile_failures = CompileFailure.query(ancestor=build.key).fetch() self.assertEqual(2, len(compile_failures)) for failure in compile_failures: if failure.output_targets == ['target1']: self.assertEqual(group_failure1.key, failure.merged_failure_key) else: self.assertEqual(group_failure2.key, failure.merged_failure_key)
def testSaveCompileFailures(self, _): detailed_compile_failures = { 'compile': { 'failures': { frozenset(['target1', 'target2']): { 'rule': 'CXX', 'first_failed_build': { 'id': 8000000000121, 'number': 121, 'commit_id': 'git_sha_121' }, 'last_passed_build': { 'id': 8000000000120, 'number': 120, 'commit_id': 'git_sha' }, }, }, 'first_failed_build': { 'id': 8000000000121, 'number': 121, 'commit_id': 'git_sha_121' }, 'last_passed_build': { 'id': 8000000000120, 'number': 120, 'commit_id': 'git_sha' }, }, } # Prepares data for existing failure group. group_build = self._MockBuild(8000003400121, 12134, 'git_sha_121', builder_name='Mac') group_build_entity = luci_build.SaveFailedBuild( self.context, group_build, StepTypeEnum.COMPILE) group_failure = CompileFailure.Create(group_build_entity.key, 'compile', ['target1', 'target2'], 'CXX') group_failure.put() # Prepares data for first failed build. first_failed_build = self._MockBuild(8000000000121, 121, 'git_sha_121') first_failed_build_entity = luci_build.SaveFailedBuild( self.context, first_failed_build, StepTypeEnum.COMPILE) first_failure = CompileFailure.Create(first_failed_build_entity.key, 'compile', ['target1', 'target2'], 'CXX') first_failure.merged_failure_key = group_failure.key first_failure.put() pre_compile_analysis.SaveCompileFailures(self.context, self.build, detailed_compile_failures) build = LuciFailedBuild.get_by_id(self.build_id) self.assertIsNotNone(build) compile_failures = CompileFailure.query(ancestor=build.key).fetch() self.assertEqual(1, len(compile_failures)) self.assertEqual(8000000000121, compile_failures[0].first_failed_build_id) self.assertEqual(group_failure.key, compile_failures[0].merged_failure_key)
def testOnTestFailureAnalysisResultRequestedGetCulpritFromMergedFailure(self): build_id = 800000000123 request = findit_result.BuildFailureAnalysisRequest( build_id=build_id, failed_steps=[self.test_step_name]) culprit_id = 'git_hash_65432' culprit_commit_position = 65432 culprit = Culprit.Create( self.context.gitiles_host, self.context.gitiles_project, self.context.gitiles_ref, culprit_id, culprit_commit_position) culprit.put() merge_failure = TestFailure.Create( ndb.Key(LuciFailedBuild, build_id), self.test_step_name, 'test7') merge_failure.culprit_commit_key = culprit.key merge_failure.first_failed_build_id = build_id merge_failure.failure_group_build_id = build_id merge_failure.put() analysis = TestFailureAnalysis.Create( luci_project=self.context.luci_project_name, luci_bucket='postsubmit', luci_builder='Linux Builder', build_id=build_id, gitiles_host=self.context.gitiles_host, gitiles_project=self.context.gitiles_project, gitiles_ref=self.context.gitiles_ref, last_passed_gitiles_id='last_passed_git_hash', last_passed_commit_position=65430, first_failed_gitiles_id='git_hash', first_failed_commit_position=65450, rerun_builder_id='chromeos/postsubmit/builder-bisect', test_failure_keys=[merge_failure.key]) analysis.status = analysis_status.COMPLETED analysis.Save() build = LuciFailedBuild.Create( luci_project='chromium', luci_bucket='ci', luci_builder='Linux Builder', build_id=800000000124, legacy_build_number=12345, gitiles_host='chromium.googlesource.com', gitiles_project='chromium/src', gitiles_ref='refs/heads/master', gitiles_id='git_hash', commit_position=65450, status=20, create_time=datetime(2019, 3, 28), start_time=datetime(2019, 3, 28, 0, 1), end_time=datetime(2019, 3, 28, 1), build_failure_type=StepTypeEnum.TEST) build.put() test_failure = TestFailure.Create( ndb.Key(LuciFailedBuild, 800000000124), self.test_step_name, 'test7') test_failure.merged_failure_key = merge_failure.key test_failure.first_failed_build_id = build.build_id test_failure.failure_group_build_id = build.build_id test_failure.put() responses = test_analysis.OnTestFailureAnalysisResultRequested( request, build) self.assertEqual(1, len(responses)) self.assertEqual(1, len(responses[0].culprits)) self.assertEqual(culprit_id, responses[0].culprits[0].commit.id) self.assertTrue(responses[0].is_finished) self.assertEqual('test7', responses[0].test_name)