Chromium Code Reviews| 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 """Front end tool to manage .isolate files and corresponding tests. | 6 """Front end tool to manage .isolate files and corresponding tests. |
| 7 | 7 |
| 8 Run ./isolate.py --help for more detailed information. | 8 Run ./isolate.py --help for more detailed information. |
| 9 | 9 |
| 10 See more information at | 10 See more information at |
| (...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 658 complete_state.root_dir, | 658 complete_state.root_dir, |
| 659 complete_state.saved_state.variables, | 659 complete_state.saved_state.variables, |
| 660 complete_state.result.relative_cwd) | 660 complete_state.result.relative_cwd) |
| 661 return value | 661 return value |
| 662 except trace_inputs.TracingFailure, e: | 662 except trace_inputs.TracingFailure, e: |
| 663 raise ExecutionError( | 663 raise ExecutionError( |
| 664 'Reading traces failed for: %s\n%s' % | 664 'Reading traces failed for: %s\n%s' % |
| 665 (' '.join(complete_state.result.command), str(e))) | 665 (' '.join(complete_state.result.command), str(e))) |
| 666 | 666 |
| 667 | 667 |
| 668 def merge(complete_state): | |
| 669 """Reads a trace and merges it back into the source .isolate file.""" | |
| 670 value = read(complete_state) | |
|
csharp
2012/09/06 12:59:37
Nit: what exactly does value contain? Is it a dict
M-A Ruel
2012/09/06 19:26:50
A dict, as the read() docstring says.
| |
| 671 | |
| 672 # Now take that data and union it into the original .isolate file. | |
| 673 with open(complete_state.saved_state.isolate_file, 'r') as f: | |
| 674 prev_content = f.read() | |
| 675 prev_config = merge_isolate.load_gyp( | |
| 676 merge_isolate.eval_content(prev_content), | |
| 677 merge_isolate.extract_comment(prev_content), | |
| 678 merge_isolate.DEFAULT_OSES) | |
| 679 new_config = merge_isolate.load_gyp( | |
| 680 value, | |
| 681 '', | |
| 682 merge_isolate.DEFAULT_OSES) | |
| 683 config = merge_isolate.union(prev_config, new_config) | |
| 684 # pylint: disable=E1103 | |
| 685 data = merge_isolate.convert_map_to_gyp( | |
| 686 *merge_isolate.reduce_inputs(*merge_isolate.invert_map(config.flatten()))) | |
| 687 print 'Updating %s' % complete_state.saved_state.isolate_file | |
| 688 with open(complete_state.saved_state.isolate_file, 'wb') as f: | |
| 689 merge_isolate.print_all(config.file_comment, data, f) | |
| 690 | |
| 691 | |
| 668 def CMDcheck(args): | 692 def CMDcheck(args): |
| 669 """Checks that all the inputs are present and update .result.""" | 693 """Checks that all the inputs are present and update .result.""" |
| 670 parser = OptionParserIsolate(command='check') | 694 parser = OptionParserIsolate(command='check') |
| 671 options, _ = parser.parse_args(args) | 695 options, _ = parser.parse_args(args) |
| 672 complete_state = load_complete_state(options, NO_INFO) | 696 complete_state = load_complete_state(options, NO_INFO) |
| 673 | 697 |
| 674 # Nothing is done specifically. Just store the result and state. | 698 # Nothing is done specifically. Just store the result and state. |
| 675 complete_state.save_files() | 699 complete_state.save_files() |
| 676 return 0 | 700 return 0 |
| 677 | 701 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 741 | 765 |
| 742 | 766 |
| 743 def CMDmerge(args): | 767 def CMDmerge(args): |
| 744 """Reads and merges the data from the trace back into the original .isolate. | 768 """Reads and merges the data from the trace back into the original .isolate. |
| 745 | 769 |
| 746 Ignores --outdir. | 770 Ignores --outdir. |
| 747 """ | 771 """ |
| 748 parser = OptionParserIsolate(command='merge', require_result=False) | 772 parser = OptionParserIsolate(command='merge', require_result=False) |
| 749 options, _ = parser.parse_args(args) | 773 options, _ = parser.parse_args(args) |
| 750 complete_state = load_complete_state(options, NO_INFO) | 774 complete_state = load_complete_state(options, NO_INFO) |
| 751 value = read(complete_state) | 775 merge(complete_state) |
| 752 | |
| 753 # Now take that data and union it into the original .isolate file. | |
| 754 with open(complete_state.saved_state.isolate_file, 'r') as f: | |
| 755 prev_content = f.read() | |
| 756 prev_config = merge_isolate.load_gyp( | |
| 757 merge_isolate.eval_content(prev_content), | |
| 758 merge_isolate.extract_comment(prev_content), | |
| 759 merge_isolate.DEFAULT_OSES) | |
| 760 new_config = merge_isolate.load_gyp( | |
| 761 value, | |
| 762 '', | |
| 763 merge_isolate.DEFAULT_OSES) | |
| 764 config = merge_isolate.union(prev_config, new_config) | |
| 765 # pylint: disable=E1103 | |
| 766 data = merge_isolate.convert_map_to_gyp( | |
| 767 *merge_isolate.reduce_inputs(*merge_isolate.invert_map(config.flatten()))) | |
| 768 print 'Updating %s' % complete_state.saved_state.isolate_file | |
| 769 with open(complete_state.saved_state.isolate_file, 'wb') as f: | |
| 770 merge_isolate.print_all(config.file_comment, data, f) | |
| 771 | |
| 772 return 0 | 776 return 0 |
| 773 | 777 |
| 774 | 778 |
| 775 def CMDread(args): | 779 def CMDread(args): |
| 776 """Reads the trace file generated with command 'trace'. | 780 """Reads the trace file generated with command 'trace'. |
| 777 | 781 |
| 778 Ignores --outdir. | 782 Ignores --outdir. |
| 779 """ | 783 """ |
| 780 parser = OptionParserIsolate(command='read', require_result=False) | 784 parser = OptionParserIsolate(command='read', require_result=False) |
| 781 options, _ = parser.parse_args(args) | 785 options, _ = parser.parse_args(args) |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 876 It runs the executable without remapping it, and traces all the files it and | 880 It runs the executable without remapping it, and traces all the files it and |
| 877 its child processes access. Then the 'read' command can be used to generate an | 881 its child processes access. Then the 'read' command can be used to generate an |
| 878 updated .isolate file out of it. | 882 updated .isolate file out of it. |
| 879 | 883 |
| 880 Argument processing stops at the first non-recognized argument and these | 884 Argument processing stops at the first non-recognized argument and these |
| 881 arguments are appended to the command line of the target to run. For example, | 885 arguments are appended to the command line of the target to run. For example, |
| 882 use: isolate.py -r foo.results -- --gtest_filter=Foo.Bar | 886 use: isolate.py -r foo.results -- --gtest_filter=Foo.Bar |
| 883 """ | 887 """ |
| 884 parser = OptionParserIsolate(command='trace') | 888 parser = OptionParserIsolate(command='trace') |
| 885 parser.enable_interspersed_args() | 889 parser.enable_interspersed_args() |
| 890 parser.add_option( | |
| 891 '-m', '--merge', action='store_true', | |
| 892 help='After tracing, merge the results back in the .isolate file') | |
| 886 options, args = parser.parse_args(args) | 893 options, args = parser.parse_args(args) |
| 887 complete_state = load_complete_state(options, STATS_ONLY) | 894 complete_state = load_complete_state(options, STATS_ONLY) |
| 888 cmd = complete_state.result.command + args | 895 cmd = complete_state.result.command + args |
| 889 if not cmd: | 896 if not cmd: |
| 890 raise ExecutionError('No command to run') | 897 raise ExecutionError('No command to run') |
| 891 cmd = trace_inputs.fix_python_path(cmd) | 898 cmd = trace_inputs.fix_python_path(cmd) |
| 892 cwd = os.path.normpath(os.path.join( | 899 cwd = os.path.normpath(os.path.join( |
| 893 complete_state.root_dir, complete_state.result.relative_cwd)) | 900 complete_state.root_dir, complete_state.result.relative_cwd)) |
| 894 logging.info('Running %s, cwd=%s' % (cmd, cwd)) | 901 logging.info('Running %s, cwd=%s' % (cmd, cwd)) |
| 895 api = trace_inputs.get_api() | 902 api = trace_inputs.get_api() |
| 896 logfile = complete_state.result_file + '.log' | 903 logfile = complete_state.result_file + '.log' |
| 897 api.clean_trace(logfile) | 904 api.clean_trace(logfile) |
| 898 try: | 905 try: |
| 899 with api.get_tracer(logfile) as tracer: | 906 with api.get_tracer(logfile) as tracer: |
| 900 result, _ = tracer.trace( | 907 result, _ = tracer.trace( |
| 901 cmd, | 908 cmd, |
| 902 cwd, | 909 cwd, |
| 903 'default', | 910 'default', |
| 904 True) | 911 True) |
| 905 except trace_inputs.TracingFailure, e: | 912 except trace_inputs.TracingFailure, e: |
| 906 raise ExecutionError('Tracing failed for: %s\n%s' % (' '.join(cmd), str(e))) | 913 raise ExecutionError('Tracing failed for: %s\n%s' % (' '.join(cmd), str(e))) |
| 907 | 914 |
| 908 complete_state.save_files() | 915 complete_state.save_files() |
| 916 | |
| 917 if options.merge: | |
| 918 merge(complete_state) | |
| 919 | |
| 909 return result | 920 return result |
| 910 | 921 |
| 911 | 922 |
| 912 class OptionParserWithNiceDescription(optparse.OptionParser): | 923 class OptionParserWithNiceDescription(optparse.OptionParser): |
| 913 """Generates the description with the command's docstring.""" | 924 """Generates the description with the command's docstring.""" |
| 914 def __init__(self, *args, **kwargs): | 925 def __init__(self, *args, **kwargs): |
| 915 """Sets 'description' and 'usage' if not already specified.""" | 926 """Sets 'description' and 'usage' if not already specified.""" |
| 916 command = kwargs.pop('command', None) | 927 command = kwargs.pop('command', None) |
| 917 if not 'description' in kwargs: | 928 if not 'description' in kwargs: |
| 918 kwargs['description'] = re.sub( | 929 kwargs['description'] = re.sub( |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1066 return command(argv[1:]) | 1077 return command(argv[1:]) |
| 1067 except (ExecutionError, run_test_from_archive.MappingError), e: | 1078 except (ExecutionError, run_test_from_archive.MappingError), e: |
| 1068 sys.stderr.write('\nError: ') | 1079 sys.stderr.write('\nError: ') |
| 1069 sys.stderr.write(str(e)) | 1080 sys.stderr.write(str(e)) |
| 1070 sys.stderr.write('\n') | 1081 sys.stderr.write('\n') |
| 1071 return 1 | 1082 return 1 |
| 1072 | 1083 |
| 1073 | 1084 |
| 1074 if __name__ == '__main__': | 1085 if __name__ == '__main__': |
| 1075 sys.exit(main(sys.argv[1:])) | 1086 sys.exit(main(sys.argv[1:])) |
| OLD | NEW |