def testGetV2Build(self, mock_post):
    build_id = '8945610992972640896'
    mock_build = Build()
    mock_build.id = int(build_id)
    mock_build.status = 12
    mock_build.output.properties['mastername'] = 'chromium.linux'
    mock_build.output.properties['buildername'] = 'Linux Builder'
    mock_build.output.properties.get_or_create_struct(
        'swarm_hashes_ref/heads/mockmaster(at){#123}'
    )['mock_target'] = 'mock_hash'
    gitiles_commit = mock_build.input.gitiles_commit
    gitiles_commit.host = 'gitiles.host'
    gitiles_commit.project = 'gitiles/project'
    gitiles_commit.ref = 'refs/heads/mockmaster'
    mock_build.builder.project = 'mock_luci_project'
    mock_build.builder.bucket = 'mock_bucket'
    mock_build.builder.builder = 'Linux Builder'
    mock_headers = {'X-Prpc-Grpc-Code': '0'}
    binary_data = mock_build.SerializeToString()
    mock_post.return_value = (200, binary_data, mock_headers)
    build = buildbucket_client.GetV2Build(build_id)
    self.assertIsNotNone(build)
    self.assertEqual(mock_build.id, build.id)

    mock_headers = {'X-Prpc-Grpc-Code': '4'}
    binary_data = mock_build.SerializeToString()
    mock_post.return_value = (404, binary_data, mock_headers)
    self.assertIsNone(buildbucket_client.GetV2Build(build_id))
Example #2
0
def GetBuildAndContextForAnalysis(project, build_id):
    """Gets all information about a build and generates context from it.

  Args:
    project (str): Luci project of the build.
    build_id (int): Id of the build.

  Returns:
    (buildbucket build.proto): ALL info about the build.
    (Context): Context of an analysis.

  """
    build = buildbucket_client.GetV2Build(build_id,
                                          fields=FieldMask(paths=['*']))

    if not build:
        logging.error('Failed to get build info for build %d.', build_id)
        return None, None

    if (build.input.gitiles_commit.host !=
            projects.GERRIT_PROJECTS[project]['gitiles-host']
            or build.input.gitiles_commit.project !=
            projects.GERRIT_PROJECTS[project]['name']):
        logging.warning('Unexpected gitiles project for build: %r', build_id)
        return None, None

    context = Context(luci_project_name=project,
                      gitiles_host=build.input.gitiles_commit.host,
                      gitiles_project=build.input.gitiles_commit.project,
                      gitiles_ref=build.input.gitiles_commit.ref,
                      gitiles_id=build.input.gitiles_commit.id)
    return build, context
Example #3
0
def GetStepLogForLuciBuild(build_id,
                           full_step_name,
                           http_client,
                           log_name='stdout'):
    """Returns specific log of the specified step in a LUCI build.

  Args:
    build_id(str): Buildbucket id.
    full_step_name(str): Full name of the step.
    http_client(FinditHttpClient): Http_client to make the request.
    log_name(str): Name of the log.

  Returns:
    Requested Log after processing based on the log_name.
    - return the log as it is if the log name is 'stdout' or
      'json.output[ninja_info]'
    - return the deserialized log otherwise.
  """

    build = buildbucket_client.GetV2Build(build_id, FieldMask(paths=['steps']))
    if not build:
        logging.exception('Error retrieving buildbucket build id: %s' %
                          build_id)
        return None

    return GetStepLogFromBuildObject(build, full_step_name, http_client,
                                     log_name)
Example #4
0
def GetBuildInfo(master_name, builder_name, build_number):
    """Gets build info given a master, builder, and build number.

  Args:
    master_name (str): The name of the master.
    builder_name (str): The name of the builder.
    build_number (int): The build number.

  Returns:
    Build information as an instance of BuildInfo.
  """
    build = DownloadBuildData(master_name, builder_name, build_number)
    if not build.build_id:
        return None

    bb_build = buildbucket_client.GetV2Build(build.build_id,
                                             fields=FieldMask(paths=['*']))
    build_info = buildbot.ExtractBuildInfoFromV2Build(master_name,
                                                      builder_name,
                                                      build_number, bb_build)

    if not build.completed:
        build.start_time = build_info.build_start_time
        build.completed = build_info.completed
        build.result = build_info.result
        build.put()

    return build_info
def _GetPreviousCompileStepsAndFailuresInPreviousBuild(
    project_api, prev_build, detailed_compile_failures):
  """Gets compile failures in the previous build.

  Args:
    project_api (ProjectAPI): API for project specific logic.
    prev_build (buildbucket build.proto): SIMPLE info about the build.
    detailed_compile_failures (dict): A dict of detailed compile failures.
  """
  detailed_prev_build = buildbucket_client.GetV2Build(
      prev_build.id, fields=FieldMask(paths=['*']))

  # Looks for compile steps in previous build. Here only the failed compile
  # steps in current build are relevant.
  prev_compile_steps = {
      s.name: s
      for s in detailed_prev_build.steps
      if s.name in detailed_compile_failures
  }
  # Looks for compile steps that failed in both current build and this build.
  prev_failed_compile_steps = {
      step_name: step
      for step_name, step in prev_compile_steps.iteritems()
      if step.status == common_pb2.FAILURE
  }
  prev_failures = project_api.GetCompileFailures(
      detailed_prev_build,
      prev_failed_compile_steps.values()) if prev_failed_compile_steps else {}
  return prev_compile_steps, prev_failures
Example #6
0
def GetBuilderInfoForLUCIBuild(build_id):
    """Gets a build's project and bucket info.

  Args:
    build_id(str): Buildbucket id of a LUCI build.
  """
    build_proto = buildbucket_client.GetV2Build(
        build_id, fields=FieldMask(paths=['builder']))
    if not build_proto:
        logging.exception('Error retrieving buildbucket build id: %s',
                          build_id)
        return None, None

    return build_proto.builder.project, build_proto.builder.bucket
Example #7
0
  def GetTestRerunBuildInputProperties(self, tests, analyzed_build_id):
    properties = {}
    build = buildbucket_client.GetV2Build(
        analyzed_build_id,
        fields=FieldMask(paths=['input.properties', 'builder']))
    properties['target_builder'] = {
        'master': build.input.properties['mastername'],
        'builder': build.builder.builder
    }
    properties['mastername'] = build.input.properties['mastername']
    properties['tests'] = {
        s: [t['name'] for t in tests_in_suite['tests']
           ] for s, tests_in_suite in tests.iteritems()
    }

    return properties
Example #8
0
 def GetRerunDimensions(self, analyzed_build_id):
   # Copy these dimensions from the analyzed builder to the rerun job request.
   dimension_whitelist = set([
       'os',
       'gpu',
   ])
   build = buildbucket_client.GetV2Build(
       analyzed_build_id,
       fields=FieldMask(paths=['infra.swarming.taskDimensions']))
   assert build, "Could not get analyzed build %d" % analyzed_build_id
   dimension_dicts = []
   for dimension_proto in build.infra.swarming.task_dimensions:
     if dimension_proto.key in dimension_whitelist:
       # Explicitly include only the 'key' and 'value' keys to discard
       # 'expiration' which is unrelated.
       dimension_dicts.append({
           'key': dimension_proto.key,
           'value': dimension_proto.value
       })
   return dimension_dicts
Example #9
0
  def GetCompileRerunBuildInputProperties(self, failed_targets,
                                          analyzed_build_id):
    all_targets = set()
    for step, targets in failed_targets.iteritems():
      # Assume the step is a compile step.
      assert step == 'compile'
      all_targets |= set(targets)

    properties = {}
    build = buildbucket_client.GetV2Build(
        analyzed_build_id,
        fields=FieldMask(paths=['input.properties', 'builder']))
    # The recipe depends on the mastername being set.
    # TODO(crbug.com/1008119): Fix the recipe so that it populates this property
    # based on target_builder.
    properties['mastername'] = build.input.properties['mastername']
    properties['target_builder'] = {
        'master': build.input.properties['mastername'],
        'builder': build.builder.builder
    }
    properties['compile_targets'] = list(all_targets)
    return properties
def ProcessBuildForFlakes(task_param):
    """Detects a type of flakes from a build.

  Args:
    task_param(DetectFlakesFromFlakyCQBuildParam): Parameters of the task to
      detect cq false rejection or retry with patch flakes from a flaky cq
      build.
  """
    build_id = task_param.build_id
    flake_type_enum = DESCRIPTION_TO_FLAKE_TYPE.get(task_param.flake_type_desc)

    build_pb = buildbucket_client.GetV2Build(
        build_id, FieldMask(paths=['number', 'builder', 'input', 'steps']))
    assert build_pb, 'Error retrieving buildbucket build id: {}'.format(
        build_id)

    luci_project = build_pb.builder.project
    luci_bucket = build_pb.builder.bucket
    luci_builder = build_pb.builder.builder
    legacy_master_name = build_pb.input.properties['mastername']
    legacy_build_number = build_pb.number
    gerrit_changes = build_pb.input.gerrit_changes

    gerrit_cl_id = None
    gerrit_project = None
    if gerrit_changes:
        gerrit_cl_id = build_pb.input.gerrit_changes[0].change
        gerrit_project = build_pb.input.gerrit_changes[0].project

    # Fall-back approach to get gerrit_cl_id and gerrit_project
    gerrit_cl_id = gerrit_cl_id or (build_pb.input.properties['patch_issue']
                                    if 'patch_issue'
                                    in build_pb.input.properties else None)
    gerrit_project = gerrit_project or (
        build_pb.input.properties['patch_project']
        if 'patch_project' in build_pb.input.properties else None)

    if not gerrit_cl_id:
        return

    flake_info = GetFlakesFromFlakyCQBuild(build_id, build_pb, flake_type_enum)

    row = {
        'luci_project': luci_project,
        'luci_bucket': luci_bucket,
        'luci_builder': luci_builder,
        'legacy_master_name': legacy_master_name,
        'legacy_build_number': legacy_build_number,
        'build_id': build_id,
        'gerrit_project': gerrit_project,
        'gerrit_cl_id': gerrit_cl_id
    }

    new_flakes = []
    new_occurrences = []
    for step_ui_name, tests in flake_info.iteritems():
        # Uses the start time of a step as the flake happen time.
        step_start_time, _ = step_util.GetStepStartAndEndTime(
            build_pb, step_ui_name)
        row['step_ui_name'] = step_ui_name
        row['test_start_msec'] = step_start_time
        for test in tests:
            row['test_name'] = test
            new_flakes.append(_CreateFlakeFromRow(row))
            new_occurrences.append(
                _CreateFlakeOccurrenceFromRow(row, flake_type_enum))

    _StoreMultipleLocalEntities(new_flakes)
    _StoreMultipleLocalEntities(new_occurrences)
    _UpdateFlakeMetadata(new_occurrences)
Example #11
0
    def _GetV2AnalysisResultFromV1(self, request):
        """Constructs v2 analysis results based on v1 analysis.

    This is a temporary work around to make sure Findit's analysis results for
    chromium build failures are still available on SoM during v1 to v2
    migration.

    Args:
      request (findit_result.BuildFailureAnalysisRequest)

    Returns:
      [findit_result.BuildFailureAnalysisResponse] for results of a v1 analysis,
      otherwise return None.
    """
        if (request.build_alternative_id
                and request.build_alternative_id.project != 'chromium'):
            return None

        build = None
        if request.build_id:
            build = buildbucket_client.GetV2Build(
                request.build_id,
                fields=FieldMask(
                    paths=['id', 'number', 'builder', 'output.properties']))
        elif request.build_alternative_id:
            build = buildbucket_client.GetV2BuildByBuilderAndBuildNumber(
                request.build_alternative_id.project,
                request.build_alternative_id.bucket,
                request.build_alternative_id.builder,
                request.build_alternative_id.number,
                fields=FieldMask(
                    paths=['id', 'number', 'builder', 'output.properties']))

        if not build:
            logging.error('Failed to download build when requesting for %s',
                          request)
            return None

        if build.builder.project != 'chromium':
            return None

        properties = json_format.MessageToDict(build.output.properties)
        build_number = build.number
        master_name = properties.get('target_mastername',
                                     properties.get('mastername'))
        if not build_number or not master_name:
            logging.error('Missing master_name or build_number for build %d',
                          build.id)
            return None

        heuristic_analysis = WfAnalysis.Get(master_name, build.builder.builder,
                                            build_number)
        if not heuristic_analysis:
            return None

        results = []
        v1_build_request = _BuildFailure(builder_name=build.builder.builder,
                                         build_number=build_number)
        self._GenerateResultsForBuild(v1_build_request, heuristic_analysis,
                                      results, None)
        return self._GetV2ResultFromV1(request, results)