Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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(os.path.dirname(__file__), 'telemetry')) |
| 51 | 51 |
| 52 from auto_bisect import bisect_utils | 52 import bisect_utils |
| 53 from auto_bisect import builder | 53 import builder |
| 54 from auto_bisect import math_utils | 54 import math_utils |
| 55 from auto_bisect import request_build | 55 import request_build |
| 56 from auto_bisect import source_control as source_control_module | 56 import source_control as source_control_module |
| 57 from auto_bisect import ttest | 57 import ttest |
| 58 from telemetry.util import cloud_storage | 58 from telemetry.util import cloud_storage |
| 59 | 59 |
| 60 # Below is the map of "depot" names to information about each depot. Each depot | 60 # 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 | 61 # is a repository, and in the process of bisecting, revision ranges in these |
| 62 # repositories may also be bisected. | 62 # repositories may also be bisected. |
| 63 # | 63 # |
| 64 # Each depot information dictionary may contain: | 64 # Each depot information dictionary may contain: |
| 65 # src: Path to the working directory. | 65 # src: Path to the working directory. |
| 66 # recurse: True if this repository will get bisected. | 66 # recurse: True if this repository will get bisected. |
| 67 # depends: A list of other repositories that are actually part of the same | 67 # 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 Loading... | |
| 143 'svn': 'http://skia.googlecode.com/svn/trunk/gyp', | 143 'svn': 'http://skia.googlecode.com/svn/trunk/gyp', |
| 144 'depends': None, | 144 'depends': None, |
| 145 'from': ['chromium'], | 145 'from': ['chromium'], |
| 146 'viewvc': 'https://code.google.com/p/skia/source/detail?r=', | 146 'viewvc': 'https://code.google.com/p/skia/source/detail?r=', |
| 147 'deps_var': 'None' | 147 'deps_var': 'None' |
| 148 } | 148 } |
| 149 } | 149 } |
| 150 | 150 |
| 151 DEPOT_NAMES = DEPOT_DEPS_NAME.keys() | 151 DEPOT_NAMES = DEPOT_DEPS_NAME.keys() |
| 152 | 152 |
| 153 # The script is in chromium/src/tools/auto_bisect. Throughout this script, | |
| 154 # we use paths to other things in the chromium/src repository. | |
| 155 SRC_DIR = os.path.join(os.path.dirname(__file__), | |
| 156 os.path.pardir, | |
| 157 os.path.pardir) | |
| 158 | |
| 153 CROS_CHROMEOS_PATTERN = 'chromeos-base/chromeos-chrome' | 159 CROS_CHROMEOS_PATTERN = 'chromeos-base/chromeos-chrome' |
| 154 | 160 |
| 155 # Possible return values from BisectPerformanceMetrics.RunTest. | 161 # Possible return values from BisectPerformanceMetrics.RunTest. |
| 156 BUILD_RESULT_SUCCEED = 0 | 162 BUILD_RESULT_SUCCEED = 0 |
| 157 BUILD_RESULT_FAIL = 1 | 163 BUILD_RESULT_FAIL = 1 |
| 158 BUILD_RESULT_SKIPPED = 2 | 164 BUILD_RESULT_SKIPPED = 2 |
| 159 | 165 |
| 160 # Maximum time in seconds to wait after posting build request to the try server. | 166 # 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 | 167 # TODO: Change these values based on the actual time taken by buildbots on |
| 162 # the try server. | 168 # the try server. |
| (...skipping 744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 907 revisions to narrow down where performance regressions may have occurred. | 913 revisions to narrow down where performance regressions may have occurred. |
| 908 | 914 |
| 909 The main entry-point is the Run method. | 915 The main entry-point is the Run method. |
| 910 """ | 916 """ |
| 911 | 917 |
| 912 def __init__(self, source_control, opts): | 918 def __init__(self, source_control, opts): |
| 913 super(BisectPerformanceMetrics, self).__init__() | 919 super(BisectPerformanceMetrics, self).__init__() |
| 914 | 920 |
| 915 self.opts = opts | 921 self.opts = opts |
| 916 self.source_control = source_control | 922 self.source_control = source_control |
| 917 self.src_cwd = os.getcwd() | 923 self.cros_cwd = os.path.join(SRC_DIR, 'tools', 'cros') |
| 918 self.cros_cwd = os.path.join(os.getcwd(), '..', 'cros') | |
| 919 self.depot_cwd = {} | 924 self.depot_cwd = {} |
| 920 self.cleanup_commands = [] | 925 self.cleanup_commands = [] |
| 921 self.warnings = [] | 926 self.warnings = [] |
| 922 self.builder = builder.Builder.FromOpts(opts) | 927 self.builder = builder.Builder.FromOpts(opts) |
| 923 | 928 |
| 924 for d in DEPOT_NAMES: | 929 for d in DEPOT_NAMES: |
| 925 # The working directory of each depot is just the path to the depot, but | 930 # The working directory of each depot is just the path to the depot, but |
| 926 # since we're already in 'src', we can skip that part. | 931 # since we're already in 'src', we can skip that part. |
| 927 | 932 |
| 928 self.depot_cwd[d] = os.path.join( | 933 self.depot_cwd[d] = os.path.join( |
| 929 self.src_cwd, DEPOT_DEPS_NAME[d]['src'][4:]) | 934 SRC_DIR, DEPOT_DEPS_NAME[d]['src'][4:]) |
| 930 | 935 |
| 931 def PerformCleanup(self): | 936 def PerformCleanup(self): |
| 932 """Performs cleanup when script is finished.""" | 937 """Performs cleanup when script is finished.""" |
| 933 os.chdir(self.src_cwd) | 938 os.chdir(SRC_DIR) |
| 934 for c in self.cleanup_commands: | 939 for c in self.cleanup_commands: |
| 935 if c[0] == 'mv': | 940 if c[0] == 'mv': |
| 936 shutil.move(c[1], c[2]) | 941 shutil.move(c[1], c[2]) |
| 937 else: | 942 else: |
| 938 assert False, 'Invalid cleanup command.' | 943 assert False, 'Invalid cleanup command.' |
| 939 | 944 |
| 940 def GetRevisionList(self, depot, bad_revision, good_revision): | 945 def GetRevisionList(self, depot, bad_revision, good_revision): |
| 941 """Retrieves a list of all the commits between the bad revision and | 946 """Retrieves a list of all the commits between the bad revision and |
| 942 last known good revision.""" | 947 last known good revision.""" |
| 943 | 948 |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1084 results = {} | 1089 results = {} |
| 1085 for depot_name, depot_data in DEPOT_DEPS_NAME.iteritems(): | 1090 for depot_name, depot_data in DEPOT_DEPS_NAME.iteritems(): |
| 1086 if (depot_data.get('platform') and | 1091 if (depot_data.get('platform') and |
| 1087 depot_data.get('platform') != os.name): | 1092 depot_data.get('platform') != os.name): |
| 1088 continue | 1093 continue |
| 1089 | 1094 |
| 1090 if (depot_data.get('recurse') and depot in depot_data.get('from')): | 1095 if (depot_data.get('recurse') and depot in depot_data.get('from')): |
| 1091 depot_data_src = depot_data.get('src') or depot_data.get('src_old') | 1096 depot_data_src = depot_data.get('src') or depot_data.get('src_old') |
| 1092 src_dir = deps_data.get(depot_data_src) | 1097 src_dir = deps_data.get(depot_data_src) |
| 1093 if src_dir: | 1098 if src_dir: |
| 1094 self.depot_cwd[depot_name] = os.path.join(self.src_cwd, | 1099 self.depot_cwd[depot_name] = os.path.join(SRC_DIR, |
| 1095 depot_data_src[4:]) | 1100 depot_data_src[4:]) |
| 1096 re_results = rxp.search(src_dir) | 1101 re_results = rxp.search(src_dir) |
| 1097 if re_results: | 1102 if re_results: |
| 1098 results[depot_name] = re_results.group('revision') | 1103 results[depot_name] = re_results.group('revision') |
| 1099 else: | 1104 else: |
| 1100 warning_text = ('Could not parse revision for %s while bisecting ' | 1105 warning_text = ('Could not parse revision for %s while bisecting ' |
| 1101 '%s' % (depot_name, depot)) | 1106 '%s' % (depot_name, depot)) |
| 1102 if not warning_text in self.warnings: | 1107 if not warning_text in self.warnings: |
| 1103 self.warnings.append(warning_text) | 1108 self.warnings.append(warning_text) |
| 1104 else: | 1109 else: |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1191 """Backs up or restores build output directory based on restore argument. | 1196 """Backs up or restores build output directory based on restore argument. |
| 1192 | 1197 |
| 1193 Args: | 1198 Args: |
| 1194 restore: Indicates whether to restore or backup. Default is False(Backup) | 1199 restore: Indicates whether to restore or backup. Default is False(Backup) |
| 1195 build_type: Target build type ('Release', 'Debug', 'Release_x64' etc.) | 1200 build_type: Target build type ('Release', 'Debug', 'Release_x64' etc.) |
| 1196 | 1201 |
| 1197 Returns: | 1202 Returns: |
| 1198 Path to backup or restored location as string. otherwise None if it fails. | 1203 Path to backup or restored location as string. otherwise None if it fails. |
| 1199 """ | 1204 """ |
| 1200 build_dir = os.path.abspath( | 1205 build_dir = os.path.abspath( |
| 1201 builder.GetBuildOutputDirectory(self.opts, self.src_cwd)) | 1206 builder.GetBuildOutputDirectory(self.opts, SRC_DIR)) |
| 1202 source_dir = os.path.join(build_dir, build_type) | 1207 source_dir = os.path.join(build_dir, build_type) |
| 1203 destination_dir = os.path.join(build_dir, '%s.bak' % build_type) | 1208 destination_dir = os.path.join(build_dir, '%s.bak' % build_type) |
| 1204 if restore: | 1209 if restore: |
| 1205 source_dir, destination_dir = destination_dir, source_dir | 1210 source_dir, destination_dir = destination_dir, source_dir |
| 1206 if os.path.exists(source_dir): | 1211 if os.path.exists(source_dir): |
| 1207 RmTreeAndMkDir(destination_dir, skip_makedir=True) | 1212 RmTreeAndMkDir(destination_dir, skip_makedir=True) |
| 1208 shutil.move(source_dir, destination_dir) | 1213 shutil.move(source_dir, destination_dir) |
| 1209 return destination_dir | 1214 return destination_dir |
| 1210 return None | 1215 return None |
| 1211 | 1216 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1255 if patch: | 1260 if patch: |
| 1256 # Get the SHA of the DEPS changes patch. | 1261 # Get the SHA of the DEPS changes patch. |
| 1257 patch_sha = GetSHA1HexDigest(patch) | 1262 patch_sha = GetSHA1HexDigest(patch) |
| 1258 | 1263 |
| 1259 # Update the DEPS changes patch with a patch to create a new file named | 1264 # Update the DEPS changes patch with a patch to create a new file named |
| 1260 # 'DEPS.sha' and add patch_sha evaluated above to it. | 1265 # 'DEPS.sha' and add patch_sha evaluated above to it. |
| 1261 patch = '%s\n%s' % (patch, DEPS_SHA_PATCH % {'deps_sha': patch_sha}) | 1266 patch = '%s\n%s' % (patch, DEPS_SHA_PATCH % {'deps_sha': patch_sha}) |
| 1262 | 1267 |
| 1263 # Get Build output directory | 1268 # Get Build output directory |
| 1264 abs_build_dir = os.path.abspath( | 1269 abs_build_dir = os.path.abspath( |
| 1265 builder.GetBuildOutputDirectory(self.opts, self.src_cwd)) | 1270 builder.GetBuildOutputDirectory(self.opts, SRC_DIR)) |
| 1266 | 1271 |
| 1267 fetch_build_func = lambda: self.GetBuildArchiveForRevision( | 1272 fetch_build_func = lambda: self.GetBuildArchiveForRevision( |
| 1268 revision, self.opts.gs_bucket, self.opts.target_arch, | 1273 revision, self.opts.gs_bucket, self.opts.target_arch, |
| 1269 patch_sha, abs_build_dir) | 1274 patch_sha, abs_build_dir) |
| 1270 | 1275 |
| 1271 # Downloaded archive file path, downloads build archive for given revision. | 1276 # Downloaded archive file path, downloads build archive for given revision. |
| 1272 downloaded_file = fetch_build_func() | 1277 downloaded_file = fetch_build_func() |
| 1273 | 1278 |
| 1274 # When build archive doesn't exists, post a build request to tryserver | 1279 # When build archive doesn't exists, post a build request to tryserver |
| 1275 # and wait for the build to be produced. | 1280 # and wait for the build to be produced. |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1478 def CreateDEPSPatch(self, depot, revision): | 1483 def CreateDEPSPatch(self, depot, revision): |
| 1479 """Modifies DEPS and returns diff as text. | 1484 """Modifies DEPS and returns diff as text. |
| 1480 | 1485 |
| 1481 Args: | 1486 Args: |
| 1482 depot: Current depot being bisected. | 1487 depot: Current depot being bisected. |
| 1483 revision: A git hash revision of the dependency repository. | 1488 revision: A git hash revision of the dependency repository. |
| 1484 | 1489 |
| 1485 Returns: | 1490 Returns: |
| 1486 A tuple with git hash of chromium revision and DEPS patch text. | 1491 A tuple with git hash of chromium revision and DEPS patch text. |
| 1487 """ | 1492 """ |
| 1488 deps_file_path = os.path.join(self.src_cwd, bisect_utils.FILE_DEPS) | 1493 deps_file_path = os.path.join(SRC_DIR, bisect_utils.FILE_DEPS) |
| 1489 if not os.path.exists(deps_file_path): | 1494 if not os.path.exists(deps_file_path): |
| 1490 raise RuntimeError('DEPS file does not exists.[%s]' % deps_file_path) | 1495 raise RuntimeError('DEPS file does not exists.[%s]' % deps_file_path) |
| 1491 # Get current chromium revision (git hash). | 1496 # Get current chromium revision (git hash). |
| 1492 cmd = ['rev-parse', 'HEAD'] | 1497 cmd = ['rev-parse', 'HEAD'] |
| 1493 chromium_sha = bisect_utils.CheckRunGit(cmd).strip() | 1498 chromium_sha = bisect_utils.CheckRunGit(cmd).strip() |
| 1494 if not chromium_sha: | 1499 if not chromium_sha: |
| 1495 raise RuntimeError('Failed to determine Chromium revision for %s' % | 1500 raise RuntimeError('Failed to determine Chromium revision for %s' % |
| 1496 revision) | 1501 revision) |
| 1497 if ('chromium' in DEPOT_DEPS_NAME[depot]['from'] or | 1502 if ('chromium' in DEPOT_DEPS_NAME[depot]['from'] or |
| 1498 'v8' in DEPOT_DEPS_NAME[depot]['from']): | 1503 'v8' in DEPOT_DEPS_NAME[depot]['from']): |
| 1499 # Checkout DEPS file for the current chromium revision. | 1504 # Checkout DEPS file for the current chromium revision. |
| 1500 if self.source_control.CheckoutFileAtRevision( | 1505 if self.source_control.CheckoutFileAtRevision( |
| 1501 bisect_utils.FILE_DEPS, chromium_sha, cwd=self.src_cwd): | 1506 bisect_utils.FILE_DEPS, chromium_sha, cwd=SRC_DIR): |
| 1502 if self.UpdateDeps(revision, depot, deps_file_path): | 1507 if self.UpdateDeps(revision, depot, deps_file_path): |
| 1503 diff_command = [ | 1508 diff_command = [ |
| 1504 'diff', | 1509 'diff', |
| 1505 '--src-prefix=src/', | 1510 '--src-prefix=src/', |
| 1506 '--dst-prefix=src/', | 1511 '--dst-prefix=src/', |
| 1507 '--no-ext-diff', | 1512 '--no-ext-diff', |
| 1508 bisect_utils.FILE_DEPS, | 1513 bisect_utils.FILE_DEPS, |
| 1509 ] | 1514 ] |
| 1510 diff_text = bisect_utils.CheckRunGit(diff_command, cwd=self.src_cwd) | 1515 diff_text = bisect_utils.CheckRunGit(diff_command, cwd=SRC_DIR) |
| 1511 return (chromium_sha, ChangeBackslashToSlashInPatch(diff_text)) | 1516 return (chromium_sha, ChangeBackslashToSlashInPatch(diff_text)) |
| 1512 else: | 1517 else: |
| 1513 raise RuntimeError( | 1518 raise RuntimeError( |
| 1514 'Failed to update DEPS file for chromium: [%s]' % chromium_sha) | 1519 'Failed to update DEPS file for chromium: [%s]' % chromium_sha) |
| 1515 else: | 1520 else: |
| 1516 raise RuntimeError( | 1521 raise RuntimeError( |
| 1517 'DEPS checkout Failed for chromium revision : [%s]' % chromium_sha) | 1522 'DEPS checkout Failed for chromium revision : [%s]' % chromium_sha) |
| 1518 return (None, None) | 1523 return (None, None) |
| 1519 | 1524 |
| 1520 def BuildCurrentRevision(self, depot, revision=None): | 1525 def BuildCurrentRevision(self, depot, revision=None): |
| 1521 """Builds chrome and performance_ui_tests on the current revision. | 1526 """Builds chrome and performance_ui_tests on the current revision. |
| 1522 | 1527 |
| 1523 Returns: | 1528 Returns: |
| 1524 True if the build was successful. | 1529 True if the build was successful. |
| 1525 """ | 1530 """ |
| 1526 if self.opts.debug_ignore_build: | 1531 if self.opts.debug_ignore_build: |
| 1527 return True | 1532 return True |
| 1528 | 1533 |
| 1529 build_success = False | 1534 build_success = False |
| 1530 cwd = os.getcwd() | 1535 cwd = os.getcwd() |
| 1531 os.chdir(self.src_cwd) | 1536 os.chdir(SRC_DIR) |
| 1532 # Fetch build archive for the given revision from the cloud storage when | 1537 # Fetch build archive for the given revision from the cloud storage when |
| 1533 # the storage bucket is passed. | 1538 # the storage bucket is passed. |
| 1534 if self.IsDownloadable(depot) and revision: | 1539 if self.IsDownloadable(depot) and revision: |
| 1535 deps_patch = None | 1540 deps_patch = None |
| 1536 if depot != 'chromium': | 1541 if depot != 'chromium': |
| 1537 # Create a DEPS patch with new revision for dependency repository. | 1542 # Create a DEPS patch with new revision for dependency repository. |
| 1538 revision, deps_patch = self.CreateDEPSPatch(depot, revision) | 1543 revision, deps_patch = self.CreateDEPSPatch(depot, revision) |
| 1539 if self.DownloadCurrentBuild(revision, patch=deps_patch): | 1544 if self.DownloadCurrentBuild(revision, patch=deps_patch): |
| 1540 if deps_patch: | 1545 if deps_patch: |
| 1541 # Reverts the changes to DEPS file. | 1546 # Reverts the changes to DEPS file. |
| 1542 self.source_control.CheckoutFileAtRevision( | 1547 self.source_control.CheckoutFileAtRevision( |
| 1543 bisect_utils.FILE_DEPS, revision, cwd=self.src_cwd) | 1548 bisect_utils.FILE_DEPS, revision, cwd=SRC_DIR) |
| 1544 build_success = True | 1549 build_success = True |
| 1545 else: | 1550 else: |
| 1546 # These codes are executed when bisect bots builds binaries locally. | 1551 # These codes are executed when bisect bots builds binaries locally. |
| 1547 build_success = self.builder.Build(depot, self.opts) | 1552 build_success = self.builder.Build(depot, self.opts) |
| 1548 os.chdir(cwd) | 1553 os.chdir(cwd) |
| 1549 return build_success | 1554 return build_success |
| 1550 | 1555 |
| 1551 def RunGClientHooks(self): | 1556 def RunGClientHooks(self): |
| 1552 """Runs gclient with runhooks command. | 1557 """Runs gclient with runhooks command. |
| 1553 | 1558 |
| 1554 Returns: | 1559 Returns: |
| 1555 True if gclient reports no errors. | 1560 True if gclient reports no errors. |
| 1556 """ | 1561 """ |
| 1557 if self.opts.debug_ignore_build: | 1562 if self.opts.debug_ignore_build: |
| 1558 return True | 1563 return True |
| 1559 return not bisect_utils.RunGClient(['runhooks'], cwd=self.src_cwd) | 1564 return not bisect_utils.RunGClient(['runhooks'], cwd=SRC_DIR) |
| 1560 | 1565 |
| 1561 def _IsBisectModeUsingMetric(self): | 1566 def _IsBisectModeUsingMetric(self): |
| 1562 return self.opts.bisect_mode in [BISECT_MODE_MEAN, BISECT_MODE_STD_DEV] | 1567 return self.opts.bisect_mode in [BISECT_MODE_MEAN, BISECT_MODE_STD_DEV] |
| 1563 | 1568 |
| 1564 def _IsBisectModeReturnCode(self): | 1569 def _IsBisectModeReturnCode(self): |
| 1565 return self.opts.bisect_mode in [BISECT_MODE_RETURN_CODE] | 1570 return self.opts.bisect_mode in [BISECT_MODE_RETURN_CODE] |
| 1566 | 1571 |
| 1567 def _IsBisectModeStandardDeviation(self): | 1572 def _IsBisectModeStandardDeviation(self): |
| 1568 return self.opts.bisect_mode in [BISECT_MODE_STD_DEV] | 1573 return self.opts.bisect_mode in [BISECT_MODE_STD_DEV] |
| 1569 | 1574 |
| 1570 def GetCompatibleCommand(self, command_to_run, revision, depot): | 1575 def GetCompatibleCommand(self, command_to_run, revision, depot): |
| 1571 # Prior to crrev.com/274857 *only* android-chromium-testshell | 1576 # Prior to crrev.com/274857 *only* android-chromium-testshell |
| 1572 # Then until crrev.com/276628 *both* (android-chromium-testshell and | 1577 # Then until crrev.com/276628 *both* (android-chromium-testshell and |
| 1573 # android-chrome-shell) work. After that rev 276628 *only* | 1578 # android-chrome-shell) work. After that rev 276628 *only* |
| 1574 # android-chrome-shell works. bisect-perf-regression.py script should | 1579 # android-chrome-shell works. bisect-perf-regression.py script should |
| 1575 # handle these cases and set appropriate browser type based on revision. | 1580 # handle these cases and set appropriate browser type based on revision. |
| 1576 if self.opts.target_platform in ['android']: | 1581 if self.opts.target_platform in ['android']: |
| 1577 # When its a third_party depot, get the chromium revision. | 1582 # When its a third_party depot, get the chromium revision. |
| 1578 if depot != 'chromium': | 1583 if depot != 'chromium': |
| 1579 revision = bisect_utils.CheckRunGit( | 1584 revision = bisect_utils.CheckRunGit( |
| 1580 ['rev-parse', 'HEAD'], cwd=self.src_cwd).strip() | 1585 ['rev-parse', 'HEAD'], cwd=SRC_DIR).strip() |
| 1581 commit_position = self.source_control.GetCommitPosition(revision, | 1586 commit_position = self.source_control.GetCommitPosition(revision, |
| 1582 cwd=self.src_cwd) | 1587 cwd=SRC_DIR) |
| 1583 if not commit_position: | 1588 if not commit_position: |
| 1584 return command_to_run | 1589 return command_to_run |
| 1585 cmd_re = re.compile('--browser=(?P<browser_type>\S+)') | 1590 cmd_re = re.compile('--browser=(?P<browser_type>\S+)') |
| 1586 matches = cmd_re.search(command_to_run) | 1591 matches = cmd_re.search(command_to_run) |
| 1587 if bisect_utils.IsStringInt(commit_position) and matches: | 1592 if bisect_utils.IsStringInt(commit_position) and matches: |
| 1588 cmd_browser = matches.group('browser_type') | 1593 cmd_browser = matches.group('browser_type') |
| 1589 if commit_position <= 274857 and cmd_browser == 'android-chrome-shell': | 1594 if commit_position <= 274857 and cmd_browser == 'android-chrome-shell': |
| 1590 return command_to_run.replace(cmd_browser, | 1595 return command_to_run.replace(cmd_browser, |
| 1591 'android-chromium-testshell') | 1596 'android-chromium-testshell') |
| 1592 elif (commit_position >= 276628 and | 1597 elif (commit_position >= 276628 and |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1653 current_args = copy.copy(args) | 1658 current_args = copy.copy(args) |
| 1654 if is_telemetry: | 1659 if is_telemetry: |
| 1655 if i == 0 and reset_on_first_run: | 1660 if i == 0 and reset_on_first_run: |
| 1656 current_args.append('--reset-results') | 1661 current_args.append('--reset-results') |
| 1657 elif i == self.opts.repeat_test_count - 1 and upload_on_last_run: | 1662 elif i == self.opts.repeat_test_count - 1 and upload_on_last_run: |
| 1658 current_args.append('--upload-results') | 1663 current_args.append('--upload-results') |
| 1659 if results_label: | 1664 if results_label: |
| 1660 current_args.append('--results-label=%s' % results_label) | 1665 current_args.append('--results-label=%s' % results_label) |
| 1661 try: | 1666 try: |
| 1662 output, return_code = bisect_utils.RunProcessAndRetrieveOutput( | 1667 output, return_code = bisect_utils.RunProcessAndRetrieveOutput( |
| 1663 current_args, cwd=self.src_cwd) | 1668 current_args, cwd=SRC_DIR) |
| 1664 except OSError, e: | 1669 except OSError, e: |
| 1665 if e.errno == errno.ENOENT: | 1670 if e.errno == errno.ENOENT: |
| 1666 err_text = ('Something went wrong running the performance test. ' | 1671 err_text = ('Something went wrong running the performance test. ' |
| 1667 'Please review the command line:\n\n') | 1672 'Please review the command line:\n\n') |
| 1668 if 'src/' in ' '.join(args): | 1673 if 'src/' in ' '.join(args): |
| 1669 err_text += ('Check that you haven\'t accidentally specified a ' | 1674 err_text += ('Check that you haven\'t accidentally specified a ' |
| 1670 'path with src/ in the command.\n\n') | 1675 'path with src/ in the command.\n\n') |
| 1671 err_text += ' '.join(args) | 1676 err_text += ' '.join(args) |
| 1672 err_text += '\n' | 1677 err_text += '\n' |
| 1673 | 1678 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1780 num_resolved = len(revisions_to_sync) | 1785 num_resolved = len(revisions_to_sync) |
| 1781 num_needed = len(DEPOT_DEPS_NAME[depot]['depends']) | 1786 num_needed = len(DEPOT_DEPS_NAME[depot]['depends']) |
| 1782 | 1787 |
| 1783 self.ChangeToDepotWorkingDirectory(depot) | 1788 self.ChangeToDepotWorkingDirectory(depot) |
| 1784 | 1789 |
| 1785 if not ((num_resolved - 1) == num_needed): | 1790 if not ((num_resolved - 1) == num_needed): |
| 1786 return None | 1791 return None |
| 1787 | 1792 |
| 1788 return revisions_to_sync | 1793 return revisions_to_sync |
| 1789 | 1794 |
| 1790 def PerformPreBuildCleanup(self): | 1795 @staticmethod |
| 1796 def PerformPreBuildCleanup(): | |
| 1791 """Performs cleanup between runs.""" | 1797 """Performs cleanup between runs.""" |
| 1792 print 'Cleaning up between runs.' | 1798 print 'Cleaning up between runs.' |
| 1793 print | 1799 print |
| 1794 | 1800 |
| 1795 # Leaving these .pyc files around between runs may disrupt some perf tests. | 1801 # Leaving these .pyc files around between runs may disrupt some perf tests. |
| 1796 for (path, _, files) in os.walk(self.src_cwd): | 1802 for (path, _, files) in os.walk(SRC_DIR): |
| 1797 for cur_file in files: | 1803 for cur_file in files: |
| 1798 if cur_file.endswith('.pyc'): | 1804 if cur_file.endswith('.pyc'): |
| 1799 path_to_file = os.path.join(path, cur_file) | 1805 path_to_file = os.path.join(path, cur_file) |
| 1800 os.remove(path_to_file) | 1806 os.remove(path_to_file) |
| 1801 | 1807 |
| 1802 def PerformCrosChrootCleanup(self): | 1808 def PerformCrosChrootCleanup(self): |
| 1803 """Deletes the chroot. | 1809 """Deletes the chroot. |
| 1804 | 1810 |
| 1805 Returns: | 1811 Returns: |
| 1806 True if successful. | 1812 True if successful. |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 1830 | 1836 |
| 1831 Args: | 1837 Args: |
| 1832 depot: Depot name. | 1838 depot: Depot name. |
| 1833 | 1839 |
| 1834 Returns: | 1840 Returns: |
| 1835 True if successful. | 1841 True if successful. |
| 1836 """ | 1842 """ |
| 1837 if depot == 'chromium' or depot == 'android-chrome': | 1843 if depot == 'chromium' or depot == 'android-chrome': |
| 1838 # Removes third_party/libjingle. At some point, libjingle was causing | 1844 # Removes third_party/libjingle. At some point, libjingle was causing |
| 1839 # issues syncing when using the git workflow (crbug.com/266324). | 1845 # issues syncing when using the git workflow (crbug.com/266324). |
| 1840 os.chdir(self.src_cwd) | 1846 os.chdir(SRC_DIR) |
| 1841 if not bisect_utils.RemoveThirdPartyDirectory('libjingle'): | 1847 if not bisect_utils.RemoveThirdPartyDirectory('libjingle'): |
| 1842 return False | 1848 return False |
| 1843 # Removes third_party/skia. At some point, skia was causing | 1849 # Removes third_party/skia. At some point, skia was causing |
| 1844 # issues syncing when using the git workflow (crbug.com/377951). | 1850 # issues syncing when using the git workflow (crbug.com/377951). |
| 1845 if not bisect_utils.RemoveThirdPartyDirectory('skia'): | 1851 if not bisect_utils.RemoveThirdPartyDirectory('skia'): |
| 1846 return False | 1852 return False |
| 1847 elif depot == 'cros': | 1853 elif depot == 'cros': |
| 1848 return self.PerformCrosChrootCleanup() | 1854 return self.PerformCrosChrootCleanup() |
| 1849 return True | 1855 return True |
| 1850 | 1856 |
| 1851 def _RunPostSync(self, depot): | 1857 def _RunPostSync(self, depot): |
| 1852 """Performs any work after syncing. | 1858 """Performs any work after syncing. |
| 1853 | 1859 |
| 1854 Args: | 1860 Args: |
| 1855 depot: Depot name. | 1861 depot: Depot name. |
| 1856 | 1862 |
| 1857 Returns: | 1863 Returns: |
| 1858 True if successful. | 1864 True if successful. |
| 1859 """ | 1865 """ |
| 1860 if self.opts.target_platform == 'android': | 1866 if self.opts.target_platform == 'android': |
| 1861 if not builder.SetupAndroidBuildEnvironment(self.opts, | 1867 if not builder.SetupAndroidBuildEnvironment(self.opts, |
| 1862 path_to_src=self.src_cwd): | 1868 path_to_src=SRC_DIR): |
| 1863 return False | 1869 return False |
| 1864 | 1870 |
| 1865 if depot == 'cros': | 1871 if depot == 'cros': |
| 1866 return self.CreateCrosChroot() | 1872 return self.CreateCrosChroot() |
| 1867 else: | 1873 else: |
| 1868 return self.RunGClientHooks() | 1874 return self.RunGClientHooks() |
| 1869 return True | 1875 return True |
| 1870 | 1876 |
| 1871 def ShouldSkipRevision(self, depot, revision): | 1877 def ShouldSkipRevision(self, depot, revision): |
| 1872 """Checks whether a particular revision can be safely skipped. | 1878 """Checks whether a particular revision can be safely skipped. |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2017 dist_to_bad_value = abs(current_value['std_dev'] - | 2023 dist_to_bad_value = abs(current_value['std_dev'] - |
| 2018 known_bad_value['std_dev']) | 2024 known_bad_value['std_dev']) |
| 2019 else: | 2025 else: |
| 2020 dist_to_good_value = abs(current_value['mean'] - known_good_value['mean']) | 2026 dist_to_good_value = abs(current_value['mean'] - known_good_value['mean']) |
| 2021 dist_to_bad_value = abs(current_value['mean'] - known_bad_value['mean']) | 2027 dist_to_bad_value = abs(current_value['mean'] - known_bad_value['mean']) |
| 2022 | 2028 |
| 2023 return dist_to_good_value < dist_to_bad_value | 2029 return dist_to_good_value < dist_to_bad_value |
| 2024 | 2030 |
| 2025 def _GetDepotDirectory(self, depot_name): | 2031 def _GetDepotDirectory(self, depot_name): |
| 2026 if depot_name == 'chromium': | 2032 if depot_name == 'chromium': |
| 2027 return self.src_cwd | 2033 return SRC_DIR |
| 2028 elif depot_name == 'cros': | 2034 elif depot_name == 'cros': |
| 2029 return self.cros_cwd | 2035 return self.cros_cwd |
| 2030 elif depot_name in DEPOT_NAMES: | 2036 elif depot_name in DEPOT_NAMES: |
| 2031 return self.depot_cwd[depot_name] | 2037 return self.depot_cwd[depot_name] |
| 2032 else: | 2038 else: |
| 2033 assert False, ('Unknown depot [ %s ] encountered. Possibly a new one ' | 2039 assert False, ('Unknown depot [ %s ] encountered. Possibly a new one ' |
| 2034 'was added without proper support?' % depot_name) | 2040 'was added without proper support?' % depot_name) |
| 2035 | 2041 |
| 2036 def ChangeToDepotWorkingDirectory(self, depot_name): | 2042 def ChangeToDepotWorkingDirectory(self, depot_name): |
| 2037 """Given a depot, changes to the appropriate working directory. | 2043 """Given a depot, changes to the appropriate working directory. |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2114 A list containing the revisions between |start_revision| and | 2120 A list containing the revisions between |start_revision| and |
| 2115 |end_revision| inclusive. | 2121 |end_revision| inclusive. |
| 2116 """ | 2122 """ |
| 2117 # Change into working directory of external library to run | 2123 # Change into working directory of external library to run |
| 2118 # subsequent commands. | 2124 # subsequent commands. |
| 2119 self.ChangeToDepotWorkingDirectory(current_depot) | 2125 self.ChangeToDepotWorkingDirectory(current_depot) |
| 2120 | 2126 |
| 2121 # V8 (and possibly others) is merged in periodically. Bisecting | 2127 # V8 (and possibly others) is merged in periodically. Bisecting |
| 2122 # this directory directly won't give much good info. | 2128 # this directory directly won't give much good info. |
| 2123 if DEPOT_DEPS_NAME[current_depot].has_key('custom_deps'): | 2129 if DEPOT_DEPS_NAME[current_depot].has_key('custom_deps'): |
| 2124 config_path = os.path.join(self.src_cwd, '..') | 2130 config_path = os.path.join(SRC_DIR, '..') |
| 2125 if bisect_utils.RunGClientAndCreateConfig(self.opts, | 2131 if bisect_utils.RunGClientAndCreateConfig(self.opts, |
| 2126 DEPOT_DEPS_NAME[current_depot]['custom_deps'], cwd=config_path): | 2132 DEPOT_DEPS_NAME[current_depot]['custom_deps'], cwd=config_path): |
| 2127 return [] | 2133 return [] |
| 2128 if bisect_utils.RunGClient( | 2134 if bisect_utils.RunGClient( |
| 2129 ['sync', '--revision', previous_revision], cwd=self.src_cwd): | 2135 ['sync', '--revision', previous_revision], cwd=SRC_DIR): |
| 2130 return [] | 2136 return [] |
| 2131 | 2137 |
| 2132 if current_depot == 'v8_bleeding_edge': | 2138 if current_depot == 'v8_bleeding_edge': |
| 2133 self.ChangeToDepotWorkingDirectory('chromium') | 2139 self.ChangeToDepotWorkingDirectory('chromium') |
| 2134 | 2140 |
| 2135 shutil.move('v8', 'v8.bak') | 2141 shutil.move('v8', 'v8.bak') |
| 2136 shutil.move('v8_bleeding_edge', 'v8') | 2142 shutil.move('v8_bleeding_edge', 'v8') |
| 2137 | 2143 |
| 2138 self.cleanup_commands.append(['mv', 'v8', 'v8_bleeding_edge']) | 2144 self.cleanup_commands.append(['mv', 'v8', 'v8_bleeding_edge']) |
| 2139 self.cleanup_commands.append(['mv', 'v8.bak', 'v8']) | 2145 self.cleanup_commands.append(['mv', 'v8.bak', 'v8']) |
| 2140 | 2146 |
| 2141 self.depot_cwd['v8_bleeding_edge'] = os.path.join(self.src_cwd, 'v8') | 2147 self.depot_cwd['v8_bleeding_edge'] = os.path.join(SRC_DIR, 'v8') |
| 2142 self.depot_cwd['v8'] = os.path.join(self.src_cwd, 'v8.bak') | 2148 self.depot_cwd['v8'] = os.path.join(SRC_DIR, 'v8.bak') |
| 2143 | 2149 |
| 2144 self.ChangeToDepotWorkingDirectory(current_depot) | 2150 self.ChangeToDepotWorkingDirectory(current_depot) |
| 2145 | 2151 |
| 2146 depot_revision_list = self.GetRevisionList(current_depot, | 2152 depot_revision_list = self.GetRevisionList(current_depot, |
| 2147 end_revision, | 2153 end_revision, |
| 2148 start_revision) | 2154 start_revision) |
| 2149 | 2155 |
| 2150 self.ChangeToDepotWorkingDirectory('chromium') | 2156 self.ChangeToDepotWorkingDirectory('chromium') |
| 2151 | 2157 |
| 2152 return depot_revision_list | 2158 return depot_revision_list |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2277 | 2283 |
| 2278 Args: | 2284 Args: |
| 2279 good_revision: Known good revision. | 2285 good_revision: Known good revision. |
| 2280 bad_revision: Known bad revision. | 2286 bad_revision: Known bad revision. |
| 2281 | 2287 |
| 2282 Returns: | 2288 Returns: |
| 2283 A dictionary indicating the result. If revision is not bisectable, | 2289 A dictionary indicating the result. If revision is not bisectable, |
| 2284 this will contain the field "error", otherwise None. | 2290 this will contain the field "error", otherwise None. |
| 2285 """ | 2291 """ |
| 2286 if self.opts.target_platform == 'android': | 2292 if self.opts.target_platform == 'android': |
| 2287 revision_to_check = self.source_control.GetCommitPosition(good_revision) | 2293 good_revision = self.source_control.GetCommitPosition(good_revision) |
|
qyearsley
2014/09/11 16:38:38
revision_to_check was not referenced. Pylint caugh
| |
| 2288 if (bisect_utils.IsStringInt(good_revision) | 2294 if (bisect_utils.IsStringInt(good_revision) |
| 2289 and good_revision < 265549): | 2295 and good_revision < 265549): |
| 2290 return {'error': ( | 2296 return {'error': ( |
| 2291 'Bisect cannot continue for the given revision range.\n' | 2297 'Bisect cannot continue for the given revision range.\n' |
| 2292 'It is impossible to bisect Android regressions ' | 2298 'It is impossible to bisect Android regressions ' |
| 2293 'prior to r265549, which allows the bisect bot to ' | 2299 'prior to r265549, which allows the bisect bot to ' |
| 2294 'rely on Telemetry to do apk installation of the most recently ' | 2300 'rely on Telemetry to do apk installation of the most recently ' |
| 2295 'built local ChromeShell(refer to crbug.com/385324).\n' | 2301 'built local ChromeShell(refer to crbug.com/385324).\n' |
| 2296 'Please try bisecting revisions greater than or equal to r265549.')} | 2302 'Please try bisecting revisions greater than or equal to r265549.')} |
| 2297 | 2303 |
| (...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3398 # bugs. If you change this, please update the perf dashboard as well. | 3404 # bugs. If you change this, please update the perf dashboard as well. |
| 3399 bisect_utils.OutputAnnotationStepStart('Results') | 3405 bisect_utils.OutputAnnotationStepStart('Results') |
| 3400 print 'Error: %s' % e.message | 3406 print 'Error: %s' % e.message |
| 3401 if opts.output_buildbot_annotations: | 3407 if opts.output_buildbot_annotations: |
| 3402 bisect_utils.OutputAnnotationStepClosed() | 3408 bisect_utils.OutputAnnotationStepClosed() |
| 3403 return 1 | 3409 return 1 |
| 3404 | 3410 |
| 3405 | 3411 |
| 3406 if __name__ == '__main__': | 3412 if __name__ == '__main__': |
| 3407 sys.exit(main()) | 3413 sys.exit(main()) |
| OLD | NEW |