Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: tools/bisect-builds.py

Issue 492853002: bisect-builds.py: Fix official Google Chrome build bisection. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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,
11 unzipping, and opening Chromium for you. After testing the specific revision, 11 unzipping, and opening Chromium for you. After testing the specific revision,
12 it will ask you whether it is good or bad before continuing the search. 12 it will ask you whether it is good or bad before continuing the search.
13 """ 13 """
14 14
15 # The base URL for stored build archives. 15 # The base URL for stored build archives.
16 CHROMIUM_BASE_URL = ('http://commondatastorage.googleapis.com' 16 CHROMIUM_BASE_URL = ('http://commondatastorage.googleapis.com'
17 '/chromium-browser-snapshots') 17 '/chromium-browser-snapshots')
18 WEBKIT_BASE_URL = ('http://commondatastorage.googleapis.com' 18 WEBKIT_BASE_URL = ('http://commondatastorage.googleapis.com'
19 '/chromium-webkit-snapshots') 19 '/chromium-webkit-snapshots')
20 ASAN_BASE_URL = ('http://commondatastorage.googleapis.com' 20 ASAN_BASE_URL = ('http://commondatastorage.googleapis.com'
21 '/chromium-browser-asan') 21 '/chromium-browser-asan')
22 22
23 # The base URL for official builds. 23 # The base URL for official builds.
24 OFFICIAL_BASE_URL = 'http://master.chrome.corp.google.com/official_builds' 24 OFFICIAL_BASE_URL = ('http://commondatastorage.googleapis.com/'
DaleCurtis 2014/08/21 00:18:55 Construct the official base_url using the bucket_n
pshenoy 2014/08/21 16:27:23 Done.
25 'chrome-unsigned/desktop-W15K3Y')
26 # GS bucket name.
27 GS_BUCKET_NAME = 'chrome-unsigned/desktop-W15K3Y'
28
29 # Base URL for downloading official builds.
30 GOOGLE_APIS_URL = 'commondatastorage.googleapis.com'
25 31
26 # URL template for viewing changelogs between revisions. 32 # URL template for viewing changelogs between revisions.
27 CHANGELOG_URL = ('http://build.chromium.org' 33 CHANGELOG_URL = ('http://build.chromium.org'
28 '/f/chromium/perf/dashboard/ui/changelog.html' 34 '/f/chromium/perf/dashboard/ui/changelog.html'
29 '?url=/trunk/src&range=%d%%3A%d') 35 '?url=/trunk/src&range=%d%%3A%d')
30 36
31 # URL template for viewing changelogs between official versions. 37 # URL template for viewing changelogs between official versions.
32 OFFICIAL_CHANGELOG_URL = ('http://omahaproxy.appspot.com/changelog' 38 OFFICIAL_CHANGELOG_URL = ('http://omahaproxy.appspot.com/changelog'
33 '?old_version=%s&new_version=%s') 39 '?old_version=%s&new_version=%s')
34 40
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 BLINK_SEARCH_PATTERN = ( 72 BLINK_SEARCH_PATTERN = (
67 r'.*git-svn-id: svn://svn.chromium.org/blink/trunk@(\d+) ') 73 r'.*git-svn-id: svn://svn.chromium.org/blink/trunk@(\d+) ')
68 74
69 SEARCH_PATTERN = { 75 SEARCH_PATTERN = {
70 'chromium': CHROMIUM_SEARCH_PATTERN, 76 'chromium': CHROMIUM_SEARCH_PATTERN,
71 'blink': BLINK_SEARCH_PATTERN, 77 'blink': BLINK_SEARCH_PATTERN,
72 } 78 }
73 79
74 ############################################################################### 80 ###############################################################################
75 81
82 import httplib
76 import json 83 import json
77 import optparse 84 import optparse
78 import os 85 import os
79 import re 86 import re
80 import shlex 87 import shlex
81 import shutil 88 import shutil
82 import subprocess 89 import subprocess
83 import sys 90 import sys
84 import tempfile 91 import tempfile
85 import threading 92 import threading
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 self._archive_extract_dir = 'chrome-mac' 139 self._archive_extract_dir = 'chrome-mac'
133 elif self.platform == 'win': 140 elif self.platform == 'win':
134 self.archive_name = 'chrome-win32.zip' 141 self.archive_name = 'chrome-win32.zip'
135 self._archive_extract_dir = 'chrome-win32' 142 self._archive_extract_dir = 'chrome-win32'
136 self._binary_name = 'chrome.exe' 143 self._binary_name = 'chrome.exe'
137 else: 144 else:
138 raise Exception('Invalid platform: %s' % self.platform) 145 raise Exception('Invalid platform: %s' % self.platform)
139 146
140 if is_official: 147 if is_official:
141 if self.platform == 'linux': 148 if self.platform == 'linux':
142 self._listing_platform_dir = 'precise32bit/' 149 self._listing_platform_dir = 'precise32/'
143 self.archive_name = 'chrome-precise32bit.zip' 150 self.archive_name = 'chrome-precise32.zip'
144 self._archive_extract_dir = 'chrome-precise32bit' 151 self._archive_extract_dir = 'chrome-precise32'
145 elif self.platform == 'linux64': 152 elif self.platform == 'linux64':
146 self._listing_platform_dir = 'precise64bit/' 153 self._listing_platform_dir = 'precise64/'
147 self.archive_name = 'chrome-precise64bit.zip' 154 self.archive_name = 'chrome-precise64.zip'
148 self._archive_extract_dir = 'chrome-precise64bit' 155 self._archive_extract_dir = 'chrome-precise64'
149 elif self.platform == 'mac': 156 elif self.platform == 'mac':
150 self._listing_platform_dir = 'mac/' 157 self._listing_platform_dir = 'mac/'
151 self._binary_name = 'Google Chrome.app/Contents/MacOS/Google Chrome' 158 self._binary_name = 'Google Chrome.app/Contents/MacOS/Google Chrome'
152 elif self.platform == 'win': 159 elif self.platform == 'win':
153 self._listing_platform_dir = 'win/' 160 self._listing_platform_dir = 'win/'
154 else: 161 else:
155 if self.platform in ('linux', 'linux64', 'linux-arm'): 162 if self.platform in ('linux', 'linux64', 'linux-arm'):
156 self.archive_name = 'chrome-linux.zip' 163 self.archive_name = 'chrome-linux.zip'
157 self._archive_extract_dir = 'chrome-linux' 164 self._archive_extract_dir = 'chrome-linux'
158 if self.platform == 'linux': 165 if self.platform == 'linux':
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 self.good_revision) 393 self.good_revision)
387 self.bad_revision = FixChromiumRevForBlink(revlist, 394 self.bad_revision = FixChromiumRevForBlink(revlist,
388 revlist_all, 395 revlist_all,
389 self, 396 self,
390 self.bad_revision) 397 self.bad_revision)
391 return revlist 398 return revlist
392 399
393 def GetOfficialBuildsList(self): 400 def GetOfficialBuildsList(self):
394 """Gets the list of official build numbers between self.good_revision and 401 """Gets the list of official build numbers between self.good_revision and
395 self.bad_revision.""" 402 self.bad_revision."""
403
404 def CheckDepotToolsInPath():
405 delimiter = ';' if sys.platform.startswith('win') else ':'
406 path_list = os.environ['PATH'].split(delimiter)
407 for path in path_list:
408 if path.find('depot_tools') != -1:
409 return path
410 return None
411
412 def RunGsutilCommand(args):
413 gsutil_path = CheckDepotToolsInPath()
414 if gsutil_path is None:
415 print ('Follow the instructions in this document '
416 'http://dev.chromium.org/developers/how-tos/install-depot-tools'
417 ' to install depot_tools and then try again.')
418 sys.exit(1)
419 gsutil_path = os.path.join(gsutil_path, 'third_party', 'gsutil', 'gsutil')
420 gsutil = subprocess.Popen([sys.executable, gsutil_path] + args,
421 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
422 env=None)
423 stdout, stderr = gsutil.communicate()
424 if gsutil.returncode:
425 if re.findall(r'status[ |=]40[1|3]', stderr):
426 print ('Follow these steps to configure your credentials and try'
427 ' running the bisect-builds.py again.:\n'
428 ' 1. Run "python %s config" and follow its instructions.\n'
429 ' 2. If you have a @google.com account, use that account.\n'
430 ' 3. For the project-id, just enter 0.' % gsutil_path)
431 sys.exit(1)
432 else:
433 raise Exception('Error running the gsutil command')
434 return stdout
435
436 def GsutilList(bucket):
437 query = 'gs://%s/' % bucket
438 stdout = RunGsutilCommand(['ls', query])
439 return [url[len(query):].strip('/') for url in stdout.splitlines()]
440
396 # Download the revlist and filter for just the range between good and bad. 441 # Download the revlist and filter for just the range between good and bad.
397 minrev = min(self.good_revision, self.bad_revision) 442 minrev = min(self.good_revision, self.bad_revision)
398 maxrev = max(self.good_revision, self.bad_revision) 443 maxrev = max(self.good_revision, self.bad_revision)
399 handle = urllib.urlopen(OFFICIAL_BASE_URL) 444 build_numbers = GsutilList(GS_BUCKET_NAME)
400 dirindex = handle.read() 445 revision_re = re.compile(r'(\d\d\.\d\.\d{4}\.\d+)')
401 handle.close() 446 build_numbers = filter(lambda b: revision_re.search(b), build_numbers)
402 build_numbers = re.findall(r'<a href="([0-9][0-9].*)/">', dirindex)
403 final_list = [] 447 final_list = []
404 i = 0 448 i = 0
405 parsed_build_numbers = [LooseVersion(x) for x in build_numbers] 449 parsed_build_numbers = [LooseVersion(x) for x in build_numbers]
450 connection = httplib.HTTPConnection(GOOGLE_APIS_URL)
406 for build_number in sorted(parsed_build_numbers): 451 for build_number in sorted(parsed_build_numbers):
407 path = (OFFICIAL_BASE_URL + '/' + str(build_number) + '/' + 452 if build_number > maxrev:
453 break
454 if build_number < minrev:
455 continue
456 path = ('/' + GS_BUCKET_NAME + '/' + str(build_number) + '/' +
408 self._listing_platform_dir + self.archive_name) 457 self._listing_platform_dir + self.archive_name)
409 i = i + 1 458 i = i + 1
410 try: 459 connection.request('HEAD', path)
411 connection = urllib.urlopen(path) 460 response = connection.getresponse()
412 connection.close() 461 if response.status == 200:
413 if build_number > maxrev: 462 final_list.append(str(build_number))
414 break 463 response.read()
415 if build_number >= minrev: 464 connection.close()
416 final_list.append(str(build_number))
417 except urllib.HTTPError:
418 pass
419 return final_list 465 return final_list
420 466
421 def UnzipFilenameToDir(filename, directory): 467 def UnzipFilenameToDir(filename, directory):
422 """Unzip |filename| to |directory|.""" 468 """Unzip |filename| to |directory|."""
423 cwd = os.getcwd() 469 cwd = os.getcwd()
424 if not os.path.isabs(filename): 470 if not os.path.isabs(filename):
425 filename = os.path.join(cwd, filename) 471 filename = os.path.join(cwd, filename)
426 zf = zipfile.ZipFile(filename) 472 zf = zipfile.ZipFile(filename)
427 # Make base. 473 # Make base.
428 if not os.path.isdir(directory): 474 if not os.path.isdir(directory):
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 """ 696 """
651 697
652 if not profile: 698 if not profile:
653 profile = 'profile' 699 profile = 'profile'
654 700
655 good_rev = context.good_revision 701 good_rev = context.good_revision
656 bad_rev = context.bad_revision 702 bad_rev = context.bad_revision
657 cwd = os.getcwd() 703 cwd = os.getcwd()
658 704
659 print 'Downloading list of known revisions...', 705 print 'Downloading list of known revisions...',
660 if not context.use_local_repo: 706 if not context.use_local_repo and not context.is_official:
661 print '(use --use-local-repo for speed if you have a local checkout)' 707 print '(use --use-local-repo for speed if you have a local checkout)'
662 else: 708 else:
663 print 709 print
664 _GetDownloadPath = lambda rev: os.path.join(cwd, 710 _GetDownloadPath = lambda rev: os.path.join(cwd,
665 '%s-%s' % (str(rev), context.archive_name)) 711 '%s-%s' % (str(rev), context.archive_name))
666 if context.is_official: 712 if context.is_official:
667 revlist = context.GetOfficialBuildsList() 713 revlist = context.GetOfficialBuildsList()
668 else: 714 else:
669 revlist = context.GetRevList() 715 revlist = context.GetRevList()
670 716
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after
1088 1134
1089 print 'CHANGELOG URL:' 1135 print 'CHANGELOG URL:'
1090 if opts.official_builds: 1136 if opts.official_builds:
1091 print OFFICIAL_CHANGELOG_URL % (min_chromium_rev, max_chromium_rev) 1137 print OFFICIAL_CHANGELOG_URL % (min_chromium_rev, max_chromium_rev)
1092 else: 1138 else:
1093 print ' ' + CHANGELOG_URL % (min_chromium_rev, max_chromium_rev) 1139 print ' ' + CHANGELOG_URL % (min_chromium_rev, max_chromium_rev)
1094 1140
1095 1141
1096 if __name__ == '__main__': 1142 if __name__ == '__main__':
1097 sys.exit(main()) 1143 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698