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 |