Exemple #1
0
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)
Exemple #2
0
def GetRecentCompletedBuilds(master_name, builder_name, page_size=None):
  """Returns a sorted list of recent completed builds for the given builder.

  Sorted by completed time, newer builds at beginning of the returned list.
  """
  luci_project, luci_bucket = GetLuciProjectAndBucketForMaster(master_name)
  search_builds_response = buildbucket_client.SearchV2BuildsOnBuilder(
      BuilderID(project=luci_project, bucket=luci_bucket, builder=builder_name),
      status=common_pb2.ENDED_MASK,
      page_size=page_size)

  return [build.number for build in search_builds_response.builds
         ] if search_builds_response else None
Exemple #3
0
def GetLatestCommitPositionAndRevision(master_name, builder_name, target_name):
    """Gets the latest commit position and revision for a configuration.

  Args:
    master_name (str): The name of the master to query.
    builder_name (str): The name of the builder to query.
    target_name (str): The desired target name.

  Returns:
    (int, str): The latest commit position known and its corresponding revision.
  
  """
    latest_targets = (IsolatedTarget.FindLatestIsolateByMaster(
        master_name, builder_name, services_constants.GITILES_HOST,
        services_constants.GITILES_PROJECT, services_constants.GITILES_REF,
        target_name))

    if latest_targets:
        commit_position = latest_targets[0].commit_position
        revision = latest_targets[0].revision
        if not revision:
            # Historical data doesn't have revision.
            commit_info = crrev.RedirectByCommitPosition(
                FinditHttpClient(), commit_position)
            assert commit_info is not None, 'No info: r%d' % commit_position
            revision = commit_info['git_sha']

        return commit_position, revision

    # Fallback to buildbot for builds not yet migrated to LUCI.
    # TODO (crbug.com/804617): Remove fallback logic after migration is complete.
    luci_project, luci_bucket = buildbot.GetLuciProjectAndBucketForMaster(
        master_name)
    search_builds_response = buildbucket_client.SearchV2BuildsOnBuilder(
        BuilderID(project=luci_project,
                  bucket=luci_bucket,
                  builder=builder_name),
        page_size=1)

    if not search_builds_response:
        # Something is wrong. Calling code should be responsible for checking for
        # the return value.
        return None, None

    latest_build = search_builds_response.builds[0]
    revision = latest_build.input.gitiles_commit.id
    repo_url = git.GetRepoUrlFromV2Build(latest_build)
    return git.GetCommitPositionFromRevision(
        latest_build.input.gitiles_commit.id, repo_url=repo_url), revision
  def testSearchV2BuildsOnBuilder(self, mock_post):
    builder = BuilderID(project='chromium', bucket='try', builder='linux-rel')

    mock_build = Build(number=100)
    mock_response = SearchBuildsResponse(
        next_page_token='next_page_token', builds=[mock_build])
    mock_headers = {'X-Prpc-Grpc-Code': '0'}
    binary_data = mock_response.SerializeToString()
    mock_post.return_value = (200, binary_data, mock_headers)

    res = buildbucket_client.SearchV2BuildsOnBuilder(builder)

    self.assertEqual('next_page_token', res.next_page_token)
    self.assertEqual(1, len(res.builds))
    self.assertEqual(100, res.builds[0].number)
Exemple #5
0
def IteratePreviousBuildsFrom(master_name, builder_name, build_id,
                              entry_limit):
    luci_project, luci_bucket = buildbot.GetLuciProjectAndBucketForMaster(
        master_name)
    builder = BuilderID(project=luci_project,
                        bucket=luci_bucket,
                        builder=builder_name)

    entry_number = 0
    # End_build_id in build_range when query the previous build.
    end_build_id = build_id
    while entry_number <= entry_limit:  # pragma: no branch.
        search_builds_response = buildbucket_client.SearchV2BuildsOnBuilder(
            builder,
            build_range=(None, end_build_id),
            page_size=2,
            fields=FieldMask(paths=['builds.*.*']))

        if not search_builds_response.builds:
            # No more previous build.
            return

        previous_build = None
        # TODO(crbug.com/969124): remove the loop when SearchBuilds RPC works as
        # expected.
        for search_build in search_builds_response.builds:
            if search_build.id != end_build_id:
                previous_build = search_build
                break

        if not previous_build:
            logging.warning('No previous build found for build %d.',
                            end_build_id)
            return

        end_build_id = previous_build.id
        entry_number += 1
        yield previous_build
def UpdateCompileFailuresWithFirstFailureInfo(context, build,
                                              detailed_compile_failures):
  """Updates detailed_compile_failures with first failure info.

  Args:
    context (findit_v2.services.context.Context): Scope of the analysis.
    build (buildbucket build.proto): ALL info about the build.
    detailed_compile_failures (dict): A dict of detailed compile failures.
      {
        'step_name': {
          'failures': {
            frozenset(['target1', 'target2']): {
              'rule': 'emerge',
              'first_failed_build': {
                'id': 8765432109,
                'number': 123,
                'commit_id': 654321
              },
              'last_passed_build': None,
            },
            ...
          },
          'first_failed_build': {
            'id': 8765432109,
            'number': 123,
            'commit_id': 654321
          },
          'last_passed_build': None,
        },
      }
  """
  luci_project = context.luci_project_name
  project_api = projects.GetProjectAPI(luci_project)
  assert project_api, 'Unsupported project {}'.format(luci_project)

  # Gets previous builds, the builds are sorted by build number in descending
  # order.
  # No steps info in each build considering the response size.
  # Requests to buildbucket for each failed build separately.
  search_builds_response = buildbucket_client.SearchV2BuildsOnBuilder(
      build.builder,
      build_range=(None, build.id),
      page_size=constants.MAX_BUILDS_TO_CHECK)
  previous_builds = search_builds_response.builds

  need_go_back = False
  for prev_build in previous_builds:
    if prev_build.id == build.id:
      # TODO(crbug.com/969124): remove the check when SearchBuilds RPC works as
      # expected.
      continue

    prev_build_info = {
        'id': prev_build.id,
        'number': prev_build.number,
        'commit_id': prev_build.input.gitiles_commit.id
    }

    if prev_build.status == common_pb2.SUCCESS:
      # Found a passed build, update all failures.
      _UpdateCompileFailuresWithPreviousBuildInfo(detailed_compile_failures,
                                                  prev_build_info)
      return

    prev_compile_steps, prev_failures = (
        _GetPreviousCompileStepsAndFailuresInPreviousBuild(
            project_api, prev_build, detailed_compile_failures))

    for step_ui_name, step_info in detailed_compile_failures.iteritems():
      if not prev_compile_steps.get(step_ui_name):
        # For some reason the compile step didn't run in the previous build.
        need_go_back = True
        continue

      if prev_compile_steps.get(step_ui_name) and prev_compile_steps[
          step_ui_name].status == common_pb2.SUCCESS:
        # The step passed in the previous build, update all failures in this
        # step.
        _UpdateCompileFailuresWithPreviousBuildInfo(
            detailed_compile_failures,
            prev_build_info,
            prev_step_ui_name=step_ui_name)
        continue

      if not prev_failures.get(step_ui_name):
        # The step didn't pass nor fail, Findit cannot get useful information
        # from it, going back.
        need_go_back = True
        continue

      step_last_passed_found = True
      failures = step_info['failures']
      for targets_str, failure in failures.iteritems():
        if failure['last_passed_build']:
          # Last pass has been found for this failure, skip the failure.
          continue

        if prev_failures[step_ui_name]['failures'].get(targets_str):
          # The same failure happened in the previous build, going back.
          failure['first_failed_build'] = prev_build_info
          step_info['first_failed_build'] = prev_build_info
          need_go_back = True
          step_last_passed_found = False
        else:
          # The failure didn't happen in the previous build, first failure found
          failure['last_passed_build'] = prev_build_info

      if step_last_passed_found:
        step_info['last_passed_build'] = prev_build_info

    if not need_go_back:
      return