Index: build/util/run-bisect-perf-regression.py |
diff --git a/build/util/run-bisect-perf-regression.py b/build/util/run-bisect-perf-regression.py |
new file mode 100755 |
index 0000000000000000000000000000000000000000..83808c5ee1f68cf70272f203c208b8a27f0dde06 |
--- /dev/null |
+++ b/build/util/run-bisect-perf-regression.py |
@@ -0,0 +1,202 @@ |
+#!/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 errno |
+import imp |
+import optparse |
+import os |
+import subprocess |
+import sys |
+ |
+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://simonhatch@gerrit-int.chromium.org:29419/" + |
tonyg
2013/02/19 18:01:25
I don't think we want to check in your user id her
shatch
2013/02/19 18:33:51
Ah darn, forgot about that.
Q for Mike: Do I need
|
+ "chrome/src-internal.git", |
+ "deps_file" : ".DEPS.git", |
+ }, |
+] |
+""" |
+GCLIENT_SPEC = ''.join([l for l in GCLIENT_SPEC.splitlines()]) |
+ |
+ |
+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) |
+ |
tonyg
2013/02/19 18:01:25
2 line breaks between top level definitions (throu
shatch
2013/02/19 18:33:51
Done.
|
+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(): |
+ """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' |
+ print '@@@SEED_STEP %s@@@' % name |
+ print '@@@STEP_CURSOR %s@@@' % name |
+ print '@@@STEP_STARTED@@@' |
+ |
+ passed = False |
+ |
+ if not RunGClientAndCreateConfig(): |
+ if not RunGClientAndSync(): |
+ passed = True |
+ |
+ print '@@@STEP_CLOSED@@@' |
+ |
+ return passed |
+ |
+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: |
+ cfg_file = imp.load_source('config', 'run-bisect-perf-regression.cfg') |
+ |
+ return cfg_file.config |
+ except (KeyError, TypeError, IOError): |
+ return None |
+ |
+def RunBisectionScript(config): |
+ """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 = [os.path.join('tools', 'bisect-perf-regression.py'), |
+ '-c', config['command'], |
+ '-g', config['good_revision'], |
+ '-b', config['bad_revision'], |
+ '-m', config['metric'], |
+ '--debug_ignore_sync', |
tonyg
2013/02/19 18:01:25
Is this supposed to be checked in? If so, please a
shatch
2013/02/19 18:33:51
Done.
|
+ '--output_buildbot_annotations'] |
+ |
+ return_code = subprocess.call(cmd) |
+ |
+ if return_code: |
+ print 'Error: bisect-perf-regression.py returned with error %d' %\ |
+ return_code |
+ return 1 |
+ |
+ return 0 |
+ |
+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(os.path.join(working_directory)) |
tonyg
2013/02/19 18:01:25
why the join call? Isn't working_directory just a
shatch
2013/02/19 18:33:51
Done.
|
+ try: |
+ os.mkdir('bisect') |
+ except OSError, e: |
+ if e.errno != errno.EEXIST: |
tonyg
2013/02/19 18:01:25
To make sure I understand this: the directory is n
shatch
2013/02/19 18:33:51
Yep the intention is that the directory sticks aro
|
+ return False |
+ os.chdir('bisect') |
+ return True |
+ |
+def main(): |
+ |
tonyg
2013/02/19 18:01:25
nit: extra line break
shatch
2013/02/19 18:33:51
Done.
|
+ 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.\n') |
+ |
+ parser = optparse.OptionParser(usage=usage) |
+ parser.add_option('-w', '--working_directory', |
+ type='str', |
+ help='Path to the src directory of the git depot to start ' |
+ 'the bisection.') |
tonyg
2013/02/19 18:01:25
This description doesn't seem quite right. It is t
shatch
2013/02/19 18:33:51
Done.
|
+ (opts, args) = parser.parse_args() |
+ |
+ if not opts.working_directory: |
+ print 'Error: missing required parameter: --working_directory' |
+ parser.print_help() |
+ return 1 |
+ |
+ config = LoadConfigFile() |
+ if not config: |
+ print 'Error: Could not load config file.' |
+ return 1 |
+ |
+ if not CreateAndChangeToSourceDirectory(opts.working_directory): |
+ print 'Error: Could not create bisect directory.' |
+ return 1 |
+ |
+ if not SetupGitDepot(): |
tonyg
2013/02/19 18:01:25
Did you consider making the git checkout creation
shatch
2013/02/19 18:33:51
Yeah I was a bit undecided on whether to put the f
tonyg
2013/02/19 19:45:57
The thing about running the wrapper locally is tha
shatch
2013/02/19 23:01:32
Done.
|
+ print 'Error: Failed to grab source.' |
+ return 1 |
+ |
+ # The bisect script expects to be in /src |
+ os.chdir(os.path.join(os.getcwd(), 'src')) |
+ |
+ return RunBisectionScript(config) |
+ |
+ |
+if __name__ == '__main__': |
+ sys.exit(main()) |