Пример #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
Пример #3
0
    def testGetIsolateShaForCommitPositionPipelineMatchingTarget(
            self, mocked_reference_build):
        master_name = 'm'
        builder_name = 'b'
        parent_mastername = 'p_m'
        parent_buildername = 'p_b'
        build_number = 100
        build_id = 123
        test_name = 't'
        requested_commit_position = 1000
        requested_revision = 'r1000'
        expected_sha = 'sha1'
        build_url = 'url'
        luci_name = 'chromium'
        bucket_name = 'ci'
        gitiles_host = 'chromium.googlesource.com'
        gitiles_project = 'chromium/src'
        gitiles_ref = 'refs/heads/master'
        gerrit_patch = ''
        isolate_target_name = 'browser_tests'
        step_name = 's'
        isolated_hash = 'isolated_hash'

        expected_output = GetIsolateShaOutput(isolate_sha=expected_sha,
                                              build_number=None,
                                              build_url=build_url,
                                              try_job_url=None)

        analysis = MasterFlakeAnalysis.Create(master_name, builder_name,
                                              build_number, step_name,
                                              test_name)
        analysis.Save()

        build = BuildInfo(master_name, builder_name, build_number)
        build.commit_position = requested_commit_position
        build.parent_mastername = parent_mastername
        build.parent_buildername = parent_buildername
        mocked_reference_build.return_value = build

        isolated_target = IsolatedTarget.Create(
            build_id, luci_name, bucket_name, parent_mastername,
            parent_buildername, gitiles_host, gitiles_project, gitiles_ref,
            gerrit_patch, isolate_target_name, isolated_hash,
            requested_commit_position, requested_revision)
        isolated_target.put()

        step_metadata = StepMetadata(canonical_step_name=None,
                                     dimensions=None,
                                     full_step_name=None,
                                     isolate_target_name=isolate_target_name,
                                     patched=True,
                                     swarm_task_ids=None,
                                     waterfall_buildername=None,
                                     waterfall_mastername=None)

        get_sha_input = GetIsolateShaForCommitPositionParameters(
            analysis_urlsafe_key=unicode(analysis.key.urlsafe()),
            commit_position=requested_commit_position,
            dimensions=ListOfBasestring.FromSerializable([]),
            revision=requested_revision,
            step_metadata=step_metadata,
            upper_bound_build_number=analysis.build_number)

        get_sha_for_target_input = GetIsolateShaForTargetInput(
            isolated_target_urlsafe_key=isolated_target.key.urlsafe())

        self.MockSynchronousPipeline(GetIsolateShaForTargetPipeline,
                                     get_sha_for_target_input, expected_output)

        pipeline_job = GetIsolateShaForCommitPositionPipeline(get_sha_input)
        pipeline_job.start()
        self.execute_queued_tasks()

        pipeline_job = pipelines.pipeline.Pipeline.from_id(
            pipeline_job.pipeline_id)
        pipeline_output = pipeline_job.outputs.default.value

        self.assertEqual(expected_output.ToSerializable(), pipeline_output)
  def testNextCommitPositionPipelineContinueAnalysis(
      self, mock_reference_build, mock_heuristic, mock_next_commit,
      mock_bound_commits):
    master_name = 'm'
    builder_name = 'b'
    parent_mastername = 'p_m'
    parent_buildername = 'p_b'
    build_number = 100
    build_id = 10000
    step_name = 's'
    test_name = 't'
    start_commit_position = 1000
    expected_next_commit_id = CommitID(commit_position=990, revision='r990')

    reference_build = BuildInfo(master_name, builder_name, build_number)
    reference_build.commit_position = start_commit_position
    reference_build.parent_mastername = parent_mastername
    reference_build.parent_buildername = parent_buildername
    mock_reference_build.return_value = reference_build
    mock_heuristic.return_value = False

    calculated_next_commit_id = CommitID(commit_position=999, revision='r999')
    mock_next_commit.return_value = (calculated_next_commit_id, None)

    target_name = 'browser_tests'
    step_metadata = StepMetadata(
        canonical_step_name=None,
        dimensions=None,
        full_step_name=None,
        isolate_target_name=target_name,
        patched=True,
        swarm_task_ids=None,
        waterfall_buildername=None,
        waterfall_mastername=None)

    luci_name = 'chromium'
    bucket_name = 'ci'
    gitiles_host = 'chromium.googlesource.com'
    gitiles_project = 'chromium/src'
    gitiles_ref = 'refs/heads/master'
    gerrit_patch = ''

    lower_bound_target = IsolatedTarget.Create(
        build_id - 1, luci_name, bucket_name, parent_mastername,
        parent_buildername, gitiles_host, gitiles_project, gitiles_ref,
        gerrit_patch, target_name, 'hash_1',
        expected_next_commit_id.commit_position, None)
    lower_bound_target.put()

    upper_bound_target = IsolatedTarget.Create(
        build_id, luci_name, bucket_name, parent_mastername, parent_buildername,
        gitiles_host, gitiles_project, gitiles_ref, gerrit_patch, target_name,
        'hash_2', start_commit_position, None)
    upper_bound_target.put()
    mock_bound_commits.return_value = (
        expected_next_commit_id,
        CommitID(commit_position=start_commit_position, revision='r1000'))

    analysis = MasterFlakeAnalysis.Create(master_name, builder_name,
                                          build_number, step_name, test_name)
    analysis.data_points = [
        DataPoint.Create(commit_position=start_commit_position)
    ]
    analysis.Save()

    next_commit_position_input = NextCommitPositionInput(
        analysis_urlsafe_key=analysis.key.urlsafe(),
        commit_position_range=IntRange(lower=None, upper=start_commit_position),
        step_metadata=step_metadata)

    pipeline_job = NextCommitPositionPipeline(next_commit_position_input)
    pipeline_job.start()
    self.execute_queued_tasks()

    pipeline_job = pipelines.pipeline.Pipeline.from_id(pipeline_job.pipeline_id)
    next_commit_position_output = pipeline_job.outputs.default.value

    self.assertFalse(pipeline_job.was_aborted)
    self.assertIsNone(next_commit_position_output['culprit_commit_id'])
    self.assertEqual(expected_next_commit_id.ToSerializable(),
                     next_commit_position_output['next_commit_id'])
    mock_bound_commits.assert_called_once_with(
        analysis.data_points, lower_bound_target, upper_bound_target)