Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(343)

Side by Side Diff: tools/bisect-perf-regression.py

Issue 12261026: Added separate checkout and config file generation to bisect script (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Changes from review. Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/PRESUBMIT.py ('k') | tools/run-bisect-perf-regression.cfg » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Performance Test Bisect Tool 6 """Performance Test Bisect Tool
7 7
8 This script bisects a series of changelists using binary search. It starts at 8 This script bisects a series of changelists using binary search. It starts at
9 a bad revision where a performance metric has regressed, and asks for a last 9 a bad revision where a performance metric has regressed, and asks for a last
10 known-good revision. It will then binary search across this revision range by 10 known-good revision. It will then binary search across this revision range by
(...skipping 17 matching lines...) Expand all
28 An example usage (using git hashes): 28 An example usage (using git hashes):
29 29
30 ./tools/bisect-perf-regression.py -c\ 30 ./tools/bisect-perf-regression.py -c\
31 "out/Release/performance_ui_tests --gtest_filter=ShutdownTest.SimpleUserQuit"\ 31 "out/Release/performance_ui_tests --gtest_filter=ShutdownTest.SimpleUserQuit"\
32 -g 1f6e67861535121c5c819c16a666f2436c207e7b\ 32 -g 1f6e67861535121c5c819c16a666f2436c207e7b\
33 -b b732f23b4f81c382db0b23b9035f3dadc7d925bb\ 33 -b b732f23b4f81c382db0b23b9035f3dadc7d925bb\
34 -m shutdown/simple-user-quit 34 -m shutdown/simple-user-quit
35 35
36 """ 36 """
37 37
38 38 import errno
39 import imp
40 import optparse
41 import os
39 import re 42 import re
40 import os 43 import shlex
41 import imp 44 import subprocess
42 import sys 45 import sys
43 import shlex
44 import optparse
45 import subprocess
46 46
47 47
48 # The additional repositories that might need to be bisected. 48 # The additional repositories that might need to be bisected.
49 # If the repository has any dependant repositories (such as skia/src needs 49 # If the repository has any dependant repositories (such as skia/src needs
50 # skia/include and skia/gyp to be updated), specify them in the 'depends' 50 # skia/include and skia/gyp to be updated), specify them in the 'depends'
51 # so that they're synced appropriately. 51 # so that they're synced appropriately.
52 # Format is: 52 # Format is:
53 # src: path to the working directory. 53 # src: path to the working directory.
54 # recurse: True if this repositry will get bisected. 54 # recurse: True if this repositry will get bisected.
55 # depends: A list of other repositories that are actually part of the same 55 # depends: A list of other repositories that are actually part of the same
(...skipping 26 matching lines...) Expand all
82 "recurse" : False, 82 "recurse" : False,
83 "svn" : "http://skia.googlecode.com/svn/trunk/gyp", 83 "svn" : "http://skia.googlecode.com/svn/trunk/gyp",
84 "depends" : None 84 "depends" : None
85 } 85 }
86 } 86 }
87 87
88 DEPOT_NAMES = DEPOT_DEPS_NAME.keys() 88 DEPOT_NAMES = DEPOT_DEPS_NAME.keys()
89 89
90 FILE_DEPS_GIT = '.DEPS.git' 90 FILE_DEPS_GIT = '.DEPS.git'
91 91
92 GCLIENT_SPEC = """
93 solutions = [
94 { "name" : "src",
95 "url" : "https://chromium.googlesource.com/chromium/src.git",
96 "deps_file" : ".DEPS.git",
97 "managed" : True,
98 "custom_deps" : {
99 },
100 "safesync_url": "",
101 },
102 { "name" : "src-internal",
103 "url" : "ssh://gerrit-int.chromium.org:29419/" +
104 "chrome/src-internal.git",
105 "deps_file" : ".DEPS.git",
106 },
107 ]
108 """
109 GCLIENT_SPEC = ''.join([l for l in GCLIENT_SPEC.splitlines()])
110
92 111
93 112
94 def IsStringFloat(string_to_check): 113 def IsStringFloat(string_to_check):
95 """Checks whether or not the given string can be converted to a floating 114 """Checks whether or not the given string can be converted to a floating
96 point number. 115 point number.
97 116
98 Args: 117 Args:
99 string_to_check: Input string to check if it can be converted to a float. 118 string_to_check: Input string to check if it can be converted to a float.
100 119
101 Returns: 120 Returns:
(...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after
1127 """ 1146 """
1128 1147
1129 (output, return_code) = RunGit(['rev-parse', '--is-inside-work-tree']) 1148 (output, return_code) = RunGit(['rev-parse', '--is-inside-work-tree'])
1130 1149
1131 if output.strip() == 'true': 1150 if output.strip() == 'true':
1132 return GitSourceControl() 1151 return GitSourceControl()
1133 1152
1134 return None 1153 return None
1135 1154
1136 1155
1156 def CreateAndChangeToSourceDirectory(working_directory):
1157 """Creates a directory 'bisect' as a subdirectory of 'working_directory'. If
1158 the function is successful, the current working directory will change to that
1159 of the new 'bisect' directory.
1160
1161 Returns:
1162 True if the directory was successfully created (or already existed).
1163 """
1164 cwd = os.getcwd()
1165 os.chdir(working_directory)
1166 try:
1167 os.mkdir('bisect')
1168 except OSError, e:
1169 if e.errno != errno.EEXIST:
1170 return False
1171 os.chdir('bisect')
1172 return True
1173
1174
1175 def RunGClient(params):
1176 """Runs gclient with the specified parameters.
1177
1178 Args:
1179 params: A list of parameters to pass to gclient.
1180
1181 Returns:
1182 The return code of the call.
1183 """
1184 cmd = ['gclient'] + params
1185 return subprocess.call(cmd)
1186
1187
1188 def RunGClientAndCreateConfig():
1189 """Runs gclient and creates a config containing both src and src-internal.
1190
1191 Returns:
1192 The return code of the call.
1193 """
1194 return_code = RunGClient(
1195 ['config', '--spec=%s' % GCLIENT_SPEC, '--git-deps'])
1196 return return_code
1197
1198
1199 def RunGClientAndSync():
1200 """Runs gclient and does a normal sync.
1201
1202 Returns:
1203 The return code of the call.
1204 """
1205 return RunGClient(['sync'])
1206
1207
1208 def SetupGitDepot(output_buildbot_annotations):
1209 """Sets up the depot for the bisection. The depot will be located in a
1210 subdirectory called 'bisect'.
1211
1212 Returns:
1213 True if gclient successfully created the config file and did a sync, False
1214 otherwise.
1215 """
1216 name = 'Setting up Bisection Depot'
1217
1218 if output_buildbot_annotations:
1219 OutputAnnotationStepStart(name)
1220
1221 passed = False
1222
1223 if not RunGClientAndCreateConfig():
1224 if not RunGClientAndSync():
1225 passed = True
1226
1227 if output_buildbot_annotations:
1228 print
1229 OutputAnnotationStepClosed()
1230
1231 return passed
1232
1233
1137 def main(): 1234 def main():
1138 1235
1139 usage = ('%prog [options] [-- chromium-options]\n' 1236 usage = ('%prog [options] [-- chromium-options]\n'
1140 'Perform binary search on revision history to find a minimal ' 1237 'Perform binary search on revision history to find a minimal '
1141 'range of revisions where a peformance metric regressed.\n') 1238 'range of revisions where a peformance metric regressed.\n')
1142 1239
1143 parser = optparse.OptionParser(usage=usage) 1240 parser = optparse.OptionParser(usage=usage)
1144 1241
1145 parser.add_option('-c', '--command', 1242 parser.add_option('-c', '--command',
1146 type='str', 1243 type='str',
1147 help='A command to execute your performance test at' + 1244 help='A command to execute your performance test at' +
1148 ' each point in the bisection.') 1245 ' each point in the bisection.')
1149 parser.add_option('-b', '--bad_revision', 1246 parser.add_option('-b', '--bad_revision',
1150 type='str', 1247 type='str',
1151 help='A bad revision to start bisection. ' + 1248 help='A bad revision to start bisection. ' +
1152 'Must be later than good revision. May be either a git' + 1249 'Must be later than good revision. May be either a git' +
1153 ' or svn revision.') 1250 ' or svn revision.')
1154 parser.add_option('-g', '--good_revision', 1251 parser.add_option('-g', '--good_revision',
1155 type='str', 1252 type='str',
1156 help='A revision to start bisection where performance' + 1253 help='A revision to start bisection where performance' +
1157 ' test is known to pass. Must be earlier than the ' + 1254 ' test is known to pass. Must be earlier than the ' +
1158 'bad revision. May be either a git or svn revision.') 1255 'bad revision. May be either a git or svn revision.')
1159 parser.add_option('-m', '--metric', 1256 parser.add_option('-m', '--metric',
1160 type='str', 1257 type='str',
1161 help='The desired metric to bisect on. For example ' + 1258 help='The desired metric to bisect on. For example ' +
1162 '"vm_rss_final_b/vm_rss_f_b"') 1259 '"vm_rss_final_b/vm_rss_f_b"')
1260 parser.add_option('-w', '--working_directory',
1261 type='str',
1262 help='Path to the working directory where the script will '
1263 'do an initial checkout of the chromium depot. The '
1264 'files will be placed in a subdirectory "bisect" under '
1265 'working_directory and that will be used to perform the '
1266 'bisection. This parameter is optional, if it is not '
1267 'supplied, the script will work from the current depot.')
1163 parser.add_option('--use_goma', 1268 parser.add_option('--use_goma',
1164 action="store_true", 1269 action="store_true",
1165 help='Add a bunch of extra threads for goma.') 1270 help='Add a bunch of extra threads for goma.')
1166 parser.add_option('--output_buildbot_annotations', 1271 parser.add_option('--output_buildbot_annotations',
1167 action="store_true", 1272 action="store_true",
1168 help='Add extra annotation output for buildbot.') 1273 help='Add extra annotation output for buildbot.')
1169 parser.add_option('--debug_ignore_build', 1274 parser.add_option('--debug_ignore_build',
1170 action="store_true", 1275 action="store_true",
1171 help='DEBUG: Don\'t perform builds.') 1276 help='DEBUG: Don\'t perform builds.')
1172 parser.add_option('--debug_ignore_sync', 1277 parser.add_option('--debug_ignore_sync',
(...skipping 27 matching lines...) Expand all
1200 print 1305 print
1201 parser.print_help() 1306 parser.print_help()
1202 return 1 1307 return 1
1203 1308
1204 # Haven't tested the script out on any other platforms yet. 1309 # Haven't tested the script out on any other platforms yet.
1205 if not os.name in ['posix']: 1310 if not os.name in ['posix']:
1206 print "Sorry, this platform isn't supported yet." 1311 print "Sorry, this platform isn't supported yet."
1207 print 1312 print
1208 return 1 1313 return 1
1209 1314
1315 metric_values = opts.metric.split('/')
1316 if len(metric_values) != 2:
1317 print "Invalid metric specified: [%s]" % (opts.metric,)
1318 print
1319 return 1
1320
1321 if opts.working_directory:
1322 if not CreateAndChangeToSourceDirectory(opts.working_directory):
1323 print 'Error: Could not create bisect directory.'
1324 print
1325 return 1
1326
1327 if not SetupGitDepot(opts.output_buildbot_annotations):
1328 print 'Error: Failed to grab source.'
1329 print
1330 return 1
1331
1332 os.chdir(os.path.join(os.getcwd(), 'src'))
1210 1333
1211 # Check what source control method they're using. Only support git workflow 1334 # Check what source control method they're using. Only support git workflow
1212 # at the moment. 1335 # at the moment.
1213 source_control = DetermineAndCreateSourceControl() 1336 source_control = DetermineAndCreateSourceControl()
1214 1337
1215 if not source_control: 1338 if not source_control:
1216 print "Sorry, only the git workflow is supported at the moment." 1339 print "Sorry, only the git workflow is supported at the moment."
1217 print 1340 print
1218 return 1 1341 return 1
1219 1342
1220 # gClient sync seems to fail if you're not in master branch. 1343 # gClient sync seems to fail if you're not in master branch.
1221 if not source_control.IsInProperBranch() and not opts.debug_ignore_sync: 1344 if not source_control.IsInProperBranch() and not opts.debug_ignore_sync:
1222 print "You must switch to master branch to run bisection." 1345 print "You must switch to master branch to run bisection."
1223 print 1346 print
1224 return 1 1347 return 1
1225 1348
1226 metric_values = opts.metric.split('/')
1227 if len(metric_values) < 2:
1228 print "Invalid metric specified: [%s]" % (opts.metric,)
1229 print
1230 return 1
1231
1232
1233 bisect_test = BisectPerformanceMetrics(source_control, opts) 1349 bisect_test = BisectPerformanceMetrics(source_control, opts)
1234 bisect_results = bisect_test.Run(opts.command, 1350 bisect_results = bisect_test.Run(opts.command,
1235 opts.bad_revision, 1351 opts.bad_revision,
1236 opts.good_revision, 1352 opts.good_revision,
1237 metric_values) 1353 metric_values)
1238 1354
1239 if not(bisect_results['error']): 1355 if not(bisect_results['error']):
1240 bisect_test.FormatAndPrintResults(bisect_results) 1356 bisect_test.FormatAndPrintResults(bisect_results)
1241 return 0 1357 return 0
1242 else: 1358 else:
1243 print 'Error: ' + bisect_results['error'] 1359 print 'Error: ' + bisect_results['error']
1244 print 1360 print
1245 return 1 1361 return 1
1246 1362
1247 if __name__ == '__main__': 1363 if __name__ == '__main__':
1248 sys.exit(main()) 1364 sys.exit(main())
OLDNEW
« no previous file with comments | « tools/PRESUBMIT.py ('k') | tools/run-bisect-perf-regression.cfg » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698