Home | History | Annotate | Download | only in tools
      1 #!/usr/bin/env python
      2 # Copyright 2013 The Chromium Authors. All rights reserved.
      3 # Use of this source code is governed by a BSD-style license that can be
      4 # found in the LICENSE file.
      5 
      6 """Run Manual Test Bisect Tool
      7 
      8 An example usage:
      9 tools/run-bisect-manual-test.py -g 201281 -b 201290
     10 
     11 On Linux platform, follow the instructions in this document
     12 https://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment
     13 to setup the sandbox manually before running the script. Otherwise the script
     14 fails to launch Chrome and exits with an error.
     15 
     16 This script serves a similar function to bisect-builds.py, except it uses
     17 the bisect_perf_regression.py. This means that that it can obtain builds of
     18 Chromium for revisions where builds aren't available in cloud storage.
     19 """
     20 
     21 import os
     22 import subprocess
     23 import sys
     24 
     25 CROS_BOARD_ENV = 'BISECT_CROS_BOARD'
     26 CROS_IP_ENV = 'BISECT_CROS_IP'
     27 _TOOLS_DIR = os.path.abspath(os.path.dirname(__file__))
     28 _BISECT_SCRIPT_PATH = os.path.join(
     29     _TOOLS_DIR, 'auto_bisect', 'bisect_perf_regression.py')
     30 
     31 sys.path.append(os.path.join(_TOOLS_DIR, 'telemetry'))
     32 from telemetry.core import browser_options
     33 
     34 
     35 def _RunBisectionScript(options):
     36   """Attempts to execute the bisect script (bisect_perf_regression.py).
     37 
     38   Args:
     39     options: The configuration options to pass to the bisect script.
     40 
     41   Returns:
     42     An exit code; 0 for success, 1 for failure.
     43   """
     44   test_command = ('python %s --browser=%s --chrome-root=.' %
     45                   (os.path.join(_TOOLS_DIR, 'bisect-manual-test.py'),
     46                    options.browser_type))
     47 
     48   cmd = ['python', _BISECT_SCRIPT_PATH,
     49          '-c', test_command,
     50          '-g', options.good_revision,
     51          '-b', options.bad_revision,
     52          '-m', 'manual_test/manual_test',
     53          '-r', '1',
     54          '--working_directory', options.working_directory,
     55          '--build_preference', 'ninja',
     56          '--use_goma',
     57          '--no_custom_deps']
     58 
     59   if options.extra_src:
     60     cmd.extend(['--extra_src', options.extra_src])
     61 
     62   if 'cros' in options.browser_type:
     63     cmd.extend(['--target_platform', 'cros'])
     64 
     65     if os.environ[CROS_BOARD_ENV] and os.environ[CROS_IP_ENV]:
     66       cmd.extend(['--cros_board', os.environ[CROS_BOARD_ENV]])
     67       cmd.extend(['--cros_remote_ip', os.environ[CROS_IP_ENV]])
     68     else:
     69       print ('Error: Cros build selected, but BISECT_CROS_IP or'
     70              'BISECT_CROS_BOARD undefined.\n')
     71       return 1
     72   elif 'android-chrome' in options.browser_type:
     73     cmd.extend(['--target_platform', 'android-chrome'])
     74   elif 'android' in options.browser_type:
     75     cmd.extend(['--target_platform', 'android'])
     76   elif not options.target_build_type:
     77     cmd.extend(['--target_build_type', options.browser_type.title()])
     78 
     79   if options.target_build_type:
     80     cmd.extend(['--target_build_type', options.target_build_type])
     81 
     82   cmd = [str(c) for c in cmd]
     83 
     84   return_code = subprocess.call(cmd)
     85 
     86   if return_code:
     87     print 'Error: bisect_perf_regression.py had exit code %d.' % return_code
     88     print
     89 
     90   return return_code
     91 
     92 
     93 def main():
     94   """Does a bisect based on the command-line arguments passed in.
     95 
     96   The user will be prompted to classify each revision as good or bad.
     97   """
     98   usage = ('%prog [options]\n'
     99            'Used to run the bisection script with a manual test.')
    100 
    101   options = browser_options.BrowserFinderOptions('release')
    102   parser = options.CreateParser(usage)
    103 
    104   parser.add_option('-b', '--bad_revision',
    105                     type='str',
    106                     help='A bad revision to start bisection. ' +
    107                     'Must be later than good revision. May be either a git' +
    108                     ' or svn revision.')
    109   parser.add_option('-g', '--good_revision',
    110                     type='str',
    111                     help='A revision to start bisection where performance' +
    112                     ' test is known to pass. Must be earlier than the ' +
    113                     'bad revision. May be either a git or svn revision.')
    114   parser.add_option('-w', '--working_directory',
    115                     type='str',
    116                     default='..',
    117                     help='A working directory to supply to the bisection '
    118                     'script, which will use it as the location to checkout '
    119                     'a copy of the chromium depot.')
    120   parser.add_option('--extra_src',
    121                     type='str',
    122                     help='Path to extra source file. If this is supplied, '
    123                     'bisect script will use this to override default behavior.')
    124   parser.add_option('--target_build_type',
    125                      type='choice',
    126                      choices=['Release', 'Debug'],
    127                      help='The target build type. Choices are "Release" '
    128                      'or "Debug".')
    129   options, _ = parser.parse_args()
    130   error_msg = ''
    131   if not options.good_revision:
    132     error_msg += 'Error: missing required parameter: --good_revision\n'
    133   if not options.bad_revision:
    134     error_msg += 'Error: missing required parameter: --bad_revision\n'
    135 
    136   if error_msg:
    137     print error_msg
    138     parser.print_help()
    139     return 1
    140 
    141   if 'android' not in options.browser_type and sys.platform.startswith('linux'):
    142     if not os.environ.get('CHROME_DEVEL_SANDBOX'):
    143       print 'SUID sandbox has not been setup.'\
    144             ' See https://code.google.com/p/chromium/wiki/'\
    145             'LinuxSUIDSandboxDevelopment for more information.'
    146       return 1
    147 
    148   return _RunBisectionScript(options)
    149 
    150 
    151 if __name__ == '__main__':
    152   sys.exit(main())
    153