old_contents: # 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))
  
new_contents: # 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.
  _UNBISECTABLE_SUITES = [
      'arc-perf-test',
      'browser_tests',
      'content_browsertests',
      '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))
  
subject: Remove resource_sizes from list of unbisectable suites.