示例#1
0
def ExtractBuildInfo(master_name, builder_name, build_number, build_data):
    """Extracts and returns build information as an instance of BuildInfo."""
    build_info = BuildInfo(master_name, builder_name, build_number)
    data_json = json.loads(build_data)
    chromium_revision = GetBuildProperty(data_json.get('properties', []),
                                         'got_revision')
    commit_position_line = GetBuildProperty(data_json.get('properties', []),
                                            'got_revision_cp')
    parent_buildername = GetBuildProperty(data_json.get('properties', []),
                                          'parent_buildername')
    parent_mastername = GetBuildProperty(data_json.get('properties', []),
                                         'parent_mastername')

    build_info.build_start_time = GetBuildStartTime(data_json)
    build_info.build_end_time = GetBuildEndTime(data_json)
    build_info.chromium_revision = chromium_revision
    build_info.commit_position = _GetCommitPosition(commit_position_line)
    build_info.completed = data_json.get('currentStep') is None
    build_info.result = GetBuildResult(data_json)
    build_info.parent_buildername = parent_buildername
    build_info.parent_mastername = parent_mastername

    changes = data_json.get('sourceStamp', {}).get('changes', [])
    for change in changes:
        if change['revision'] not in build_info.blame_list:
            build_info.blame_list.append(change['revision'])

    # Step categories:
    # 1. A step is passed if it is in SUCCESS or WARNINGS status.
    # 2. A step is failed if it is in FAILED status.
    # 3. A step is not passed if it is not in SUCCESS or WARNINGS status. This
    #    category includes steps in statuses: FAILED, SKIPPED, EXCEPTION, RETRY,
    #    CANCELLED, etc.
    steps = data_json.get('steps', [])
    for step_data in steps:
        step_name = step_data['name']

        if not step_data.get('isFinished', False):
            # Skip steps that haven't started yet or are still running.
            continue

        step_result = GetStepResult(step_data)
        if step_result not in (SUCCESS, WARNINGS):
            build_info.not_passed_steps.append(step_name)

        step_logs = step_data.get('logs')
        if step_logs and 'preamble' == step_logs[0][0]:
            # Skip a annotating step like "steps" or "slave_steps", which wraps other
            # steps. A failed annotated step like "content_browsertests" will make
            # the annotating step like "steps" fail too. Such annotating steps have a
            # log with name "preamble".
            continue

        if step_result in (SUCCESS, WARNINGS):
            build_info.passed_steps.append(step_name)
        elif step_result == FAILURE:
            build_info.failed_steps.append(step_name)

    return build_info
示例#2
0
def ExtractBuildInfoFromV2Build(master_name, builder_name, build_number, build):
  """Generates BuildInfo using bb v2 build info.

  This conversion is needed to keep Findit v1 running, will be deprecated in
  v2 (TODO: crbug.com/966982).

  Args:
    master_name (str): The name of the master.
    builder_name (str): The name of the builder.
    build_number (int): The build number.
    build (build_pb2.Build): All info about the build.

  Returns:
    (BuildInfo)
  """
  build_info = BuildInfo(master_name, builder_name, build_number)

  input_properties = json_format.MessageToDict(build.input.properties)

  chromium_revision = build.input.gitiles_commit.id
  runtime = input_properties.get('$recipe_engine/runtime') or {}

  build_info.chromium_revision = chromium_revision

  repo_url = git.GetRepoUrlFromV2Build(build)
  build_info.commit_position = git.GetCommitPositionFromRevision(
      build.input.gitiles_commit.id, repo_url=repo_url)

  build_info.build_start_time = build.create_time.ToDatetime()
  build_info.build_end_time = build.end_time.ToDatetime()
  build_info.completed = bool(build_info.build_end_time)
  build_info.result = build.status
  build_info.parent_buildername = input_properties.get('parent_buildername')
  build_info.parent_mastername = input_properties.get('parent_mastername')
  build_info.buildbucket_id = str(build.id)
  build_info.buildbucket_bucket = build.builder.bucket
  build_info.is_luci = runtime.get('is_luci')

  build_info.blame_list = GetBlameListForV2Build(build)

  # Step categories:
  # 1. A step is passed if it is in SUCCESS status.
  # 2. A step is failed if it is in FAILURE status.
  # 3. A step is not passed if it is not in SUCCESS status. This category
  #   includes steps in statuses: FAILURE, INFRA_FAILURE, CANCELED, etc.
  for step in build.steps:
    step_name = step.name
    step_status = step.status

    if step_status in [
        common_pb2.STATUS_UNSPECIFIED, common_pb2.SCHEDULED, common_pb2.STARTED
    ]:
      continue

    if step_status != common_pb2.SUCCESS:
      build_info.not_passed_steps.append(step_name)

    if step_name == 'Failure reason':
      # 'Failure reason' is always red when the build breaks or has exception,
      # but it is not a failed step.
      continue

    if not step.logs:
      # Skip wrapping steps.
      continue

    if step_status == common_pb2.SUCCESS:
      build_info.passed_steps.append(step_name)
    elif step_status == common_pb2.FAILURE:
      build_info.failed_steps.append(step_name)

  return build_info