blob: b01a078b651c1735dd06ba69a3a32462ffaded79 [file] [log] [blame]
# Copyright 2016 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.
"""A handler and functions to check whether bisect is supported."""
import re
from dashboard import request_handler
from dashboard import namespaced_stored_object
# A set of suites for which we can't do performance bisects.
# This list currently also exists in the front-end code.
_UNBISECTABLE_SUITES = [
'arc-perf-test',
'browser_tests',
'content_browsertests',
'resource_sizes',
'sizes',
'v8',
]
# The bisect bot map stored in datastore is expected to be
# a dict mapping master names to [perf bot, bisect bot] pairs.
# If a master name is not in the dict, bisect isn't supported.
BISECT_BOT_MAP_KEY = 'bisect_bot_map'
class CanBisectHandler(request_handler.RequestHandler):
def post(self):
"""Checks whether bisect is supported for a test.
Request parameters:
test_path: A full test path (Master/bot/benchmark/...)
start_revision: The start of the bisect revision range.
end_revision: The end of the bisect revision range.
Outputs: The string "true" or the string "false".
"""
can_bisect = (
IsValidTestForBisect(self.request.get('test_path')) and
IsValidRevisionForBisect(self.request.get('start_revision')) and
IsValidRevisionForBisect(self.request.get('end_revision')))
self.response.write('true' if can_bisect else 'false')
def IsValidTestForBisect(test_path):
"""Checks whether a test is valid for bisect."""
if not test_path:
return False
path_parts = test_path.split('/')
if len(path_parts) < 3:
return False
if not _MasterNameIsWhitelisted(path_parts[0]):
return False
if path_parts[2] in _UNBISECTABLE_SUITES:
return False
if test_path.endswith('/ref') or test_path.endswith('_ref'):
return False
return True
def _MasterNameIsWhitelisted(master_name):
"""Checks whether a master name is acceptable by checking a whitelist."""
bisect_bot_map = namespaced_stored_object.Get(BISECT_BOT_MAP_KEY)
if not bisect_bot_map:
return True # If there's no list available, all names are OK.
whitelisted_masters = list(bisect_bot_map)
return master_name in whitelisted_masters
def IsValidRevisionForBisect(revision):
"""Checks whether a revision looks like a valid revision for bisect."""
return _IsGitHash(revision) or re.match(r'^[0-9]{5,7}$', str(revision))
def _IsGitHash(revision):
"""Checks whether the input looks like a SHA1 hash."""
return re.match(r'[a-fA-F0-9]{40}$', str(revision))