blob: abc144a8cd68a880dccf5a2adb2496f299bb188d [file] [log] [blame]
# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""This encapsulate the main Findit APIs for external requests."""
import logging
from common.constants import DEFAULT_SERVICE_ACCOUNT
from findit_v2.model.luci_build import LuciFailedBuild
from findit_v2.services import build_util
from findit_v2.services import projects
from findit_v2.services.analysis.compile_failure import compile_analysis
from findit_v2.services.analysis.test_failure import test_analysis
from findit_v2.services.detection import api as detection_api
from findit_v2.services.failure_type import StepTypeEnum
def OnSupportedBuildCompletion(project, bucket, builder_name, build_id,
build_result):
"""Processes a completed build from a builder Findit is supporting.
Args:
project (str): Luci project of the build.
build_id (int): Id of the build.
Returns:
False if it is unsupported or skipped; otherwise True.
"""
if build_result != 'FAILURE':
# Skip builds that didn't fail.
logging.debug('Build %s/%s/%s/%s is not a failure', project, bucket,
builder_name, build_id)
return False
build, context = build_util.GetBuildAndContextForAnalysis(project, build_id)
if not build:
return False
detection_api.OnBuildFailure(context, build)
return True
def OnRerunBuildCompletion(project, build_id):
"""Processes a completed rerun builds.
Args:
project (str): Luci project of the build.
build_id (int): Id of the build.
Returns:
False if it is unsupported or skipped; otherwise True.
"""
rerun_build, context = build_util.GetBuildAndContextForAnalysis(
project, build_id)
if not rerun_build:
return False
if rerun_build.created_by != 'user:{}'.format(DEFAULT_SERVICE_ACCOUNT):
logging.info('Build %d is not triggered by Findit.', rerun_build.id)
return False
return detection_api.OnRerunBuildCompletion(context, rerun_build)
def OnBuildCompletion(project, bucket, builder_name, build_id, build_result):
"""Processes the completed build.
Args:
project (str): Luci project of the build.
bucket (str): Luci bucket of the build.
builder_name (str): Luci builder name of the build.
build_id (int): Id of the build.
build_result (str): Status of the build. E.g. SUCCESS, FAILURE, etc.
Returns:
False if it is unsupported or skipped; otherwise True.
"""
# Skip builders that are not in the allowlist of a supported project/bucket.
builder_type = projects.GetBuilderType(project, bucket, builder_name)
if builder_type == projects.BuilderTypeEnum.SUPPORTED:
return OnSupportedBuildCompletion(project, bucket, builder_name, build_id,
build_result)
if builder_type == projects.BuilderTypeEnum.RERUN:
return OnRerunBuildCompletion(project, build_id)
logging.info('Unsupported build %s/%s/%s/%s.', project, bucket, builder_name,
build_id)
return False
def OnBuildFailureAnalysisResultRequested(request):
"""Returns the findings of an analysis for a failed build.
Since Findit v2 only supports compile failure on cros builds, this api will
simply respond an empty response on other failures. This is to prevent Findit
spending too many pixels to tell users many failures are not supported.
Args:
request(findit_result.BuildFailureAnalysisRequest): request for a build
failure.
Returns:
(findit_result.BuildFailureAnalysisResponseCollection): Analysis results
for the requested build.
"""
build_id = request.build_id
build_alternative_id = request.build_alternative_id
if build_id:
build_entity = LuciFailedBuild.get_by_id(build_id)
if not build_entity:
logging.debug('No LuciFailedBuild entity for build %d.', request.build_id)
return []
else:
build_entity = LuciFailedBuild.GetBuildByNumber(
build_alternative_id.project, build_alternative_id.bucket,
build_alternative_id.builder, build_alternative_id.number)
if not build_entity:
logging.debug('No LuciFailedBuild entity for build %s/%s/%s/%d.',
build_alternative_id.project, build_alternative_id.bucket,
build_alternative_id.builder, build_alternative_id.number)
return []
if build_entity.build_failure_type == StepTypeEnum.COMPILE:
return compile_analysis.OnCompileFailureAnalysisResultRequested(
request, build_entity)
if build_entity.build_failure_type == StepTypeEnum.TEST:
return test_analysis.OnTestFailureAnalysisResultRequested(
request, build_entity)
logging.debug(
'Findit v2 only supports compile or test failure analysis, '
'so no results for %d with %s failures.', build_id,
build_entity.build_failure_type)
return []