OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 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 """Snapshot Build Bisect Tool | 6 """Snapshot Build Bisect Tool |
7 | 7 |
8 This script bisects a snapshot archive using binary search. It starts at | 8 This script bisects a snapshot archive using binary search. It starts at |
9 a bad revision (it will try to guess HEAD) and asks for a last known-good | 9 a bad revision (it will try to guess HEAD) and asks for a last known-good |
10 revision. It will then binary search across this revision range by downloading, | 10 revision. It will then binary search across this revision range by downloading, |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 (new_revisions, next_marker) = _FetchAndParse(next_url) | 214 (new_revisions, next_marker) = _FetchAndParse(next_url) |
215 revisions.extend(new_revisions) | 215 revisions.extend(new_revisions) |
216 return revisions | 216 return revisions |
217 | 217 |
218 def GetRevList(self): | 218 def GetRevList(self): |
219 """Gets the list of revision numbers between self.good_revision and | 219 """Gets the list of revision numbers between self.good_revision and |
220 self.bad_revision.""" | 220 self.bad_revision.""" |
221 # Download the revlist and filter for just the range between good and bad. | 221 # Download the revlist and filter for just the range between good and bad. |
222 minrev = min(self.good_revision, self.bad_revision) | 222 minrev = min(self.good_revision, self.bad_revision) |
223 maxrev = max(self.good_revision, self.bad_revision) | 223 maxrev = max(self.good_revision, self.bad_revision) |
224 revlist = map(int, self.ParseDirectoryIndex()) | 224 revlist_all = map(int, self.ParseDirectoryIndex()) |
225 revlist = [x for x in revlist if x >= int(minrev) and x <= int(maxrev)] | 225 |
| 226 revlist = [x for x in revlist_all if x >= int(minrev) and x <= int(maxrev)] |
226 revlist.sort() | 227 revlist.sort() |
| 228 |
| 229 # Set good and bad revisions to be legit revisions. |
| 230 if revlist: |
| 231 if self.good_revision < self.bad_revision: |
| 232 self.good_revision = revlist[0] |
| 233 self.bad_revision = revlist[-1] |
| 234 else: |
| 235 self.bad_revision = revlist[0] |
| 236 self.good_revision = revlist[-1] |
| 237 |
| 238 # Fix chromium rev so that the deps blink revision matches REVISIONS file. |
| 239 if self.base_url == WEBKIT_BASE_URL: |
| 240 revlist_all.sort() |
| 241 self.good_revision = FixChromiumRevForBlink(revlist, |
| 242 revlist_all, |
| 243 self, |
| 244 self.good_revision) |
| 245 self.bad_revision = FixChromiumRevForBlink(revlist, |
| 246 revlist_all, |
| 247 self, |
| 248 self.bad_revision) |
227 return revlist | 249 return revlist |
228 | 250 |
229 def GetOfficialBuildsList(self): | 251 def GetOfficialBuildsList(self): |
230 """Gets the list of official build numbers between self.good_revision and | 252 """Gets the list of official build numbers between self.good_revision and |
231 self.bad_revision.""" | 253 self.bad_revision.""" |
232 # Download the revlist and filter for just the range between good and bad. | 254 # Download the revlist and filter for just the range between good and bad. |
233 minrev = min(self.good_revision, self.bad_revision) | 255 minrev = min(self.good_revision, self.bad_revision) |
234 maxrev = max(self.good_revision, self.bad_revision) | 256 maxrev = max(self.good_revision, self.bad_revision) |
235 handle = urllib.urlopen(OFFICIAL_BASE_URL) | 257 handle = urllib.urlopen(OFFICIAL_BASE_URL) |
236 dirindex = handle.read() | 258 dirindex = handle.read() |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 os.unlink(f) | 623 os.unlink(f) |
602 except OSError: | 624 except OSError: |
603 pass | 625 pass |
604 sys.exit(0) | 626 sys.exit(0) |
605 | 627 |
606 rev = revlist[pivot] | 628 rev = revlist[pivot] |
607 | 629 |
608 return (revlist[minrev], revlist[maxrev]) | 630 return (revlist[minrev], revlist[maxrev]) |
609 | 631 |
610 | 632 |
| 633 def GetBlinkDEPSRevisionForChromiumRevision(rev): |
| 634 """Returns the blink revision that was in REVISIONS file at |
| 635 chromium revision |rev|.""" |
| 636 # . doesn't match newlines without re.DOTALL, so this is safe. |
| 637 blink_re = re.compile(r'webkit_revision\D*(\d+)') |
| 638 url = urllib.urlopen(DEPS_FILE % rev) |
| 639 m = blink_re.search(url.read()) |
| 640 url.close() |
| 641 if m: |
| 642 return int(m.group(1)) |
| 643 else: |
| 644 raise Exception('Could not get Blink revision for Chromium rev %d' |
| 645 % rev) |
| 646 |
| 647 |
611 def GetBlinkRevisionForChromiumRevision(self, rev): | 648 def GetBlinkRevisionForChromiumRevision(self, rev): |
612 """Returns the blink revision that was in REVISIONS file at | 649 """Returns the blink revision that was in REVISIONS file at |
613 chromium revision |rev|.""" | 650 chromium revision |rev|.""" |
614 # . doesn't match newlines without re.DOTALL, so this is safe. | |
615 file_url = "%s/%s%d/REVISIONS" % (self.base_url, | 651 file_url = "%s/%s%d/REVISIONS" % (self.base_url, |
616 self._listing_platform_dir, rev) | 652 self._listing_platform_dir, rev) |
617 url = urllib.urlopen(file_url) | 653 url = urllib.urlopen(file_url) |
618 data = json.loads(url.read()) | 654 data = json.loads(url.read()) |
619 url.close() | 655 url.close() |
620 if 'webkit_revision' in data: | 656 if 'webkit_revision' in data: |
621 return data['webkit_revision'] | 657 return data['webkit_revision'] |
622 else: | 658 else: |
623 raise Exception('Could not get blink revision for cr rev %d' % rev) | 659 raise Exception('Could not get blink revision for cr rev %d' % rev) |
624 | 660 |
| 661 def FixChromiumRevForBlink(revisions_final, revisions, self, rev): |
| 662 """Returns the chromium revision that has the correct blink revision |
| 663 for blink bisect, DEPS and REVISIONS file might not match since |
| 664 blink snapshots point to tip of tree blink. |
| 665 Note: The revisions_final variable might get modified to include |
| 666 additional revisions.""" |
| 667 |
| 668 blink_deps_rev = GetBlinkDEPSRevisionForChromiumRevision(rev) |
| 669 |
| 670 while (GetBlinkRevisionForChromiumRevision(self, rev) > blink_deps_rev): |
| 671 idx = revisions.index(rev) |
| 672 if idx > 0: |
| 673 rev = revisions[idx-1] |
| 674 if rev not in revisions_final: |
| 675 revisions_final.insert(0, rev) |
| 676 |
| 677 revisions_final.sort() |
| 678 return rev |
625 | 679 |
626 def GetChromiumRevision(url): | 680 def GetChromiumRevision(url): |
627 """Returns the chromium revision read from given URL.""" | 681 """Returns the chromium revision read from given URL.""" |
628 try: | 682 try: |
629 # Location of the latest build revision number | 683 # Location of the latest build revision number |
630 return int(urllib.urlopen(url).read()) | 684 return int(urllib.urlopen(url).read()) |
631 except Exception, e: | 685 except Exception, e: |
632 print('Could not determine latest revision. This could be bad...') | 686 print('Could not determine latest revision. This could be bad...') |
633 return 999999999 | 687 return 999999999 |
634 | 688 |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 print 'BLINK CHANGELOG URL:' | 819 print 'BLINK CHANGELOG URL:' |
766 print ' ' + BLINK_CHANGELOG_URL % (max_blink_rev, min_blink_rev) | 820 print ' ' + BLINK_CHANGELOG_URL % (max_blink_rev, min_blink_rev) |
767 print 'CHANGELOG URL:' | 821 print 'CHANGELOG URL:' |
768 if opts.official_builds: | 822 if opts.official_builds: |
769 print OFFICIAL_CHANGELOG_URL % (min_chromium_rev, max_chromium_rev) | 823 print OFFICIAL_CHANGELOG_URL % (min_chromium_rev, max_chromium_rev) |
770 else: | 824 else: |
771 print ' ' + CHANGELOG_URL % (min_chromium_rev, max_chromium_rev) | 825 print ' ' + CHANGELOG_URL % (min_chromium_rev, max_chromium_rev) |
772 | 826 |
773 if __name__ == '__main__': | 827 if __name__ == '__main__': |
774 sys.exit(main()) | 828 sys.exit(main()) |
OLD | NEW |