| OLD | NEW |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """This module is to provide Findit service APIs through Cloud Endpoints: | 5 """This module is to provide Findit service APIs through Cloud Endpoints: |
| 6 | 6 |
| 7 Current APIs include: | 7 Current APIs include: |
| 8 1. Analysis of build failures in Chromium waterfalls. | 8 1. Analysis of compile/test failures in Chromium waterfalls. |
| 9 Analyzes build failures and detects suspected CLs. | 9 Analyzes failures and detects suspected CLs. |
| 10 """ | 10 """ |
| 11 | 11 |
| 12 import json | 12 import json |
| 13 import logging | 13 import logging |
| 14 | 14 |
| 15 import endpoints | 15 import endpoints |
| 16 from google.appengine.api import taskqueue | 16 from google.appengine.api import taskqueue |
| 17 from protorpc import messages | 17 from protorpc import messages |
| 18 from protorpc import remote | 18 from protorpc import remote |
| 19 | 19 |
| 20 from common import appengine_util | 20 from common import appengine_util |
| 21 from common import constants |
| 21 from model.wf_analysis import WfAnalysis | 22 from model.wf_analysis import WfAnalysis |
| 22 from waterfall import buildbot | 23 from waterfall import buildbot |
| 23 from waterfall import waterfall_config | 24 from waterfall import waterfall_config |
| 24 | 25 |
| 25 | 26 |
| 26 # This is used by the underlying ProtoRpc when creating names for the ProtoRPC | 27 # This is used by the underlying ProtoRpc when creating names for the ProtoRPC |
| 27 # messages below. This package name will show up as a prefix to the message | 28 # messages below. This package name will show up as a prefix to the message |
| 28 # class names in the discovery doc and client libraries. | 29 # class names in the discovery doc and client libraries. |
| 29 package = 'FindIt' | 30 package = 'FindIt' |
| 30 | 31 |
| 31 | 32 |
| 32 _REQUEST_PROCESS_QUEUE = 'request-process-queue' | |
| 33 _REQUEST_HANDLER_URL = '/trigger-analyses' | |
| 34 | |
| 35 | |
| 36 # These subclasses of Message are basically definitions of Protocol RPC | 33 # These subclasses of Message are basically definitions of Protocol RPC |
| 37 # messages. https://cloud.google.com/appengine/docs/python/tools/protorpc/ | 34 # messages. https://cloud.google.com/appengine/docs/python/tools/protorpc/ |
| 38 class _BuildFailure(messages.Message): | 35 class _BuildFailure(messages.Message): |
| 39 master_url = messages.StringField(1, required=True) | 36 master_url = messages.StringField(1, required=True) |
| 40 builder_name = messages.StringField(2, required=True) | 37 builder_name = messages.StringField(2, required=True) |
| 41 build_number = messages.IntegerField(3, variant=messages.Variant.INT32, | 38 build_number = messages.IntegerField(3, variant=messages.Variant.INT32, |
| 42 required=True) | 39 required=True) |
| 43 # All failed steps of the build reported by the client. | 40 # All failed steps of the build reported by the client. |
| 44 failed_steps = messages.StringField(4, repeated=True, required=False) | 41 failed_steps = messages.StringField(4, repeated=True, required=False) |
| 45 | 42 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 69 suspected_cls = messages.MessageField(_SuspectedCL, 8, repeated=True) | 66 suspected_cls = messages.MessageField(_SuspectedCL, 8, repeated=True) |
| 70 | 67 |
| 71 | 68 |
| 72 class _BuildFailureAnalysisResultCollection(messages.Message): | 69 class _BuildFailureAnalysisResultCollection(messages.Message): |
| 73 """Represents a response to the client, eg. builder_alerts.""" | 70 """Represents a response to the client, eg. builder_alerts.""" |
| 74 results = messages.MessageField(_BuildFailureAnalysisResult, 1, repeated=True) | 71 results = messages.MessageField(_BuildFailureAnalysisResult, 1, repeated=True) |
| 75 | 72 |
| 76 | 73 |
| 77 def _TriggerNewAnalysesOnDemand(builds_to_check): | 74 def _TriggerNewAnalysesOnDemand(builds_to_check): |
| 78 """Pushes a task to run on the backend to trigger new analyses on demand.""" | 75 """Pushes a task to run on the backend to trigger new analyses on demand.""" |
| 79 target = appengine_util.GetTargetNameForModule('build-failure-analysis') | 76 target = appengine_util.GetTargetNameForModule(constants.WATERFALL_BACKEND) |
| 80 payload = json.dumps({'builds': builds_to_check}) | 77 payload = json.dumps({'builds': builds_to_check}) |
| 81 taskqueue.add( | 78 taskqueue.add( |
| 82 url=_REQUEST_HANDLER_URL, payload=payload, target=target, | 79 url=constants.WATERFALL_TRIGGER_ANALYSIS_URL, payload=payload, |
| 83 queue_name=_REQUEST_PROCESS_QUEUE) | 80 target=target, queue_name=constants.WATERFALL_SERIAL_QUEUE) |
| 84 | 81 |
| 85 | 82 |
| 86 # Create a Cloud Endpoints API. | 83 # Create a Cloud Endpoints API. |
| 87 # https://cloud.google.com/appengine/docs/python/endpoints/create_api | 84 # https://cloud.google.com/appengine/docs/python/endpoints/create_api |
| 88 @endpoints.api(name='findit', version='v1', description='FindIt API') | 85 @endpoints.api(name='findit', version='v1', description='FindIt API') |
| 89 class FindItApi(remote.Service): | 86 class FindItApi(remote.Service): |
| 90 """FindIt API v1.""" | 87 """FindIt API v1.""" |
| 91 | 88 |
| 92 def _GenerateBuildFailureAnalysisResult( | 89 def _GenerateBuildFailureAnalysisResult( |
| 93 self, build, suspected_cls_in_result, step_name, | 90 self, build, suspected_cls_in_result, step_name, |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 logging.info('%d build failure(s), while %d are supported', | 169 logging.info('%d build failure(s), while %d are supported', |
| 173 len(request.builds), len(builds_to_check)) | 170 len(request.builds), len(builds_to_check)) |
| 174 try: | 171 try: |
| 175 _TriggerNewAnalysesOnDemand(builds_to_check) | 172 _TriggerNewAnalysesOnDemand(builds_to_check) |
| 176 except Exception: # pragma: no cover. | 173 except Exception: # pragma: no cover. |
| 177 # If we fail to post a task to the task queue, we ignore and wait for next | 174 # If we fail to post a task to the task queue, we ignore and wait for next |
| 178 # request. | 175 # request. |
| 179 logging.exception('Failed to trigger new analyses on demand.') | 176 logging.exception('Failed to trigger new analyses on demand.') |
| 180 | 177 |
| 181 return _BuildFailureAnalysisResultCollection(results=results) | 178 return _BuildFailureAnalysisResultCollection(results=results) |
| OLD | NEW |