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

Side by Side Diff: tools/auto_bisect/bisect_perf_regression.py

Issue 660393002: Refactoring the output of bisect script. Switching from plain printing to a combination of: (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Applying recommendations Created 6 years, 1 month 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 | « no previous file | tools/auto_bisect/run_tests » ('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 ./tools/bisect_perf_regression.py -c\ 28 ./tools/bisect_perf_regression.py -c\
29 "out/Release/performance_ui_tests --gtest_filter=ShutdownTest.SimpleUserQuit"\ 29 "out/Release/performance_ui_tests --gtest_filter=ShutdownTest.SimpleUserQuit"\
30 -g 1f6e67861535121c5c819c16a666f2436c207e7b\ 30 -g 1f6e67861535121c5c819c16a666f2436c207e7b\
31 -b b732f23b4f81c382db0b23b9035f3dadc7d925bb\ 31 -b b732f23b4f81c382db0b23b9035f3dadc7d925bb\
32 -m shutdown/simple-user-quit 32 -m shutdown/simple-user-quit
33 """ 33 """
34 34
35 import copy 35 import copy
36 import errno 36 import errno
37 import hashlib 37 import hashlib
38 import logging
38 import optparse 39 import optparse
39 import os 40 import os
40 import re 41 import re
41 import shlex 42 import shlex
42 import shutil 43 import shutil
43 import StringIO 44 import StringIO
44 import sys 45 import sys
45 import time 46 import time
46 import zipfile 47 import zipfile
47 48
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 bucket_name: Google Storage bucket name. 186 bucket_name: Google Storage bucket name.
186 source_path: Source file path. 187 source_path: Source file path.
187 destination_path: Destination file path. 188 destination_path: Destination file path.
188 189
189 Returns: 190 Returns:
190 Downloaded file path if exists, otherwise None. 191 Downloaded file path if exists, otherwise None.
191 """ 192 """
192 target_file = os.path.join(destination_path, os.path.basename(source_path)) 193 target_file = os.path.join(destination_path, os.path.basename(source_path))
193 try: 194 try:
194 if cloud_storage.Exists(bucket_name, source_path): 195 if cloud_storage.Exists(bucket_name, source_path):
195 print 'Fetching file from gs//%s/%s ...' % (bucket_name, source_path) 196 logging.info('Fetching file from gs//%s/%s ...',
197 bucket_name, source_path)
196 cloud_storage.Get(bucket_name, source_path, destination_path) 198 cloud_storage.Get(bucket_name, source_path, destination_path)
197 if os.path.exists(target_file): 199 if os.path.exists(target_file):
198 return target_file 200 return target_file
199 else: 201 else:
200 print ('File gs://%s/%s not found in cloud storage.' % ( 202 logging.info('File gs://%s/%s not found in cloud storage.',
201 bucket_name, source_path)) 203 bucket_name, source_path)
202 except Exception as e: 204 except Exception as e:
203 print 'Something went wrong while fetching file from cloud: %s' % e 205 logging.warn('Something went wrong while fetching file from cloud: %s', e)
204 if os.path.exists(target_file): 206 if os.path.exists(target_file):
205 os.remove(target_file) 207 os.remove(target_file)
206 return None 208 return None
207 209
208 210
209 # This is copied from build/scripts/common/chromium_utils.py. 211 # This is copied from build/scripts/common/chromium_utils.py.
210 def MaybeMakeDirectory(*path): 212 def MaybeMakeDirectory(*path):
211 """Creates an entire path, if it doesn't already exist.""" 213 """Creates an entire path, if it doesn't already exist."""
212 file_path = os.path.join(*path) 214 file_path = os.path.join(*path)
213 try: 215 try:
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 command = unzip_cmd + [filepath] 252 command = unzip_cmd + [filepath]
251 result = bisect_utils.RunProcess(command) 253 result = bisect_utils.RunProcess(command)
252 os.chdir(saved_dir) 254 os.chdir(saved_dir)
253 if result: 255 if result:
254 raise IOError('unzip failed: %s => %s' % (str(command), result)) 256 raise IOError('unzip failed: %s => %s' % (str(command), result))
255 else: 257 else:
256 assert bisect_utils.IsWindowsHost() or bisect_utils.IsMacHost() 258 assert bisect_utils.IsWindowsHost() or bisect_utils.IsMacHost()
257 zf = zipfile.ZipFile(filename) 259 zf = zipfile.ZipFile(filename)
258 for name in zf.namelist(): 260 for name in zf.namelist():
259 if verbose: 261 if verbose:
260 print 'Extracting %s' % name 262 logging.info('Extracting %s', name)
261 zf.extract(name, output_dir) 263 zf.extract(name, output_dir)
262 if bisect_utils.IsMacHost(): 264 if bisect_utils.IsMacHost():
263 # Restore permission bits. 265 # Restore permission bits.
264 os.chmod(os.path.join(output_dir, name), 266 os.chmod(os.path.join(output_dir, name),
265 zf.getinfo(name).external_attr >> 16L) 267 zf.getinfo(name).external_attr >> 16L)
266 268
267 269
268 def WriteStringToFile(text, file_name): 270 def WriteStringToFile(text, file_name):
269 """Writes text to a file, raising an RuntimeError on failure.""" 271 """Writes text to a file, raising an RuntimeError on failure."""
270 try: 272 try:
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 # Note: Build is treated as PENDING if build number is not found 366 # Note: Build is treated as PENDING if build number is not found
365 # on the the try server. 367 # on the the try server.
366 build_status, status_link = request_build.GetBuildStatus( 368 build_status, status_link = request_build.GetBuildStatus(
367 build_num, bot_name, builder_host, builder_port) 369 build_num, bot_name, builder_host, builder_port)
368 if build_status == request_build.FAILED: 370 if build_status == request_build.FAILED:
369 return (None, 'Failed to produce build, log: %s' % status_link) 371 return (None, 'Failed to produce build, log: %s' % status_link)
370 elapsed_time = time.time() - start_time 372 elapsed_time = time.time() - start_time
371 if elapsed_time > max_timeout: 373 if elapsed_time > max_timeout:
372 return (None, 'Timed out: %ss without build' % max_timeout) 374 return (None, 'Timed out: %ss without build' % max_timeout)
373 375
374 print 'Time elapsed: %ss without build.' % elapsed_time 376 logging.info('Time elapsed: %ss without build.', elapsed_time)
375 time.sleep(poll_interval) 377 time.sleep(poll_interval)
376 # For some reason, mac bisect bots were not flushing stdout periodically. 378 # For some reason, mac bisect bots were not flushing stdout periodically.
377 # As a result buildbot command is timed-out. Flush stdout on all platforms 379 # As a result buildbot command is timed-out. Flush stdout on all platforms
378 # while waiting for build. 380 # while waiting for build.
379 sys.stdout.flush() 381 sys.stdout.flush()
380 382
381 383
382 def _UpdateV8Branch(deps_content): 384 def _UpdateV8Branch(deps_content):
383 """Updates V8 branch in DEPS file to process v8_bleeding_edge. 385 """Updates V8 branch in DEPS file to process v8_bleeding_edge.
384 386
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 new_data = re.sub(angle_rev_pattern, revision, deps_contents) 437 new_data = re.sub(angle_rev_pattern, revision, deps_contents)
436 else: 438 else:
437 # Check whether the depot and revision pattern in DEPS file deps 439 # Check whether the depot and revision pattern in DEPS file deps
438 # variable. e.g., 440 # variable. e.g.,
439 # "src/third_party/angle": Var("chromium_git") + 441 # "src/third_party/angle": Var("chromium_git") +
440 # "/angle/angle.git@fa63e947cb3eccf463648d21a05d5002c9b8adfa",. 442 # "/angle/angle.git@fa63e947cb3eccf463648d21a05d5002c9b8adfa",.
441 angle_rev_pattern = re.compile( 443 angle_rev_pattern = re.compile(
442 r'(?<=angle\.git@)([a-fA-F0-9]{40})(?=")', re.MULTILINE) 444 r'(?<=angle\.git@)([a-fA-F0-9]{40})(?=")', re.MULTILINE)
443 match = re.search(angle_rev_pattern, deps_contents) 445 match = re.search(angle_rev_pattern, deps_contents)
444 if not match: 446 if not match:
445 print 'Could not find angle revision information in DEPS file.' 447 logging.info('Could not find angle revision information in DEPS file.')
446 return False 448 return False
447 new_data = re.sub(angle_rev_pattern, revision, deps_contents) 449 new_data = re.sub(angle_rev_pattern, revision, deps_contents)
448 # Write changes to DEPS file 450 # Write changes to DEPS file
449 WriteStringToFile(new_data, deps_file) 451 WriteStringToFile(new_data, deps_file)
450 return True 452 return True
451 except IOError, e: 453 except IOError, e:
452 print 'Something went wrong while updating DEPS file, %s' % e 454 logging.warn('Something went wrong while updating DEPS file, %s', e)
453 return False 455 return False
454 456
455 457
456 def _TryParseHistogramValuesFromOutput(metric, text): 458 def _TryParseHistogramValuesFromOutput(metric, text):
457 """Attempts to parse a metric in the format HISTOGRAM <graph: <trace>. 459 """Attempts to parse a metric in the format HISTOGRAM <graph: <trace>.
458 460
459 Args: 461 Args:
460 metric: The metric as a list of [<trace>, <value>] strings. 462 metric: The metric as a list of [<trace>, <value>] strings.
461 text: The text to parse the metric values from. 463 text: The text to parse the metric values from.
462 464
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 '-n', bisect_job_name, 752 '-n', bisect_job_name,
751 '--svn_repo=%s' % SVN_REPO_URL, 753 '--svn_repo=%s' % SVN_REPO_URL,
752 '--diff=%s' % patch_content 754 '--diff=%s' % patch_content
753 ] 755 ]
754 # Execute try job to build revision. 756 # Execute try job to build revision.
755 output, returncode = bisect_utils.RunGit(try_cmd) 757 output, returncode = bisect_utils.RunGit(try_cmd)
756 758
757 if returncode: 759 if returncode:
758 raise RunGitError('Could not execute tryjob: %s.\n Error: %s' % ( 760 raise RunGitError('Could not execute tryjob: %s.\n Error: %s' % (
759 'git %s' % ' '.join(try_cmd), output)) 761 'git %s' % ' '.join(try_cmd), output))
760 print ('Try job successfully submitted.\n TryJob Details: %s\n%s' % ( 762 logging.info('Try job successfully submitted.\n TryJob Details: %s\n%s',
761 'git %s' % ' '.join(try_cmd), output)) 763 'git %s' % ' '.join(try_cmd), output)
762 finally: 764 finally:
763 # Delete patch file if exists 765 # Delete patch file if exists
764 try: 766 try:
765 os.remove(BISECT_PATCH_FILE) 767 os.remove(BISECT_PATCH_FILE)
766 except OSError as e: 768 except OSError as e:
767 if e.errno != errno.ENOENT: 769 if e.errno != errno.ENOENT:
768 raise 770 raise
769 # Checkout master branch and delete bisect-tryjob branch. 771 # Checkout master branch and delete bisect-tryjob branch.
770 bisect_utils.RunGit(['checkout', '-f', BISECT_MASTER_BRANCH]) 772 bisect_utils.RunGit(['checkout', '-f', BISECT_MASTER_BRANCH])
771 bisect_utils.RunGit(['branch', '-D', BISECT_TRYJOB_BRANCH]) 773 bisect_utils.RunGit(['branch', '-D', BISECT_TRYJOB_BRANCH])
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
967 self.warnings.append(warning_text) 969 self.warnings.append(warning_text)
968 else: 970 else:
969 results[depot_name] = None 971 results[depot_name] = None
970 return results 972 return results
971 except ImportError: 973 except ImportError:
972 deps_file_contents = ReadStringFromFile(deps_file) 974 deps_file_contents = ReadStringFromFile(deps_file)
973 parse_results = _ParseRevisionsFromDEPSFileManually(deps_file_contents) 975 parse_results = _ParseRevisionsFromDEPSFileManually(deps_file_contents)
974 results = {} 976 results = {}
975 for depot_name, depot_revision in parse_results.iteritems(): 977 for depot_name, depot_revision in parse_results.iteritems():
976 depot_revision = depot_revision.strip('@') 978 depot_revision = depot_revision.strip('@')
977 print depot_name, depot_revision 979 logging.warn(depot_name, depot_revision)
978 for cur_name, cur_data in bisect_utils.DEPOT_DEPS_NAME.iteritems(): 980 for cur_name, cur_data in bisect_utils.DEPOT_DEPS_NAME.iteritems():
979 if (cur_data.has_key('deps_var') and 981 if (cur_data.has_key('deps_var') and
980 cur_data['deps_var'] == depot_name): 982 cur_data['deps_var'] == depot_name):
981 src_name = cur_name 983 src_name = cur_name
982 results[src_name] = depot_revision 984 results[src_name] = depot_revision
983 break 985 break
984 return results 986 return results
985 987
986 def _Get3rdPartyRevisions(self, depot): 988 def _Get3rdPartyRevisions(self, depot):
987 """Parses the DEPS file to determine WebKit/v8/etc... versions. 989 """Parses the DEPS file to determine WebKit/v8/etc... versions.
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 target_build_output_dir = os.path.join(abs_build_dir, build_type) 1162 target_build_output_dir = os.path.join(abs_build_dir, build_type)
1161 ExtractZip(downloaded_file, abs_build_dir) 1163 ExtractZip(downloaded_file, abs_build_dir)
1162 if not os.path.exists(output_dir): 1164 if not os.path.exists(output_dir):
1163 # Due to recipe changes, the builds extract folder contains 1165 # Due to recipe changes, the builds extract folder contains
1164 # out/Release instead of full-build-<platform>/Release. 1166 # out/Release instead of full-build-<platform>/Release.
1165 if os.path.exists(os.path.join(abs_build_dir, 'out', build_type)): 1167 if os.path.exists(os.path.join(abs_build_dir, 'out', build_type)):
1166 output_dir = os.path.join(abs_build_dir, 'out', build_type) 1168 output_dir = os.path.join(abs_build_dir, 'out', build_type)
1167 else: 1169 else:
1168 raise IOError('Missing extracted folder %s ' % output_dir) 1170 raise IOError('Missing extracted folder %s ' % output_dir)
1169 1171
1170 print 'Moving build from %s to %s' % ( 1172 logging.info('Moving build from %s to %s',
1171 output_dir, target_build_output_dir) 1173 output_dir, target_build_output_dir)
1172 shutil.move(output_dir, target_build_output_dir) 1174 shutil.move(output_dir, target_build_output_dir)
1173 return True 1175 return True
1174 except Exception as e: 1176 except Exception as e:
1175 print 'Something went wrong while extracting archive file: %s' % e 1177 logging.info('Something went wrong while extracting archive file: %s', e)
1176 self.BackupOrRestoreOutputDirectory(restore=True) 1178 self.BackupOrRestoreOutputDirectory(restore=True)
1177 # Cleanup any leftovers from unzipping. 1179 # Cleanup any leftovers from unzipping.
1178 if os.path.exists(output_dir): 1180 if os.path.exists(output_dir):
1179 RemoveDirectoryTree(output_dir) 1181 RemoveDirectoryTree(output_dir)
1180 finally: 1182 finally:
1181 # Delete downloaded archive 1183 # Delete downloaded archive
1182 if os.path.exists(downloaded_file): 1184 if os.path.exists(downloaded_file):
1183 os.remove(downloaded_file) 1185 os.remove(downloaded_file)
1184 return False 1186 return False
1185 1187
(...skipping 28 matching lines...) Expand all
1214 bot_name = self._GetBuilderName(self.opts.target_platform) 1216 bot_name = self._GetBuilderName(self.opts.target_platform)
1215 build_timeout = self._GetBuilderBuildTime() 1217 build_timeout = self._GetBuilderBuildTime()
1216 target_file = None 1218 target_file = None
1217 try: 1219 try:
1218 # Execute try job request to build revision with patch. 1220 # Execute try job request to build revision with patch.
1219 _BuilderTryjob(git_revision, bot_name, build_request_id, patch) 1221 _BuilderTryjob(git_revision, bot_name, build_request_id, patch)
1220 target_file, error_msg = _WaitUntilBuildIsReady( 1222 target_file, error_msg = _WaitUntilBuildIsReady(
1221 fetch_build, bot_name, self.opts.builder_host, 1223 fetch_build, bot_name, self.opts.builder_host,
1222 self.opts.builder_port, build_request_id, build_timeout) 1224 self.opts.builder_port, build_request_id, build_timeout)
1223 if not target_file: 1225 if not target_file:
1224 print '%s [revision: %s]' % (error_msg, git_revision) 1226 logging.warn('%s [revision: %s]', error_msg, git_revision)
1225 except RunGitError as e: 1227 except RunGitError as e:
1226 print ('Failed to post builder try job for revision: [%s].\n' 1228 logging.warn('Failed to post builder try job for revision: [%s].\n'
1227 'Error: %s' % (git_revision, e)) 1229 'Error: %s', git_revision, e)
1228 1230
1229 return target_file 1231 return target_file
1230 1232
1231 @staticmethod 1233 @staticmethod
1232 def _GetBuilderName(target_platform): 1234 def _GetBuilderName(target_platform):
1233 """Gets builder bot name and build time in seconds based on platform.""" 1235 """Gets builder bot name and build time in seconds based on platform."""
1234 if bisect_utils.IsWindowsHost(): 1236 if bisect_utils.IsWindowsHost():
1235 return 'win_perf_bisect_builder' 1237 return 'win_perf_bisect_builder'
1236 if bisect_utils.IsLinuxHost(): 1238 if bisect_utils.IsLinuxHost():
1237 if target_platform == 'android': 1239 if target_platform == 'android':
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 """ 1277 """
1276 # Check whether the depot and revision pattern in DEPS file vars 1278 # Check whether the depot and revision pattern in DEPS file vars
1277 # e.g. for webkit the format is "webkit_revision": "12345". 1279 # e.g. for webkit the format is "webkit_revision": "12345".
1278 deps_revision = re.compile(r'(?<="%s": ")([0-9]+)(?=")' % deps_key, 1280 deps_revision = re.compile(r'(?<="%s": ")([0-9]+)(?=")' % deps_key,
1279 re.MULTILINE) 1281 re.MULTILINE)
1280 new_data = None 1282 new_data = None
1281 if re.search(deps_revision, deps_contents): 1283 if re.search(deps_revision, deps_contents):
1282 commit_position = source_control.GetCommitPosition( 1284 commit_position = source_control.GetCommitPosition(
1283 git_revision, self.depot_registry.GetDepotDir(depot)) 1285 git_revision, self.depot_registry.GetDepotDir(depot))
1284 if not commit_position: 1286 if not commit_position:
1285 print 'Could not determine commit position for %s' % git_revision 1287 logging.warn('Could not determine commit position for %s', git_revision)
1286 return None 1288 return None
1287 # Update the revision information for the given depot 1289 # Update the revision information for the given depot
1288 new_data = re.sub(deps_revision, str(commit_position), deps_contents) 1290 new_data = re.sub(deps_revision, str(commit_position), deps_contents)
1289 else: 1291 else:
1290 # Check whether the depot and revision pattern in DEPS file vars 1292 # Check whether the depot and revision pattern in DEPS file vars
1291 # e.g. for webkit the format is "webkit_revision": "559a6d4ab7a84c539..". 1293 # e.g. for webkit the format is "webkit_revision": "559a6d4ab7a84c539..".
1292 deps_revision = re.compile( 1294 deps_revision = re.compile(
1293 r'(?<=["\']%s["\']: ["\'])([a-fA-F0-9]{40})(?=["\'])' % deps_key, 1295 r'(?<=["\']%s["\']: ["\'])([a-fA-F0-9]{40})(?=["\'])' % deps_key,
1294 re.MULTILINE) 1296 re.MULTILINE)
1295 if re.search(deps_revision, deps_contents): 1297 if re.search(deps_revision, deps_contents):
(...skipping 21 matching lines...) Expand all
1317 1319
1318 Returns: 1320 Returns:
1319 True if DEPS file is modified successfully, otherwise False. 1321 True if DEPS file is modified successfully, otherwise False.
1320 """ 1322 """
1321 if not os.path.exists(deps_file): 1323 if not os.path.exists(deps_file):
1322 return False 1324 return False
1323 1325
1324 deps_var = bisect_utils.DEPOT_DEPS_NAME[depot]['deps_var'] 1326 deps_var = bisect_utils.DEPOT_DEPS_NAME[depot]['deps_var']
1325 # Don't update DEPS file if deps_var is not set in DEPOT_DEPS_NAME. 1327 # Don't update DEPS file if deps_var is not set in DEPOT_DEPS_NAME.
1326 if not deps_var: 1328 if not deps_var:
1327 print 'DEPS update not supported for Depot: %s', depot 1329 logging.warn('DEPS update not supported for Depot: %s', depot)
1328 return False 1330 return False
1329 1331
1330 # Hack for Angle repository. In the DEPS file, "vars" dictionary variable 1332 # Hack for Angle repository. In the DEPS file, "vars" dictionary variable
1331 # contains "angle_revision" key that holds git hash instead of SVN revision. 1333 # contains "angle_revision" key that holds git hash instead of SVN revision.
1332 # And sometime "angle_revision" key is not specified in "vars" variable. 1334 # And sometime "angle_revision" key is not specified in "vars" variable.
1333 # In such cases check, "deps" dictionary variable that matches 1335 # In such cases check, "deps" dictionary variable that matches
1334 # angle.git@[a-fA-F0-9]{40}$ and replace git hash. 1336 # angle.git@[a-fA-F0-9]{40}$ and replace git hash.
1335 if depot == 'angle': 1337 if depot == 'angle':
1336 return _UpdateDEPSForAngle(revision, depot, deps_file) 1338 return _UpdateDEPSForAngle(revision, depot, deps_file)
1337 1339
1338 try: 1340 try:
1339 deps_contents = ReadStringFromFile(deps_file) 1341 deps_contents = ReadStringFromFile(deps_file)
1340 updated_deps_content = self.UpdateDepsContents( 1342 updated_deps_content = self.UpdateDepsContents(
1341 deps_contents, depot, revision, deps_var) 1343 deps_contents, depot, revision, deps_var)
1342 # Write changes to DEPS file 1344 # Write changes to DEPS file
1343 if updated_deps_content: 1345 if updated_deps_content:
1344 WriteStringToFile(updated_deps_content, deps_file) 1346 WriteStringToFile(updated_deps_content, deps_file)
1345 return True 1347 return True
1346 except IOError, e: 1348 except IOError, e:
1347 print 'Something went wrong while updating DEPS file. [%s]' % e 1349 logging.warn('Something went wrong while updating DEPS file. [%s]', e)
1348 return False 1350 return False
1349 1351
1350 def CreateDEPSPatch(self, depot, revision): 1352 def CreateDEPSPatch(self, depot, revision):
1351 """Modifies DEPS and returns diff as text. 1353 """Modifies DEPS and returns diff as text.
1352 1354
1353 Args: 1355 Args:
1354 depot: Current depot being bisected. 1356 depot: Current depot being bisected.
1355 revision: A git hash revision of the dependency repository. 1357 revision: A git hash revision of the dependency repository.
1356 1358
1357 Returns: 1359 Returns:
(...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after
2264 if metric_increased: 2266 if metric_increased:
2265 message += "and the metric appears to have increased. " 2267 message += "and the metric appears to have increased. "
2266 else: 2268 else:
2267 message += "and the metric appears to have decreased. " 2269 message += "and the metric appears to have decreased. "
2268 if ((higher_is_better and metric_increased) or 2270 if ((higher_is_better and metric_increased) or
2269 (not higher_is_better and not metric_increased)): 2271 (not higher_is_better and not metric_increased)):
2270 error = (message + 'Then, the test results for the ends of the given ' 2272 error = (message + 'Then, the test results for the ends of the given '
2271 '\'good\' - \'bad\' range of revisions represent an ' 2273 '\'good\' - \'bad\' range of revisions represent an '
2272 'improvement (and not a regression).') 2274 'improvement (and not a regression).')
2273 return BisectResults(error=error) 2275 return BisectResults(error=error)
2274 print message, "Therefore we continue to bisect." 2276 logging.info(message + "Therefore we continue to bisect.")
2275 2277
2276 bisect_state = BisectState(target_depot, revision_list) 2278 bisect_state = BisectState(target_depot, revision_list)
2277 revision_states = bisect_state.GetRevisionStates() 2279 revision_states = bisect_state.GetRevisionStates()
2278 2280
2279 min_revision = 0 2281 min_revision = 0
2280 max_revision = len(revision_states) - 1 2282 max_revision = len(revision_states) - 1
2281 # Check how likely it is that the good and bad results are different 2283 # Check how likely it is that the good and bad results are different
2282 # beyond chance-induced variation. 2284 # beyond chance-induced variation.
2283 if not self.opts.debug_ignore_regression_confidence: 2285 if not self.opts.debug_ignore_regression_confidence:
2284 error = _CheckRegressionConfidenceError(good_revision, 2286 error = _CheckRegressionConfidenceError(good_revision,
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
2763 opts.metric = metric_values 2765 opts.metric = metric_values
2764 2766
2765 opts.repeat_test_count = min(max(opts.repeat_test_count, 1), 100) 2767 opts.repeat_test_count = min(max(opts.repeat_test_count, 1), 100)
2766 opts.max_time_minutes = min(max(opts.max_time_minutes, 1), 60) 2768 opts.max_time_minutes = min(max(opts.max_time_minutes, 1), 60)
2767 opts.truncate_percent = min(max(opts.truncate_percent, 0), 25) 2769 opts.truncate_percent = min(max(opts.truncate_percent, 0), 25)
2768 opts.truncate_percent = opts.truncate_percent / 100.0 2770 opts.truncate_percent = opts.truncate_percent / 100.0
2769 2771
2770 return opts 2772 return opts
2771 2773
2772 2774
2775 def _ConfigureLogging():
2776 """Trivial logging config.
2777
2778 Configures logging to output any messages at or above INFO to standard out,
2779 without any additional formatting.
2780 """
2781 logging_format = '%(message)s'
2782 logging.basicConfig(
2783 stream=logging.sys.stdout, level=logging.INFO, format=logging_format)
2784
2785
2773 def main(): 2786 def main():
2774 2787 _ConfigureLogging()
2775 try: 2788 try:
2776 opts = BisectOptions() 2789 opts = BisectOptions()
2777 opts.ParseCommandLine() 2790 opts.ParseCommandLine()
2778 2791
2779 if opts.extra_src: 2792 if opts.extra_src:
2780 extra_src = bisect_utils.LoadExtraSrc(opts.extra_src) 2793 extra_src = bisect_utils.LoadExtraSrc(opts.extra_src)
2781 if not extra_src: 2794 if not extra_src:
2782 raise RuntimeError('Invalid or missing --extra_src.') 2795 raise RuntimeError('Invalid or missing --extra_src.')
2783 bisect_utils.AddAdditionalDepotInfo(extra_src.GetAdditionalDepotInfo()) 2796 bisect_utils.AddAdditionalDepotInfo(extra_src.GetAdditionalDepotInfo())
2784 2797
(...skipping 29 matching lines...) Expand all
2814 raise RuntimeError(results.error) 2827 raise RuntimeError(results.error)
2815 bisect_printer.FormatAndPrintResults(results) 2828 bisect_printer.FormatAndPrintResults(results)
2816 return 0 2829 return 0
2817 finally: 2830 finally:
2818 bisect_test.PerformCleanup() 2831 bisect_test.PerformCleanup()
2819 except RuntimeError, e: 2832 except RuntimeError, e:
2820 if opts.output_buildbot_annotations: 2833 if opts.output_buildbot_annotations:
2821 # The perf dashboard scrapes the "results" step in order to comment on 2834 # The perf dashboard scrapes the "results" step in order to comment on
2822 # bugs. If you change this, please update the perf dashboard as well. 2835 # bugs. If you change this, please update the perf dashboard as well.
2823 bisect_utils.OutputAnnotationStepStart('Results') 2836 bisect_utils.OutputAnnotationStepStart('Results')
2824 print 'Error: %s' % e.message 2837 print 'Error: ', e.message
2838 logging.warn('A RuntimeError was caught: %s', e.message)
2825 if opts.output_buildbot_annotations: 2839 if opts.output_buildbot_annotations:
2826 bisect_utils.OutputAnnotationStepClosed() 2840 bisect_utils.OutputAnnotationStepClosed()
2827 return 1 2841 return 1
2828 2842
2829 2843
2830 if __name__ == '__main__': 2844 if __name__ == '__main__':
2831 sys.exit(main()) 2845 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | tools/auto_bisect/run_tests » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698