def Post(self): owner = self.request.get('owner') cc = self.request.get('cc') summary = self.request.get('summary') description = self.request.get('description') labels = self.request.get_all('label') components = self.request.get_all('component') keys = self.request.get_all('key') bisect = api_utils.ParseBool(self.request.get('bisect', 'true')) http = utils.ServiceAccountHttp() return file_bug.FileBug(http, owner, cc, summary, description, labels, components, keys, bisect)
def Post(self): owner = self.request.get('owner') cc = self.request.get('cc') summary = self.request.get('summary') description = self.request.get('description') labels = self.request.get_all('label') components = self.request.get_all('component') keys = self.request.get_all('key') bisect = api_utils.ParseBool(self.request.get('bisect', 'true')) # TODO(924228): After v2spa launches, change its client id to something # that is whitelisted by the issue tracker service (or have its client id # whitelisted), then forward the bearer token from # self.request.headers.get('Authorization') to the issue tracker service by # overriding httplib2.Http().request. http = utils.ServiceAccountHttp() return file_bug.FileBug( http, owner, cc, summary, description, labels, components, keys, bisect)
def UnprivilegedPost(self, *args): """Returns alert data in response to API requests. Possible list types: keys: A comma-separated list of urlsafe Anomaly keys. bug_id: A bug number on the Chromium issue tracker. rev: A revision number. Outputs: Alerts data; see README.md. """ alert_list = None response = {} try: if len(args) == 0: is_improvement = utils.ParseBool( self.request.get('is_improvement', None)) recovered = utils.ParseBool(self.request.get( 'recovered', None)) start_cursor = self.request.get('cursor', None) if start_cursor: start_cursor = datastore_query.Cursor(urlsafe=start_cursor) min_timestamp = utils.ParseISO8601( self.request.get('min_timestamp', None)) max_timestamp = utils.ParseISO8601( self.request.get('max_timestamp', None)) test_keys = [] for template_id in self.request.get_all('report'): test_keys.extend( report_template.TestKeysForReportTemplate(template_id)) try: alert_list, next_cursor, _ = anomaly.Anomaly.QueryAsync( bot_name=self.request.get('bot', None), bug_id=self.request.get('bug_id', None), is_improvement=is_improvement, key=self.request.get('key', None), limit=int(self.request.get('limit', 100)), master_name=self.request.get('master', None), max_end_revision=self.request.get( 'max_end_revision', None), max_start_revision=self.request.get( 'max_start_revision', None), max_timestamp=max_timestamp, min_end_revision=self.request.get( 'min_end_revision', None), min_start_revision=self.request.get( 'min_start_revision', None), min_timestamp=min_timestamp, recovered=recovered, sheriff=self.request.get('sheriff', None), start_cursor=start_cursor, test=self.request.get('test', None), test_keys=test_keys, test_suite_name=self.request.get('test_suite', None)).get_result() except AssertionError: alert_list, next_cursor = [], None if next_cursor: response['next_cursor'] = next_cursor.urlsafe() else: list_type = args[0] if list_type.startswith('bug_id'): bug_id = list_type.replace('bug_id/', '') try: bug_id = int(bug_id) except ValueError as e: raise api_request_handler.BadRequestError( 'Invalid bug ID "%s".' % bug_id) response['DEPRECATION WARNING'] = ( 'Please use /api/alerts?bug_id=%s' % bug_id) alert_list, _, _ = anomaly.Anomaly.QueryAsync( bug_id=bug_id).get_result() elif list_type.startswith('keys'): keys = list_type.replace('keys/', '').split(',') response['DEPRECATION WARNING'] = ( 'Please use /api/alerts?key=%s' % keys[0]) alert_list = group_report.GetAlertsForKeys(keys) elif list_type.startswith('rev'): rev = list_type.replace('rev/', '') response['DEPRECATION WARNING'] = ( 'Please use /api/alerts?max_end_revision=%s&min_start_revision=%s' % (rev, rev)) alert_list = group_report.GetAlertsAroundRevision(rev) elif list_type.startswith('history'): try: days = int(list_type.replace('history/', '')) except ValueError: days = 7 cutoff = datetime.datetime.now() - datetime.timedelta( days=days) sheriff_name = self.request.get('sheriff', 'Chromium Perf Sheriff') sheriff_key = ndb.Key('Sheriff', sheriff_name) sheriff = sheriff_key.get() if not sheriff: raise api_request_handler.BadRequestError( 'Invalid sheriff %s' % sheriff_name) response['DEPRECATION WARNING'] = ( 'Please use /api/alerts?min_timestamp=%s&sheriff=%s' % (urllib.quote( cutoff.isoformat()), urllib.quote(sheriff_name))) include_improvements = bool( self.request.get('improvements')) filter_for_benchmark = self.request.get('benchmark') is_improvement = None if not include_improvements: is_improvement = False response[ 'DEPRECATION WARNING'] += '&is_improvement=false' if filter_for_benchmark: response['DEPRECATION WARNING'] += ( '&test_suite=' + filter_for_benchmark) alert_list, _, _ = anomaly.Anomaly.QueryAsync( sheriff=sheriff_key.id(), min_timestamp=cutoff, is_improvement=is_improvement, test_suite_name=filter_for_benchmark).get_result() else: raise api_request_handler.BadRequestError( 'Invalid alert type %s' % list_type) except AssertionError: # The only known assertion is in InternalOnlyModel._post_get_hook when a # non-internal user requests an internal-only entity. raise api_request_handler.BadRequestError('Not found') except request_handler.InvalidInputError as e: raise api_request_handler.BadRequestError(e.message) anomaly_dicts = alerts.AnomalyDicts( [a for a in alert_list if a.key.kind() == 'Anomaly']) response['anomalies'] = anomaly_dicts return response
def AuthorizedPost(self, *args): """Returns alert data in response to API requests. Argument: bug_id: issue id on the chromium issue tracker Outputs: JSON data for the bug, see README.md. """ # Users must log in with privileged access to see all bugs. if not datastore_hooks.IsUnalteredQueryPermitted(): raise api_request_handler.BadRequestError('No access.') try: bug_id = int(args[0]) except ValueError: raise api_request_handler.BadRequestError('Invalid bug ID "%s".' % args[0]) try: include_comments = api_utils.ParseBool( self.request.get('include_comments', None)) except ValueError: raise api_request_handler.BadRequestError( "value of |with_comments| should be 'true' or 'false'") service = issue_tracker_service.IssueTrackerService( utils.ServiceAccountHttp()) issue = service.GetIssue(bug_id) bisects = try_job.TryJob.query(try_job.TryJob.bug_id == bug_id).fetch() def _FormatDate(d): if not d: return '' return d.isoformat() response = { 'bug': { 'author': issue.get('author', {}).get('name'), 'owner': issue.get('owner', {}).get('name'), 'legacy_bisects': [{ 'status': b.status, 'bot': b.bot, 'bug_id': b.bug_id, 'buildbucket_link': ('https://chromeperf.appspot.com/buildbucket_job_status/%s' % b.buildbucket_job_id), 'command': b.GetConfigDict()['command'], 'culprit': self._GetCulpritInfo(b), 'metric': (b.results_data or {}).get('metric'), 'started_timestamp': _FormatDate(b.last_ran_timestamp), } for b in bisects], 'cc': [cc.get('name') for cc in issue.get('cc', [])], 'components': issue.get('components', []), 'id': bug_id, 'labels': issue.get('labels', []), 'published': issue.get('published'), 'updated': issue.get('updated'), 'state': issue.get('state'), 'status': issue.get('status'), 'summary': issue.get('summary'), } } if include_comments: comments = service.GetIssueComments(bug_id) response['bug']['comments'] = [{ 'content': comment.get('content'), 'author': comment.get('author'), 'published': comment.get('published'), } for comment in comments] return response
def Post(self): """Returns alert data in response to API requests. Possible list types: keys: A comma-separated list of urlsafe Anomaly keys. bug_id: A bug number on the Chromium issue tracker. rev: A revision number. Outputs: Alerts data; see README.md. """ alert_list = None response = {} try: is_improvement = utils.ParseBool( self.request.get('is_improvement', None)) recovered = utils.ParseBool(self.request.get('recovered', None)) start_cursor = self.request.get('cursor', None) if start_cursor: start_cursor = datastore_query.Cursor(urlsafe=start_cursor) min_timestamp = utils.ParseISO8601( self.request.get('min_timestamp', None)) max_timestamp = utils.ParseISO8601( self.request.get('max_timestamp', None)) test_keys = [] for template_id in self.request.get_all('report'): test_keys.extend( report_template.TestKeysForReportTemplate(template_id)) try: alert_list, next_cursor, count = anomaly.Anomaly.QueryAsync( bot_name=self.request.get('bot', None), bug_id=self.request.get('bug_id', None), is_improvement=is_improvement, key=self.request.get('key', None), limit=int(self.request.get('limit', 100)), count_limit=int(self.request.get('count_limit', 0)), master_name=self.request.get('master', None), max_end_revision=self.request.get('max_end_revision', None), max_start_revision=self.request.get( 'max_start_revision', None), max_timestamp=max_timestamp, min_end_revision=self.request.get('min_end_revision', None), min_start_revision=self.request.get( 'min_start_revision', None), min_timestamp=min_timestamp, recovered=recovered, sheriff=self.request.get('sheriff', None), start_cursor=start_cursor, test=self.request.get('test', None), test_keys=test_keys, test_suite_name=self.request.get('test_suite', None)).get_result() response['count'] = count except AssertionError: alert_list, next_cursor = [], None if next_cursor: response['next_cursor'] = next_cursor.urlsafe() except AssertionError: # The only known assertion is in InternalOnlyModel._post_get_hook when a # non-internal user requests an internal-only entity. raise api_request_handler.BadRequestError('Not found') except request_handler.InvalidInputError as e: raise api_request_handler.BadRequestError(e.message) response['anomalies'] = alerts.AnomalyDicts( alert_list, utils.ParseBool(self.request.get('v2', None))) return response
def testInvalidValueRaises(self): with self.assertRaises(ValueError): utils.ParseBool('foo')
def testNoneValueIsNone(self): self.assertIsNone(utils.ParseBool(None))
def testFalseValues(self): self.assertFalse(utils.ParseBool('0')) self.assertFalse(utils.ParseBool('false')) self.assertFalse(utils.ParseBool('False')) self.assertFalse(utils.ParseBool('FALSE'))
def testTrueValues(self): self.assertTrue(utils.ParseBool('1')) self.assertTrue(utils.ParseBool('true')) self.assertTrue(utils.ParseBool('True')) self.assertTrue(utils.ParseBool('TRUE'))
def Post(self, *args, **kwargs): """Returns alert data in response to API requests. Argument: bug_id: issue id on the chromium issue tracker Outputs: JSON data for the bug, see README.md. """ if len(args) == 0: raise api_request_handler.BadRequestError('Invalid bug ID "None".') bug_id = args[0] service = issue_tracker_service.IssueTrackerService( utils.ServiceAccountHttp()) project = kwargs.get('project', 'chromium') if bug_id == 'recent': response = service.List(project=project, q='opened-after:today-5', label='Type-Bug-Regression,Performance', sort='-id') return {'bugs': response.get('items', [])} try: bug_id = int(bug_id) except ValueError: raise api_request_handler.BadRequestError('Invalid bug ID "%s".' % bug_id) try: include_comments = api_utils.ParseBool( self.request.get('include_comments', None)) except ValueError: raise api_request_handler.BadRequestError( "value of |with_comments| should be 'true' or 'false'") issue = service.GetIssue(bug_id, project=project) bisects = [] def _FormatDate(d): if not d: return '' return d.isoformat() response = { 'bug': { 'author': issue.get('author', {}).get('name'), 'owner': issue.get('owner', {}).get('name'), 'legacy_bisects': [{ 'status': b.status, 'bot': b.bot, 'bug_id': b.bug_id, 'buildbucket_link': ('https://chromeperf.appspot.com/buildbucket_job_status/%s' % b.buildbucket_job_id), 'command': b.GetConfigDict()['command'], 'culprit': None, 'metric': (b.results_data or {}).get('metric'), 'started_timestamp': _FormatDate(b.last_ran_timestamp), } for b in bisects], 'cc': [cc.get('name') for cc in issue.get('cc', [])], 'components': issue.get('components', []), 'projectId': project, 'id': bug_id, 'labels': issue.get('labels', []), 'published': issue.get('published'), 'updated': issue.get('updated'), 'state': issue.get('state'), 'status': issue.get('status'), 'summary': issue.get('summary'), } } if include_comments: comments = service.GetIssueComments(bug_id) response['bug']['comments'] = [{ 'content': comment.get('content'), 'author': comment.get('author'), 'published': comment.get('published'), } for comment in comments] return response