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

Side by Side Diff: tools/rebaseline.py

Issue 23478011: rebaseline.py: add --bugs and --unreviewed flags (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: add_flags Created 7 years, 3 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 | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 ''' 3 '''
4 Copyright 2012 Google Inc. 4 Copyright 2012 Google Inc.
5 5
6 Use of this source code is governed by a BSD-style license that can be 6 Use of this source code is governed by a BSD-style license that can be
7 found in the LICENSE file. 7 found in the LICENSE file.
8 ''' 8 '''
9 9
10 ''' 10 '''
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 # actuals_base_url: base URL from which to read actual-result JSON files 153 # actuals_base_url: base URL from which to read actual-result JSON files
154 # actuals_filename: filename (under actuals_base_url) from which to read a 154 # actuals_filename: filename (under actuals_base_url) from which to read a
155 # summary of results; typically "actual-results.json" 155 # summary of results; typically "actual-results.json"
156 # exception_handler: reference to rebaseline.ExceptionHandler object 156 # exception_handler: reference to rebaseline.ExceptionHandler object
157 # tests: list of tests to rebaseline, or None if we should rebaseline 157 # tests: list of tests to rebaseline, or None if we should rebaseline
158 # whatever files the JSON results summary file tells us to 158 # whatever files the JSON results summary file tells us to
159 # configs: which configs to run for each test, or None if we should 159 # configs: which configs to run for each test, or None if we should
160 # rebaseline whatever configs the JSON results summary file tells 160 # rebaseline whatever configs the JSON results summary file tells
161 # us to 161 # us to
162 # add_new: if True, add expectations for tests which don't have any yet 162 # add_new: if True, add expectations for tests which don't have any yet
163 # bugs: optional list of bug numbers which pertain to these expectations
164 # mark_unreviewed: if True, mark these expectations as NOT having been
165 # reviewed by a human; otherwise, leave that field blank.
166 # Currently, there is no way to make this script mark
167 # expectations as reviewed-by-human=True.
168 # TODO(epoger): Add that capability to a review tool.
163 def __init__(self, expectations_root, expectations_input_filename, 169 def __init__(self, expectations_root, expectations_input_filename,
164 expectations_output_filename, actuals_base_url, 170 expectations_output_filename, actuals_base_url,
165 actuals_filename, exception_handler, 171 actuals_filename, exception_handler,
166 tests=None, configs=None, add_new=False): 172 tests=None, configs=None, add_new=False, bugs=None,
173 mark_unreviewed=None):
167 self._expectations_root = expectations_root 174 self._expectations_root = expectations_root
168 self._expectations_input_filename = expectations_input_filename 175 self._expectations_input_filename = expectations_input_filename
169 self._expectations_output_filename = expectations_output_filename 176 self._expectations_output_filename = expectations_output_filename
170 self._tests = tests 177 self._tests = tests
171 self._configs = configs 178 self._configs = configs
172 self._actuals_base_url = actuals_base_url 179 self._actuals_base_url = actuals_base_url
173 self._actuals_filename = actuals_filename 180 self._actuals_filename = actuals_filename
174 self._exception_handler = exception_handler 181 self._exception_handler = exception_handler
175 self._add_new = add_new 182 self._add_new = add_new
183 self._bugs = bugs
184 self._mark_unreviewed = mark_unreviewed
176 self._image_filename_re = re.compile(gm_json.IMAGE_FILENAME_PATTERN) 185 self._image_filename_re = re.compile(gm_json.IMAGE_FILENAME_PATTERN)
177 self._using_svn = os.path.isdir(os.path.join(expectations_root, '.svn')) 186 self._using_svn = os.path.isdir(os.path.join(expectations_root, '.svn'))
178 187
179 # Executes subprocess.call(cmd). 188 # Executes subprocess.call(cmd).
180 # Raises an Exception if the command fails. 189 # Raises an Exception if the command fails.
181 def _Call(self, cmd): 190 def _Call(self, cmd):
182 if subprocess.call(cmd) != 0: 191 if subprocess.call(cmd) != 0:
183 raise _InternalException('error running command: ' + ' '.join(cmd)) 192 raise _InternalException('error running command: ' + ' '.join(cmd))
184 193
185 # Returns the full contents of filepath, as a single string. 194 # Returns the full contents of filepath, as a single string.
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 skipped_images.append(image_name) 282 skipped_images.append(image_name)
274 continue 283 continue
275 if self._configs: 284 if self._configs:
276 if config not in self._configs: 285 if config not in self._configs:
277 skipped_images.append(image_name) 286 skipped_images.append(image_name)
278 continue 287 continue
279 if not expected_results.get(image_name): 288 if not expected_results.get(image_name):
280 expected_results[image_name] = {} 289 expected_results[image_name] = {}
281 expected_results[image_name][gm_json.JSONKEY_EXPECTEDRESULTS_ALLOWEDDIGE STS] = \ 290 expected_results[image_name][gm_json.JSONKEY_EXPECTEDRESULTS_ALLOWEDDIGE STS] = \
282 [image_results] 291 [image_results]
292 if self._mark_unreviewed:
epoger 2013/08/29 19:45:31 Patchset 2 adds the --bugs and --unreviewed flags,
293 expected_results[image_name][gm_json.JSONKEY_EXPECTEDRESULTS_REVIEWED] = \
294 False
295 if self._bugs:
296 expected_results[image_name][gm_json.JSONKEY_EXPECTEDRESULTS_BUGS] = \
297 self._bugs
283 298
284 # Write out updated expectations. 299 # Write out updated expectations.
285 expectations_output_filepath = os.path.join( 300 expectations_output_filepath = os.path.join(
286 self._expectations_root, builder, self._expectations_output_filename) 301 self._expectations_root, builder, self._expectations_output_filename)
287 gm_json.WriteToFile(expectations_dict, expectations_output_filepath) 302 gm_json.WriteToFile(expectations_dict, expectations_output_filepath)
288 303
289 # Mark the JSON file as plaintext, so text-style diffs can be applied. 304 # Mark the JSON file as plaintext, so text-style diffs can be applied.
290 # Fixes https://code.google.com/p/skia/issues/detail?id=1442 305 # Fixes https://code.google.com/p/skia/issues/detail?id=1442
291 if self._using_svn: 306 if self._using_svn:
292 self._Call(['svn', 'propset', '--quiet', 'svn:mime-type', 307 self._Call(['svn', 'propset', '--quiet', 'svn:mime-type',
(...skipping 10 matching lines...) Expand all
303 help='filename (within builder-specific subdirectories ' + 318 help='filename (within builder-specific subdirectories ' +
304 'of ACTUALS_BASE_URL) to read a summary of results from; ' + 319 'of ACTUALS_BASE_URL) to read a summary of results from; ' +
305 'defaults to %(default)s', 320 'defaults to %(default)s',
306 default='actual-results.json') 321 default='actual-results.json')
307 # TODO(epoger): Add test that exercises --add-new argument. 322 # TODO(epoger): Add test that exercises --add-new argument.
308 parser.add_argument('--add-new', action='store_true', 323 parser.add_argument('--add-new', action='store_true',
309 help='in addition to the standard behavior of ' + 324 help='in addition to the standard behavior of ' +
310 'updating expectations for failing tests, add ' + 325 'updating expectations for failing tests, add ' +
311 'expectations for tests which don\'t have expectations ' + 326 'expectations for tests which don\'t have expectations ' +
312 'yet.') 327 'yet.')
328 parser.add_argument('--bugs', metavar='BUG', type=int, nargs='+',
329 help='Skia bug numbers (under ' +
330 'https://code.google.com/p/skia/issues/list ) which '+
331 'pertain to this set of rebaselines.')
313 parser.add_argument('--builders', metavar='BUILDER', nargs='+', 332 parser.add_argument('--builders', metavar='BUILDER', nargs='+',
314 help='which platforms to rebaseline; ' + 333 help='which platforms to rebaseline; ' +
315 'if unspecified, rebaseline all platforms, same as ' + 334 'if unspecified, rebaseline all platforms, same as ' +
316 '"--builders %s"' % ' '.join(sorted(TEST_BUILDERS))) 335 '"--builders %s"' % ' '.join(sorted(TEST_BUILDERS)))
317 # TODO(epoger): Add test that exercises --configs argument. 336 # TODO(epoger): Add test that exercises --configs argument.
318 parser.add_argument('--configs', metavar='CONFIG', nargs='+', 337 parser.add_argument('--configs', metavar='CONFIG', nargs='+',
319 help='which configurations to rebaseline, e.g. ' + 338 help='which configurations to rebaseline, e.g. ' +
320 '"--configs 565 8888", as a filter over the full set of ' + 339 '"--configs 565 8888", as a filter over the full set of ' +
321 'results in ACTUALS_FILENAME; if unspecified, rebaseline ' + 340 'results in ACTUALS_FILENAME; if unspecified, rebaseline ' +
322 '*all* configs that are available.') 341 '*all* configs that are available.')
(...skipping 17 matching lines...) Expand all
340 parser.add_argument('--keep-going-on-failure', action='store_true', 359 parser.add_argument('--keep-going-on-failure', action='store_true',
341 help='instead of halting at the first error encountered, ' + 360 help='instead of halting at the first error encountered, ' +
342 'keep going and rebaseline as many tests as possible, ' + 361 'keep going and rebaseline as many tests as possible, ' +
343 'and then report the full set of errors at the end') 362 'and then report the full set of errors at the end')
344 # TODO(epoger): Add test that exercises --tests argument. 363 # TODO(epoger): Add test that exercises --tests argument.
345 parser.add_argument('--tests', metavar='TEST', nargs='+', 364 parser.add_argument('--tests', metavar='TEST', nargs='+',
346 help='which tests to rebaseline, e.g. ' + 365 help='which tests to rebaseline, e.g. ' +
347 '"--tests aaclip bigmatrix", as a filter over the full ' + 366 '"--tests aaclip bigmatrix", as a filter over the full ' +
348 'set of results in ACTUALS_FILENAME; if unspecified, ' + 367 'set of results in ACTUALS_FILENAME; if unspecified, ' +
349 'rebaseline *all* tests that are available.') 368 'rebaseline *all* tests that are available.')
369 parser.add_argument('--unreviewed', action='store_true',
370 help='mark all expectations modified by this run as ' +
371 '"%s": False' % gm_json.JSONKEY_EXPECTEDRESULTS_REVIEWED)
350 args = parser.parse_args() 372 args = parser.parse_args()
351 exception_handler = ExceptionHandler( 373 exception_handler = ExceptionHandler(
352 keep_going_on_failure=args.keep_going_on_failure) 374 keep_going_on_failure=args.keep_going_on_failure)
353 if args.builders: 375 if args.builders:
354 builders = args.builders 376 builders = args.builders
355 missing_json_is_fatal = True 377 missing_json_is_fatal = True
356 else: 378 else:
357 builders = sorted(TEST_BUILDERS) 379 builders = sorted(TEST_BUILDERS)
358 missing_json_is_fatal = False 380 missing_json_is_fatal = False
359 for builder in builders: 381 for builder in builders:
360 if not builder in TEST_BUILDERS: 382 if not builder in TEST_BUILDERS:
361 raise Exception(('unrecognized builder "%s"; ' + 383 raise Exception(('unrecognized builder "%s"; ' +
362 'should be one of %s') % ( 384 'should be one of %s') % (
363 builder, TEST_BUILDERS)) 385 builder, TEST_BUILDERS))
364 386
365 expectations_json_file = os.path.join(args.expectations_root, builder, 387 expectations_json_file = os.path.join(args.expectations_root, builder,
366 args.expectations_filename) 388 args.expectations_filename)
367 if os.path.isfile(expectations_json_file): 389 if os.path.isfile(expectations_json_file):
368 rebaseliner = JsonRebaseliner( 390 rebaseliner = JsonRebaseliner(
369 expectations_root=args.expectations_root, 391 expectations_root=args.expectations_root,
370 expectations_input_filename=args.expectations_filename, 392 expectations_input_filename=args.expectations_filename,
371 expectations_output_filename=(args.expectations_filename_output or 393 expectations_output_filename=(args.expectations_filename_output or
372 args.expectations_filename), 394 args.expectations_filename),
373 tests=args.tests, configs=args.configs, 395 tests=args.tests, configs=args.configs,
374 actuals_base_url=args.actuals_base_url, 396 actuals_base_url=args.actuals_base_url,
375 actuals_filename=args.actuals_filename, 397 actuals_filename=args.actuals_filename,
376 exception_handler=exception_handler, 398 exception_handler=exception_handler,
377 add_new=args.add_new) 399 add_new=args.add_new, bugs=args.bugs, mark_unreviewed=args.unreviewed)
378 try: 400 try:
379 rebaseliner.RebaselineSubdir(builder=builder) 401 rebaseliner.RebaselineSubdir(builder=builder)
380 except BaseException as e: 402 except BaseException as e:
381 exception_handler.RaiseExceptionOrContinue(e) 403 exception_handler.RaiseExceptionOrContinue(e)
382 else: 404 else:
383 exception_handler.RaiseExceptionOrContinue(_InternalException( 405 exception_handler.RaiseExceptionOrContinue(_InternalException(
384 'expectations_json_file %s not found' % expectations_json_file)) 406 'expectations_json_file %s not found' % expectations_json_file))
385 407
386 exception_handler.ReportAllFailures() 408 exception_handler.ReportAllFailures()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698