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

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

Issue 564663002: Move bisect-perf-regression.py into auto_bisect directory. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add telemetry to PYTHONPATH for PRESUBMIT.py. Created 6 years, 2 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/auto_bisect/README ('k') | tools/auto_bisect/bisect_perf_regression_test.py » ('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
11 syncing, building, and running a performance test. If the change is 11 syncing, building, and running a performance test. If the change is
12 suspected to occur as a result of WebKit/V8 changes, the script will 12 suspected to occur as a result of WebKit/V8 changes, the script will
13 further bisect changes to those depots and attempt to narrow down the revision 13 further bisect changes to those depots and attempt to narrow down the revision
14 range. 14 range.
15 15
16 Example usage using SVN revisions: 16 Example usage using SVN revisions:
17 17
18 ./tools/bisect-perf-regression.py -c\ 18 ./tools/bisect_perf_regression.py -c\
19 "out/Release/performance_ui_tests --gtest_filter=ShutdownTest.SimpleUserQuit"\ 19 "out/Release/performance_ui_tests --gtest_filter=ShutdownTest.SimpleUserQuit"\
20 -g 168222 -b 168232 -m shutdown/simple-user-quit 20 -g 168222 -b 168232 -m shutdown/simple-user-quit
21 21
22 Be aware that if you're using the git workflow and specify an SVN revision, 22 Be aware that if you're using the git workflow and specify an SVN revision,
23 the script will attempt to find the git SHA1 where SVN changes up to that 23 the script will attempt to find the git SHA1 where SVN changes up to that
24 revision were merged in. 24 revision were merged in.
25 25
26 Example usage using git hashes: 26 Example usage using git hashes:
27 27
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 datetime 36 import datetime
37 import errno 37 import errno
38 import hashlib 38 import hashlib
39 import math 39 import math
40 import optparse 40 import optparse
41 import os 41 import os
42 import re 42 import re
43 import shlex 43 import shlex
44 import shutil 44 import shutil
45 import StringIO 45 import StringIO
46 import sys 46 import sys
47 import time 47 import time
48 import zipfile 48 import zipfile
49 49
50 sys.path.append(os.path.join(os.path.dirname(__file__), 'telemetry')) 50 sys.path.append(os.path.join(
51 os.path.dirname(__file__), os.path.pardir, 'telemetry'))
51 52
52 from auto_bisect import bisect_utils 53 import bisect_utils
53 from auto_bisect import builder 54 import builder
54 from auto_bisect import math_utils 55 import math_utils
55 from auto_bisect import request_build 56 import request_build
56 from auto_bisect import source_control as source_control_module 57 import source_control as source_control_module
57 from auto_bisect import ttest 58 import ttest
58 from telemetry.util import cloud_storage 59 from telemetry.util import cloud_storage
59 60
60 # Below is the map of "depot" names to information about each depot. Each depot 61 # Below is the map of "depot" names to information about each depot. Each depot
61 # is a repository, and in the process of bisecting, revision ranges in these 62 # is a repository, and in the process of bisecting, revision ranges in these
62 # repositories may also be bisected. 63 # repositories may also be bisected.
63 # 64 #
64 # Each depot information dictionary may contain: 65 # Each depot information dictionary may contain:
65 # src: Path to the working directory. 66 # src: Path to the working directory.
66 # recurse: True if this repository will get bisected. 67 # recurse: True if this repository will get bisected.
67 # depends: A list of other repositories that are actually part of the same 68 # depends: A list of other repositories that are actually part of the same
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 'svn': 'http://skia.googlecode.com/svn/trunk/gyp', 144 'svn': 'http://skia.googlecode.com/svn/trunk/gyp',
144 'depends': None, 145 'depends': None,
145 'from': ['chromium'], 146 'from': ['chromium'],
146 'viewvc': 'https://code.google.com/p/skia/source/detail?r=', 147 'viewvc': 'https://code.google.com/p/skia/source/detail?r=',
147 'deps_var': 'None' 148 'deps_var': 'None'
148 } 149 }
149 } 150 }
150 151
151 DEPOT_NAMES = DEPOT_DEPS_NAME.keys() 152 DEPOT_NAMES = DEPOT_DEPS_NAME.keys()
152 153
154 # The script is in chromium/src/tools/auto_bisect. Throughout this script,
155 # we use paths to other things in the chromium/src repository.
156
153 CROS_CHROMEOS_PATTERN = 'chromeos-base/chromeos-chrome' 157 CROS_CHROMEOS_PATTERN = 'chromeos-base/chromeos-chrome'
154 158
155 # Possible return values from BisectPerformanceMetrics.RunTest. 159 # Possible return values from BisectPerformanceMetrics.RunTest.
156 BUILD_RESULT_SUCCEED = 0 160 BUILD_RESULT_SUCCEED = 0
157 BUILD_RESULT_FAIL = 1 161 BUILD_RESULT_FAIL = 1
158 BUILD_RESULT_SKIPPED = 2 162 BUILD_RESULT_SKIPPED = 2
159 163
160 # Maximum time in seconds to wait after posting build request to the try server. 164 # Maximum time in seconds to wait after posting build request to the try server.
161 # TODO: Change these values based on the actual time taken by buildbots on 165 # TODO: Change these values based on the actual time taken by buildbots on
162 # the try server. 166 # the try server.
(...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 revisions to narrow down where performance regressions may have occurred. 910 revisions to narrow down where performance regressions may have occurred.
907 911
908 The main entry-point is the Run method. 912 The main entry-point is the Run method.
909 """ 913 """
910 914
911 def __init__(self, source_control, opts): 915 def __init__(self, source_control, opts):
912 super(BisectPerformanceMetrics, self).__init__() 916 super(BisectPerformanceMetrics, self).__init__()
913 917
914 self.opts = opts 918 self.opts = opts
915 self.source_control = source_control 919 self.source_control = source_control
920
921 # The src directory here is NOT the src/ directory for the repository
922 # where the bisect script is running from. Instead, it's the src/ directory
923 # inside the bisect/ directory which is created before running.
916 self.src_cwd = os.getcwd() 924 self.src_cwd = os.getcwd()
917 self.cros_cwd = os.path.join(os.getcwd(), '..', 'cros') 925 self.cros_cwd = os.path.join(os.getcwd(), '..', 'cros')
918 self.depot_cwd = {} 926 self.depot_cwd = {}
919 self.cleanup_commands = [] 927 self.cleanup_commands = []
920 self.warnings = [] 928 self.warnings = []
921 self.builder = builder.Builder.FromOpts(opts) 929 self.builder = builder.Builder.FromOpts(opts)
922 930
923 for d in DEPOT_NAMES: 931 for depot in DEPOT_NAMES:
924 # The working directory of each depot is just the path to the depot, but 932 # The working directory of each depot is just the path to the depot, but
925 # since we're already in 'src', we can skip that part. 933 # since we're already in 'src', we can skip that part.
926 934 self.depot_cwd[depot] = os.path.join(
927 self.depot_cwd[d] = os.path.join( 935 self.src_cwd, DEPOT_DEPS_NAME[depot]['src'][4:])
928 self.src_cwd, DEPOT_DEPS_NAME[d]['src'][4:])
929 936
930 def PerformCleanup(self): 937 def PerformCleanup(self):
931 """Performs cleanup when script is finished.""" 938 """Performs cleanup when script is finished."""
932 os.chdir(self.src_cwd) 939 os.chdir(self.src_cwd)
933 for c in self.cleanup_commands: 940 for c in self.cleanup_commands:
934 if c[0] == 'mv': 941 if c[0] == 'mv':
935 shutil.move(c[1], c[2]) 942 shutil.move(c[1], c[2])
936 else: 943 else:
937 assert False, 'Invalid cleanup command.' 944 assert False, 'Invalid cleanup command.'
938 945
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1083 results = {} 1090 results = {}
1084 for depot_name, depot_data in DEPOT_DEPS_NAME.iteritems(): 1091 for depot_name, depot_data in DEPOT_DEPS_NAME.iteritems():
1085 if (depot_data.get('platform') and 1092 if (depot_data.get('platform') and
1086 depot_data.get('platform') != os.name): 1093 depot_data.get('platform') != os.name):
1087 continue 1094 continue
1088 1095
1089 if (depot_data.get('recurse') and depot in depot_data.get('from')): 1096 if (depot_data.get('recurse') and depot in depot_data.get('from')):
1090 depot_data_src = depot_data.get('src') or depot_data.get('src_old') 1097 depot_data_src = depot_data.get('src') or depot_data.get('src_old')
1091 src_dir = deps_data.get(depot_data_src) 1098 src_dir = deps_data.get(depot_data_src)
1092 if src_dir: 1099 if src_dir:
1093 self.depot_cwd[depot_name] = os.path.join(self.src_cwd, 1100 self.depot_cwd[depot_name] = os.path.join(
1094 depot_data_src[4:]) 1101 self.src_cwd, depot_data_src[4:])
1095 re_results = rxp.search(src_dir) 1102 re_results = rxp.search(src_dir)
1096 if re_results: 1103 if re_results:
1097 results[depot_name] = re_results.group('revision') 1104 results[depot_name] = re_results.group('revision')
1098 else: 1105 else:
1099 warning_text = ('Could not parse revision for %s while bisecting ' 1106 warning_text = ('Could not parse revision for %s while bisecting '
1100 '%s' % (depot_name, depot)) 1107 '%s' % (depot_name, depot))
1101 if not warning_text in self.warnings: 1108 if not warning_text in self.warnings:
1102 self.warnings.append(warning_text) 1109 self.warnings.append(warning_text)
1103 else: 1110 else:
1104 results[depot_name] = None 1111 results[depot_name] = None
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
1560 def _IsBisectModeUsingMetric(self): 1567 def _IsBisectModeUsingMetric(self):
1561 return self.opts.bisect_mode in [BISECT_MODE_MEAN, BISECT_MODE_STD_DEV] 1568 return self.opts.bisect_mode in [BISECT_MODE_MEAN, BISECT_MODE_STD_DEV]
1562 1569
1563 def _IsBisectModeReturnCode(self): 1570 def _IsBisectModeReturnCode(self):
1564 return self.opts.bisect_mode in [BISECT_MODE_RETURN_CODE] 1571 return self.opts.bisect_mode in [BISECT_MODE_RETURN_CODE]
1565 1572
1566 def _IsBisectModeStandardDeviation(self): 1573 def _IsBisectModeStandardDeviation(self):
1567 return self.opts.bisect_mode in [BISECT_MODE_STD_DEV] 1574 return self.opts.bisect_mode in [BISECT_MODE_STD_DEV]
1568 1575
1569 def GetCompatibleCommand(self, command_to_run, revision, depot): 1576 def GetCompatibleCommand(self, command_to_run, revision, depot):
1570 # Prior to crrev.com/274857 *only* android-chromium-testshell 1577 """Return a possibly modified test command depending on the revision.
1571 # Then until crrev.com/276628 *both* (android-chromium-testshell and 1578
1572 # android-chrome-shell) work. After that rev 276628 *only* 1579 Prior to crrev.com/274857 *only* android-chromium-testshell
1573 # android-chrome-shell works. bisect-perf-regression.py script should 1580 Then until crrev.com/276628 *both* (android-chromium-testshell and
1574 # handle these cases and set appropriate browser type based on revision. 1581 android-chrome-shell) work. After that rev 276628 *only*
1582 android-chrome-shell works. The bisect_perf_regression.py script should
1583 handle these cases and set appropriate browser type based on revision.
1584 """
1575 if self.opts.target_platform in ['android']: 1585 if self.opts.target_platform in ['android']:
1576 # When its a third_party depot, get the chromium revision. 1586 # When its a third_party depot, get the chromium revision.
1577 if depot != 'chromium': 1587 if depot != 'chromium':
1578 revision = bisect_utils.CheckRunGit( 1588 revision = bisect_utils.CheckRunGit(
1579 ['rev-parse', 'HEAD'], cwd=self.src_cwd).strip() 1589 ['rev-parse', 'HEAD'], cwd=self.src_cwd).strip()
1580 commit_position = self.source_control.GetCommitPosition(revision, 1590 commit_position = self.source_control.GetCommitPosition(revision,
1581 cwd=self.src_cwd) 1591 cwd=self.src_cwd)
1582 if not commit_position: 1592 if not commit_position:
1583 return command_to_run 1593 return command_to_run
1584 cmd_re = re.compile('--browser=(?P<browser_type>\S+)') 1594 cmd_re = re.compile('--browser=(?P<browser_type>\S+)')
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after
2276 2286
2277 Args: 2287 Args:
2278 good_revision: Known good revision. 2288 good_revision: Known good revision.
2279 bad_revision: Known bad revision. 2289 bad_revision: Known bad revision.
2280 2290
2281 Returns: 2291 Returns:
2282 A dictionary indicating the result. If revision is not bisectable, 2292 A dictionary indicating the result. If revision is not bisectable,
2283 this will contain the field "error", otherwise None. 2293 this will contain the field "error", otherwise None.
2284 """ 2294 """
2285 if self.opts.target_platform == 'android': 2295 if self.opts.target_platform == 'android':
2286 revision_to_check = self.source_control.GetCommitPosition(good_revision) 2296 good_revision = self.source_control.GetCommitPosition(good_revision)
2287 if (bisect_utils.IsStringInt(good_revision) 2297 if (bisect_utils.IsStringInt(good_revision)
2288 and good_revision < 265549): 2298 and good_revision < 265549):
2289 return {'error': ( 2299 return {'error': (
2290 'Bisect cannot continue for the given revision range.\n' 2300 'Bisect cannot continue for the given revision range.\n'
2291 'It is impossible to bisect Android regressions ' 2301 'It is impossible to bisect Android regressions '
2292 'prior to r265549, which allows the bisect bot to ' 2302 'prior to r265549, which allows the bisect bot to '
2293 'rely on Telemetry to do apk installation of the most recently ' 2303 'rely on Telemetry to do apk installation of the most recently '
2294 'built local ChromeShell(refer to crbug.com/385324).\n' 2304 'built local ChromeShell(refer to crbug.com/385324).\n'
2295 'Please try bisecting revisions greater than or equal to r265549.')} 2305 'Please try bisecting revisions greater than or equal to r265549.')}
2296 2306
(...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after
3397 # bugs. If you change this, please update the perf dashboard as well. 3407 # bugs. If you change this, please update the perf dashboard as well.
3398 bisect_utils.OutputAnnotationStepStart('Results') 3408 bisect_utils.OutputAnnotationStepStart('Results')
3399 print 'Error: %s' % e.message 3409 print 'Error: %s' % e.message
3400 if opts.output_buildbot_annotations: 3410 if opts.output_buildbot_annotations:
3401 bisect_utils.OutputAnnotationStepClosed() 3411 bisect_utils.OutputAnnotationStepClosed()
3402 return 1 3412 return 1
3403 3413
3404 3414
3405 if __name__ == '__main__': 3415 if __name__ == '__main__':
3406 sys.exit(main()) 3416 sys.exit(main())
OLDNEW
« no previous file with comments | « tools/auto_bisect/README ('k') | tools/auto_bisect/bisect_perf_regression_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698