def testCompileStep(self): step = Step() step.name = 'compile' log = step.logs.add() log.name = 'stdout' self.assertEqual(StepTypeEnum.COMPILE, ChromiumProjectAPI().ClassifyStepType(None, step))
def testTestStep(self): step = Step() step.name = 'browser_tests' log = step.logs.add() log.name = 'step_metadata' self.assertEqual(StepTypeEnum.TEST, ChromiumProjectAPI().ClassifyStepType(None, step))
def testUpdateCompileFailuresWithFirstFailureInfoPrevBuildInfraFailure( self, mock_prev_builds, mock_get_build): """Test for previous build failed with different steps.""" mock_step1 = Step() mock_step1.name = 'compile' mock_step1.status = common_pb2.INFRA_FAILURE build_122_id = 8000000000122 build_122 = Build(id=build_122_id, builder=self.builder, number=self.build_number - 1, status=common_pb2.FAILURE) build_122.steps.extend([mock_step1]) build_121_id = 8000000000121 build_121 = Build(id=build_121_id, builder=self.builder, number=self.build_number - 2, status=common_pb2.SUCCESS) build_121.input.gitiles_commit.id = 'git_sha_121' build_121_info = { 'id': build_121_id, 'number': self.build_number - 2, 'commit_id': 'git_sha_121' } mock_prev_builds.return_value = SearchBuildsResponse( builds=[build_122, build_121]) mock_get_build.return_value = build_122 detailed_compile_failures = { 'compile': { 'failures': { frozenset(['target1', 'target2']): { 'rule': 'CXX', 'first_failed_build': self.build_info, 'last_passed_build': None, }, }, 'first_failed_build': self.build_info, 'last_passed_build': None, }, } pre_compile_analysis.UpdateCompileFailuresWithFirstFailureInfo( self.context, self.build, detailed_compile_failures) expected_failures = { 'compile': { 'failures': { frozenset(['target1', 'target2']): { 'rule': 'CXX', 'first_failed_build': self.build_info, 'last_passed_build': build_121_info, }, }, 'first_failed_build': self.build_info, 'last_passed_build': build_121_info, }, } self.assertEqual(expected_failures, detailed_compile_failures)
def testInfraStep(self): step = Step() step.name = 'infra' log = step.logs.add() log.name = 'report' self.assertEqual(StepTypeEnum.INFRA, ChromiumProjectAPI().ClassifyStepType(None, step))
def testGetTestFailures(self): step_name = 'results|xx test results|[FAILED] <suite1>' build_id = 8765432109123 build_number = 123 build = self._CreateBuildbucketBuildForTest(build_id, build_number, step_name=step_name) step = Step() step.name = step_name expected_failures = { step_name: { 'failures': {}, 'first_failed_build': { 'id': build_id, 'number': build_number, 'commit_id': 'git_sha', }, 'last_passed_build': None, 'properties': { 'failure_type': 'xx_test_failures', 'test_spec': 'test_spec', 'suite': 'suite', 'needs_bisection': True, } }, } self.assertEqual(expected_failures, ChromeOSProjectAPI().GetTestFailures(build, [step]))
def testExtractBuildInfoFromV2BuildComplete(self, *_): master_name = 'chromium.linux' builder_name = 'Linux Tests' bucket = 'ci' build_id = 8765000000056123 build_number = 56123 build_start_time = datetime(2019, 5, 21) build_end_time = datetime(2019, 5, 21, 1) gitiles_id = 'rev4' build = Build(id=build_id, number=build_number, builder=BuilderID(project='chromium', bucket=bucket, builder=builder_name)) build.input.gitiles_commit.project = 'chromium/src' build.input.gitiles_commit.host = 'chromium.googlesource.com' build.input.gitiles_commit.ref = 'refs/heads/master' build.input.gitiles_commit.id = gitiles_id build.input.properties['$recipe_engine/runtime'] = {'is_luci': True} build.input.properties['parent_buildername'] = 'Linux Builder' build.input.properties['parent_mastername'] = 'chromium.linux' build.create_time.FromDatetime(build_start_time) build.end_time.FromDatetime(build_end_time) build.status = common_pb2.FAILURE step1 = Step(name='s1', status=common_pb2.SUCCESS) log = step1.logs.add() log.name = 'stdout' step2 = Step(name='s2', status=common_pb2.SUCCESS) step3 = Step(name='s3', status=common_pb2.FAILURE) log = step3.logs.add() log.name = 'stdout' step4 = Step(name='s4', status=common_pb2.FAILURE) step_fr = Step(name='Failure reason', status=common_pb2.FAILURE) build.steps.extend([step1, step2, step3, step4, step_fr]) build_info = buildbot.ExtractBuildInfoFromV2Build( master_name, builder_name, build_number, build) self.assertEqual(master_name, build_info.master_name) self.assertEqual(builder_name, build_info.builder_name) self.assertEqual(build_number, build_info.build_number) self.assertEqual(build_start_time, build_info.build_start_time) self.assertEqual(build_end_time, build_info.build_end_time) self.assertEqual(gitiles_id, build_info.chromium_revision) self.assertEqual(654332, build_info.commit_position) self.assertTrue(build_info.completed) self.assertEqual(common_pb2.FAILURE, build_info.result) self.assertItemsEqual(['rev2', 'rev3'], build_info.blame_list) self.assertItemsEqual(['s3'], build_info.failed_steps) self.assertItemsEqual(['s1'], build_info.passed_steps) self.assertItemsEqual(['s3', 's4', 'Failure reason'], build_info.not_passed_steps) self.assertEqual(bucket, build_info.buildbucket_bucket) self.assertEqual(str(build_id), build_info.buildbucket_id) self.assertTrue(build_info.is_luci)
def testGetBuildFailureInfo(self, mock_build, *_): master_name = 'm' builder_name = 'b' build_number = 223 self._CreateAndSaveWfAnanlysis(master_name, builder_name, build_number, analysis_status.PENDING) build = WfBuild.Create(master_name, builder_name, build_number) build.build_id = '80000000223' build.completed = True build.put() build_223 = Build( id=80000000223, number=build_number, status=common_pb2.FAILURE) build_223.input.gitiles_commit.id = 'rev223' step1 = Step(name='compile', status=common_pb2.SUCCESS) log = step1.logs.add() log.name = 'stdout' step2 = Step(name='abc_test', status=common_pb2.FAILURE) log = step2.logs.add() log.name = 'stdout' build_223.steps.extend([step1, step2]) mock_build.return_value = build_223 failure_info, should_proceed = ci_failure.GetBuildFailureInfo( master_name, builder_name, build_number) expected_failure_info = { 'failed': True, 'master_name': master_name, 'builder_name': builder_name, 'build_number': build_number, 'is_luci': None, 'buildbucket_bucket': '', 'buildbucket_id': '80000000223', 'chromium_revision': 'rev223', 'builds': { build_number: { 'blame_list': ['rev223'], 'chromium_revision': 'rev223' } }, 'failed_steps': { 'abc_test': { 'current_failure': build_number, 'first_failure': build_number, 'supported': True } }, 'failure_type': failure_type.TEST, 'parent_mastername': None, 'parent_buildername': None, } self.assertEqual(expected_failure_info, failure_info) self.assertTrue(should_proceed)
def testGetBuildFailureInfoBuildSuccess(self, mock_monitoring, mock_build, *_): master_name = 'm' builder_name = 'b' build_number = 121 self._CreateAndSaveWfAnanlysis(master_name, builder_name, build_number, analysis_status.PENDING) build = WfBuild.Create(master_name, builder_name, build_number) build.build_id = '80000000223' build.completed = True build.put() build_121 = Build( id=80000000121, number=build_number, status=common_pb2.FAILURE) build_121.input.gitiles_commit.id = 'rev121' step1 = Step(name='net_unittests', status=common_pb2.SUCCESS) log = step1.logs.add() log.name = 'stdout' step2 = Step(name='unit_tests', status=common_pb2.SUCCESS) log = step2.logs.add() log.name = 'stdout' build_121.steps.extend([step1, step2]) mock_build.return_value = build_121 failure_info, should_proceed = ci_failure.GetBuildFailureInfo( master_name, builder_name, build_number) expected_failure_info = { 'failed': False, 'master_name': master_name, 'builder_name': builder_name, 'build_number': build_number, 'chromium_revision': 'rev121', 'builds': {}, 'failed_steps': {}, 'failure_type': failure_type.UNKNOWN, 'parent_mastername': None, 'parent_buildername': None, 'is_luci': None, 'buildbucket_bucket': '', 'buildbucket_id': '80000000121', } self.assertEqual(expected_failure_info, failure_info) self.assertFalse(should_proceed) mock_monitoring.assert_called_once_with( master_name='m', builder_name='b', failure_type='unknown', canonical_step_name='unknown', isolate_target_name='unknown', status='Completed', analysis_type='Pre-Analysis')
def testInfraStepFromABuildWithoutCompileFailure(self): step_name = 'test step' build_id = 8765432109123 build_number = 123 build = self._CreateBuildbucketBuild(build_id, build_number) step = Step() step.name = step_name log = step.logs.add() log.name = 'reason' self.assertEqual(StepTypeEnum.INFRA, ChromeOSProjectAPI().ClassifyStepType(build, step))
def testInfraStepFromABuildWithTestStep(self): step_name = 'results|xx test results|[FAILED] <suite1>' build_id = 8765432109123 build_number = 123 build = self._CreateBuildbucketBuildForTest(build_id, build_number, step_name=step_name) step = Step() step.name = 'another_step' self.assertEqual(StepTypeEnum.INFRA, ChromeOSProjectAPI().ClassifyStepType(build, step))
def testInfraStepFromABuildWithCompileFailureNoFailedStep(self): compile_step_name = 'install packages|installation results' build_id = 8765432109123 build_number = 123 build = self._CreateBuildbucketBuildForCompile(build_id, build_number, self.output_targets) step = Step() step.name = compile_step_name log = step.logs.add() log.name = 'reason' self.assertEqual(StepTypeEnum.INFRA, ChromeOSProjectAPI().ClassifyStepType(build, step))
def testGetCompileFailuresNoFailure(self): step_name = 'install packages' build_id = 8765432109123 build_number = 123 build = self._CreateBuildbucketBuild(build_id, build_number, [], step_name=step_name) step = Step() step.name = step_name self.assertEqual({}, ChromeOSProjectAPI().GetCompileFailures( build, [step]))
def testGetTestFailuresMalFormedOutput(self): step_name = 'no spec' build_id = 8765432109123 build_number = 123 build = self._CreateBuildbucketBuildForTest(build_id, build_number, step_name=step_name) step = Step() step.name = step_name expected_failures = {} self.assertEqual(expected_failures, ChromeOSProjectAPI().GetTestFailures(build, [step]))
def testGetCompileFailures(self, mock_get_log): build_id = 8765432109123 build_number = 123 build = self._CreateBuildbucketBuild(build_id, build_number) step_name = 'compile' log = Log() log.name = 'json.output[ninja_info]' log.view_url = 'https://dummy/path' step = Step() step.name = step_name step.logs.extend([log]) build.steps.extend([step]) mock_get_log.return_value = { 'failures': [{ 'output': '...some very long \n multi-line \n string', 'output_nodes': [ 'broken_target1', 'broken_target2', ], 'rule': 'ACTION', }], } expected_response = { 'compile': { 'failures': { frozenset(['broken_target1', 'broken_target2']): { 'properties': { 'rule': 'ACTION' }, 'first_failed_build': { 'commit_id': 'git_sha', 'id': 8765432109123, 'number': 123, }, 'last_passed_build': None } }, 'first_failed_build': { 'commit_id': 'git_sha', 'id': 8765432109123, 'number': 123, }, 'last_passed_build': None } } self.assertEqual( expected_response, ChromiumProjectAPI().GetCompileFailures(build, [step]))
def testCompileStep(self): compile_step_name = 'install packages|installation results' build_id = 8765432109123 build_number = 123 build = self._CreateBuildbucketBuildForCompile( build_id, build_number, self.output_targets, step_name=compile_step_name) step = Step() step.name = compile_step_name log = step.logs.add() log.name = 'stdout' self.assertEqual(StepTypeEnum.COMPILE, ChromeOSProjectAPI().ClassifyStepType(build, step))
def testGetStepStartAndEndTime(self): build_id = '8945610992972640896' start_time = datetime.datetime(2019, 3, 6) end_time = datetime.datetime(2019, 3, 6, 0, 0, 10) step = Step() step.name = 's' step.start_time.FromDatetime(start_time) step.end_time.FromDatetime(end_time) build = Build() build.id = int(build_id) build.steps.extend([step]) self.assertEqual((start_time, end_time), step_util.GetStepStartAndEndTime(build, 's')) self.assertEqual((None, None), step_util.GetStepStartAndEndTime(build, 's2'))
def testGetStepLogForLuciBuildNoViewUrl(self, mock_get_build, mock_get_log, _): build_id = '8945610992972640896' mock_log = Step.Log() mock_log.name = 'step_metadata' mock_log.view_url = 'view_url' mock_step = Step() mock_step.name = 's' mock_step.logs.extend([mock_log]) mock_build = Build() mock_build.id = int(build_id) mock_build.steps.extend([mock_step]) mock_get_build.return_value = mock_build self.assertIsNone( step_util.GetStepLogForLuciBuild(build_id, 's', None, 'step_metadata')) self.assertFalse(mock_get_log.called)
def testGetStepLogForLuciBuild(self, mock_get_build, mock_get_log, _): build_id = '8945610992972640896' mock_log = Step.Log() mock_log.name = 'step_metadata' mock_log.view_url = 'view_url' mock_step = Step() mock_step.name = 's' mock_step.logs.extend([mock_log]) mock_build = Build() mock_build.id = int(build_id) mock_build.steps.extend([mock_step]) mock_get_build.return_value = mock_build self.assertEqual( 'log', step_util.GetStepLogForLuciBuild(build_id, 's', None, 'step_metadata')) mock_get_log.assert_called_once_with('view_url', None)
def testGetCompileFailuresNoFailedStep(self): step_name = 'install packages' build_id = 8765432109123 build_number = 123 output_target = json.dumps({ 'category': 'chromeos-base', 'packageName': 'target2' }) build = self._CreateBuildbucketBuild(build_id, build_number, [output_target]) step = Step() step.name = step_name self.assertEqual({}, ChromeOSProjectAPI().GetCompileFailures( build, [step]))
def testProcessRerunBuildResultBuildPassed(self, mock_compile_failures, mock_analysis): build_id = 8000000000123 build_number = 123 builder = BuilderID(project='chromeos', bucket='postsubmit', builder='findit-variable') build = Build(id=build_id, builder=builder, number=build_number, status=common_pb2.SUCCESS, tags=[{ 'key': 'analyzed_build_id', 'value': str(self.analyzed_build_id) }]) build.input.gitiles_commit.host = 'gitiles.host.com' build.input.gitiles_commit.project = 'project/name' build.input.gitiles_commit.ref = 'ref/heads/master' build.input.gitiles_commit.id = 'git_sha_6543221' build.create_time.FromDatetime(datetime(2019, 4, 9)) step1 = Step(name='s1', status=common_pb2.SUCCESS) step2 = Step(name=self.compile_step_name, status=common_pb2.SUCCESS) build.steps.extend([step1, step2]) CompileRerunBuild.Create(luci_project=self.context.luci_project_name, luci_bucket=build.builder.bucket, luci_builder=build.builder.builder, build_id=build_id, legacy_build_number=build_number, gitiles_host=self.context.gitiles_host, gitiles_project=self.context.gitiles_project, gitiles_ref=self.context.gitiles_ref, gitiles_id='git_sha_6543221', commit_position=6543221, status=build.status, create_time=build.create_time.ToDatetime(), parent_key=self.analysis.key).put() self.assertTrue( compile_analysis.OnCompileRerunBuildCompletion( self.context, build)) self.assertFalse(mock_compile_failures.called) rerun_build = CompileRerunBuild.get_by_id(build_id, parent=self.analysis.key) self.assertEqual({}, rerun_build.GetFailuresInBuild()) self.assertTrue(mock_analysis.called)
def testGetCompileFailures(self): step_name = 'install packages' build_id = 8765432109123 build_number = 123 output_target1 = json.dumps({ 'category': 'chromeos-base', 'packageName': 'target1' }) output_target2 = json.dumps({ 'category': 'chromeos-base', 'packageName': 'target2' }) build = self._CreateBuildbucketBuild(build_id, build_number, [output_target1, output_target2], step_name=step_name) step = Step() step.name = step_name expected_failures = { 'install packages': { 'failures': { frozenset([output_target1, output_target2]): { 'rule': 'emerge', 'first_failed_build': { 'id': build_id, 'number': build_number, 'commit_id': 'git_sha' }, 'last_passed_build': None, }, }, 'first_failed_build': { 'id': build_id, 'number': build_number, 'commit_id': 'git_sha' }, 'last_passed_build': None, }, } self.assertEqual( expected_failures, ChromeOSProjectAPI().GetCompileFailures(build, [step]))
def testInfraStepFromABuildWithCompileFailureNoFailedStep(self): compile_step_name = 'install packages|installation results' build_id = 8765432109123 build_number = 123 output_target1 = json.dumps({ 'category': 'chromeos-base', 'packageName': 'target1' }) output_target2 = json.dumps({ 'category': 'chromeos-base', 'packageName': 'target2' }) build = self._CreateBuildbucketBuild(build_id, build_number, [output_target1, output_target2]) step = Step() step.name = compile_step_name log = step.logs.add() log.name = 'reason' self.assertEqual(StepTypeEnum.INFRA, ChromeOSProjectAPI().ClassifyStepType(build, step))
def testGetCompileFailuresEmptyNinjaInfo(self, mock_get_log): build_id = 8765432109123 build_number = 123 build = self._CreateBuildbucketBuild(build_id, build_number) step_name = 'compile' log = Log() log.name = 'json.output[ninja_info]' log.view_url = 'https://dummy/path' step = Step() step.name = step_name step.logs.extend([log]) build.steps.extend([step]) # Cover the case when the retrieval of the log returns a string with # json-encoded info. mock_get_log.return_value = "{}" expected_response = {} self.assertEqual( expected_response, ChromiumProjectAPI().GetCompileFailures(build, [step]))
def testGetStepLogViewUrlPartialMatching(self, partial_match, full_step_name, expected_url_in_build1, expected_url_in_build2): mock_step1 = Step() mock_step1.name = 'step_name' mock_log1 = common_pb2.Log() mock_log1.name = 'log' mock_log1.view_url = 'view_url' mock_step1.logs.extend([mock_log1]) mock_step2 = Step() mock_step2.name = 'step_name_longer' mock_log2 = common_pb2.Log() mock_log2.name = 'log' mock_log2.view_url = 'view_url_partial_match' mock_step2.logs.extend([mock_log2]) mock_build1 = Build() mock_build1.steps.extend([mock_step1, mock_step2]) self.assertEqual( expected_url_in_build1, step_util._GetStepLogViewUrl(mock_build1, full_step_name, 'log', partial_match=partial_match)) mock_build2 = Build() mock_build2.steps.extend([mock_step2]) self.assertEqual( expected_url_in_build2, step_util._GetStepLogViewUrl(mock_build2, full_step_name, 'log', partial_match=partial_match))
def testGetCompileFailures(self): step_name = 'install packages' build_id = 8765432109123 build_number = 123 build = self._CreateBuildbucketBuildForCompile(build_id, build_number, self.output_targets, step_name=step_name) step = Step() step.name = step_name expected_failures = { 'install packages': { 'failures': { frozenset(self.output_targets): { 'properties': { 'rule': 'emerge', }, 'first_failed_build': { 'id': build_id, 'number': build_number, 'commit_id': 'git_sha', }, 'last_passed_build': None, }, }, 'first_failed_build': { 'id': build_id, 'number': build_number, 'commit_id': 'git_sha', }, 'last_passed_build': None, }, } self.assertEqual( expected_failures, ChromeOSProjectAPI().GetCompileFailures(build, [step]))
def testGetFailedStepsInBuild(self): build_id = 8000000000123 build_number = 123 builder = BuilderID(project='chromium', bucket='try', builder='linux-rel') build = Build(id=build_id, builder=builder, number=build_number, status=common_pb2.FAILURE) step1 = Step(name='s1', status=common_pb2.SUCCESS) step2 = Step(name='compile', status=common_pb2.FAILURE) build.steps.extend([step1, step2]) context = Context(luci_project_name='chromium', gitiles_host='gitiles.host.com', gitiles_project='project/name', gitiles_ref='ref/heads/master', gitiles_id='git_sha') failed_steps = build_util.GetFailedStepsInBuild(context, build) self.assertEqual(1, len(failed_steps)) self.assertEqual('compile', failed_steps[0][0].name) self.assertEqual(StepTypeEnum.COMPILE, failed_steps[0][1])
def testGetStepLogViewUrlNoMatchingLog(self): build_id = 8945610992972640896 mock_log = Step.Log() mock_log.name = 'another_log' mock_log.view_url = 'view_url' mock_step1 = Step() mock_step1.name = 's1' mock_step1.logs.extend([mock_log]) mock_step2 = Step() mock_step2.name = 's2' mock_step2.logs.extend([mock_log]) mock_build = Build() mock_build.id = build_id mock_build.steps.extend([mock_step1, mock_step2]) self.assertIsNone(step_util._GetStepLogViewUrl(mock_build, 's2', 'log'))
def testProcessBuildForFlakes(self, mock_metadata, mock_build, mock_normalized_test_name, mock_lable_name, *_): flake_type_enum = FlakeType.CQ_FALSE_REJECTION build_id = 123 luci_project = 'luci_project' luci_bucket = 'luci_bucket' luci_builder = 'luci_builder' legacy_master_name = 'legacy_master_name' start_time = datetime(2019, 3, 6) end_time = datetime(2019, 3, 6, 0, 0, 10) findit_step = Step() findit_step.name = 'FindIt Flakiness' step1 = Step() step1.name = 'step1 (with patch)' step1.start_time.FromDatetime(start_time) step1.end_time.FromDatetime(end_time) builder = BuilderID( project=luci_project, bucket=luci_bucket, builder=luci_builder, ) build = Build(id=build_id, builder=builder, number=build_id) build.steps.extend([findit_step, step1]) build.input.properties['mastername'] = legacy_master_name build.input.properties['patch_project'] = 'chromium/src' mock_change = build.input.gerrit_changes.add() mock_change.host = 'mock.gerrit.host' mock_change.change = 12345 mock_change.patchset = 1 mock_build.return_value = build def _MockTestName(test_name, _step_ui_name): # pylint: disable=unused-argument return test_name mock_normalized_test_name.side_effect = _MockTestName mock_lable_name.side_effect = _MockTestName flakiness_metadata = { 'Failing With Patch Tests That Caused Build Failure': { 'step1 (with patch)': ['s1_t1', 's1_t2'] }, 'Step Layer Flakiness': {} } mock_metadata.return_value = flakiness_metadata # Flake object for s2_t1 exists. flake1 = Flake.Create( luci_project=luci_project, normalized_step_name='step1', normalized_test_name='s1_t1', test_label_name='s1_t1') flake1.put() detect_flake_occurrences.ProcessBuildForFlakes( detect_flake_occurrences.DetectFlakesFromFlakyCQBuildParam( build_id=build_id, flake_type_desc=FLAKE_TYPE_DESCRIPTIONS[flake_type_enum])) flake1_occurrence_num = FlakeOccurrence.query(ancestor=flake1.key).count() self.assertEqual(1, flake1_occurrence_num) flake2 = Flake.Get(luci_project, 'step1', 's1_t2') self.assertIsNotNone(flake2)
def testUpdateCompileFailuresWithFirstFailureInfoDifferentFirstFailure( self, mock_prev_builds, mock_get_build, mock_prev_failures): """Test for targets in current build failed from different builds.""" mock_step = Step() mock_step.name = 'compile' mock_step.status = common_pb2.FAILURE build_122_id = 8000000000122 build_122 = Build(id=build_122_id, builder=self.builder, number=self.build_number - 1, status=common_pb2.FAILURE) build_122.steps.extend([mock_step]) build_122.input.gitiles_commit.id = 'git_sha_122' build_122_info = { 'id': build_122_id, 'number': self.build_number - 1, 'commit_id': 'git_sha_122' } mock_step1 = Step() mock_step1.name = 'compile' mock_step1.status = common_pb2.FAILURE build_121_id = 8000000000121 build_121 = Build(id=build_121_id, builder=self.builder, number=self.build_number - 2, status=common_pb2.FAILURE) build_121.steps.extend([mock_step1]) build_121.input.gitiles_commit.id = 'git_sha_121' build_121_info = { 'id': build_121_id, 'number': self.build_number - 2, 'commit_id': 'git_sha_121' } mock_step2 = Step() mock_step2.name = 'compile' mock_step2.status = common_pb2.FAILURE build_120_id = 8000000000121 build_120 = Build(id=build_120_id, builder=self.builder, number=self.build_number - 3, status=common_pb2.FAILURE) build_120.steps.extend([mock_step2]) build_120.input.gitiles_commit.id = 'git_sha_120' build_120_info = { 'id': build_120_id, 'number': self.build_number - 3, 'commit_id': 'git_sha_120' } mock_prev_builds.return_value = SearchBuildsResponse( builds=[build_122, build_121, build_120]) mock_get_build.side_effect = [build_122, build_121, build_120] # Failed compiling target3 but successfully compiled target1&2. failures_122 = { 'compile': { 'failures': { frozenset(['target3']): { 'rule': 'ACTION', 'first_failed_build': build_122_info, 'last_passed_build': None, }, }, 'first_failed_build': build_122_info, 'last_passed_build': None, }, } # Has the same failed targets as current build. failures_121 = { 'compile': { 'failures': { frozenset(['target3']): { 'rule': 'ACTION', 'first_failed_build': build_121_info, 'last_passed_build': None, }, frozenset(['target1', 'target2']): { 'rule': 'CXX', 'first_failed_build': build_121_info, 'last_passed_build': None, }, }, 'first_failed_build': build_121_info, 'last_passed_build': None, }, } # Failed compile step, but only different targets. failures_120 = { 'compile': { 'failures': { frozenset(['target4']): { 'rule': 'CC', 'first_failed_build': build_120_info, 'last_passed_build': None, }, }, 'first_failed_build': build_120_info, 'last_passed_build': None, }, } mock_prev_failures.side_effect = [ failures_122, failures_121, failures_120 ] detailed_compile_failures = { 'compile': { 'failures': { frozenset(['target1', 'target2']): { 'rule': 'CXX', 'first_failed_build': self.build_info, 'last_passed_build': None, }, frozenset(['target3']): { 'rule': 'ACTION', 'first_failed_build': self.build_info, 'last_passed_build': None, }, }, 'first_failed_build': self.build_info, 'last_passed_build': None, }, } pre_compile_analysis.UpdateCompileFailuresWithFirstFailureInfo( self.context, self.build, detailed_compile_failures) expected_failures = { 'compile': { 'failures': { frozenset(['target1', 'target2']): { 'rule': 'CXX', 'first_failed_build': self.build_info, 'last_passed_build': build_122_info, }, frozenset(['target3']): { 'rule': 'ACTION', 'first_failed_build': build_121_info, 'last_passed_build': build_120_info, }, }, 'first_failed_build': build_121_info, 'last_passed_build': build_120_info, }, } self.assertEqual(expected_failures, detailed_compile_failures)
def testProcessRerunBuildResult(self, mock_compile_failures): build_id = 8000000000123 build_number = 123 builder = BuilderID(project='chromeos', bucket='postsubmit', builder='findit-variable') build = Build(id=build_id, builder=builder, number=build_number, status=common_pb2.FAILURE, tags=[{ 'key': 'analyzed_build_id', 'value': str(self.analyzed_build_id) }]) build.input.gitiles_commit.host = 'gitiles.host.com' build.input.gitiles_commit.project = 'project/name' build.input.gitiles_commit.ref = 'ref/heads/master' build.input.gitiles_commit.id = 'git_sha_6543221' build.create_time.FromDatetime(datetime(2019, 4, 9)) step1 = Step(name='s1', status=common_pb2.SUCCESS) step2 = Step(name=self.compile_step_name, status=common_pb2.FAILURE) build.steps.extend([step1, step2]) output_target = json.dumps({ 'category': 'chromeos-base', 'packageName': 'target2' }) build.output.properties['build_compile_failure_output'] = { 'failures': [ { 'output_targets': [output_target], 'rule': 'emerge' }, ], 'failed_step': self.compile_step_name } mock_compile_failures.return_value = { self.compile_step_name: { 'failures': { frozenset(['target1.o', 'target2.o']): { 'rule': 'CXX', 'first_failed_build': { 'id': build_id, 'number': build_number, 'commit_id': 'git_sha_6543221' }, 'last_passed_build': None }, }, 'first_failed_build': { 'id': build_id, 'number': build_number, 'commit_id': 'git_sha_6543221' }, 'last_passed_build': None }, } CompileRerunBuild.Create(luci_project=self.context.luci_project_name, luci_bucket=build.builder.bucket, luci_builder=build.builder.builder, build_id=build_id, legacy_build_number=build_number, gitiles_host=self.context.gitiles_host, gitiles_project=self.context.gitiles_project, gitiles_ref=self.context.gitiles_ref, gitiles_id='git_sha_6543221', commit_position=6543221, status=build.status, create_time=build.create_time.ToDatetime(), parent_key=self.analysis.key).put() self.assertTrue( compile_api._ProcessAndSaveRerunBuildResult( self.context, self.analyzed_build_id, build)) rerun_build = CompileRerunBuild.get_by_id(build_id, parent=self.analysis.key) self.assertItemsEqual( ['target1.o', 'target2.o'], rerun_build.GetFailedTargets()[self.compile_step_name])