def GetFailureEntitiesForABuild(self, build): compile_failure_entities = CompileFailure.query( ancestor=ndb.Key(luci_build.LuciFailedBuild, build.id)).fetch() assert compile_failure_entities, ( 'No compile failure saved in datastore for build {}'.format( build.id)) return compile_failure_entities
def testCompileFailure(self): build_key = ndb.Key('LuciFailedBuild', self.build_id) failures_in_build = CompileFailure.query(ancestor=build_key).fetch() self.assertEqual(2, len(failures_in_build)) self.assertItemsEqual( [{'target1.o'}, {'target2.o'}], [f.GetFailureIdentifier() for f in failures_in_build]) self.assertEqual(self.build_id, failures_in_build[0].build_id)
def _GetCompileFailureEntitiesForABuild(build): build_entity = luci_build.LuciFailedBuild.get_by_id(build.id) assert build_entity, 'No LuciFailedBuild entity for build {}'.format(build.id) compile_failure_entities = CompileFailure.query( ancestor=build_entity.key).fetch() assert compile_failure_entities, ( 'No compile failure saved in datastore for build {}'.format(build.id)) return compile_failure_entities
def OnCompileFailureAnalysisResultRequested(request, requested_build): """Returns the findings for the requested build's compile failure. Since SoM doesn't have atomic failure info for compile steps, currently Findit will only respond with aggregated step level results. Args: request(findit_result.BuildFailureAnalysisRequest): request for a build failure. requested_build(LuciFailedBuild): A LuciFailedBuild entity with COMPILE build_failure_type. Returns: [findit_result.BuildFailureAnalysisResponse]: Analysis results for the requested build. """ compile_failures = CompileFailure.query( ancestor=requested_build.key).fetch() if not compile_failures: return None requested_steps = request.failed_steps requested_failures = defaultdict(list) for failure in compile_failures: if requested_steps and failure.step_ui_name not in requested_steps: continue requested_failures[failure.step_ui_name].append(failure) responses = [] for step_ui_name, requested_failures_in_step in requested_failures.iteritems( ): merged_failures = [] for failure in requested_failures_in_step: # Merged failures are the failures being actually analyzed and only they # have stored culprits info. merged_failures.append(failure.GetMergedFailure()) culprits = CompileAnalysisAPI().GetCulpritsForFailures(merged_failures) response = BuildFailureAnalysisResponse( build_id=request.build_id, build_alternative_id=request.build_alternative_id, step_name=step_ui_name, test_name=None, culprits=culprits, is_finished=_IsAnalysisFinished(merged_failures), is_supported=True, ) responses.append(response) return responses
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 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)