Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2014 The Chromium Authors. All rights reserved. | 2 # Copyright 2014 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 """Compare the artifacts from two builds.""" | 6 """Compare the artifacts from two builds.""" |
| 7 | 7 |
| 8 import difflib | 8 import difflib |
| 9 import json | 9 import json |
| 10 import optparse | 10 import optparse |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 429 elif isinstance(va, dict): | 429 elif isinstance(va, dict): |
| 430 c = diff_dict(va, vb) | 430 c = diff_dict(va, vb) |
| 431 if c: | 431 if c: |
| 432 out += '- %s:\n%s\n' % ( | 432 out += '- %s:\n%s\n' % ( |
| 433 key, '\n'.join(' ' + l for l in c.splitlines())) | 433 key, '\n'.join(' ' + l for l in c.splitlines())) |
| 434 elif va != vb: | 434 elif va != vb: |
| 435 out += '- %s: %s != %s\n' % (key, va, vb) | 435 out += '- %s: %s != %s\n' % (key, va, vb) |
| 436 return out.rstrip() | 436 return out.rstrip() |
| 437 | 437 |
| 438 | 438 |
| 439 def may_skip_coff_header(lhs_header, rhs_header): | |
| 440 """Returns True if we can skip checking COFF headers.""" | |
| 441 # COFF header: | |
| 442 # 0 - 1: magic. | |
| 443 # 2 - 3: # sections. | |
| 444 # 4 - 8: timestamp. | |
| 445 # ... | |
| 446 if len(lhs_header) < 8: | |
| 447 return False | |
| 448 lhs_data = [l for l in lhs_header] | |
|
M-A Ruel
2016/09/06 15:35:54
Replace the lines 448-452 with:
return lhs_data[4:
Yoshisato Yanagisawa
2016/09/07 01:50:28
I would basically change the code like so but let
| |
| 449 rhs_data = [r for r in rhs_header] | |
| 450 for x in xrange(4): | |
| 451 lhs_data[4 + x] = rhs_data[4 + x] = chr(0) | |
| 452 return rhs_data == lhs_data | |
| 453 | |
| 454 | |
| 439 def diff_binary(first_filepath, second_filepath, file_len): | 455 def diff_binary(first_filepath, second_filepath, file_len): |
| 440 """Returns a compact binary diff if the diff is small enough.""" | 456 """Returns a compact binary diff if the diff is small enough.""" |
| 441 CHUNK_SIZE = 32 | 457 CHUNK_SIZE = 32 |
| 442 MAX_STREAMS = 10 | 458 MAX_STREAMS = 10 |
| 443 diffs = 0 | 459 diffs = 0 |
| 444 streams = [] | 460 streams = [] |
| 445 offset = 0 | 461 offset = 0 |
| 446 with open(first_filepath, 'rb') as lhs: | 462 with open(first_filepath, 'rb') as lhs: |
| 447 with open(second_filepath, 'rb') as rhs: | 463 with open(second_filepath, 'rb') as rhs: |
| 464 # Skip COFF header on Win32 object file if only timestamps are different. | |
| 465 if sys.platform == 'win32' and first_filepath.endswith('.obj'): | |
| 466 COFF_HEADER_SIZE = 22 | |
| 467 lhs_data = lhs.read(COFF_HEADER_SIZE) | |
| 468 rhs_data = rhs.read(COFF_HEADER_SIZE) | |
| 469 if may_skip_coff_header(lhs_data, rhs_data): | |
| 470 offset += COFF_HEADER_SIZE | |
| 471 else: | |
| 472 lhs.seek(0) | |
| 473 rhs.seek(0) | |
| 474 | |
| 448 while True: | 475 while True: |
| 449 lhs_data = lhs.read(CHUNK_SIZE) | 476 lhs_data = lhs.read(CHUNK_SIZE) |
| 450 rhs_data = rhs.read(CHUNK_SIZE) | 477 rhs_data = rhs.read(CHUNK_SIZE) |
| 451 if not lhs_data: | 478 if not lhs_data: |
| 452 break | 479 break |
| 453 if lhs_data != rhs_data: | 480 if lhs_data != rhs_data: |
| 454 diffs += sum(l != r for l, r in zip(lhs_data, rhs_data)) | 481 diffs += sum(l != r for l, r in zip(lhs_data, rhs_data)) |
| 455 if streams is not None: | 482 if streams is not None: |
| 456 if len(streams) < MAX_STREAMS: | 483 if len(streams) < MAX_STREAMS: |
| 457 streams.append((offset, lhs_data, rhs_data)) | 484 streams.append((offset, lhs_data, rhs_data)) |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 552 # for this case. | 579 # for this case. |
| 553 print 'deps on %s are different: %s' % ( | 580 print 'deps on %s are different: %s' % ( |
| 554 target, set(first_deps).symmetric_difference(set(second_deps))) | 581 target, set(first_deps).symmetric_difference(set(second_deps))) |
| 555 continue | 582 continue |
| 556 max_filepath_len = max(len(n) for n in first_deps) | 583 max_filepath_len = max(len(n) for n in first_deps) |
| 557 for d in first_deps: | 584 for d in first_deps: |
| 558 first_file = os.path.join(first_dir, d) | 585 first_file = os.path.join(first_dir, d) |
| 559 second_file = os.path.join(second_dir, d) | 586 second_file = os.path.join(second_dir, d) |
| 560 result = compare_files(first_file, second_file) | 587 result = compare_files(first_file, second_file) |
| 561 if result: | 588 if result: |
| 562 print('%-*s: %s' % (max_filepath_len, d, result)) | 589 print(' %-*s: %s' % (max_filepath_len, d, result)) |
| 563 | 590 |
| 564 | 591 |
| 565 def compare_build_artifacts(first_dir, second_dir, target_platform, | 592 def compare_build_artifacts(first_dir, second_dir, target_platform, |
| 566 recursive=False): | 593 recursive=False): |
| 567 """Compares the artifacts from two distinct builds.""" | 594 """Compares the artifacts from two distinct builds.""" |
| 568 if not os.path.isdir(first_dir): | 595 if not os.path.isdir(first_dir): |
| 569 print >> sys.stderr, '%s isn\'t a valid directory.' % first_dir | 596 print >> sys.stderr, '%s isn\'t a valid directory.' % first_dir |
| 570 return 1 | 597 return 1 |
| 571 if not os.path.isdir(second_dir): | 598 if not os.path.isdir(second_dir): |
| 572 print >> sys.stderr, '%s isn\'t a valid directory.' % second_dir | 599 print >> sys.stderr, '%s isn\'t a valid directory.' % second_dir |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 658 parser.error('--target-platform is required') | 685 parser.error('--target-platform is required') |
| 659 | 686 |
| 660 return compare_build_artifacts(os.path.abspath(options.first_build_dir), | 687 return compare_build_artifacts(os.path.abspath(options.first_build_dir), |
| 661 os.path.abspath(options.second_build_dir), | 688 os.path.abspath(options.second_build_dir), |
| 662 options.target_platform, | 689 options.target_platform, |
| 663 options.recursive) | 690 options.recursive) |
| 664 | 691 |
| 665 | 692 |
| 666 if __name__ == '__main__': | 693 if __name__ == '__main__': |
| 667 sys.exit(main()) | 694 sys.exit(main()) |
| OLD | NEW |