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

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

Issue 664793002: Rename and refactor DownloadCurrentBuild and related functions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased 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 | no next file » | 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 994 matching lines...) Expand 10 before | Expand all | Expand 10 after
1005 source_dir = os.path.join(build_dir, build_type) 1005 source_dir = os.path.join(build_dir, build_type)
1006 destination_dir = os.path.join(build_dir, '%s.bak' % build_type) 1006 destination_dir = os.path.join(build_dir, '%s.bak' % build_type)
1007 if restore: 1007 if restore:
1008 source_dir, destination_dir = destination_dir, source_dir 1008 source_dir, destination_dir = destination_dir, source_dir
1009 if os.path.exists(source_dir): 1009 if os.path.exists(source_dir):
1010 RemoveDirectoryTree(destination_dir) 1010 RemoveDirectoryTree(destination_dir)
1011 shutil.move(source_dir, destination_dir) 1011 shutil.move(source_dir, destination_dir)
1012 return destination_dir 1012 return destination_dir
1013 return None 1013 return None
1014 1014
1015 def GetBuildArchiveForRevision(self, revision, gs_bucket, target_arch, 1015 def _GetBuildArchiveForRevision(self, revision, gs_bucket, target_arch,
1016 patch_sha, out_dir): 1016 patch_sha, out_dir):
1017 """Checks and downloads build archive for a given revision. 1017 """Checks and downloads build archive for a given revision.
1018 1018
1019 Checks for build archive with Git hash or SVN revision. If either of the 1019 Checks for build archive with Git hash or SVN revision. If either of the
1020 file exists, then downloads the archive file. 1020 file exists, then downloads the archive file.
1021 1021
1022 Args: 1022 Args:
1023 revision: A Git hash revision. 1023 revision: A git commit hash.
1024 gs_bucket: Cloud storage bucket name 1024 gs_bucket: Cloud storage bucket name.
1025 target_arch: 32 or 64 bit build target 1025 target_arch: Architecture name string, e.g. "ia32" or "x64".
1026 patch: A DEPS patch (used while bisecting 3rd party repositories). 1026 patch_sha: A SHA1 hex digest of a DEPS file patch, used while
1027 bisecting 3rd party repositories.
1027 out_dir: Build output directory where downloaded file is stored. 1028 out_dir: Build output directory where downloaded file is stored.
1028 1029
1029 Returns: 1030 Returns:
1030 Downloaded archive file path if exists, otherwise None. 1031 Downloaded archive file path if exists, otherwise None.
1031 """ 1032 """
1032 # Source archive file path on cloud storage using Git revision. 1033 # Source archive file path on cloud storage using Git revision.
1033 source_file = GetRemoteBuildPath( 1034 source_file = GetRemoteBuildPath(
1034 revision, self.opts.target_platform, target_arch, patch_sha) 1035 revision, self.opts.target_platform, target_arch, patch_sha)
1035 downloaded_archive = FetchFromCloudStorage(gs_bucket, source_file, out_dir) 1036 downloaded_archive = FetchFromCloudStorage(gs_bucket, source_file, out_dir)
1036 if not downloaded_archive: 1037 if not downloaded_archive:
1037 # Get commit position for the given SHA. 1038 # Get commit position for the given SHA.
1038 commit_position = source_control.GetCommitPosition(revision) 1039 commit_position = source_control.GetCommitPosition(revision)
1039 if commit_position: 1040 if commit_position:
1040 # Source archive file path on cloud storage using SVN revision. 1041 # Source archive file path on cloud storage using SVN revision.
1041 source_file = GetRemoteBuildPath( 1042 source_file = GetRemoteBuildPath(
1042 commit_position, self.opts.target_platform, target_arch, patch_sha) 1043 commit_position, self.opts.target_platform, target_arch, patch_sha)
1043 return FetchFromCloudStorage(gs_bucket, source_file, out_dir) 1044 return FetchFromCloudStorage(gs_bucket, source_file, out_dir)
1044 return downloaded_archive 1045 return downloaded_archive
1045 1046
1046 def DownloadCurrentBuild(self, revision, depot, build_type='Release'): 1047 def _DownloadAndUnzipBuild(self, revision, depot, build_type='Release'):
1047 """Downloads the build archive for the given revision. 1048 """Downloads the build archive for the given revision.
1048 1049
1049 Args: 1050 Args:
1050 revision: The git revision to download or build. 1051 revision: The git revision to download.
1051 depot: The name of a dependency repository. Should be in DEPOT_NAMES. 1052 depot: The name of a dependency repository. Should be in DEPOT_NAMES.
1052 build_type: Target build type, e.g. Release', 'Debug', 'Release_x64' etc. 1053 build_type: Target build type, e.g. Release', 'Debug', 'Release_x64' etc.
1053 1054
1054 Returns: 1055 Returns:
1055 True if download succeeds, otherwise False. 1056 True if download succeeds, otherwise False.
1056 """ 1057 """
1057 patch = None 1058 patch = None
1058 patch_sha = None 1059 patch_sha = None
1059 if depot != 'chromium': 1060 if depot != 'chromium':
1060 # Create a DEPS patch with new revision for dependency repository. 1061 # Create a DEPS patch with new revision for dependency repository.
1061 revision, patch = self.CreateDEPSPatch(depot, revision) 1062 revision, patch = self.CreateDEPSPatch(depot, revision)
1062 1063
1063 if patch: 1064 if patch:
1064 # Get the SHA of the DEPS changes patch. 1065 # Get the SHA of the DEPS changes patch.
1065 patch_sha = GetSHA1HexDigest(patch) 1066 patch_sha = GetSHA1HexDigest(patch)
1066 1067
1067 # Update the DEPS changes patch with a patch to create a new file named 1068 # Update the DEPS changes patch with a patch to create a new file named
1068 # 'DEPS.sha' and add patch_sha evaluated above to it. 1069 # 'DEPS.sha' and add patch_sha evaluated above to it.
1069 patch = '%s\n%s' % (patch, DEPS_SHA_PATCH % {'deps_sha': patch_sha}) 1070 patch = '%s\n%s' % (patch, DEPS_SHA_PATCH % {'deps_sha': patch_sha})
1070 1071
1071 # Get build output directory.
1072 build_dir = builder.GetBuildOutputDirectory(self.opts, self.src_cwd) 1072 build_dir = builder.GetBuildOutputDirectory(self.opts, self.src_cwd)
1073 downloaded_file = self._WaitForBuildDownload(
1074 revision, build_dir, deps_patch=patch, deps_patch_sha=patch_sha)
1075 if not downloaded_file:
1076 return False
1077 return self._UnzipAndMoveBuildProducts(downloaded_file, build_dir,
1078 build_type=build_type)
1079
1080 def _WaitForBuildDownload(self, revision, build_dir, deps_patch=None,
1081 deps_patch_sha=None):
1082 """Tries to download a zip archive for a build.
1083
1084 This involves seeing whether the archive is already available, and if not,
1085 then requesting a build and waiting before downloading.
1086
1087 Args:
1088 revision: A git commit hash.
1089 build_dir: The directory to download the build into.
1090 deps_patch: A patch which changes a dependency repository revision in
1091 the DEPS, if applicable.
1092 deps_patch_sha: The SHA1 hex digest of the above patch.
1093
1094 Returns:
1095 File path of the downloaded file if successful, otherwise None.
1096 """
1073 abs_build_dir = os.path.abspath(build_dir) 1097 abs_build_dir = os.path.abspath(build_dir)
1074 1098 fetch_build_func = lambda: self._GetBuildArchiveForRevision(
1075 fetch_build_func = lambda: self.GetBuildArchiveForRevision( 1099 revision, self.opts.gs_bucket, self.opts.target_arch,
1076 revision, self.opts.gs_bucket, self.opts.target_arch, 1100 deps_patch_sha, abs_build_dir)
1077 patch_sha, abs_build_dir)
1078 1101
1079 # Downloaded archive file path, downloads build archive for given revision. 1102 # Downloaded archive file path, downloads build archive for given revision.
1103 # This will be False if the build isn't yet available.
1080 downloaded_file = fetch_build_func() 1104 downloaded_file = fetch_build_func()
1081 1105
1082 # When build archive doesn't exists, post a build request to tryserver 1106 # When build archive doesn't exist, post a build request to try server
1083 # and wait for the build to be produced. 1107 # and wait for the build to be produced.
1084 if not downloaded_file: 1108 if not downloaded_file:
1085 downloaded_file = self._RequestBuildAndWait( 1109 downloaded_file = self._RequestBuildAndWait(
1086 revision, fetch_build=fetch_build_func, patch=patch) 1110 revision, fetch_build=fetch_build_func, patch=deps_patch)
1087 if not downloaded_file: 1111 if not downloaded_file:
1088 return False 1112 return None
1089 1113
1090 # Generic name for the archive, created when archive file is extracted. 1114 return downloaded_file
1091 output_dir = os.path.join(
1092 abs_build_dir, GetZipFileName(target_arch=self.opts.target_arch))
1093
1094 # Unzip build archive directory.
1095 try:
1096 RemoveDirectoryTree(output_dir)
1097 self.BackupOrRestoreOutputDirectory(restore=False)
1098 # Build output directory based on target(e.g. out/Release, out/Debug).
1099 target_build_output_dir = os.path.join(abs_build_dir, build_type)
1100 ExtractZip(downloaded_file, abs_build_dir)
1101 if not os.path.exists(output_dir):
1102 # Due to recipe changes, the builds extract folder contains
1103 # out/Release instead of full-build-<platform>/Release.
1104 if os.path.exists(os.path.join(abs_build_dir, 'out', build_type)):
1105 output_dir = os.path.join(abs_build_dir, 'out', build_type)
1106 else:
1107 raise IOError('Missing extracted folder %s ' % output_dir)
1108
1109 print 'Moving build from %s to %s' % (
1110 output_dir, target_build_output_dir)
1111 shutil.move(output_dir, target_build_output_dir)
1112 return True
1113 except Exception as e:
1114 print 'Something went wrong while extracting archive file: %s' % e
1115 self.BackupOrRestoreOutputDirectory(restore=True)
1116 # Cleanup any leftovers from unzipping.
1117 if os.path.exists(output_dir):
1118 RemoveDirectoryTree(output_dir)
1119 finally:
1120 # Delete downloaded archive
1121 if os.path.exists(downloaded_file):
1122 os.remove(downloaded_file)
1123 return False
1124 1115
1125 def _RequestBuildAndWait(self, git_revision, fetch_build, patch=None): 1116 def _RequestBuildAndWait(self, git_revision, fetch_build, patch=None):
1126 """Triggers a try job for a build job. 1117 """Triggers a try job for a build job.
1127 1118
1128 This function prepares and starts a try job on the tryserver.chromium.perf 1119 This function prepares and starts a try job on the tryserver.chromium.perf
1129 master, and waits for the binaries to be produced and archived in cloud 1120 master, and waits for the binaries to be produced and archived in cloud
1130 storage. Once the build is ready it's downloaded. 1121 storage. Once the build is ready it's downloaded.
1131 1122
1132 Args: 1123 Args:
1133 git_revision: A Git hash revision. 1124 git_revision: A Git hash revision.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 def _GetBuilderBuildTime(): 1175 def _GetBuilderBuildTime():
1185 """Returns the time to wait for a build after requesting one.""" 1176 """Returns the time to wait for a build after requesting one."""
1186 if bisect_utils.IsWindowsHost(): 1177 if bisect_utils.IsWindowsHost():
1187 return MAX_WIN_BUILD_TIME 1178 return MAX_WIN_BUILD_TIME
1188 if bisect_utils.IsLinuxHost(): 1179 if bisect_utils.IsLinuxHost():
1189 return MAX_LINUX_BUILD_TIME 1180 return MAX_LINUX_BUILD_TIME
1190 if bisect_utils.IsMacHost(): 1181 if bisect_utils.IsMacHost():
1191 return MAX_MAC_BUILD_TIME 1182 return MAX_MAC_BUILD_TIME
1192 raise NotImplementedError('Unsupported Platform "%s".' % sys.platform) 1183 raise NotImplementedError('Unsupported Platform "%s".' % sys.platform)
1193 1184
1185 def _UnzipAndMoveBuildProducts(self, downloaded_file, build_dir,
1186 build_type='Release'):
1187 """Unzips the build archive and moves it to the build output directory.
1188
1189 The build output directory is whereever the binaries are expected to
1190 be in order to start Chrome and run tests.
1191
1192 Args:
1193 downloaded_file: File path of the downloaded zip file.
1194 build_dir: Directory where the the zip file was downloaded to.
1195 build_type: "Release" or "Debug".
1196
1197 Returns:
1198 True if successful, False otherwise.
1199 """
1200 abs_build_dir = os.path.abspath(build_dir)
1201 output_dir = os.path.join(
1202 abs_build_dir, GetZipFileName(target_arch=self.opts.target_arch))
1203
1204 try:
1205 RemoveDirectoryTree(output_dir)
1206 self.BackupOrRestoreOutputDirectory(restore=False)
1207 # Build output directory based on target(e.g. out/Release, out/Debug).
1208 target_build_output_dir = os.path.join(abs_build_dir, build_type)
1209 ExtractZip(downloaded_file, abs_build_dir)
1210 if not os.path.exists(output_dir):
1211 # Due to recipe changes, the builds extract folder contains
1212 # out/Release instead of full-build-<platform>/Release.
1213 if os.path.exists(os.path.join(abs_build_dir, 'out', build_type)):
1214 output_dir = os.path.join(abs_build_dir, 'out', build_type)
1215 else:
1216 raise IOError('Missing extracted folder %s ' % output_dir)
1217
1218 print 'Moving build from %s to %s' % (
1219 output_dir, target_build_output_dir)
1220 shutil.move(output_dir, target_build_output_dir)
1221 return True
1222 except Exception as e:
1223 print 'Something went wrong while extracting archive file: %s' % e
1224 self.BackupOrRestoreOutputDirectory(restore=True)
1225 # Cleanup any leftovers from unzipping.
1226 if os.path.exists(output_dir):
1227 RemoveDirectoryTree(output_dir)
1228 finally:
1229 # Delete downloaded archive
1230 if os.path.exists(downloaded_file):
1231 os.remove(downloaded_file)
1232 return False
1233
1194 def IsDownloadable(self, depot): 1234 def IsDownloadable(self, depot):
1195 """Checks if build can be downloaded based on target platform and depot.""" 1235 """Checks if build can be downloaded based on target platform and depot."""
1196 if (self.opts.target_platform in ['chromium', 'android'] and 1236 if (self.opts.target_platform in ['chromium', 'android'] and
1197 self.opts.gs_bucket): 1237 self.opts.gs_bucket):
1198 return (depot == 'chromium' or 1238 return (depot == 'chromium' or
1199 'chromium' in bisect_utils.DEPOT_DEPS_NAME[depot]['from'] or 1239 'chromium' in bisect_utils.DEPOT_DEPS_NAME[depot]['from'] or
1200 'v8' in bisect_utils.DEPOT_DEPS_NAME[depot]['from']) 1240 'v8' in bisect_utils.DEPOT_DEPS_NAME[depot]['from'])
1201 return False 1241 return False
1202 1242
1203 def UpdateDepsContents(self, deps_contents, depot, git_revision, deps_key): 1243 def UpdateDepsContents(self, deps_contents, depot, git_revision, deps_key):
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1321 diff_text = bisect_utils.CheckRunGit(diff_command, cwd=self.src_cwd) 1361 diff_text = bisect_utils.CheckRunGit(diff_command, cwd=self.src_cwd)
1322 return (chromium_sha, ChangeBackslashToSlashInPatch(diff_text)) 1362 return (chromium_sha, ChangeBackslashToSlashInPatch(diff_text))
1323 else: 1363 else:
1324 raise RuntimeError( 1364 raise RuntimeError(
1325 'Failed to update DEPS file for chromium: [%s]' % chromium_sha) 1365 'Failed to update DEPS file for chromium: [%s]' % chromium_sha)
1326 else: 1366 else:
1327 raise RuntimeError( 1367 raise RuntimeError(
1328 'DEPS checkout Failed for chromium revision : [%s]' % chromium_sha) 1368 'DEPS checkout Failed for chromium revision : [%s]' % chromium_sha)
1329 return (None, None) 1369 return (None, None)
1330 1370
1331 def BuildCurrentRevision(self, depot, revision=None): 1371 def _ObtainBuild(self, depot, revision=None):
1332 """Builds chrome and performance_ui_tests on the current revision. 1372 """Obtains a build by either downloading or building directly.
1373
1374 Args:
1375 depot: Dependency repository name.
1376 revision: A git commit hash. If None is given, the currently checked-out
1377 revision is built.
1333 1378
1334 Returns: 1379 Returns:
1335 True if the build was successful. 1380 True for success.
1336 """ 1381 """
1337 if self.opts.debug_ignore_build: 1382 if self.opts.debug_ignore_build:
1338 return True 1383 return True
1339 1384
1340 build_success = False 1385 build_success = False
1341 cwd = os.getcwd() 1386 cwd = os.getcwd()
1342 os.chdir(self.src_cwd) 1387 os.chdir(self.src_cwd)
1343 # Fetch build archive for the given revision from the cloud storage when 1388 # Fetch build archive for the given revision from the cloud storage when
1344 # the storage bucket is passed. 1389 # the storage bucket is passed.
1345 if self.IsDownloadable(depot) and revision: 1390 if self.IsDownloadable(depot) and revision:
1346 build_success = self.DownloadCurrentBuild(revision, depot) 1391 build_success = self._DownloadAndUnzipBuild(revision, depot)
1347 else: 1392 else:
1348 # These codes are executed when bisect bots builds binaries locally. 1393 # These codes are executed when bisect bots builds binaries locally.
1349 build_success = self.builder.Build(depot, self.opts) 1394 build_success = self.builder.Build(depot, self.opts)
1350 os.chdir(cwd) 1395 os.chdir(cwd)
1351 return build_success 1396 return build_success
1352 1397
1353 def RunGClientHooks(self): 1398 def RunGClientHooks(self):
1354 """Runs gclient with runhooks command. 1399 """Runs gclient with runhooks command.
1355 1400
1356 Returns: 1401 Returns:
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
1733 return ('Failed to run [gclient runhooks].', BUILD_RESULT_FAIL) 1778 return ('Failed to run [gclient runhooks].', BUILD_RESULT_FAIL)
1734 1779
1735 # Skip this revision if it can be skipped. 1780 # Skip this revision if it can be skipped.
1736 if skippable and self.ShouldSkipRevision(depot, revision): 1781 if skippable and self.ShouldSkipRevision(depot, revision):
1737 return ('Skipped revision: [%s]' % str(revision), 1782 return ('Skipped revision: [%s]' % str(revision),
1738 BUILD_RESULT_SKIPPED) 1783 BUILD_RESULT_SKIPPED)
1739 1784
1740 # Obtain a build for this revision. This may be done by requesting a build 1785 # Obtain a build for this revision. This may be done by requesting a build
1741 # from another builder, waiting for it and downloading it. 1786 # from another builder, waiting for it and downloading it.
1742 start_build_time = time.time() 1787 start_build_time = time.time()
1743 build_success = self.BuildCurrentRevision(depot, revision) 1788 build_success = self._ObtainBuild(depot, revision)
1744 if not build_success: 1789 if not build_success:
1745 return ('Failed to build revision: [%s]' % str(revision), 1790 return ('Failed to build revision: [%s]' % str(revision),
1746 BUILD_RESULT_FAIL) 1791 BUILD_RESULT_FAIL)
1747 after_build_time = time.time() 1792 after_build_time = time.time()
1748 1793
1749 # Possibly alter the command. 1794 # Possibly alter the command.
1750 command = self.GetCompatibleCommand(command, revision, depot) 1795 command = self.GetCompatibleCommand(command, revision, depot)
1751 1796
1752 # Run the command and get the results. 1797 # Run the command and get the results.
1753 results = self.RunPerformanceTestAndParseResults(command, metric) 1798 results = self.RunPerformanceTestAndParseResults(command, metric)
(...skipping 993 matching lines...) Expand 10 before | Expand all | Expand 10 after
2747 # bugs. If you change this, please update the perf dashboard as well. 2792 # bugs. If you change this, please update the perf dashboard as well.
2748 bisect_utils.OutputAnnotationStepStart('Results') 2793 bisect_utils.OutputAnnotationStepStart('Results')
2749 print 'Error: %s' % e.message 2794 print 'Error: %s' % e.message
2750 if opts.output_buildbot_annotations: 2795 if opts.output_buildbot_annotations:
2751 bisect_utils.OutputAnnotationStepClosed() 2796 bisect_utils.OutputAnnotationStepClosed()
2752 return 1 2797 return 1
2753 2798
2754 2799
2755 if __name__ == '__main__': 2800 if __name__ == '__main__':
2756 sys.exit(main()) 2801 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698