Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: testing/buildbot/manage.py

Issue 1203753002: Improve manage.py to automate CL creation further. (Closed) Base URL: https://chromium.googlesource.com/a/chromium/src.git@7_components_browsertests
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 """
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 class Error(Exception): 86 class Error(Exception):
87 """Processing error.""" 87 """Processing error."""
88 88
89 89
90 def get_isolates(): 90 def get_isolates():
91 """Returns the list of all isolate files.""" 91 """Returns the list of all isolate files."""
92 files = subprocess.check_output(['git', 'ls-files'], cwd=SRC_DIR).splitlines() 92 files = subprocess.check_output(['git', 'ls-files'], cwd=SRC_DIR).splitlines()
93 return [os.path.basename(f) for f in files if f.endswith('.isolate')] 93 return [os.path.basename(f) for f in files if f.endswith('.isolate')]
94 94
95 95
96 def process_builder_convert(data, filename, builder, test_name): 96 def process_builder_convert(data, test_name):
97 """Converts 'test_name' to run on Swarming in 'data'. 97 """Converts 'test_name' to run on Swarming in 'data'.
98 98
99 Returns True if 'test_name' was found. 99 Returns True if 'test_name' was found.
100 """ 100 """
101 result = False 101 result = False
102 for test in data['gtest_tests']: 102 for test in data['gtest_tests']:
103 if test['test'] != test_name: 103 if test['test'] != test_name:
104 continue 104 continue
105 test.setdefault('swarming', {}) 105 test.setdefault('swarming', {})
106 if not test['swarming'].get('can_use_on_swarming_builders'): 106 if not test['swarming'].get('can_use_on_swarming_builders'):
107 print('- %s: %s' % (filename, builder))
108 test['swarming']['can_use_on_swarming_builders'] = True 107 test['swarming']['can_use_on_swarming_builders'] = True
109 result = True 108 result = True
110 return result 109 return result
111 110
112 111
113 def process_builder_remaining(data, filename, builder, tests_location): 112 def process_builder_remaining(data, filename, builder, tests_location):
114 """Calculates tests_location when mode is --remaining.""" 113 """Calculates tests_location when mode is --remaining."""
115 for test in data['gtest_tests']: 114 for test in data['gtest_tests']:
116 name = test['test'] 115 name = test['test']
117 if test.get('swarming', {}).get('can_use_on_swarming_builders'): 116 if test.get('swarming', {}).get('can_use_on_swarming_builders'):
118 tests_location[name]['count_run_on_swarming'] += 1 117 tests_location[name]['count_run_on_swarming'] += 1
119 else: 118 else:
120 tests_location[name]['count_run_local'] += 1 119 tests_location[name]['count_run_local'] += 1
121 tests_location[name]['local_configs'].setdefault( 120 tests_location[name]['local_configs'].setdefault(
122 filename, []).append(builder) 121 filename, []).append(builder)
123 122
124 123
125 def process_file(mode, test_name, tests_location, filepath, ninja_targets, 124 def process_file(mode, test_name, tests_location, filepath, ninja_targets,
126 ninja_targets_seen): 125 ninja_targets_seen):
127 """Processes a file. 126 """Processes a json file describing what tests should be run for each recipe.
128 127
129 The action depends on mode. Updates tests_location. 128 The action depends on mode. Updates tests_location.
130 129
131 Return False if the process exit code should be 1. 130 Return False if the process exit code should be 1.
132 """ 131 """
133 filename = os.path.basename(filepath) 132 filename = os.path.basename(filepath)
134 with open(filepath) as f: 133 with open(filepath) as f:
135 content = f.read() 134 content = f.read()
136 try: 135 try:
137 config = json.loads(content) 136 config = json.loads(content)
(...skipping 18 matching lines...) Expand all
156 for d in data['gtest_tests']: 155 for d in data['gtest_tests']:
157 if (d['test'] not in ninja_targets and 156 if (d['test'] not in ninja_targets and
158 d['test'] not in SKIP_NINJA_TO_GN_TARGETS): 157 d['test'] not in SKIP_NINJA_TO_GN_TARGETS):
159 raise Error('%s: %s / %s is not listed in ninja_to_gn.pyl.' % 158 raise Error('%s: %s / %s is not listed in ninja_to_gn.pyl.' %
160 (filename, builder, d['test'])) 159 (filename, builder, d['test']))
161 elif d['test'] in ninja_targets: 160 elif d['test'] in ninja_targets:
162 ninja_targets_seen.add(d['test']) 161 ninja_targets_seen.add(d['test'])
163 162
164 config[builder]['gtest_tests'] = sorted( 163 config[builder]['gtest_tests'] = sorted(
165 data['gtest_tests'], key=lambda x: x['test']) 164 data['gtest_tests'], key=lambda x: x['test'])
166 if mode == 'remaining': 165
166 # The trick here is that process_builder_remaining() is called before
167 # process_builder_convert() so tests_location can be used to know how many
168 # tests were converted.
169 if mode in ('convert', 'remaining'):
167 process_builder_remaining(data, filename, builder, tests_location) 170 process_builder_remaining(data, filename, builder, tests_location)
168 elif mode == 'convert': 171 if mode == 'convert':
169 process_builder_convert(data, filename, builder, test_name) 172 process_builder_convert(data, test_name)
170 173
171 expected = json.dumps( 174 expected = json.dumps(
172 config, sort_keys=True, indent=2, separators=(',', ': ')) + '\n' 175 config, sort_keys=True, indent=2, separators=(',', ': ')) + '\n'
173 if content != expected: 176 if content != expected:
174 if mode in ('convert', 'write'): 177 if mode in ('convert', 'write'):
175 with open(filepath, 'wb') as f: 178 with open(filepath, 'wb') as f:
176 f.write(expected) 179 f.write(expected)
177 if mode == 'write': 180 if mode == 'write':
178 print('Updated %s' % filename) 181 print('Updated %s' % filename)
179 else: 182 else:
180 print('%s is not in canonical format' % filename) 183 print('%s is not in canonical format' % filename)
181 print('run `testing/buildbot/manage.py -w` to fix') 184 print('run `testing/buildbot/manage.py -w` to fix')
182 return mode != 'check' 185 return mode != 'check'
183 return True 186 return True
184 187
185 188
186 def print_remaining(test_name,tests_location): 189 def print_convert(test_name, tests_location):
190 """Prints statistics for a test being converted for use in a CL description.
191 """
192 data = tests_location[test_name]
193 print('Convert %s to run exclusively on Swarming' % test_name)
194 print('')
195 print(
196 '%d configs used to already run on Swarming' %
Dirk Pranke 2015/06/23 19:25:41 "%d configs already ran on Swarming" maybe?
M-A Ruel 2015/06/23 19:29:51 Done.
197 data['count_run_on_swarming'])
Dirk Pranke 2015/06/23 19:24:39 this formatting is a bit odd; why isn't the string
198 print('%d used to run locally and were converted:' % data['count_run_local'])
199 for master, builders in sorted(data['local_configs'].iteritems()):
200 for builder in builders:
201 print('- %s: %s' % (master, builder))
202 print('')
203 print('Ran:')
204 print(' ./manage.py --convert %s' % test_name)
205 print('')
206 print('R=')
207 print('BUG=98637')
208
209
210 def print_remaining(test_name, tests_location):
187 """Prints a visual summary of what tests are yet to be converted to run on 211 """Prints a visual summary of what tests are yet to be converted to run on
188 Swarming. 212 Swarming.
189 """ 213 """
190 if test_name: 214 if test_name:
191 if test_name not in tests_location: 215 if test_name not in tests_location:
192 raise Error('Unknown test %s' % test_name) 216 raise Error('Unknown test %s' % test_name)
193 for config, builders in sorted( 217 for config, builders in sorted(
194 tests_location[test_name]['local_configs'].iteritems()): 218 tests_location[test_name]['local_configs'].iteritems()):
195 print('%s:' % config) 219 print('%s:' % config)
196 for builder in sorted(builders): 220 for builder in sorted(builders):
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 300
277 extra_targets = set(ninja_targets) - ninja_targets_seen 301 extra_targets = set(ninja_targets) - ninja_targets_seen
278 if extra_targets: 302 if extra_targets:
279 if len(extra_targets) > 1: 303 if len(extra_targets) > 1:
280 extra_targets_str = ', '.join(extra_targets) + ' are' 304 extra_targets_str = ', '.join(extra_targets) + ' are'
281 else: 305 else:
282 extra_targets_str = list(extra_targets)[0] + ' is' 306 extra_targets_str = list(extra_targets)[0] + ' is'
283 raise Error('%s listed in ninja_to_gn.pyl but not in any .json files' % 307 raise Error('%s listed in ninja_to_gn.pyl but not in any .json files' %
284 extra_targets_str) 308 extra_targets_str)
285 309
286 if args.mode == 'remaining': 310 if args.mode == 'convert':
311 print_convert(args.test_name, tests_location)
312 elif args.mode == 'remaining':
287 print_remaining(args.test_name, tests_location) 313 print_remaining(args.test_name, tests_location)
288 return result 314 return result
289 except Error as e: 315 except Error as e:
290 sys.stderr.write('%s\n' % e) 316 sys.stderr.write('%s\n' % e)
291 return 1 317 return 1
292 318
293 319
294 if __name__ == "__main__": 320 if __name__ == "__main__":
295 sys.exit(main()) 321 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698