Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 """URL endpoint to allow bisect bots to post results to the dashboard.""" | |
| 6 | |
| 7 import json | |
| 8 import logging | |
| 9 | |
| 10 from google.appengine.api import app_identity | |
| 11 from google.appengine.ext import ndb | |
| 12 | |
| 13 from dashboard import datastore_hooks | |
| 14 from dashboard import post_data_handler | |
| 15 from dashboard import rietveld_service | |
| 16 from dashboard import update_bug_with_results | |
| 17 from dashboard import utils | |
| 18 from dashboard.models import try_job | |
| 19 | |
| 20 _EXPECTED_RESULT_PROPERTIES = { | |
| 21 'status': ['completed', 'failed', 'pending', 'aborted'], | |
| 22 } | |
| 23 | |
| 24 | |
| 25 class BadRequestError(Exception): | |
| 26 """An error indicating that a 400 response status should be returned.""" | |
| 27 pass | |
| 28 | |
| 29 | |
| 30 class PostBisectResultsHandler(post_data_handler.PostDataHandler): | |
| 31 | |
| 32 def post(self): | |
| 33 """Validates data parameter and saves to TryJob entity. | |
| 34 | |
| 35 Bisect results come from a "data" parameter, which is a JSON encoding of a | |
| 36 dictionary. | |
| 37 | |
| 38 The required fields are "master", "bot", "test". | |
| 39 | |
| 40 Request parameters: | |
| 41 data: JSON encoding of a dictionary. | |
| 42 | |
| 43 Outputs: | |
| 44 Empty 200 response with if successful, | |
| 45 200 response with warning message if optional data is invalid, | |
| 46 403 response with error message if sender IP is not white-listed, | |
| 47 400 response with error message if required data is invalid. | |
| 48 500 with error message otherwise. | |
| 49 """ | |
| 50 datastore_hooks.SetPrivilegedRequest() | |
| 51 if not self._CheckIpAgainstWhitelist(): | |
| 52 return | |
| 53 | |
| 54 data = self.request.get('data') | |
| 55 if not data: | |
| 56 self.ReportError('Missing "data" parameter.', status=400) | |
| 57 return | |
| 58 | |
| 59 try: | |
| 60 data = json.loads(self.request.get('data')) | |
| 61 except ValueError: | |
| 62 self.ReportError('Invalid JSON string.', status=400) | |
| 63 return | |
| 64 | |
| 65 logging.info('Received data: %s', data) | |
| 66 | |
| 67 try: | |
| 68 _ValidateResultsData(data) | |
| 69 job = _GetTryJob(data) | |
| 70 if not job: | |
|
chrisphan
2016/02/09 20:34:40
Going to give 200 status code for non-existing job
| |
| 71 self.ReportWarning('No try job found.') | |
| 72 return | |
| 73 _UpdateTryJob(job, data) | |
| 74 update_bug_with_results.UpdateQuickLog(job) | |
| 75 except BadRequestError as error: | |
| 76 self.ReportError(error.message, status=400) | |
| 77 | |
| 78 | |
| 79 def _ValidateResultsData(results_data): | |
| 80 utils.Validate(_EXPECTED_RESULT_PROPERTIES, results_data) | |
| 81 # TODO(chrisphan): Validate other values. | |
| 82 | |
| 83 | |
| 84 def _UpdateTryJob(job, results_data): | |
| 85 if not job.results_data: | |
| 86 job.results_data = {} | |
| 87 job.results_data.update(results_data) | |
| 88 job.results_data['issue_url'] = (job.results_data.get('issue_url') or | |
| 89 _IssueURL(job)) | |
| 90 job.put() | |
| 91 | |
| 92 | |
| 93 def _GetTryJob(results_data): | |
| 94 try_job_id = results_data.get('try_job_id') | |
| 95 if not try_job_id: | |
| 96 return None | |
| 97 job = ndb.Key(try_job.TryJob, try_job_id).get() | |
| 98 return job | |
| 99 | |
| 100 | |
| 101 def _IssueURL(job): | |
| 102 """Returns a URL for information about a bisect try job.""" | |
| 103 if job.use_buildbucket: | |
| 104 hostname = app_identity.get_default_version_hostname() | |
| 105 job_id = job.buildbucket_job_id | |
| 106 return 'https://%s/buildbucket_job_status/%s' % (hostname, job_id) | |
| 107 else: | |
| 108 config = rietveld_service.GetDefaultRietveldConfig() | |
| 109 host = (config.internal_server_url if job.internal_only else | |
| 110 config.server_url) | |
| 111 return '%s/%d' % (host, job.rietveld_issue_id) | |
| OLD | NEW |