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 1304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1315 fetch_build_func = lambda: self.GetBuildArchiveForRevision( | 1315 fetch_build_func = lambda: self.GetBuildArchiveForRevision( |
1316 revision, self.opts.gs_bucket, self.opts.target_arch, | 1316 revision, self.opts.gs_bucket, self.opts.target_arch, |
1317 patch_sha, abs_build_dir) | 1317 patch_sha, abs_build_dir) |
1318 | 1318 |
1319 # Downloaded archive file path, downloads build archive for given revision. | 1319 # Downloaded archive file path, downloads build archive for given revision. |
1320 downloaded_file = fetch_build_func() | 1320 downloaded_file = fetch_build_func() |
1321 | 1321 |
1322 # When build archive doesn't exists, post a build request to tryserver | 1322 # When build archive doesn't exists, post a build request to tryserver |
1323 # and wait for the build to be produced. | 1323 # and wait for the build to be produced. |
1324 if not downloaded_file: | 1324 if not downloaded_file: |
1325 downloaded_file = self.PostBuildRequestAndWait( | 1325 downloaded_file = self._RequestBuildAndWait( |
1326 revision, fetch_build=fetch_build_func, patch=patch) | 1326 revision, fetch_build=fetch_build_func, patch=patch) |
1327 if not downloaded_file: | 1327 if not downloaded_file: |
1328 return False | 1328 return False |
1329 | 1329 |
1330 # Generic name for the archive, created when archive file is extracted. | 1330 # Generic name for the archive, created when archive file is extracted. |
1331 output_dir = os.path.join( | 1331 output_dir = os.path.join( |
1332 abs_build_dir, GetZipFileName(target_arch=self.opts.target_arch)) | 1332 abs_build_dir, GetZipFileName(target_arch=self.opts.target_arch)) |
1333 | 1333 |
1334 # Unzip build archive directory. | 1334 # Unzip build archive directory. |
1335 try: | 1335 try: |
(...skipping 19 matching lines...) Expand all Loading... |
1355 self.BackupOrRestoreOutputDirectory(restore=True) | 1355 self.BackupOrRestoreOutputDirectory(restore=True) |
1356 # Cleanup any leftovers from unzipping. | 1356 # Cleanup any leftovers from unzipping. |
1357 if os.path.exists(output_dir): | 1357 if os.path.exists(output_dir): |
1358 RemoveDirectoryTree(output_dir) | 1358 RemoveDirectoryTree(output_dir) |
1359 finally: | 1359 finally: |
1360 # Delete downloaded archive | 1360 # Delete downloaded archive |
1361 if os.path.exists(downloaded_file): | 1361 if os.path.exists(downloaded_file): |
1362 os.remove(downloaded_file) | 1362 os.remove(downloaded_file) |
1363 return False | 1363 return False |
1364 | 1364 |
1365 def PostBuildRequestAndWait(self, git_revision, fetch_build, patch=None): | 1365 def _RequestBuildAndWait(self, git_revision, fetch_build, patch=None): |
1366 """POSTs the build request job to the try server instance. | 1366 """Triggers a try job for a build job. |
1367 | 1367 |
1368 A try job build request is posted to tryserver.chromium.perf master, | 1368 This function prepares and starts a try job on the tryserver.chromium.perf |
1369 and waits for the binaries to be produced and archived on cloud storage. | 1369 master, and waits for the binaries to be produced and archived in cloud |
1370 Once the build is ready and stored onto cloud, build archive is downloaded | 1370 storage. Once the build is ready it's downloaded. |
1371 into the output folder. | |
1372 | 1371 |
1373 Args: | 1372 Args: |
1374 git_revision: A Git hash revision. | 1373 git_revision: A Git hash revision. |
1375 fetch_build: Function to check and download build from cloud storage. | 1374 fetch_build: Function to check and download build from cloud storage. |
1376 patch: A DEPS patch (used while bisecting 3rd party repositories). | 1375 patch: A DEPS patch (used while bisecting 3rd party repositories). |
1377 | 1376 |
1378 Returns: | 1377 Returns: |
1379 Downloaded archive file path when requested build exists and download is | 1378 Downloaded archive file path when requested build exists and download is |
1380 successful, otherwise None. | 1379 successful, otherwise None. |
1381 """ | 1380 """ |
1382 def GetBuilderNameAndBuildTime(target_platform, target_arch='ia32'): | |
1383 """Gets builder bot name and build time in seconds based on platform.""" | |
1384 # Bot names should match the one listed in tryserver.chromium's | |
1385 # master.cfg which produces builds for bisect. | |
1386 if bisect_utils.IsWindowsHost(): | |
1387 if bisect_utils.Is64BitWindows() and target_arch == 'x64': | |
1388 return ('win_perf_bisect_builder', MAX_WIN_BUILD_TIME) | |
1389 return ('win_perf_bisect_builder', MAX_WIN_BUILD_TIME) | |
1390 if bisect_utils.IsLinuxHost(): | |
1391 if target_platform == 'android': | |
1392 return ('android_perf_bisect_builder', MAX_LINUX_BUILD_TIME) | |
1393 return ('linux_perf_bisect_builder', MAX_LINUX_BUILD_TIME) | |
1394 if bisect_utils.IsMacHost(): | |
1395 return ('mac_perf_bisect_builder', MAX_MAC_BUILD_TIME) | |
1396 raise NotImplementedError('Unsupported Platform "%s".' % sys.platform) | |
1397 if not fetch_build: | 1381 if not fetch_build: |
1398 return False | 1382 return False |
1399 | 1383 |
1400 # Create a unique ID for each build request posted to try server builders. | 1384 # Create a unique ID for each build request posted to try server builders. |
1401 # This ID is added to "Reason" property of the build. | 1385 # This ID is added to "Reason" property of the build. |
1402 build_request_id = GetSHA1HexDigest( | 1386 build_request_id = GetSHA1HexDigest( |
1403 '%s-%s-%s' % (git_revision, patch, time.time())) | 1387 '%s-%s-%s' % (git_revision, patch, time.time())) |
1404 | 1388 |
1405 # Reverts any changes to DEPS file. | 1389 # Reverts any changes to DEPS file. |
1406 source_control.CheckoutFileAtRevision( | 1390 source_control.CheckoutFileAtRevision( |
1407 bisect_utils.FILE_DEPS, git_revision, cwd=self.src_cwd) | 1391 bisect_utils.FILE_DEPS, git_revision, cwd=self.src_cwd) |
1408 | 1392 |
1409 bot_name, build_timeout = GetBuilderNameAndBuildTime( | 1393 bot_name = self._GetBuilderName(self.opts.target_platform) |
1410 self.opts.target_platform, self.opts.target_arch) | 1394 build_timeout = self._GetBuilderBuildTime() |
1411 target_file = None | 1395 target_file = None |
1412 try: | 1396 try: |
1413 # Execute try job request to build revision with patch. | 1397 # Execute try job request to build revision with patch. |
1414 _BuilderTryjob(git_revision, bot_name, build_request_id, patch) | 1398 _BuilderTryjob(git_revision, bot_name, build_request_id, patch) |
1415 target_file, error_msg = _WaitUntilBuildIsReady( | 1399 target_file, error_msg = _WaitUntilBuildIsReady( |
1416 fetch_build, bot_name, self.opts.builder_host, | 1400 fetch_build, bot_name, self.opts.builder_host, |
1417 self.opts.builder_port, build_request_id, build_timeout) | 1401 self.opts.builder_port, build_request_id, build_timeout) |
1418 if not target_file: | 1402 if not target_file: |
1419 print '%s [revision: %s]' % (error_msg, git_revision) | 1403 print '%s [revision: %s]' % (error_msg, git_revision) |
1420 except RunGitError as e: | 1404 except RunGitError as e: |
1421 print ('Failed to post builder try job for revision: [%s].\n' | 1405 print ('Failed to post builder try job for revision: [%s].\n' |
1422 'Error: %s' % (git_revision, e)) | 1406 'Error: %s' % (git_revision, e)) |
1423 | 1407 |
1424 return target_file | 1408 return target_file |
1425 | 1409 |
| 1410 @staticmethod |
| 1411 def _GetBuilderName(target_platform): |
| 1412 """Gets builder bot name and build time in seconds based on platform.""" |
| 1413 if bisect_utils.IsWindowsHost(): |
| 1414 return 'win_perf_bisect_builder' |
| 1415 if bisect_utils.IsLinuxHost(): |
| 1416 if target_platform == 'android': |
| 1417 return 'android_perf_bisect_builder' |
| 1418 return 'linux_perf_bisect_builder' |
| 1419 if bisect_utils.IsMacHost(): |
| 1420 return 'mac_perf_bisect_builder' |
| 1421 raise NotImplementedError('Unsupported Platform "%s".' % sys.platform) |
| 1422 |
| 1423 @staticmethod |
| 1424 def _GetBuilderBuildTime(): |
| 1425 """Returns the time to wait for a build after requesting one.""" |
| 1426 if bisect_utils.IsWindowsHost(): |
| 1427 return MAX_WIN_BUILD_TIME |
| 1428 if bisect_utils.IsLinuxHost(): |
| 1429 return MAX_LINUX_BUILD_TIME |
| 1430 if bisect_utils.IsMacHost(): |
| 1431 return MAX_MAC_BUILD_TIME |
| 1432 raise NotImplementedError('Unsupported Platform "%s".' % sys.platform) |
| 1433 |
1426 def IsDownloadable(self, depot): | 1434 def IsDownloadable(self, depot): |
1427 """Checks if build can be downloaded based on target platform and depot.""" | 1435 """Checks if build can be downloaded based on target platform and depot.""" |
1428 if (self.opts.target_platform in ['chromium', 'android'] and | 1436 if (self.opts.target_platform in ['chromium', 'android'] and |
1429 self.opts.gs_bucket): | 1437 self.opts.gs_bucket): |
1430 return (depot == 'chromium' or | 1438 return (depot == 'chromium' or |
1431 'chromium' in DEPOT_DEPS_NAME[depot]['from'] or | 1439 'chromium' in DEPOT_DEPS_NAME[depot]['from'] or |
1432 'v8' in DEPOT_DEPS_NAME[depot]['from']) | 1440 'v8' in DEPOT_DEPS_NAME[depot]['from']) |
1433 return False | 1441 return False |
1434 | 1442 |
1435 def UpdateDepsContents(self, deps_contents, depot, git_revision, deps_key): | 1443 def UpdateDepsContents(self, deps_contents, depot, git_revision, deps_key): |
(...skipping 1853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3289 # bugs. If you change this, please update the perf dashboard as well. | 3297 # bugs. If you change this, please update the perf dashboard as well. |
3290 bisect_utils.OutputAnnotationStepStart('Results') | 3298 bisect_utils.OutputAnnotationStepStart('Results') |
3291 print 'Error: %s' % e.message | 3299 print 'Error: %s' % e.message |
3292 if opts.output_buildbot_annotations: | 3300 if opts.output_buildbot_annotations: |
3293 bisect_utils.OutputAnnotationStepClosed() | 3301 bisect_utils.OutputAnnotationStepClosed() |
3294 return 1 | 3302 return 1 |
3295 | 3303 |
3296 | 3304 |
3297 if __name__ == '__main__': | 3305 if __name__ == '__main__': |
3298 sys.exit(main()) | 3306 sys.exit(main()) |
OLD | NEW |