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 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 CROS_CHROMEOS_PATTERN = 'chromeos-base/chromeos-chrome' | 153 CROS_CHROMEOS_PATTERN = 'chromeos-base/chromeos-chrome' |
154 | 154 |
155 # Possible return values from BisectPerformanceMetrics.SyncBuildAndRunRevision. | 155 # Possible return values from BisectPerformanceMetrics.RunTest. |
156 BUILD_RESULT_SUCCEED = 0 | 156 BUILD_RESULT_SUCCEED = 0 |
157 BUILD_RESULT_FAIL = 1 | 157 BUILD_RESULT_FAIL = 1 |
158 BUILD_RESULT_SKIPPED = 2 | 158 BUILD_RESULT_SKIPPED = 2 |
159 | 159 |
160 # Maximum time in seconds to wait after posting build request to the try server. | 160 # 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 | 161 # TODO: Change these values based on the actual time taken by buildbots on |
162 # the try server. | 162 # the try server. |
163 MAX_MAC_BUILD_TIME = 14400 | 163 MAX_MAC_BUILD_TIME = 14400 |
164 MAX_WIN_BUILD_TIME = 14400 | 164 MAX_WIN_BUILD_TIME = 14400 |
165 MAX_LINUX_BUILD_TIME = 14400 | 165 MAX_LINUX_BUILD_TIME = 14400 |
(...skipping 1014 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1180 results['chromium'] = output.strip() | 1180 results['chromium'] = output.strip() |
1181 | 1181 |
1182 if depot == 'v8': | 1182 if depot == 'v8': |
1183 # We can't try to map the trunk revision to bleeding edge yet, because | 1183 # We can't try to map the trunk revision to bleeding edge yet, because |
1184 # we don't know which direction to try to search in. Have to wait until | 1184 # we don't know which direction to try to search in. Have to wait until |
1185 # the bisect has narrowed the results down to 2 v8 rolls. | 1185 # the bisect has narrowed the results down to 2 v8 rolls. |
1186 results['v8_bleeding_edge'] = None | 1186 results['v8_bleeding_edge'] = None |
1187 | 1187 |
1188 return results | 1188 return results |
1189 | 1189 |
1190 def BackupOrRestoreOutputdirectory(self, restore=False, build_type='Release'): | 1190 def BackupOrRestoreOutputDirectory(self, restore=False, build_type='Release'): |
1191 """Backs up or restores build output directory based on restore argument. | 1191 """Backs up or restores build output directory based on restore argument. |
1192 | 1192 |
1193 Args: | 1193 Args: |
1194 restore: Indicates whether to restore or backup. Default is False(Backup) | 1194 restore: Indicates whether to restore or backup. Default is False(Backup) |
1195 build_type: Target build type ('Release', 'Debug', 'Release_x64' etc.) | 1195 build_type: Target build type ('Release', 'Debug', 'Release_x64' etc.) |
1196 | 1196 |
1197 Returns: | 1197 Returns: |
1198 Path to backup or restored location as string. otherwise None if it fails. | 1198 Path to backup or restored location as string. otherwise None if it fails. |
1199 """ | 1199 """ |
1200 build_dir = os.path.abspath( | 1200 build_dir = os.path.abspath( |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1278 revision, fetch_build=fetch_build_func, patch=patch) | 1278 revision, fetch_build=fetch_build_func, patch=patch) |
1279 if not downloaded_file: | 1279 if not downloaded_file: |
1280 return False | 1280 return False |
1281 | 1281 |
1282 # Generic name for the archive, created when archive file is extracted. | 1282 # Generic name for the archive, created when archive file is extracted. |
1283 output_dir = os.path.join( | 1283 output_dir = os.path.join( |
1284 abs_build_dir, GetZipFileName(target_arch=self.opts.target_arch)) | 1284 abs_build_dir, GetZipFileName(target_arch=self.opts.target_arch)) |
1285 # Unzip build archive directory. | 1285 # Unzip build archive directory. |
1286 try: | 1286 try: |
1287 RmTreeAndMkDir(output_dir, skip_makedir=True) | 1287 RmTreeAndMkDir(output_dir, skip_makedir=True) |
1288 self.BackupOrRestoreOutputdirectory(restore=False) | 1288 self.BackupOrRestoreOutputDirectory(restore=False) |
1289 # Build output directory based on target(e.g. out/Release, out/Debug). | 1289 # Build output directory based on target(e.g. out/Release, out/Debug). |
1290 target_build_output_dir = os.path.join(abs_build_dir, build_type) | 1290 target_build_output_dir = os.path.join(abs_build_dir, build_type) |
1291 ExtractZip(downloaded_file, abs_build_dir) | 1291 ExtractZip(downloaded_file, abs_build_dir) |
1292 if not os.path.exists(output_dir): | 1292 if not os.path.exists(output_dir): |
1293 # Due to recipe changes, the builds extract folder contains | 1293 # Due to recipe changes, the builds extract folder contains |
1294 # out/Release instead of full-build-<platform>/Release. | 1294 # out/Release instead of full-build-<platform>/Release. |
1295 if os.path.exists(os.path.join(abs_build_dir, 'out', build_type)): | 1295 if os.path.exists(os.path.join(abs_build_dir, 'out', build_type)): |
1296 output_dir = os.path.join(abs_build_dir, 'out', build_type) | 1296 output_dir = os.path.join(abs_build_dir, 'out', build_type) |
1297 else: | 1297 else: |
1298 raise IOError('Missing extracted folder %s ' % output_dir) | 1298 raise IOError('Missing extracted folder %s ' % output_dir) |
1299 | 1299 |
1300 print 'Moving build from %s to %s' % ( | 1300 print 'Moving build from %s to %s' % ( |
1301 output_dir, target_build_output_dir) | 1301 output_dir, target_build_output_dir) |
1302 shutil.move(output_dir, target_build_output_dir) | 1302 shutil.move(output_dir, target_build_output_dir) |
1303 return True | 1303 return True |
1304 except Exception as e: | 1304 except Exception as e: |
1305 print 'Something went wrong while extracting archive file: %s' % e | 1305 print 'Something went wrong while extracting archive file: %s' % e |
1306 self.BackupOrRestoreOutputdirectory(restore=True) | 1306 self.BackupOrRestoreOutputDirectory(restore=True) |
1307 # Cleanup any leftovers from unzipping. | 1307 # Cleanup any leftovers from unzipping. |
1308 if os.path.exists(output_dir): | 1308 if os.path.exists(output_dir): |
1309 RmTreeAndMkDir(output_dir, skip_makedir=True) | 1309 RmTreeAndMkDir(output_dir, skip_makedir=True) |
1310 finally: | 1310 finally: |
1311 # Delete downloaded archive | 1311 # Delete downloaded archive |
1312 if os.path.exists(downloaded_file): | 1312 if os.path.exists(downloaded_file): |
1313 os.remove(downloaded_file) | 1313 os.remove(downloaded_file) |
1314 return False | 1314 return False |
1315 | 1315 |
1316 def PostBuildRequestAndWait(self, git_revision, fetch_build, patch=None): | 1316 def PostBuildRequestAndWait(self, git_revision, fetch_build, patch=None): |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1704 'std_err': standard_err, | 1704 'std_err': standard_err, |
1705 'std_dev': standard_dev, | 1705 'std_dev': standard_dev, |
1706 'values': metric_values, | 1706 'values': metric_values, |
1707 } | 1707 } |
1708 | 1708 |
1709 print 'Results of performance test: %12f %12f' % ( | 1709 print 'Results of performance test: %12f %12f' % ( |
1710 truncated_mean, standard_err) | 1710 truncated_mean, standard_err) |
1711 print | 1711 print |
1712 return (values, success_code, output_of_all_runs) | 1712 return (values, success_code, output_of_all_runs) |
1713 | 1713 |
1714 def FindAllRevisionsToSync(self, revision, depot): | 1714 def _FindAllRevisionsToSync(self, revision, depot): |
1715 """Finds all dependent revisions and depots that need to be synced. | 1715 """Finds all dependent revisions and depots that need to be synced. |
1716 | 1716 |
1717 For example skia is broken up into 3 git mirrors over skia/src, | 1717 For example skia is broken up into 3 git mirrors over skia/src, |
1718 skia/gyp, and skia/include. To sync skia/src properly, one has to find | 1718 skia/gyp, and skia/include. To sync skia/src properly, one has to find |
1719 the proper revisions in skia/gyp and skia/include. | 1719 the proper revisions in skia/gyp and skia/include. |
1720 | 1720 |
1721 This is only useful in the git workflow, as an SVN depot may be split into | 1721 This is only useful in the git workflow, as an SVN depot may be split into |
1722 multiple mirrors. | 1722 multiple mirrors. |
1723 | 1723 |
1724 Args: | 1724 Args: |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1792 Returns: | 1792 Returns: |
1793 True if successful. | 1793 True if successful. |
1794 """ | 1794 """ |
1795 cwd = os.getcwd() | 1795 cwd = os.getcwd() |
1796 self.ChangeToDepotWorkingDirectory('cros') | 1796 self.ChangeToDepotWorkingDirectory('cros') |
1797 cmd = [bisect_utils.CROS_SDK_PATH, '--create'] | 1797 cmd = [bisect_utils.CROS_SDK_PATH, '--create'] |
1798 return_code = bisect_utils.RunProcess(cmd) | 1798 return_code = bisect_utils.RunProcess(cmd) |
1799 os.chdir(cwd) | 1799 os.chdir(cwd) |
1800 return not return_code | 1800 return not return_code |
1801 | 1801 |
1802 def PerformPreSyncCleanup(self, revision, depot): | 1802 def _PerformPreSyncCleanup(self, depot): |
1803 """Performs any necessary cleanup before syncing. | 1803 """Performs any necessary cleanup before syncing. |
1804 | 1804 |
| 1805 Args: |
| 1806 depot: Depot name. |
| 1807 |
1805 Returns: | 1808 Returns: |
1806 True if successful. | 1809 True if successful. |
1807 """ | 1810 """ |
1808 if depot == 'chromium' or depot == 'android-chrome': | 1811 if depot == 'chromium' or depot == 'android-chrome': |
1809 # Removes third_party/libjingle. At some point, libjingle was causing | 1812 # Removes third_party/libjingle. At some point, libjingle was causing |
1810 # issues syncing when using the git workflow (crbug.com/266324). | 1813 # issues syncing when using the git workflow (crbug.com/266324). |
1811 os.chdir(self.src_cwd) | 1814 os.chdir(self.src_cwd) |
1812 if not bisect_utils.RemoveThirdPartyDirectory('libjingle'): | 1815 if not bisect_utils.RemoveThirdPartyDirectory('libjingle'): |
1813 return False | 1816 return False |
1814 # Removes third_party/skia. At some point, skia was causing | 1817 # Removes third_party/skia. At some point, skia was causing |
1815 # issues syncing when using the git workflow (crbug.com/377951). | 1818 # issues syncing when using the git workflow (crbug.com/377951). |
1816 if not bisect_utils.RemoveThirdPartyDirectory('skia'): | 1819 if not bisect_utils.RemoveThirdPartyDirectory('skia'): |
1817 return False | 1820 return False |
1818 elif depot == 'cros': | 1821 elif depot == 'cros': |
1819 return self.PerformCrosChrootCleanup() | 1822 return self.PerformCrosChrootCleanup() |
1820 return True | 1823 return True |
1821 | 1824 |
1822 def RunPostSync(self, depot): | 1825 def _RunPostSync(self, depot): |
1823 """Performs any work after syncing. | 1826 """Performs any work after syncing. |
1824 | 1827 |
| 1828 Args: |
| 1829 depot: Depot name. |
| 1830 |
1825 Returns: | 1831 Returns: |
1826 True if successful. | 1832 True if successful. |
1827 """ | 1833 """ |
1828 if self.opts.target_platform == 'android': | 1834 if self.opts.target_platform == 'android': |
1829 if not builder.SetupAndroidBuildEnvironment(self.opts, | 1835 if not builder.SetupAndroidBuildEnvironment(self.opts, |
1830 path_to_src=self.src_cwd): | 1836 path_to_src=self.src_cwd): |
1831 return False | 1837 return False |
1832 | 1838 |
1833 if depot == 'cros': | 1839 if depot == 'cros': |
1834 return self.CreateCrosChroot() | 1840 return self.CreateCrosChroot() |
(...skipping 19 matching lines...) Expand all Loading... |
1854 cmd = ['diff-tree', '--no-commit-id', '--name-only', '-r', revision] | 1860 cmd = ['diff-tree', '--no-commit-id', '--name-only', '-r', revision] |
1855 output = bisect_utils.CheckRunGit(cmd) | 1861 output = bisect_utils.CheckRunGit(cmd) |
1856 | 1862 |
1857 files = output.splitlines() | 1863 files = output.splitlines() |
1858 | 1864 |
1859 if len(files) == 1 and files[0] == 'DEPS': | 1865 if len(files) == 1 and files[0] == 'DEPS': |
1860 return True | 1866 return True |
1861 | 1867 |
1862 return False | 1868 return False |
1863 | 1869 |
1864 def SyncBuildAndRunRevision(self, revision, depot, command_to_run, metric, | 1870 def RunTest(self, revision, depot, command, metric, skippable=False): |
1865 skippable=False): | |
1866 """Performs a full sync/build/run of the specified revision. | 1871 """Performs a full sync/build/run of the specified revision. |
1867 | 1872 |
1868 Args: | 1873 Args: |
1869 revision: The revision to sync to. | 1874 revision: The revision to sync to. |
1870 depot: The depot that's being used at the moment (src, webkit, etc.) | 1875 depot: The depot that's being used at the moment (src, webkit, etc.) |
1871 command_to_run: The command to execute the performance test. | 1876 command: The command to execute the performance test. |
1872 metric: The performance metric being tested. | 1877 metric: The performance metric being tested. |
1873 | 1878 |
1874 Returns: | 1879 Returns: |
1875 On success, a tuple containing the results of the performance test. | 1880 On success, a tuple containing the results of the performance test. |
1876 Otherwise, a tuple with the error message. | 1881 Otherwise, a tuple with the error message. |
1877 """ | 1882 """ |
| 1883 # Decide which sync program to use. |
1878 sync_client = None | 1884 sync_client = None |
1879 if depot == 'chromium' or depot == 'android-chrome': | 1885 if depot == 'chromium' or depot == 'android-chrome': |
1880 sync_client = 'gclient' | 1886 sync_client = 'gclient' |
1881 elif depot == 'cros': | 1887 elif depot == 'cros': |
1882 sync_client = 'repo' | 1888 sync_client = 'repo' |
1883 | 1889 |
1884 revisions_to_sync = self.FindAllRevisionsToSync(revision, depot) | 1890 # Decide what depots will need to be synced to what revisions. |
1885 | 1891 revisions_to_sync = self._FindAllRevisionsToSync(revision, depot) |
1886 if not revisions_to_sync: | 1892 if not revisions_to_sync: |
1887 return ('Failed to resolve dependent depots.', BUILD_RESULT_FAIL) | 1893 return ('Failed to resolve dependent depots.', BUILD_RESULT_FAIL) |
1888 | 1894 |
1889 if not self.PerformPreSyncCleanup(revision, depot): | 1895 if not self._PerformPreSyncCleanup(depot): |
1890 return ('Failed to perform pre-sync cleanup.', BUILD_RESULT_FAIL) | 1896 return ('Failed to perform pre-sync cleanup.', BUILD_RESULT_FAIL) |
1891 | 1897 |
1892 success = True | 1898 # Do the syncing for all depots. |
| 1899 if not self.opts.debug_ignore_sync: |
| 1900 if not self._SyncAllRevisions(revisions_to_sync, sync_client): |
| 1901 return ('Failed to sync: [%s]' % str(revision), BUILD_RESULT_FAIL) |
1893 | 1902 |
1894 if not self.opts.debug_ignore_sync: | 1903 # Try to do any post-sync steps. This may include "gclient runhooks". |
1895 for r in revisions_to_sync: | 1904 if not self._RunPostSync(depot): |
1896 self.ChangeToDepotWorkingDirectory(r[0]) | 1905 return ('Failed to run [gclient runhooks].', BUILD_RESULT_FAIL) |
1897 | 1906 |
1898 if sync_client: | 1907 # Skip this revision if it can be skipped. |
1899 self.PerformPreBuildCleanup() | 1908 if skippable and self.ShouldSkipRevision(depot, revision): |
| 1909 return ('Skipped revision: [%s]' % str(revision), |
| 1910 BUILD_RESULT_SKIPPED) |
1900 | 1911 |
1901 # If you're using gclient to sync, you need to specify the depot you | 1912 # Obtain a build for this revision. This may be done by requesting a build |
1902 # want so that all the dependencies sync properly as well. | 1913 # from another builder, waiting for it and downloading it. |
1903 # i.e. gclient sync src@<SHA1> | 1914 start_build_time = time.time() |
1904 current_revision = r[1] | 1915 build_success = self.BuildCurrentRevision(depot, revision) |
1905 if sync_client == 'gclient': | 1916 if not build_success: |
1906 current_revision = '%s@%s' % (DEPOT_DEPS_NAME[depot]['src'], | 1917 return ('Failed to build revision: [%s]' % str(revision), |
1907 current_revision) | 1918 BUILD_RESULT_FAIL) |
1908 if not self.source_control.SyncToRevision(current_revision, | 1919 after_build_time = time.time() |
1909 sync_client): | |
1910 success = False | |
1911 | 1920 |
1912 break | 1921 # Possibly alter the command. |
| 1922 command = self.GetCompatibleCommand(command, revision, depot) |
1913 | 1923 |
1914 if success: | 1924 # Run the command and get the results. |
1915 success = self.RunPostSync(depot) | 1925 results = self.RunPerformanceTestAndParseResults(command, metric) |
1916 if success: | |
1917 if skippable and self.ShouldSkipRevision(depot, revision): | |
1918 return ('Skipped revision: [%s]' % str(revision), | |
1919 BUILD_RESULT_SKIPPED) | |
1920 | 1926 |
1921 start_build_time = time.time() | 1927 # Restore build output directory once the tests are done, to avoid |
1922 if self.BuildCurrentRevision(depot, revision): | 1928 # any discrepancies. |
1923 after_build_time = time.time() | 1929 if self.IsDownloadable(depot) and revision: |
1924 # Hack to support things that got changed. | 1930 self.BackupOrRestoreOutputDirectory(restore=True) |
1925 command_to_run = self.GetCompatibleCommand( | |
1926 command_to_run, revision, depot) | |
1927 results = self.RunPerformanceTestAndParseResults(command_to_run, | |
1928 metric) | |
1929 # Restore build output directory once the tests are done, to avoid | |
1930 # any discrepancies. | |
1931 if self.IsDownloadable(depot) and revision: | |
1932 self.BackupOrRestoreOutputdirectory(restore=True) | |
1933 | 1931 |
1934 if results[1] == 0: | 1932 # A value other than 0 indicates that the test couldn't be run, and results |
1935 external_revisions = self._Get3rdPartyRevisions(depot) | 1933 # should also include an error message. |
| 1934 if results[1] != 0: |
| 1935 return results |
1936 | 1936 |
1937 if not external_revisions is None: | 1937 external_revisions = self._Get3rdPartyRevisions(depot) |
1938 return (results[0], results[1], external_revisions, | 1938 |
1939 time.time() - after_build_time, after_build_time - | 1939 if not external_revisions is None: |
1940 start_build_time) | 1940 return (results[0], results[1], external_revisions, |
1941 else: | 1941 time.time() - after_build_time, after_build_time - |
1942 return ('Failed to parse DEPS file for external revisions.', | 1942 start_build_time) |
1943 BUILD_RESULT_FAIL) | |
1944 else: | |
1945 return results | |
1946 else: | |
1947 return ('Failed to build revision: [%s]' % str(revision), | |
1948 BUILD_RESULT_FAIL) | |
1949 else: | |
1950 return ('Failed to run [gclient runhooks].', BUILD_RESULT_FAIL) | |
1951 else: | 1943 else: |
1952 return ('Failed to sync revision: [%s]' % str(revision), | 1944 return ('Failed to parse DEPS file for external revisions.', |
1953 BUILD_RESULT_FAIL) | 1945 BUILD_RESULT_FAIL) |
| 1946 |
| 1947 def _SyncAllRevisions(self, revisions_to_sync, sync_client): |
| 1948 """Syncs multiple depots to particular revisions. |
| 1949 |
| 1950 Args: |
| 1951 revisions_to_sync: A list of (depot, revision) pairs to be synced. |
| 1952 sync_client: Program used to sync, e.g. "gclient", "repo". Can be None. |
| 1953 |
| 1954 Returns: |
| 1955 True if successful, False otherwise. |
| 1956 """ |
| 1957 for depot, revision in revisions_to_sync: |
| 1958 self.ChangeToDepotWorkingDirectory(depot) |
| 1959 |
| 1960 if sync_client: |
| 1961 self.PerformPreBuildCleanup() |
| 1962 |
| 1963 # When using gclient to sync, you need to specify the depot you |
| 1964 # want so that all the dependencies sync properly as well. |
| 1965 # i.e. gclient sync src@<SHA1> |
| 1966 if sync_client == 'gclient': |
| 1967 revision = '%s@%s' % (DEPOT_DEPS_NAME[depot]['src'], revision) |
| 1968 |
| 1969 sync_success = self.source_control.SyncToRevision(revision, sync_client) |
| 1970 if not sync_success: |
| 1971 return False |
| 1972 |
| 1973 return True |
1954 | 1974 |
1955 def _CheckIfRunPassed(self, current_value, known_good_value, known_bad_value): | 1975 def _CheckIfRunPassed(self, current_value, known_good_value, known_bad_value): |
1956 """Given known good and bad values, decide if the current_value passed | 1976 """Given known good and bad values, decide if the current_value passed |
1957 or failed. | 1977 or failed. |
1958 | 1978 |
1959 Args: | 1979 Args: |
1960 current_value: The value of the metric being checked. | 1980 current_value: The value of the metric being checked. |
1961 known_bad_value: The reference value for a "failed" run. | 1981 known_bad_value: The reference value for a "failed" run. |
1962 known_good_value: The reference value for a "passed" run. | 1982 known_good_value: The reference value for a "passed" run. |
1963 | 1983 |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2112 Args: | 2132 Args: |
2113 good_rev: The last known good revision where the performance regression | 2133 good_rev: The last known good revision where the performance regression |
2114 has not occurred yet. | 2134 has not occurred yet. |
2115 bad_rev: A revision where the performance regression has already occurred. | 2135 bad_rev: A revision where the performance regression has already occurred. |
2116 cmd: The command to execute the performance test. | 2136 cmd: The command to execute the performance test. |
2117 metric: The metric being tested for regression. | 2137 metric: The metric being tested for regression. |
2118 | 2138 |
2119 Returns: | 2139 Returns: |
2120 A tuple with the results of building and running each revision. | 2140 A tuple with the results of building and running each revision. |
2121 """ | 2141 """ |
2122 bad_run_results = self.SyncBuildAndRunRevision( | 2142 bad_run_results = self.RunTest(bad_rev, target_depot, cmd, metric) |
2123 bad_rev, target_depot, cmd, metric) | |
2124 | 2143 |
2125 good_run_results = None | 2144 good_run_results = None |
2126 | 2145 |
2127 if not bad_run_results[1]: | 2146 if not bad_run_results[1]: |
2128 good_run_results = self.SyncBuildAndRunRevision( | 2147 good_run_results = self.RunTest(good_rev, target_depot, cmd, metric) |
2129 good_rev, target_depot, cmd, metric) | |
2130 | 2148 |
2131 return (bad_run_results, good_run_results) | 2149 return (bad_run_results, good_run_results) |
2132 | 2150 |
2133 def PrintRevisionsToBisectMessage(self, revision_list, depot): | 2151 def PrintRevisionsToBisectMessage(self, revision_list, depot): |
2134 if self.opts.output_buildbot_annotations: | 2152 if self.opts.output_buildbot_annotations: |
2135 step_name = 'Bisection Range: [%s - %s]' % ( | 2153 step_name = 'Bisection Range: [%s - %s]' % ( |
2136 revision_list[len(revision_list)-1], revision_list[0]) | 2154 revision_list[len(revision_list)-1], revision_list[0]) |
2137 bisect_utils.OutputAnnotationStepStart(step_name) | 2155 bisect_utils.OutputAnnotationStepStart(step_name) |
2138 | 2156 |
2139 print | 2157 print |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2503 next_revision_depot = next_revision_data['depot'] | 2521 next_revision_depot = next_revision_data['depot'] |
2504 | 2522 |
2505 self.ChangeToDepotWorkingDirectory(next_revision_depot) | 2523 self.ChangeToDepotWorkingDirectory(next_revision_depot) |
2506 | 2524 |
2507 if self.opts.output_buildbot_annotations: | 2525 if self.opts.output_buildbot_annotations: |
2508 step_name = 'Working on [%s]' % next_revision_id | 2526 step_name = 'Working on [%s]' % next_revision_id |
2509 bisect_utils.OutputAnnotationStepStart(step_name) | 2527 bisect_utils.OutputAnnotationStepStart(step_name) |
2510 | 2528 |
2511 print 'Working on revision: [%s]' % next_revision_id | 2529 print 'Working on revision: [%s]' % next_revision_id |
2512 | 2530 |
2513 run_results = self.SyncBuildAndRunRevision(next_revision_id, | 2531 run_results = self.RunTest( |
2514 next_revision_depot, | 2532 next_revision_id, next_revision_depot, command_to_run, metric, |
2515 command_to_run, | 2533 skippable=True) |
2516 metric, skippable=True) | |
2517 | 2534 |
2518 # If the build is successful, check whether or not the metric | 2535 # If the build is successful, check whether or not the metric |
2519 # had regressed. | 2536 # had regressed. |
2520 if not run_results[1]: | 2537 if not run_results[1]: |
2521 if len(run_results) > 2: | 2538 if len(run_results) > 2: |
2522 next_revision_data['external'] = run_results[2] | 2539 next_revision_data['external'] = run_results[2] |
2523 next_revision_data['perf_time'] = run_results[3] | 2540 next_revision_data['perf_time'] = run_results[3] |
2524 next_revision_data['build_time'] = run_results[4] | 2541 next_revision_data['build_time'] = run_results[4] |
2525 | 2542 |
2526 passed_regression = self._CheckIfRunPassed(run_results[0], | 2543 passed_regression = self._CheckIfRunPassed(run_results[0], |
(...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3342 # bugs. If you change this, please update the perf dashboard as well. | 3359 # bugs. If you change this, please update the perf dashboard as well. |
3343 bisect_utils.OutputAnnotationStepStart('Results') | 3360 bisect_utils.OutputAnnotationStepStart('Results') |
3344 print 'Error: %s' % e.message | 3361 print 'Error: %s' % e.message |
3345 if opts.output_buildbot_annotations: | 3362 if opts.output_buildbot_annotations: |
3346 bisect_utils.OutputAnnotationStepClosed() | 3363 bisect_utils.OutputAnnotationStepClosed() |
3347 return 1 | 3364 return 1 |
3348 | 3365 |
3349 | 3366 |
3350 if __name__ == '__main__': | 3367 if __name__ == '__main__': |
3351 sys.exit(main()) | 3368 sys.exit(main()) |
OLD | NEW |