def GetBlameListForV2Build(build): """ Uses gitiles_commit from the previous build and current build to get blame_list. Args: build (build_pb2.Build): All info about the build. Returns: (list of str): Blame_list of the build. """ search_builds_response = buildbucket_client.SearchV2BuildsOnBuilder( build.builder, build_range=(None, build.id), page_size=2) previous_build = None for search_build in search_builds_response.builds: # TODO(crbug.com/969124): remove the loop when SearchBuilds RPC works as # expected. if search_build.id != build.id: previous_build = search_build break if not previous_build: logging.error( 'No previous build found for build %d, cannot get blame list.', build.id) return [] repo_url = git.GetRepoUrlFromV2Build(build) return git.GetCommitsBetweenRevisionsInOrder( previous_build.input.gitiles_commit.id, build.input.gitiles_commit.id, repo_url)
def IdentifySuspectedRevisions(analysis): """Identifies revisions to have introduced flakiness. Args: analysis (MasterFlakeAnalysis): The MasterFlakeAnalysis entity to perform heuristic analysis on. Returns: (list): A list of revisions in chronological order suspected to have introduced test flakiness. """ regression_range = analysis.GetLatestRegressionRange() if regression_range.lower is None or regression_range.upper is None: analysis.LogWarning( 'Unable to identify suspects without a complete regression range') return [] upper_data_point = analysis.FindMatchingDataPointWithCommitPosition( regression_range.upper.commit_position) assert upper_data_point, 'Cannot get test location without data point' assert upper_data_point.git_hash, 'Upper bound revision is None' test_location = swarmed_test_util.GetTestLocation( upper_data_point.GetSwarmingTaskId(), analysis.test_name) if not test_location: analysis.LogWarning( 'Failed to get test location. Heuristic results will ' 'not be available.') return [] normalized_file_path = extractor_util.NormalizeFilePath(test_location.file) git_blame = git.GetGitBlame(constants.CHROMIUM_GIT_REPOSITORY_URL, upper_data_point.git_hash, normalized_file_path) if git_blame is None: analysis.LogWarning('Failed to get git blame for {}, {}'.format( normalized_file_path, upper_data_point.git_hash)) return [] lower_revision = regression_range.lower.revision assert lower_revision, 'Lower bound revision is None' revisions = git.GetCommitsBetweenRevisionsInOrder( lower_revision, upper_data_point.git_hash, repo_url=constants.CHROMIUM_GIT_REPOSITORY_URL, ascending=True) if not revisions: analysis.LogWarning('Failed to get revisions in range [{}, {}]'.format( lower_revision, upper_data_point.git_hash)) return [] return GetSuspectedRevisions(git_blame, revisions)
def GetCompileFailureInfo(self, context, build, first_failures_in_current_build): """Creates structured object expected by heuristic analysis code.""" # As per common/waterfall/failure_type.py LEGACY_COMPILE_TYPE = 0x08 return CompileFailureInfo.FromSerializable({ 'failed_steps': { 'compile': { 'supported': True, 'last_pass': first_failures_in_current_build['last_passed_build'] ['number'], 'current_failure': build.number, 'first_failure': build.number, }, }, 'master_name': build.input.properties['mastername'], 'builder_name': build.builder.builder, 'build_number': build.number, 'parent_mastername': None, # These only apply to some testers. 'parent_buildername': None, 'builds': { build.number: { # Construct a list of revisions since the last passing build. 'blame_list': git.GetCommitsBetweenRevisionsInOrder( first_failures_in_current_build['last_passed_build'] ['commit_id'], context.gitiles_id, ascending=False), 'chromium_revision': context.gitiles_id, }, }, 'failure_type': LEGACY_COMPILE_TYPE, 'failed': True, 'chromium_revision': context.gitiles_id, 'is_luci': True, 'buildbucket_bucket': 'luci.%s.%s' % (build.builder.project, build.builder.bucket), 'buildbucket_id': str(build.id), })
def GetTestFailureInfo(self, context, build, first_failures_in_current_build): """Creates structured object expected by heuristic analysis code.""" # As per common/waterfall/failure_type.py LEGACY_TEST_TYPE = 0x10 build_info = build_util.GetBuildInfo(build.input.properties['mastername'], build.builder.builder, build.number) result = { 'failed_steps': {}, 'master_name': build.input.properties['mastername'], 'builder_name': build.builder.builder, 'build_number': build.number, 'parent_mastername': build_info.parent_mastername, 'parent_buildername': build_info.parent_buildername, 'builds': {}, 'failure_type': LEGACY_TEST_TYPE, 'failed': True, 'chromium_revision': context.gitiles_id, 'is_luci': True, 'buildbucket_bucket': 'luci.%s.%s' % (build.builder.project, build.builder.bucket), 'buildbucket_id': str(build.id), build.number: { # Construct a list of revisions since the last passing build. 'blame_list': git.GetCommitsBetweenRevisionsInOrder( first_failures_in_current_build['last_passed_build'] ['commit_id'], context.gitiles_id, ascending=False), 'chromium_revision': context.gitiles_id, }, } for step, failure in first_failures_in_current_build['failures'].iteritems( ): result['failed_steps'][step] = { 'supported': True, 'last_pass': failure['last_passed_build']['number'], 'current_failure': build.number, 'first_failure': build.number, } return TestFailureInfo.FromSerializable(result)
def testGetCommitsBetweenRevisionsInOrderDescending(self, _): self.assertEqual(['r4', 'r3', 'r2', 'r1'], git.GetCommitsBetweenRevisionsInOrder( 'r0', 'r4', ascending=False))