| 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 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 | 475 |
| 476 def FetchFromCloudStorage(bucket_name, source_path, destination_path): | 476 def FetchFromCloudStorage(bucket_name, source_path, destination_path): |
| 477 """Fetches file(s) from the Google Cloud Storage. | 477 """Fetches file(s) from the Google Cloud Storage. |
| 478 | 478 |
| 479 Args: | 479 Args: |
| 480 bucket_name: Google Storage bucket name. | 480 bucket_name: Google Storage bucket name. |
| 481 source_path: Source file path. | 481 source_path: Source file path. |
| 482 destination_path: Destination file path. | 482 destination_path: Destination file path. |
| 483 | 483 |
| 484 Returns: | 484 Returns: |
| 485 True if the fetching succeeds, otherwise False. | 485 Downloaded file path if exisits, otherwise None. |
| 486 """ | 486 """ |
| 487 target_file = os.path.join(destination_path, os.path.basename(source_path)) | 487 target_file = os.path.join(destination_path, os.path.basename(source_path)) |
| 488 try: | 488 try: |
| 489 if cloud_storage.Exists(bucket_name, source_path): | 489 if cloud_storage.Exists(bucket_name, source_path): |
| 490 print 'Fetching file from gs//%s/%s ...' % (bucket_name, source_path) | 490 print 'Fetching file from gs//%s/%s ...' % (bucket_name, source_path) |
| 491 cloud_storage.Get(bucket_name, source_path, destination_path) | 491 cloud_storage.Get(bucket_name, source_path, destination_path) |
| 492 if os.path.exists(target_file): | 492 if os.path.exists(target_file): |
| 493 return True | 493 return target_file |
| 494 else: | 494 else: |
| 495 print ('File gs://%s/%s not found in cloud storage.' % ( | 495 print ('File gs://%s/%s not found in cloud storage.' % ( |
| 496 bucket_name, source_path)) | 496 bucket_name, source_path)) |
| 497 except Exception as e: | 497 except Exception as e: |
| 498 print 'Something went wrong while fetching file from cloud: %s' % e | 498 print 'Something went wrong while fetching file from cloud: %s' % e |
| 499 if os.path.exists(target_file): | 499 if os.path.exists(target_file): |
| 500 os.remove(target_file) | 500 os.remove(target_file) |
| 501 return False | 501 return None |
| 502 | 502 |
| 503 | 503 |
| 504 # This is copied from Chromium's project build/scripts/common/chromium_utils.py. | 504 # This is copied from Chromium's project build/scripts/common/chromium_utils.py. |
| 505 def MaybeMakeDirectory(*path): | 505 def MaybeMakeDirectory(*path): |
| 506 """Creates an entire path, if it doesn't already exist.""" | 506 """Creates an entire path, if it doesn't already exist.""" |
| 507 file_path = os.path.join(*path) | 507 file_path = os.path.join(*path) |
| 508 try: | 508 try: |
| 509 os.makedirs(file_path) | 509 os.makedirs(file_path) |
| 510 except OSError, e: | 510 except OSError, e: |
| 511 if e.errno != errno.EEXIST: | 511 if e.errno != errno.EEXIST: |
| (...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1546 source_dir = os.path.join(build_dir, build_type) | 1546 source_dir = os.path.join(build_dir, build_type) |
| 1547 destination_dir = os.path.join(build_dir, '%s.bak' % build_type) | 1547 destination_dir = os.path.join(build_dir, '%s.bak' % build_type) |
| 1548 if restore: | 1548 if restore: |
| 1549 source_dir, destination_dir = destination_dir, source_dir | 1549 source_dir, destination_dir = destination_dir, source_dir |
| 1550 if os.path.exists(source_dir): | 1550 if os.path.exists(source_dir): |
| 1551 RmTreeAndMkDir(destination_dir, skip_makedir=True) | 1551 RmTreeAndMkDir(destination_dir, skip_makedir=True) |
| 1552 shutil.move(source_dir, destination_dir) | 1552 shutil.move(source_dir, destination_dir) |
| 1553 return destination_dir | 1553 return destination_dir |
| 1554 return None | 1554 return None |
| 1555 | 1555 |
| 1556 def GetBuildArchiveForRevision(self, revision, gs_bucket, target_arch, |
| 1557 patch_sha, out_dir): |
| 1558 """Checks and downloads build archive for a given revision. |
| 1559 |
| 1560 Checks for build archive with Git hash or SVN revision. If either of the |
| 1561 file exists, then downloads the archive file. |
| 1562 |
| 1563 Args: |
| 1564 revision: A Git hash revision. |
| 1565 gs_bucket: Cloud storage bucket name |
| 1566 target_arch: 32 or 64 bit build target |
| 1567 patch: A DEPS patch (used while bisecting 3rd party repositories). |
| 1568 out_dir: Build output directory where downloaded file is stored. |
| 1569 |
| 1570 Returns: |
| 1571 Downloaded archive file path if exists, otherwise None. |
| 1572 """ |
| 1573 # Source archive file path on cloud storage using Git revision. |
| 1574 source_file = GetRemoteBuildPath(revision, target_arch, patch_sha) |
| 1575 downloaded_archive = FetchFromCloudStorage(gs_bucket, source_file, out_dir) |
| 1576 if not downloaded_archive: |
| 1577 # Get SVN revision for the given SHA. |
| 1578 svn_revision = self.source_control.SVNFindRev(revision) |
| 1579 if svn_revision: |
| 1580 # Source archive file path on cloud storage using SVN revision. |
| 1581 source_file = GetRemoteBuildPath(svn_revision, target_arch, patch_sha) |
| 1582 return FetchFromCloudStorage(gs_bucket, source_file, out_dir) |
| 1583 return downloaded_archive |
| 1584 |
| 1556 def DownloadCurrentBuild(self, revision, build_type='Release', patch=None): | 1585 def DownloadCurrentBuild(self, revision, build_type='Release', patch=None): |
| 1557 """Downloads the build archive for the given revision. | 1586 """Downloads the build archive for the given revision. |
| 1558 | 1587 |
| 1559 Args: | 1588 Args: |
| 1560 revision: The SVN revision to build. | 1589 revision: The Git revision to download or build. |
| 1561 build_type: Target build type ('Release', 'Debug', 'Release_x64' etc.) | 1590 build_type: Target build type ('Release', 'Debug', 'Release_x64' etc.) |
| 1591 patch: A DEPS patch (used while bisecting 3rd party repositories). |
| 1562 | 1592 |
| 1563 Returns: | 1593 Returns: |
| 1564 True if download succeeds, otherwise False. | 1594 True if download succeeds, otherwise False. |
| 1565 """ | 1595 """ |
| 1566 patch_sha = None | 1596 patch_sha = None |
| 1567 if patch: | 1597 if patch: |
| 1568 # Get the SHA of the DEPS changes patch. | 1598 # Get the SHA of the DEPS changes patch. |
| 1569 patch_sha = GetSHA1HexDigest(patch) | 1599 patch_sha = GetSHA1HexDigest(patch) |
| 1570 | 1600 |
| 1571 # Update the DEPS changes patch with a patch to create a new file named | 1601 # Update the DEPS changes patch with a patch to create a new file named |
| 1572 # 'DEPS.sha' and add patch_sha evaluated above to it. | 1602 # 'DEPS.sha' and add patch_sha evaluated above to it. |
| 1573 patch = '%s\n%s' % (patch, DEPS_SHA_PATCH % {'deps_sha': patch_sha}) | 1603 patch = '%s\n%s' % (patch, DEPS_SHA_PATCH % {'deps_sha': patch_sha}) |
| 1574 | 1604 |
| 1575 # Source archive file path on cloud storage. | |
| 1576 source_file = GetRemoteBuildPath(revision, self.opts.target_arch, patch_sha) | |
| 1577 | |
| 1578 # Get Build output directory | 1605 # Get Build output directory |
| 1579 abs_build_dir = os.path.abspath( | 1606 abs_build_dir = os.path.abspath( |
| 1580 self.builder.GetBuildOutputDirectory(self.opts, self.src_cwd)) | 1607 self.builder.GetBuildOutputDirectory(self.opts, self.src_cwd)) |
| 1581 # Downloaded archive file path. | |
| 1582 downloaded_file = os.path.join( | |
| 1583 abs_build_dir, | |
| 1584 GetZipFileName(revision, self.opts.target_arch, patch_sha)) | |
| 1585 | 1608 |
| 1586 fetch_build_func = lambda: FetchFromCloudStorage(self.opts.gs_bucket, | 1609 fetch_build_func = lambda: self.GetBuildArchiveForRevision( |
| 1587 source_file, | 1610 revision, self.opts.gs_bucket, self.opts.target_arch, |
| 1588 abs_build_dir) | 1611 patch_sha, abs_build_dir) |
| 1589 | 1612 |
| 1590 if not fetch_build_func(): | 1613 # Downloaded archive file path, downloads build archive for given revision. |
| 1591 if not self.PostBuildRequestAndWait(revision, | 1614 downloaded_file = fetch_build_func() |
| 1592 fetch_build=fetch_build_func, | 1615 |
| 1593 patch=patch): | 1616 # When build archive doesn't exists, post a build request to tryserver |
| 1594 raise RuntimeError('Somewthing went wrong while processing build' | 1617 # and wait for the build to be produced. |
| 1595 'request for: %s' % revision) | 1618 if not downloaded_file: |
| 1619 downloaded_file = self.PostBuildRequestAndWait( |
| 1620 revision, fetch_build=fetch_build_func, patch=patch) |
| 1621 if not downloaded_file: |
| 1622 return False |
| 1623 |
| 1596 # Generic name for the archive, created when archive file is extracted. | 1624 # Generic name for the archive, created when archive file is extracted. |
| 1597 output_dir = os.path.join( | 1625 output_dir = os.path.join( |
| 1598 abs_build_dir, GetZipFileName(target_arch=self.opts.target_arch)) | 1626 abs_build_dir, GetZipFileName(target_arch=self.opts.target_arch)) |
| 1599 # Unzip build archive directory. | 1627 # Unzip build archive directory. |
| 1600 try: | 1628 try: |
| 1601 RmTreeAndMkDir(output_dir, skip_makedir=True) | 1629 RmTreeAndMkDir(output_dir, skip_makedir=True) |
| 1602 ExtractZip(downloaded_file, abs_build_dir) | 1630 ExtractZip(downloaded_file, abs_build_dir) |
| 1603 if os.path.exists(output_dir): | 1631 if os.path.exists(output_dir): |
| 1604 self.BackupOrRestoreOutputdirectory(restore=False) | 1632 self.BackupOrRestoreOutputdirectory(restore=False) |
| 1605 # Build output directory based on target(e.g. out/Release, out/Debug). | 1633 # Build output directory based on target(e.g. out/Release, out/Debug). |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1627 | 1655 |
| 1628 Args: | 1656 Args: |
| 1629 fetch_build: Function to check and download build from cloud storage. | 1657 fetch_build: Function to check and download build from cloud storage. |
| 1630 bot_name: Builder bot name on tryserver. | 1658 bot_name: Builder bot name on tryserver. |
| 1631 builder_host Tryserver hostname. | 1659 builder_host Tryserver hostname. |
| 1632 builder_port: Tryserver port. | 1660 builder_port: Tryserver port. |
| 1633 build_request_id: A unique ID of the build request posted to tryserver. | 1661 build_request_id: A unique ID of the build request posted to tryserver. |
| 1634 max_timeout: Maximum time to wait for the build. | 1662 max_timeout: Maximum time to wait for the build. |
| 1635 | 1663 |
| 1636 Returns: | 1664 Returns: |
| 1637 True if build exists and download is successful, otherwise throws | 1665 Downloaded archive file path if exists, otherwise None. |
| 1638 RuntimeError exception when time elapse. | |
| 1639 """ | 1666 """ |
| 1640 # Build number on the tryserver. | 1667 # Build number on the tryserver. |
| 1641 build_num = None | 1668 build_num = None |
| 1642 # Interval to check build on cloud storage. | 1669 # Interval to check build on cloud storage. |
| 1643 poll_interval = 60 | 1670 poll_interval = 60 |
| 1644 # Interval to check build status on tryserver. | 1671 # Interval to check build status on tryserver. |
| 1645 status_check_interval = 600 | 1672 status_check_interval = 600 |
| 1646 last_status_check = time.time() | 1673 last_status_check = time.time() |
| 1647 start_time = time.time() | 1674 start_time = time.time() |
| 1648 while True: | 1675 while True: |
| 1649 # Checks for build on gs://chrome-perf and download if exists. | 1676 # Checks for build on gs://chrome-perf and download if exists. |
| 1650 res = fetch_build() | 1677 res = fetch_build() |
| 1651 if res: | 1678 if res: |
| 1652 return (res, 'Build successfully found') | 1679 return (res, 'Build successfully found') |
| 1653 elapsed_status_check = time.time() - last_status_check | 1680 elapsed_status_check = time.time() - last_status_check |
| 1654 # To avoid overloading tryserver with status check requests, we check | 1681 # To avoid overloading tryserver with status check requests, we check |
| 1655 # build status for every 10 mins. | 1682 # build status for every 10 mins. |
| 1656 if elapsed_status_check > status_check_interval: | 1683 if elapsed_status_check > status_check_interval: |
| 1657 last_status_check = time.time() | 1684 last_status_check = time.time() |
| 1658 if not build_num: | 1685 if not build_num: |
| 1659 # Get the build number on tryserver for the current build. | 1686 # Get the build number on tryserver for the current build. |
| 1660 build_num = bisect_builder.GetBuildNumFromBuilder( | 1687 build_num = bisect_builder.GetBuildNumFromBuilder( |
| 1661 build_request_id, bot_name, builder_host, builder_port) | 1688 build_request_id, bot_name, builder_host, builder_port) |
| 1662 # Check the status of build using the build number. | 1689 # Check the status of build using the build number. |
| 1663 # Note: Build is treated as PENDING if build number is not found | 1690 # Note: Build is treated as PENDING if build number is not found |
| 1664 # on the the tryserver. | 1691 # on the the tryserver. |
| 1665 build_status, status_link = bisect_builder.GetBuildStatus( | 1692 build_status, status_link = bisect_builder.GetBuildStatus( |
| 1666 build_num, bot_name, builder_host, builder_port) | 1693 build_num, bot_name, builder_host, builder_port) |
| 1667 if build_status == bisect_builder.FAILED: | 1694 if build_status == bisect_builder.FAILED: |
| 1668 return (False, 'Failed to produce build, log: %s' % status_link) | 1695 return (None, 'Failed to produce build, log: %s' % status_link) |
| 1669 elapsed_time = time.time() - start_time | 1696 elapsed_time = time.time() - start_time |
| 1670 if elapsed_time > max_timeout: | 1697 if elapsed_time > max_timeout: |
| 1671 return (False, 'Timed out: %ss without build' % max_timeout) | 1698 return (None, 'Timed out: %ss without build' % max_timeout) |
| 1672 | 1699 |
| 1673 print 'Time elapsed: %ss without build.' % elapsed_time | 1700 print 'Time elapsed: %ss without build.' % elapsed_time |
| 1674 time.sleep(poll_interval) | 1701 time.sleep(poll_interval) |
| 1675 | 1702 |
| 1676 def PostBuildRequestAndWait(self, revision, fetch_build, patch=None): | 1703 def PostBuildRequestAndWait(self, revision, fetch_build, patch=None): |
| 1677 """POSTs the build request job to the tryserver instance.""" | 1704 """POSTs the build request job to the tryserver instance. |
| 1705 |
| 1706 A try job build request is posted to tryserver.chromium.perf master, |
| 1707 and waits for the binaries to be produced and archived on cloud storage. |
| 1708 Once the build is ready and stored onto cloud, build archive is downloaded |
| 1709 into the output folder. |
| 1710 |
| 1711 Args: |
| 1712 revision: A Git hash revision. |
| 1713 fetch_build: Function to check and download build from cloud storage. |
| 1714 patch: A DEPS patch (used while bisecting 3rd party repositories). |
| 1715 |
| 1716 Returns: |
| 1717 Downloaded archive file path when requested build exists and download is |
| 1718 successful, otherwise None. |
| 1719 """ |
| 1720 # Get SVN revision for the given SHA. |
| 1721 svn_revision = self.source_control.SVNFindRev(revision) |
| 1722 if not svn_revision: |
| 1723 raise RuntimeError( |
| 1724 'Failed to determine SVN revision for %s' % revision) |
| 1678 | 1725 |
| 1679 def GetBuilderNameAndBuildTime(target_arch='ia32'): | 1726 def GetBuilderNameAndBuildTime(target_arch='ia32'): |
| 1680 """Gets builder bot name and buildtime in seconds based on platform.""" | 1727 """Gets builder bot name and buildtime in seconds based on platform.""" |
| 1681 # Bot names should match the one listed in tryserver.chromium's | 1728 # Bot names should match the one listed in tryserver.chromium's |
| 1682 # master.cfg which produces builds for bisect. | 1729 # master.cfg which produces builds for bisect. |
| 1683 if IsWindows(): | 1730 if IsWindows(): |
| 1684 if Is64BitWindows() and target_arch == 'x64': | 1731 if Is64BitWindows() and target_arch == 'x64': |
| 1685 return ('win_perf_bisect_builder', MAX_WIN_BUILD_TIME) | 1732 return ('win_perf_bisect_builder', MAX_WIN_BUILD_TIME) |
| 1686 return ('win_perf_bisect_builder', MAX_WIN_BUILD_TIME) | 1733 return ('win_perf_bisect_builder', MAX_WIN_BUILD_TIME) |
| 1687 if IsLinux(): | 1734 if IsLinux(): |
| 1688 return ('linux_perf_bisect_builder', MAX_LINUX_BUILD_TIME) | 1735 return ('linux_perf_bisect_builder', MAX_LINUX_BUILD_TIME) |
| 1689 if IsMac(): | 1736 if IsMac(): |
| 1690 return ('mac_perf_bisect_builder', MAX_MAC_BUILD_TIME) | 1737 return ('mac_perf_bisect_builder', MAX_MAC_BUILD_TIME) |
| 1691 raise NotImplementedError('Unsupported Platform "%s".' % sys.platform) | 1738 raise NotImplementedError('Unsupported Platform "%s".' % sys.platform) |
| 1692 if not fetch_build: | 1739 if not fetch_build: |
| 1693 return False | 1740 return False |
| 1694 | 1741 |
| 1695 bot_name, build_timeout = GetBuilderNameAndBuildTime(self.opts.target_arch) | 1742 bot_name, build_timeout = GetBuilderNameAndBuildTime(self.opts.target_arch) |
| 1696 builder_host = self.opts.builder_host | 1743 builder_host = self.opts.builder_host |
| 1697 builder_port = self.opts.builder_port | 1744 builder_port = self.opts.builder_port |
| 1698 # Create a unique ID for each build request posted to tryserver builders. | 1745 # Create a unique ID for each build request posted to tryserver builders. |
| 1699 # This ID is added to "Reason" property in build's json. | 1746 # This ID is added to "Reason" property in build's json. |
| 1700 build_request_id = GetSHA1HexDigest( | 1747 build_request_id = GetSHA1HexDigest( |
| 1701 '%s-%s-%s' % (revision, patch, time.time())) | 1748 '%s-%s-%s' % (svn_revision, patch, time.time())) |
| 1702 | 1749 |
| 1703 # Creates a try job description. | 1750 # Creates a try job description. |
| 1704 job_args = {'host': builder_host, | 1751 job_args = {'host': builder_host, |
| 1705 'port': builder_port, | 1752 'port': builder_port, |
| 1706 'revision': 'src@%s' % revision, | 1753 'revision': 'src@%s' % svn_revision, |
| 1707 'bot': bot_name, | 1754 'bot': bot_name, |
| 1708 'name': build_request_id | 1755 'name': build_request_id |
| 1709 } | 1756 } |
| 1710 # Update patch information if supplied. | 1757 # Update patch information if supplied. |
| 1711 if patch: | 1758 if patch: |
| 1712 job_args['patch'] = patch | 1759 job_args['patch'] = patch |
| 1713 # Posts job to build the revision on the server. | 1760 # Posts job to build the revision on the server. |
| 1714 if bisect_builder.PostTryJob(job_args): | 1761 if bisect_builder.PostTryJob(job_args): |
| 1715 status, error_msg = self.WaitUntilBuildIsReady(fetch_build, | 1762 target_file, error_msg = self.WaitUntilBuildIsReady(fetch_build, |
| 1716 bot_name, | 1763 bot_name, |
| 1717 builder_host, | 1764 builder_host, |
| 1718 builder_port, | 1765 builder_port, |
| 1719 build_request_id, | 1766 build_request_id, |
| 1720 build_timeout) | 1767 build_timeout) |
| 1721 if not status: | 1768 if not target_file: |
| 1722 raise RuntimeError('%s [revision: %s]' % (error_msg, revision)) | 1769 print '%s [revision: %s]' % (error_msg, svn_revision) |
| 1723 return True | 1770 return None |
| 1724 return False | 1771 return target_file |
| 1772 print 'Failed to post build request for revision: [%s]' % svn_revision |
| 1773 return None |
| 1725 | 1774 |
| 1726 def IsDownloadable(self, depot): | 1775 def IsDownloadable(self, depot): |
| 1727 """Checks if build is downloadable based on target platform and depot.""" | 1776 """Checks if build is downloadable based on target platform and depot.""" |
| 1728 if self.opts.target_platform in ['chromium'] and self.opts.gs_bucket: | 1777 if self.opts.target_platform in ['chromium'] and self.opts.gs_bucket: |
| 1729 return (depot == 'chromium' or | 1778 return (depot == 'chromium' or |
| 1730 'chromium' in DEPOT_DEPS_NAME[depot]['from'] or | 1779 'chromium' in DEPOT_DEPS_NAME[depot]['from'] or |
| 1731 'v8' in DEPOT_DEPS_NAME[depot]['from']) | 1780 'v8' in DEPOT_DEPS_NAME[depot]['from']) |
| 1732 return False | 1781 return False |
| 1733 | 1782 |
| 1734 def UpdateDeps(self, revision, depot, deps_file): | 1783 def UpdateDeps(self, revision, depot, deps_file): |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1914 return True | 1963 return True |
| 1915 cwd = os.getcwd() | 1964 cwd = os.getcwd() |
| 1916 os.chdir(self.src_cwd) | 1965 os.chdir(self.src_cwd) |
| 1917 # Fetch build archive for the given revision from the cloud storage when | 1966 # Fetch build archive for the given revision from the cloud storage when |
| 1918 # the storage bucket is passed. | 1967 # the storage bucket is passed. |
| 1919 if self.IsDownloadable(depot) and revision: | 1968 if self.IsDownloadable(depot) and revision: |
| 1920 deps_patch = None | 1969 deps_patch = None |
| 1921 if depot != 'chromium': | 1970 if depot != 'chromium': |
| 1922 # Create a DEPS patch with new revision for dependency repository. | 1971 # Create a DEPS patch with new revision for dependency repository. |
| 1923 (revision, deps_patch) = self.CreateDEPSPatch(depot, revision) | 1972 (revision, deps_patch) = self.CreateDEPSPatch(depot, revision) |
| 1924 # Get SVN revision for the given SHA, since builds are archived using SVN | 1973 if self.DownloadCurrentBuild(revision, patch=deps_patch): |
| 1925 # revision. | |
| 1926 chromium_revision = self.source_control.SVNFindRev(revision) | |
| 1927 if not chromium_revision: | |
| 1928 raise RuntimeError( | |
| 1929 'Failed to determine SVN revision for %s' % revision) | |
| 1930 if self.DownloadCurrentBuild(chromium_revision, patch=deps_patch): | |
| 1931 os.chdir(cwd) | 1974 os.chdir(cwd) |
| 1932 if deps_patch: | 1975 if deps_patch: |
| 1933 # Reverts the changes to DEPS file. | 1976 # Reverts the changes to DEPS file. |
| 1934 self.source_control.CheckoutFileAtRevision(bisect_utils.FILE_DEPS, | 1977 self.source_control.CheckoutFileAtRevision(bisect_utils.FILE_DEPS, |
| 1935 revision, | 1978 revision, |
| 1936 cwd=self.src_cwd) | 1979 cwd=self.src_cwd) |
| 1937 return True | 1980 return True |
| 1938 raise RuntimeError('Failed to download build archive for revision %s.\n' | 1981 return False |
| 1939 'Unfortunately, bisection couldn\'t continue any ' | |
| 1940 'further. Please try running script without ' | |
| 1941 '--gs_bucket flag to produce local builds.' % revision) | |
| 1942 | 1982 |
| 1943 | 1983 # These codes are executed when bisect bots builds binaries locally. |
| 1944 build_success = self.builder.Build(depot, self.opts) | 1984 build_success = self.builder.Build(depot, self.opts) |
| 1945 os.chdir(cwd) | 1985 os.chdir(cwd) |
| 1946 return build_success | 1986 return build_success |
| 1947 | 1987 |
| 1948 def RunGClientHooks(self): | 1988 def RunGClientHooks(self): |
| 1949 """Runs gclient with runhooks command. | 1989 """Runs gclient with runhooks command. |
| 1950 | 1990 |
| 1951 Returns: | 1991 Returns: |
| 1952 True if gclient reports no errors. | 1992 True if gclient reports no errors. |
| 1953 """ | 1993 """ |
| (...skipping 2023 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3977 # The perf dashboard scrapes the "results" step in order to comment on | 4017 # The perf dashboard scrapes the "results" step in order to comment on |
| 3978 # bugs. If you change this, please update the perf dashboard as well. | 4018 # bugs. If you change this, please update the perf dashboard as well. |
| 3979 bisect_utils.OutputAnnotationStepStart('Results') | 4019 bisect_utils.OutputAnnotationStepStart('Results') |
| 3980 print 'Error: %s' % e.message | 4020 print 'Error: %s' % e.message |
| 3981 if opts.output_buildbot_annotations: | 4021 if opts.output_buildbot_annotations: |
| 3982 bisect_utils.OutputAnnotationStepClosed() | 4022 bisect_utils.OutputAnnotationStepClosed() |
| 3983 return 1 | 4023 return 1 |
| 3984 | 4024 |
| 3985 if __name__ == '__main__': | 4025 if __name__ == '__main__': |
| 3986 sys.exit(main()) | 4026 sys.exit(main()) |
| OLD | NEW |