OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2015 The Chromium Authors. All rights reserved. | 2 # Copyright 2015 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 """Toolbox to manage all the json files in this directory. | 6 """Toolbox to manage all the json files in this directory. |
7 | 7 |
8 It can reformat them in their canonical format or ensures they are well | 8 It can reformat them in their canonical format or ensures they are well |
9 formatted. | 9 formatted. |
10 """ | 10 """ |
11 | 11 |
12 import argparse | 12 import argparse |
13 import ast | |
13 import collections | 14 import collections |
14 import glob | 15 import glob |
15 import json | 16 import json |
16 import os | 17 import os |
17 import subprocess | 18 import subprocess |
18 import sys | 19 import sys |
19 | 20 |
20 | 21 |
21 THIS_DIR = os.path.dirname(os.path.abspath(__file__)) | 22 THIS_DIR = os.path.dirname(os.path.abspath(__file__)) |
22 SRC_DIR = os.path.dirname(os.path.dirname(THIS_DIR)) | 23 SRC_DIR = os.path.dirname(os.path.dirname(THIS_DIR)) |
(...skipping 21 matching lines...) Expand all Loading... | |
44 'ClangToTMac', | 45 'ClangToTMac', |
45 'ClangToTMacASan', | 46 'ClangToTMacASan', |
46 | 47 |
47 # One off builders. Note that Swarming does support ARM. | 48 # One off builders. Note that Swarming does support ARM. |
48 'Linux ARM Cross-Compile', | 49 'Linux ARM Cross-Compile', |
49 'Site Isolation Linux', | 50 'Site Isolation Linux', |
50 'Site Isolation Win', | 51 'Site Isolation Win', |
51 } | 52 } |
52 | 53 |
53 | 54 |
55 # TODO(GYP): These targets have not been ported to GN yet. | |
56 SKIP_NINJA_TO_GN_TARGETS = { | |
57 'cast_media_unittests', | |
58 'cast_shell_browser_test', | |
59 'chromevox_tests', | |
60 } | |
61 | |
62 | |
54 class Error(Exception): | 63 class Error(Exception): |
55 """Processing error.""" | 64 """Processing error.""" |
56 | 65 |
57 | 66 |
58 def get_isolates(): | 67 def get_isolates(): |
59 """Returns the list of all isolate files.""" | 68 """Returns the list of all isolate files.""" |
60 files = subprocess.check_output(['git', 'ls-files'], cwd=SRC_DIR).splitlines() | 69 files = subprocess.check_output(['git', 'ls-files'], cwd=SRC_DIR).splitlines() |
61 return [os.path.basename(f) for f in files if f.endswith('.isolate')] | 70 return [os.path.basename(f) for f in files if f.endswith('.isolate')] |
62 | 71 |
63 | 72 |
(...skipping 19 matching lines...) Expand all Loading... | |
83 for test in data['gtest_tests']: | 92 for test in data['gtest_tests']: |
84 name = test['test'] | 93 name = test['test'] |
85 if test.get('swarming', {}).get('can_use_on_swarming_builders'): | 94 if test.get('swarming', {}).get('can_use_on_swarming_builders'): |
86 tests_location[name]['count_run_on_swarming'] += 1 | 95 tests_location[name]['count_run_on_swarming'] += 1 |
87 else: | 96 else: |
88 tests_location[name]['count_run_local'] += 1 | 97 tests_location[name]['count_run_local'] += 1 |
89 tests_location[name]['local_configs'].setdefault( | 98 tests_location[name]['local_configs'].setdefault( |
90 filename, []).append(builder) | 99 filename, []).append(builder) |
91 | 100 |
92 | 101 |
93 def process_file(mode, test_name, tests_location, filepath): | 102 def process_file(mode, test_name, tests_location, filepath, ninja_targets, |
103 ninja_targets_seen): | |
94 """Processes a file. | 104 """Processes a file. |
95 | 105 |
96 The action depends on mode. Updates tests_location. | 106 The action depends on mode. Updates tests_location. |
97 | 107 |
98 Return False if the process exit code should be 1. | 108 Return False if the process exit code should be 1. |
99 """ | 109 """ |
100 filename = os.path.basename(filepath) | 110 filename = os.path.basename(filepath) |
101 with open(filepath) as f: | 111 with open(filepath) as f: |
102 content = f.read() | 112 content = f.read() |
103 try: | 113 try: |
104 config = json.loads(content) | 114 config = json.loads(content) |
105 except ValueError as e: | 115 except ValueError as e: |
106 raise Error('Exception raised while checking %s: %s' % (filepath, e)) | 116 raise Error('Exception raised while checking %s: %s' % (filepath, e)) |
107 | 117 |
108 for builder, data in sorted(config.iteritems()): | 118 for builder, data in sorted(config.iteritems()): |
109 if builder in SKIP: | 119 if builder in SKIP: |
110 # Oddities. | 120 # Oddities. |
111 continue | 121 continue |
112 if not isinstance(data, dict): | 122 if not isinstance(data, dict): |
113 raise Error('%s: %s is broken: %s' % (filename, builder, data)) | 123 raise Error('%s: %s is broken: %s' % (filename, builder, data)) |
114 if 'gtest_tests' not in data: | 124 if 'gtest_tests' not in data: |
115 continue | 125 continue |
116 if not isinstance(data['gtest_tests'], list): | 126 if not isinstance(data['gtest_tests'], list): |
117 raise Error( | 127 raise Error( |
118 '%s: %s is broken: %s' % (filename, builder, data['gtest_tests'])) | 128 '%s: %s is broken: %s' % (filename, builder, data['gtest_tests'])) |
119 if not all(isinstance(g, dict) for g in data['gtest_tests']): | 129 if not all(isinstance(g, dict) for g in data['gtest_tests']): |
120 raise Error( | 130 raise Error( |
121 '%s: %s is broken: %s' % (filename, builder, data['gtest_tests'])) | 131 '%s: %s is broken: %s' % (filename, builder, data['gtest_tests'])) |
122 | 132 |
133 for d in data['gtest_tests']: | |
134 if (not d['test'] in ninja_targets and | |
Paweł Hajdan Jr.
2015/06/10 09:30:08
nit: Consider "d['test'] not in ninja_targets" ins
Dirk Pranke
2015/06/10 16:07:59
will fix.
| |
135 d['test'] not in SKIP_NINJA_TO_GN_TARGETS): | |
136 raise Error('%s: %s / %s is not listed in ninja_to_gn.pyl.' % | |
137 (filename, builder, d['test'])) | |
138 elif d['test'] in ninja_targets: | |
139 ninja_targets_seen.add(d['test']) | |
140 | |
123 config[builder]['gtest_tests'] = sorted( | 141 config[builder]['gtest_tests'] = sorted( |
124 data['gtest_tests'], key=lambda x: x['test']) | 142 data['gtest_tests'], key=lambda x: x['test']) |
125 if mode == 'remaining': | 143 if mode == 'remaining': |
126 process_builder_remaining(data, filename, builder, tests_location) | 144 process_builder_remaining(data, filename, builder, tests_location) |
127 elif mode == 'convert': | 145 elif mode == 'convert': |
128 process_builder_convert(data, filename, builder, test_name) | 146 process_builder_convert(data, filename, builder, test_name) |
129 | 147 |
130 expected = json.dumps( | 148 expected = json.dumps( |
131 config, sort_keys=True, indent=2, separators=(',', ': ')) + '\n' | 149 config, sort_keys=True, indent=2, separators=(',', ': ')) + '\n' |
132 if content != expected: | 150 if content != expected: |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
215 parser.error('A test name is required with --convert') | 233 parser.error('A test name is required with --convert') |
216 if args.test_name + '.isolate' not in get_isolates(): | 234 if args.test_name + '.isolate' not in get_isolates(): |
217 parser.error('Create %s.isolate first' % args.test_name) | 235 parser.error('Create %s.isolate first' % args.test_name) |
218 | 236 |
219 # Stats when running in --remaining mode; | 237 # Stats when running in --remaining mode; |
220 tests_location = collections.defaultdict( | 238 tests_location = collections.defaultdict( |
221 lambda: { | 239 lambda: { |
222 'count_run_local': 0, 'count_run_on_swarming': 0, 'local_configs': {} | 240 'count_run_local': 0, 'count_run_on_swarming': 0, 'local_configs': {} |
223 }) | 241 }) |
224 | 242 |
243 with open(os.path.join(THIS_DIR, "ninja_to_gn.pyl")) as fp: | |
244 ninja_targets = ast.literal_eval(fp.read()) | |
245 | |
225 try: | 246 try: |
226 result = 0 | 247 result = 0 |
248 ninja_targets_seen = set() | |
227 for filepath in glob.glob(os.path.join(THIS_DIR, '*.json')): | 249 for filepath in glob.glob(os.path.join(THIS_DIR, '*.json')): |
228 if not process_file(args.mode, args.test_name, tests_location, filepath): | 250 if not process_file(args.mode, args.test_name, tests_location, filepath, |
251 ninja_targets, ninja_targets_seen): | |
229 result = 1 | 252 result = 1 |
230 | 253 |
254 extra_targets = set(ninja_targets.keys()) - ninja_targets_seen | |
M-A Ruel
2015/06/10 14:53:40
set(ninja_targets)
Dirk Pranke
2015/06/10 16:07:59
will fix.
| |
255 if extra_targets: | |
256 if len(extra_targets) > 1: | |
257 extra_targets_str = ', '.join(extra_targets) + ' are' | |
258 else: | |
259 extra_targets_str = list(extra_targets)[0] + ' is' | |
260 raise Error('%s listed in ninja_to_gn.pyl but not in any .json files' % | |
261 extra_targets_str) | |
262 | |
231 if args.mode == 'remaining': | 263 if args.mode == 'remaining': |
232 print_remaining(args.test_name, tests_location) | 264 print_remaining(args.test_name, tests_location) |
233 return result | 265 return result |
234 except Error as e: | 266 except Error as e: |
235 sys.stderr.write('%s\n' % e) | 267 sys.stderr.write('%s\n' % e) |
236 return 1 | 268 return 1 |
237 | 269 |
238 | 270 |
239 if __name__ == "__main__": | 271 if __name__ == "__main__": |
240 sys.exit(main()) | 272 sys.exit(main()) |
OLD | NEW |