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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
73 "src" : "src/third_party/WebKit", | 73 "src" : "src/third_party/WebKit", |
74 "recurse" : True, | 74 "recurse" : True, |
75 "depends" : None, | 75 "depends" : None, |
76 "from" : 'chromium' | 76 "from" : 'chromium' |
77 }, | 77 }, |
78 'v8' : { | 78 'v8' : { |
79 "src" : "src/v8", | 79 "src" : "src/v8", |
80 "recurse" : True, | 80 "recurse" : True, |
81 "depends" : None, | 81 "depends" : None, |
82 "build_with": 'v8_bleeding_edge', | 82 "build_with": 'v8_bleeding_edge', |
83 "from" : 'chromium' | 83 "from" : 'chromium', |
84 "custom_deps": bisect_utils.GCLIENT_CUSTOM_DEPS_V8 | |
84 }, | 85 }, |
85 'v8_bleeding_edge' : { | 86 'v8_bleeding_edge' : { |
86 "src" : "src/v8_bleeding_edge", | 87 "src" : "src/v8_bleeding_edge", |
87 "recurse" : False, | 88 "recurse" : False, |
88 "depends" : None, | 89 "depends" : None, |
89 "svn": "https://v8.googlecode.com/svn/branches/bleeding_edge", | 90 "svn": "https://v8.googlecode.com/svn/branches/bleeding_edge", |
90 "from" : 'chromium' | 91 "from" : 'chromium' |
91 }, | 92 }, |
92 'skia/src' : { | 93 'skia/src' : { |
93 "src" : "src/third_party/skia/src", | 94 "src" : "src/third_party/skia/src", |
(...skipping 1225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1319 elif depot_name in DEPOT_NAMES: | 1320 elif depot_name in DEPOT_NAMES: |
1320 os.chdir(self.depot_cwd[depot_name]) | 1321 os.chdir(self.depot_cwd[depot_name]) |
1321 else: | 1322 else: |
1322 assert False, 'Unknown depot [ %s ] encountered. Possibly a new one'\ | 1323 assert False, 'Unknown depot [ %s ] encountered. Possibly a new one'\ |
1323 ' was added without proper support?' %\ | 1324 ' was added without proper support?' %\ |
1324 (depot_name,) | 1325 (depot_name,) |
1325 | 1326 |
1326 def PrepareToBisectOnDepot(self, | 1327 def PrepareToBisectOnDepot(self, |
1327 current_depot, | 1328 current_depot, |
1328 end_revision, | 1329 end_revision, |
1329 start_revision): | 1330 start_revision, |
1331 previous_depot, | |
1332 previous_revision): | |
1330 """Changes to the appropriate directory and gathers a list of revisions | 1333 """Changes to the appropriate directory and gathers a list of revisions |
1331 to bisect between |start_revision| and |end_revision|. | 1334 to bisect between |start_revision| and |end_revision|. |
1332 | 1335 |
1333 Args: | 1336 Args: |
1334 current_depot: The depot we want to bisect. | 1337 current_depot: The depot we want to bisect. |
1335 end_revision: End of the revision range. | 1338 end_revision: End of the revision range. |
1336 start_revision: Start of the revision range. | 1339 start_revision: Start of the revision range. |
1340 previous_depot: The depot we were previously bisecting. | |
1341 previous_revision: The last revision we synced to on |previous_depot|. | |
1337 | 1342 |
1338 Returns: | 1343 Returns: |
1339 A list containing the revisions between |start_revision| and | 1344 A list containing the revisions between |start_revision| and |
1340 |end_revision| inclusive. | 1345 |end_revision| inclusive. |
1341 """ | 1346 """ |
1342 # Change into working directory of external library to run | 1347 # Change into working directory of external library to run |
1343 # subsequent commands. | 1348 # subsequent commands. |
1344 old_cwd = os.getcwd() | 1349 old_cwd = os.getcwd() |
1345 os.chdir(self.depot_cwd[current_depot]) | 1350 os.chdir(self.depot_cwd[current_depot]) |
1346 | 1351 |
1347 # V8 (and possibly others) is merged in periodically. Bisecting | 1352 # V8 (and possibly others) is merged in periodically. Bisecting |
1348 # this directory directly won't give much good info. | 1353 # this directory directly won't give much good info. |
1349 if DEPOT_DEPS_NAME[current_depot].has_key('build_with'): | 1354 if DEPOT_DEPS_NAME[current_depot].has_key('build_with'): |
1355 if DEPOT_DEPS_NAME[current_depot].has_key('custom_deps') and\ | |
tonyg
2013/06/21 16:38:00
Nit: Please use parens instead of \
| |
1356 previous_depot == 'chromium': | |
1357 config_path = os.path.join(self.src_cwd, '..') | |
1358 if bisect_utils.RunGClientAndCreateConfig(self.opts, | |
1359 DEPOT_DEPS_NAME[current_depot]['custom_deps'], cwd=config_path): | |
1360 return [] | |
1361 if bisect_utils.RunGClient( | |
1362 ['sync', '--revision', previous_revision], cwd=self.src_cwd): | |
1363 return [] | |
1364 | |
1350 new_depot = DEPOT_DEPS_NAME[current_depot]['build_with'] | 1365 new_depot = DEPOT_DEPS_NAME[current_depot]['build_with'] |
1351 | 1366 |
1352 svn_start_revision = self.source_control.SVNFindRev(start_revision) | 1367 svn_start_revision = self.source_control.SVNFindRev(start_revision) |
1353 svn_end_revision = self.source_control.SVNFindRev(end_revision) | 1368 svn_end_revision = self.source_control.SVNFindRev(end_revision) |
1354 os.chdir(self.depot_cwd[new_depot]) | 1369 os.chdir(self.depot_cwd[new_depot]) |
1355 | 1370 |
1356 start_revision = self.source_control.ResolveToRevision( | 1371 start_revision = self.source_control.ResolveToRevision( |
1357 svn_start_revision, new_depot, -1000) | 1372 svn_start_revision, new_depot, -1000) |
1358 end_revision = self.source_control.ResolveToRevision( | 1373 end_revision = self.source_control.ResolveToRevision( |
1359 svn_end_revision, new_depot, -1000) | 1374 svn_end_revision, new_depot, -1000) |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1644 bad_revision_data = revision_data[revision_list[0]] | 1659 bad_revision_data = revision_data[revision_list[0]] |
1645 bad_revision_data['external'] = bad_results[2] | 1660 bad_revision_data['external'] = bad_results[2] |
1646 bad_revision_data['passed'] = 0 | 1661 bad_revision_data['passed'] = 0 |
1647 bad_revision_data['value'] = known_bad_value | 1662 bad_revision_data['value'] = known_bad_value |
1648 | 1663 |
1649 good_revision_data = revision_data[revision_list[max_revision]] | 1664 good_revision_data = revision_data[revision_list[max_revision]] |
1650 good_revision_data['external'] = good_results[2] | 1665 good_revision_data['external'] = good_results[2] |
1651 good_revision_data['passed'] = 1 | 1666 good_revision_data['passed'] = 1 |
1652 good_revision_data['value'] = known_good_value | 1667 good_revision_data['value'] = known_good_value |
1653 | 1668 |
1669 next_revision_depot = target_depot | |
1670 | |
1654 while True: | 1671 while True: |
1655 if not revision_list: | 1672 if not revision_list: |
1656 break | 1673 break |
1657 | 1674 |
1658 min_revision_data = revision_data[revision_list[min_revision]] | 1675 min_revision_data = revision_data[revision_list[min_revision]] |
1659 max_revision_data = revision_data[revision_list[max_revision]] | 1676 max_revision_data = revision_data[revision_list[max_revision]] |
1660 | 1677 |
1661 if max_revision - min_revision <= 1: | 1678 if max_revision - min_revision <= 1: |
1662 if min_revision_data['passed'] == '?': | 1679 if min_revision_data['passed'] == '?': |
1663 next_revision_index = min_revision | 1680 next_revision_index = min_revision |
1664 elif max_revision_data['passed'] == '?': | 1681 elif max_revision_data['passed'] == '?': |
1665 next_revision_index = max_revision | 1682 next_revision_index = max_revision |
1666 elif min_revision_data['depot'] == 'chromium' or\ | 1683 elif min_revision_data['depot'] == 'chromium' or\ |
1667 min_revision_data['depot'] == 'cros': | 1684 min_revision_data['depot'] == 'cros': |
1668 # If there were changes to any of the external libraries we track, | 1685 # If there were changes to any of the external libraries we track, |
1669 # should bisect the changes there as well. | 1686 # should bisect the changes there as well. |
1670 external_depot = None | 1687 external_depot = None |
1671 | 1688 |
1672 for current_depot in DEPOT_NAMES: | 1689 for current_depot in DEPOT_NAMES: |
1673 if DEPOT_DEPS_NAME[current_depot]["recurse"] and\ | 1690 if DEPOT_DEPS_NAME[current_depot]["recurse"] and\ |
1674 DEPOT_DEPS_NAME[current_depot]['from'] ==\ | 1691 DEPOT_DEPS_NAME[current_depot]['from'] ==\ |
1675 min_revision_data['depot']: | 1692 min_revision_data['depot']: |
1676 if min_revision_data['external'][current_depot] !=\ | 1693 if min_revision_data['external'][current_depot] !=\ |
1677 max_revision_data['external'][current_depot]: | 1694 max_revision_data['external'][current_depot]: |
1678 external_depot = current_depot | 1695 external_depot = current_depot |
1679 | |
1680 break | 1696 break |
1681 | 1697 |
1682 # If there was no change in any of the external depots, the search | 1698 # If there was no change in any of the external depots, the search |
1683 # is over. | 1699 # is over. |
1684 if not external_depot: | 1700 if not external_depot: |
1685 break | 1701 break |
1686 | 1702 |
1687 earliest_revision = max_revision_data['external'][current_depot] | 1703 previous_revision = revision_list[min_revision] |
1688 latest_revision = min_revision_data['external'][current_depot] | 1704 |
1705 earliest_revision = max_revision_data['external'][external_depot] | |
1706 latest_revision = min_revision_data['external'][external_depot] | |
1689 | 1707 |
1690 new_revision_list = self.PrepareToBisectOnDepot(external_depot, | 1708 new_revision_list = self.PrepareToBisectOnDepot(external_depot, |
1691 latest_revision, | 1709 latest_revision, |
1692 earliest_revision) | 1710 earliest_revision, |
1711 next_revision_depot, | |
1712 previous_revision) | |
1693 | 1713 |
1694 if not new_revision_list: | 1714 if not new_revision_list: |
1695 results['error'] = 'An error occurred attempting to retrieve'\ | 1715 results['error'] = 'An error occurred attempting to retrieve'\ |
1696 ' revision range: [%s..%s]' %\ | 1716 ' revision range: [%s..%s]' %\ |
1697 (depot_rev_range[1], depot_rev_range[0]) | 1717 (depot_rev_range[1], depot_rev_range[0]) |
1698 return results | 1718 return results |
1699 | 1719 |
1700 self.AddRevisionsIntoRevisionData(new_revision_list, | 1720 self.AddRevisionsIntoRevisionData(new_revision_list, |
1701 external_depot, | 1721 external_depot, |
1702 min_revision_data['sort'], | 1722 min_revision_data['sort'], |
1703 revision_data) | 1723 revision_data) |
1704 | 1724 |
1705 # Reset the bisection and perform it on the newly inserted | 1725 # Reset the bisection and perform it on the newly inserted |
1706 # changelists. | 1726 # changelists. |
1707 revision_list = new_revision_list | 1727 revision_list = new_revision_list |
1708 min_revision = 0 | 1728 min_revision = 0 |
1709 max_revision = len(revision_list) - 1 | 1729 max_revision = len(revision_list) - 1 |
1710 sort_key_ids += len(revision_list) | 1730 sort_key_ids += len(revision_list) |
1711 | 1731 |
1712 print 'Regression in metric:%s appears to be the result of changes'\ | 1732 print 'Regression in metric:%s appears to be the result of changes'\ |
1713 ' in [%s].' % (metric, current_depot) | 1733 ' in [%s].' % (metric, external_depot) |
1714 | 1734 |
1715 self.PrintRevisionsToBisectMessage(revision_list, external_depot) | 1735 self.PrintRevisionsToBisectMessage(revision_list, external_depot) |
1716 | 1736 |
1717 continue | 1737 continue |
1718 else: | 1738 else: |
1719 break | 1739 break |
1720 else: | 1740 else: |
1721 next_revision_index = int((max_revision - min_revision) / 2) +\ | 1741 next_revision_index = int((max_revision - min_revision) / 2) +\ |
1722 min_revision | 1742 min_revision |
1723 | 1743 |
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2298 | 2318 |
2299 if not(bisect_results['error']): | 2319 if not(bisect_results['error']): |
2300 return 0 | 2320 return 0 |
2301 else: | 2321 else: |
2302 print 'Error: ' + bisect_results['error'] | 2322 print 'Error: ' + bisect_results['error'] |
2303 print | 2323 print |
2304 return 1 | 2324 return 1 |
2305 | 2325 |
2306 if __name__ == '__main__': | 2326 if __name__ == '__main__': |
2307 sys.exit(main()) | 2327 sys.exit(main()) |
OLD | NEW |