diff options
author | simonhatch@chromium.org <simonhatch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-21 17:20:04 +0000 |
---|---|---|
committer | simonhatch@chromium.org <simonhatch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-21 17:20:04 +0000 |
commit | 8997afddabf0efa3e867d50aaefa2b5f87eed08b (patch) | |
tree | 95df1961cbf6447d05f80d86a2289e301cbe0a1e | |
parent | ca2b80e9a1b578715eb85426585b7609c153e95f (diff) | |
download | chromium_src-8997afddabf0efa3e867d50aaefa2b5f87eed08b.zip chromium_src-8997afddabf0efa3e867d50aaefa2b5f87eed08b.tar.gz chromium_src-8997afddabf0efa3e867d50aaefa2b5f87eed08b.tar.bz2 |
Added separate checkout and config file generation to bisect script.
BUG=
NOTRY=true
Review URL: https://chromiumcodereview.appspot.com/12261026
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@183827 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | tools/PRESUBMIT.py | 48 | ||||
-rwxr-xr-x | tools/bisect-perf-regression.py | 140 | ||||
-rw-r--r-- | tools/run-bisect-perf-regression.cfg | 41 | ||||
-rwxr-xr-x | tools/run-bisect-perf-regression.py | 100 |
4 files changed, 317 insertions, 12 deletions
diff --git a/tools/PRESUBMIT.py b/tools/PRESUBMIT.py new file mode 100644 index 0000000..0157231 --- /dev/null +++ b/tools/PRESUBMIT.py @@ -0,0 +1,48 @@ +# Copyright (c) 2013 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. + +"""Top-level presubmit script for bisect trybot. + +See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for +details on the presubmit API built into gcl. +""" + +import imp + +def _ExamineBisectConfigFile(input_api, output_api): + for f in input_api.AffectedFiles(): + if not f.LocalPath().endswith('run-bisect-perf-regression.cfg'): + continue + + try: + cfg_file = imp.load_source('config', 'run-bisect-perf-regression.cfg') + + for k, v in cfg_file.config.iteritems(): + if v: + return f.LocalPath() + except (IOError, AttributeError, TypeError): + return f.LocalPath() + + return None + +def _CheckNoChangesToBisectConfigFile(input_api, output_api): + results = _ExamineBisectConfigFile(input_api, output_api) + if results: + return [output_api.PresubmitError( + 'The bisection config file should only contain a config dict with ' + 'empty fields. Changes to this file should never be submitted.', + items=[results])] + + return [] + +def CommonChecks(input_api, output_api): + results = [] + results.extend(_CheckNoChangesToBisectConfigFile(input_api, output_api)) + return results + +def CheckChangeOnUpload(input_api, output_api): + return CommonChecks(input_api, output_api) + +def CheckChangeOnCommit(input_api, output_api): + return CommonChecks(input_api, output_api) diff --git a/tools/bisect-perf-regression.py b/tools/bisect-perf-regression.py index 4afe1cf..fe1f19a 100755 --- a/tools/bisect-perf-regression.py +++ b/tools/bisect-perf-regression.py @@ -35,14 +35,14 @@ An example usage (using git hashes): """ - -import re -import os +import errno import imp -import sys -import shlex import optparse +import os +import re +import shlex import subprocess +import sys # The additional repositories that might need to be bisected. @@ -89,6 +89,25 @@ DEPOT_NAMES = DEPOT_DEPS_NAME.keys() FILE_DEPS_GIT = '.DEPS.git' +GCLIENT_SPEC = """ +solutions = [ + { "name" : "src", + "url" : "https://chromium.googlesource.com/chromium/src.git", + "deps_file" : ".DEPS.git", + "managed" : True, + "custom_deps" : { + }, + "safesync_url": "", + }, + { "name" : "src-internal", + "url" : "ssh://gerrit-int.chromium.org:29419/" + + "chrome/src-internal.git", + "deps_file" : ".DEPS.git", + }, +] +""" +GCLIENT_SPEC = ''.join([l for l in GCLIENT_SPEC.splitlines()]) + def IsStringFloat(string_to_check): @@ -1134,6 +1153,84 @@ def DetermineAndCreateSourceControl(): return None +def CreateAndChangeToSourceDirectory(working_directory): + """Creates a directory 'bisect' as a subdirectory of 'working_directory'. If + the function is successful, the current working directory will change to that + of the new 'bisect' directory. + + Returns: + True if the directory was successfully created (or already existed). + """ + cwd = os.getcwd() + os.chdir(working_directory) + try: + os.mkdir('bisect') + except OSError, e: + if e.errno != errno.EEXIST: + return False + os.chdir('bisect') + return True + + +def RunGClient(params): + """Runs gclient with the specified parameters. + + Args: + params: A list of parameters to pass to gclient. + + Returns: + The return code of the call. + """ + cmd = ['gclient'] + params + return subprocess.call(cmd) + + +def RunGClientAndCreateConfig(): + """Runs gclient and creates a config containing both src and src-internal. + + Returns: + The return code of the call. + """ + return_code = RunGClient( + ['config', '--spec=%s' % GCLIENT_SPEC, '--git-deps']) + return return_code + + +def RunGClientAndSync(): + """Runs gclient and does a normal sync. + + Returns: + The return code of the call. + """ + return RunGClient(['sync']) + + +def SetupGitDepot(output_buildbot_annotations): + """Sets up the depot for the bisection. The depot will be located in a + subdirectory called 'bisect'. + + Returns: + True if gclient successfully created the config file and did a sync, False + otherwise. + """ + name = 'Setting up Bisection Depot' + + if output_buildbot_annotations: + OutputAnnotationStepStart(name) + + passed = False + + if not RunGClientAndCreateConfig(): + if not RunGClientAndSync(): + passed = True + + if output_buildbot_annotations: + print + OutputAnnotationStepClosed() + + return passed + + def main(): usage = ('%prog [options] [-- chromium-options]\n' @@ -1160,6 +1257,14 @@ def main(): type='str', help='The desired metric to bisect on. For example ' + '"vm_rss_final_b/vm_rss_f_b"') + parser.add_option('-w', '--working_directory', + type='str', + help='Path to the working directory where the script will ' + 'do an initial checkout of the chromium depot. The ' + 'files will be placed in a subdirectory "bisect" under ' + 'working_directory and that will be used to perform the ' + 'bisection. This parameter is optional, if it is not ' + 'supplied, the script will work from the current depot.') parser.add_option('--use_goma', action="store_true", help='Add a bunch of extra threads for goma.') @@ -1207,6 +1312,24 @@ def main(): print return 1 + metric_values = opts.metric.split('/') + if len(metric_values) != 2: + print "Invalid metric specified: [%s]" % (opts.metric,) + print + return 1 + + if opts.working_directory: + if not CreateAndChangeToSourceDirectory(opts.working_directory): + print 'Error: Could not create bisect directory.' + print + return 1 + + if not SetupGitDepot(opts.output_buildbot_annotations): + print 'Error: Failed to grab source.' + print + return 1 + + os.chdir(os.path.join(os.getcwd(), 'src')) # Check what source control method they're using. Only support git workflow # at the moment. @@ -1223,13 +1346,6 @@ def main(): print return 1 - metric_values = opts.metric.split('/') - if len(metric_values) < 2: - print "Invalid metric specified: [%s]" % (opts.metric,) - print - return 1 - - bisect_test = BisectPerformanceMetrics(source_control, opts) bisect_results = bisect_test.Run(opts.command, opts.bad_revision, diff --git a/tools/run-bisect-perf-regression.cfg b/tools/run-bisect-perf-regression.cfg new file mode 100644 index 0000000..0cf4b5c --- /dev/null +++ b/tools/run-bisect-perf-regression.cfg @@ -0,0 +1,41 @@ +# Copyright (c) 2013 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. + +"""Config file for Run Performance Test Bisect Tool + +This script is intended for use by anyone that wants to run a remote bisection +on a range of revisions to look for a performance regression. Modify the config +below and add the revision range, performance command, and metric. You can then +run a git try <bot>. + +Changes to this file should never be submitted. + +Args: + 'command': This is the full command line to pass to the + bisect-perf-regression.py script in order to execute the test. + 'good_revision': An svn or git revision where the metric hadn't regressed yet. + 'bad_revision': An svn or git revision sometime after the metric had + regressed. + 'metric': The name of the metric to parse out from the results of the + performance test. + + +Sample config: + +config = { + 'command': './out/Release/performance_ui_tests' + + ' --gtest_filter=PageCyclerTest.Intl1File', + 'good_revision': '179755', + 'bad_revision': '179782', + 'metric': 'times/t' +} + +""" + +config = { + 'command': '', + 'good_revision': '', + 'bad_revision': '', + 'metric': '', +} diff --git a/tools/run-bisect-perf-regression.py b/tools/run-bisect-perf-regression.py new file mode 100755 index 0000000..120e407 --- /dev/null +++ b/tools/run-bisect-perf-regression.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python +# Copyright (c) 2013 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. + +"""Run Performance Test Bisect Tool + +This script is used by a trybot to run the src/tools/bisect-perf-regression.py +script with the parameters specified in run-bisect-perf-regression.cfg. It will +check out a copy of the depot in a subdirectory 'bisect' of the working +directory provided, and run the bisect-perf-regression.py script there. + +""" + +import imp +import optparse +import os +import subprocess +import sys + + +def LoadConfigFile(): + """Attempts to load the file 'run-bisect-perf-regression.cfg' as a module + and grab the global config dict. + + Returns: + The config dict which should be formatted as follows: + {'command': string, 'good_revision': string, 'bad_revision': string + 'metric': string}. + Returns None on failure. + """ + try: + local_vars = {} + execfile('run-bisect-perf-regression.cfg', local_vars) + + return local_vars['config'] + except: + return None + + +def RunBisectionScript(config, working_directory): + """Attempts to execute src/tools/bisect-perf-regression.py with the parameters + passed in. + + Args: + config: A dict containing the parameters to pass to the script. + + Returns: + 0 on success, otherwise 1. + """ + + cmd = ['python', 'bisect-perf-regression.py', + '-c', config['command'], + '-g', config['good_revision'], + '-b', config['bad_revision'], + '-m', config['metric'], + '--working_directory', working_directory, + '--output_buildbot_annotations'] + + return_code = subprocess.call(cmd) + + if return_code: + print 'Error: bisect-perf-regression.py returned with error %d' %\ + return_code + print + + return return_code + + +def main(): + + usage = ('%prog [options] [-- chromium-options]\n' + 'Used by a trybot to run the bisection script using the parameters' + ' provided in the run-bisect-perf-regression.cfg file.') + + parser = optparse.OptionParser(usage=usage) + parser.add_option('-w', '--working_directory', + type='str', + help='A working directory to supply to the bisection ' + 'script, which will use it as the location to checkout ' + 'a copy of the chromium depot.') + (opts, args) = parser.parse_args() + + if not opts.working_directory: + print 'Error: missing required parameter: --working_directory' + print + parser.print_help() + return 1 + + config = LoadConfigFile() + if not config: + print 'Error: Could not load config file.' + print + return 1 + + return RunBisectionScript(config, opts.working_directory) + + +if __name__ == '__main__': + sys.exit(main()) |