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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 pass | 233 pass |
234 return final_list | 234 return final_list |
235 | 235 |
236 def UnzipFilenameToDir(filename, dir): | 236 def UnzipFilenameToDir(filename, dir): |
237 """Unzip |filename| to directory |dir|.""" | 237 """Unzip |filename| to directory |dir|.""" |
238 cwd = os.getcwd() | 238 cwd = os.getcwd() |
239 if not os.path.isabs(filename): | 239 if not os.path.isabs(filename): |
240 filename = os.path.join(cwd, filename) | 240 filename = os.path.join(cwd, filename) |
241 zf = zipfile.ZipFile(filename) | 241 zf = zipfile.ZipFile(filename) |
242 # Make base. | 242 # Make base. |
243 try: | 243 if not os.path.isdir(dir): |
244 if not os.path.isdir(dir): | 244 os.mkdir(dir) |
245 os.mkdir(dir) | 245 os.chdir(dir) |
246 os.chdir(dir) | 246 # Extract files. |
247 # Extract files. | 247 for info in zf.infolist(): |
248 for info in zf.infolist(): | 248 name = info.filename |
249 name = info.filename | 249 if name.endswith('/'): # dir |
250 if name.endswith('/'): # dir | 250 if not os.path.isdir(name): |
251 if not os.path.isdir(name): | 251 os.makedirs(name) |
252 os.makedirs(name) | 252 else: # file |
253 else: # file | 253 dir = os.path.dirname(name) |
254 dir = os.path.dirname(name) | 254 if not os.path.isdir(dir): |
255 if not os.path.isdir(dir): | 255 os.makedirs(dir) |
256 os.makedirs(dir) | 256 out = open(name, 'wb') |
257 out = open(name, 'wb') | 257 out.write(zf.read(name)) |
258 out.write(zf.read(name)) | 258 out.close() |
259 out.close() | 259 # Set permissions. Permission info in external_attr is shifted 16 bits. |
260 # Set permissions. Permission info in external_attr is shifted 16 bits. | 260 os.chmod(name, info.external_attr >> 16L) |
261 os.chmod(name, info.external_attr >> 16L) | 261 os.chdir(cwd) |
262 os.chdir(cwd) | |
263 except Exception, e: | |
264 print >>sys.stderr, e | |
265 sys.exit(1) | |
266 | 262 |
267 | 263 |
268 def FetchRevision(context, rev, filename, quit_event=None, progress_event=None): | 264 def FetchRevision(context, rev, filename, quit_event=None, progress_event=None): |
269 """Downloads and unzips revision |rev|. | 265 """Downloads and unzips revision |rev|. |
270 @param context A PathContext instance. | 266 @param context A PathContext instance. |
271 @param rev The Chromium revision number/tag to download. | 267 @param rev The Chromium revision number/tag to download. |
272 @param filename The destination for the downloaded file. | 268 @param filename The destination for the downloaded file. |
273 @param quit_event A threading.Event which will be set by the master thread to | 269 @param quit_event A threading.Event which will be set by the master thread to |
274 indicate that the download should be aborted. | 270 indicate that the download should be aborted. |
275 @param progress_event A threading.Event which will be set by the master thread | 271 @param progress_event A threading.Event which will be set by the master thread |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 | 465 |
470 up_pivot = int((bad - pivot) / 2) + pivot | 466 up_pivot = int((bad - pivot) / 2) + pivot |
471 up_fetch = None | 467 up_fetch = None |
472 if up_pivot != pivot and up_pivot != bad: | 468 if up_pivot != pivot and up_pivot != bad: |
473 up_rev = revlist[up_pivot] | 469 up_rev = revlist[up_pivot] |
474 up_fetch = DownloadJob(context, 'up_fetch', up_rev, | 470 up_fetch = DownloadJob(context, 'up_fetch', up_rev, |
475 _GetDownloadPath(up_rev)) | 471 _GetDownloadPath(up_rev)) |
476 up_fetch.Start() | 472 up_fetch.Start() |
477 | 473 |
478 # Run test on the pivot revision. | 474 # Run test on the pivot revision. |
479 (status, stdout, stderr) = RunRevision(context, | 475 status = None |
480 rev, | 476 stdout = None |
481 zipfile, | 477 stderr = None |
482 profile, | 478 try: |
483 num_runs, | 479 (status, stdout, stderr) = RunRevision(context, |
484 try_args) | 480 rev, |
| 481 zipfile, |
| 482 profile, |
| 483 num_runs, |
| 484 try_args) |
| 485 except Exception, e: |
| 486 print >>sys.stderr, e |
485 os.unlink(zipfile) | 487 os.unlink(zipfile) |
486 zipfile = None | 488 zipfile = None |
487 | 489 |
488 # Call the evaluate function to see if the current revision is good or bad. | 490 # Call the evaluate function to see if the current revision is good or bad. |
489 # On that basis, kill one of the background downloads and complete the | 491 # On that basis, kill one of the background downloads and complete the |
490 # other, as described in the comments above. | 492 # other, as described in the comments above. |
491 try: | 493 try: |
492 answer = evaluate(rev, official_builds, status, stdout, stderr) | 494 answer = evaluate(rev, official_builds, status, stdout, stderr) |
493 if answer == 'g': | 495 if answer == 'g': |
494 good = pivot | 496 good = pivot |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 print ' ' + WEBKIT_CHANGELOG_URL % (first_known_bad_webkit_rev, | 671 print ' ' + WEBKIT_CHANGELOG_URL % (first_known_bad_webkit_rev, |
670 last_known_good_webkit_rev) | 672 last_known_good_webkit_rev) |
671 print 'CHANGELOG URL:' | 673 print 'CHANGELOG URL:' |
672 if opts.official_builds: | 674 if opts.official_builds: |
673 print OFFICIAL_CHANGELOG_URL % (last_known_good_rev, first_known_bad_rev) | 675 print OFFICIAL_CHANGELOG_URL % (last_known_good_rev, first_known_bad_rev) |
674 else: | 676 else: |
675 print ' ' + CHANGELOG_URL % (last_known_good_rev, first_known_bad_rev) | 677 print ' ' + CHANGELOG_URL % (last_known_good_rev, first_known_bad_rev) |
676 | 678 |
677 if __name__ == '__main__': | 679 if __name__ == '__main__': |
678 sys.exit(main()) | 680 sys.exit(main()) |
OLD | NEW |