def testCompileStep(self): step = Step() step.name = 'compile' log = step.logs.add() log.name = 'stdout' self.assertEqual(StepTypeEnum.COMPILE, ChromiumProjectAPI().ClassifyStepType(None, step))
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 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 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 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 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 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 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 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 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 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 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 testUpdateCompileFailuresWithFirstFailureInfoPrevBuildDifferentStep( self, mock_prev_builds, mock_get_build): """Test for previous build failed with different steps.""" mock_step = Step() mock_step.name = 'test' mock_step.status = common_pb2.FAILURE mock_step1 = Step() mock_step1.name = 'compile' mock_step1.status = common_pb2.SUCCESS 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, mock_step1]) 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' } build_121_id = 8000000000121 build_121 = Build(id=build_121_id, builder=self.builder, number=self.build_number - 2, status=common_pb2.SUCCESS) 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_122_info, }, }, 'first_failed_build': self.build_info, 'last_passed_build': build_122_info, }, } self.assertEqual(expected_failures, detailed_compile_failures)