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

Side by Side Diff: tools/rebaseline.py

Issue 23899003: rebaseline.py: fix --add-new when there are no expectations at all (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: add_platform_with_empty_expectations_and_fix_it 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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 # them to display later on. 98 # them to display later on.
99 class ExceptionHandler(object): 99 class ExceptionHandler(object):
100 100
101 # params: 101 # params:
102 # keep_going_on_failure: if False, report failures and quit right away; 102 # keep_going_on_failure: if False, report failures and quit right away;
103 # if True, collect failures until 103 # if True, collect failures until
104 # ReportAllFailures() is called 104 # ReportAllFailures() is called
105 def __init__(self, keep_going_on_failure=False): 105 def __init__(self, keep_going_on_failure=False):
106 self._keep_going_on_failure = keep_going_on_failure 106 self._keep_going_on_failure = keep_going_on_failure
107 self._failures_encountered = [] 107 self._failures_encountered = []
108 self._exiting = False
109
110 # Exit the program with the given status value.
111 def _Exit(self, status=1):
112 self._exiting = True
113 sys.exit(status)
114 108
115 # We have encountered an exception; either collect the info and keep going, 109 # We have encountered an exception; either collect the info and keep going,
116 # or exit the program right away. 110 # or exit the program right away.
rmistry 2013/09/03 17:09:35 Make this a method level comment.
epoger 2013/09/03 18:01:33 Done throughout ExceptionHandler object.
117 def RaiseExceptionOrContinue(self, e): 111 def RaiseExceptionOrContinue(self):
118 # If we are already quitting the program, propagate any exceptions 112 # Get traceback information about the most recently raised exception.
119 # so that the proper exit status will be communicated to the shell. 113 exc_info = sys.exc_info()
120 if self._exiting:
121 raise e
122 114
123 if self._keep_going_on_failure: 115 if self._keep_going_on_failure:
124 print >> sys.stderr, 'WARNING: swallowing exception %s' % e 116 # I don't understand why we need to log [exc_info[1]] instead of just
125 self._failures_encountered.append(e) 117 # exc_info[1] , but for some reason the former preserves more information.
rmistry 2013/09/03 17:09:35 Thats because exc_info[1] is like calling str(exc_
epoger 2013/09/03 18:01:33 Works as you describe... thanks! Done.
118 print >> sys.stderr, 'WARNING: swallowing exception %s' % [exc_info[1]]
119 self._failures_encountered.append(exc_info)
126 else: 120 else:
127 print >> sys.stderr, e
128 print >> sys.stderr, ( 121 print >> sys.stderr, (
129 'Halting at first exception; to keep going, re-run ' + 122 'Halting at first exception; to keep going, re-run ' +
130 'with the --keep-going-on-failure option set.') 123 'with the --keep-going-on-failure option set.')
131 self._Exit() 124 raise exc_info[1], None, exc_info[2]
epoger 2013/09/03 16:54:38 Patchset 5: While I was at it, improved error repo
132 125
133 def ReportAllFailures(self): 126 def ReportAllFailures(self):
134 if self._failures_encountered: 127 if self._failures_encountered:
135 print >> sys.stderr, ('Encountered %d failures (see above).' % 128 print >> sys.stderr, ('Encountered %d failures (see above).' %
136 len(self._failures_encountered)) 129 len(self._failures_encountered))
137 self._Exit() 130 sys.exit(1)
138 131
139 132
140 # Object that rebaselines a JSON expectations file (not individual image files). 133 # Object that rebaselines a JSON expectations file (not individual image files).
141 class JsonRebaseliner(object): 134 class JsonRebaseliner(object):
142 135
143 # params: 136 # params:
144 # expectations_root: root directory of all expectations JSON files 137 # expectations_root: root directory of all expectations JSON files
145 # expectations_input_filename: filename (under expectations_root) of JSON 138 # expectations_input_filename: filename (under expectations_root) of JSON
146 # expectations file to read; typically 139 # expectations file to read; typically
147 # "expected-results.json" 140 # "expected-results.json"
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 gm_json.JSONKEY_ACTUALRESULTS_SUCCEEDED] 246 gm_json.JSONKEY_ACTUALRESULTS_SUCCEEDED]
254 if self._add_new: 247 if self._add_new:
255 sections.append(gm_json.JSONKEY_ACTUALRESULTS_NOCOMPARISON) 248 sections.append(gm_json.JSONKEY_ACTUALRESULTS_NOCOMPARISON)
256 results_to_update = self._GetActualResults(json_url=actuals_url, 249 results_to_update = self._GetActualResults(json_url=actuals_url,
257 sections=sections) 250 sections=sections)
258 251
259 # Read in current expectations. 252 # Read in current expectations.
260 expectations_input_filepath = os.path.join( 253 expectations_input_filepath = os.path.join(
261 self._expectations_root, builder, self._expectations_input_filename) 254 self._expectations_root, builder, self._expectations_input_filename)
262 expectations_dict = gm_json.LoadFromFile(expectations_input_filepath) 255 expectations_dict = gm_json.LoadFromFile(expectations_input_filepath)
263 expected_results = expectations_dict[gm_json.JSONKEY_EXPECTEDRESULTS] 256 expected_results = expectations_dict.get(gm_json.JSONKEY_EXPECTEDRESULTS)
257 if not expected_results:
epoger 2013/09/03 16:54:38 Patchset 5: properly handle the case where there a
258 expected_results = {}
rmistry 2013/09/03 17:09:35 I think you should be able to get rid of this line
epoger 2013/09/03 18:01:33 Done, but we still need to set expectations_dict[g
rmistry 2013/09/03 18:17:18 Lets go with what you prefer, not a big deal eithe
epoger 2013/09/03 18:23:07 Went back to my old way, then. :-)
259 expectations_dict[gm_json.JSONKEY_EXPECTEDRESULTS] = expected_results
264 260
265 # Update the expectations in memory, skipping any tests/configs that 261 # Update the expectations in memory, skipping any tests/configs that
266 # the caller asked to exclude. 262 # the caller asked to exclude.
267 skipped_images = [] 263 skipped_images = []
268 if results_to_update: 264 if results_to_update:
269 for (image_name, image_results) in results_to_update.iteritems(): 265 for (image_name, image_results) in results_to_update.iteritems():
270 (test, config) = self._image_filename_re.match(image_name).groups() 266 (test, config) = self._image_filename_re.match(image_name).groups()
271 if self._tests: 267 if self._tests:
272 if test not in self._tests: 268 if test not in self._tests:
273 skipped_images.append(image_name) 269 skipped_images.append(image_name)
(...skipping 23 matching lines...) Expand all
297 parser = argparse.ArgumentParser() 293 parser = argparse.ArgumentParser()
298 parser.add_argument('--actuals-base-url', 294 parser.add_argument('--actuals-base-url',
299 help='base URL from which to read files containing JSON ' + 295 help='base URL from which to read files containing JSON ' +
300 'summaries of actual GM results; defaults to %(default)s', 296 'summaries of actual GM results; defaults to %(default)s',
301 default='http://skia-autogen.googlecode.com/svn/gm-actual') 297 default='http://skia-autogen.googlecode.com/svn/gm-actual')
302 parser.add_argument('--actuals-filename', 298 parser.add_argument('--actuals-filename',
303 help='filename (within builder-specific subdirectories ' + 299 help='filename (within builder-specific subdirectories ' +
304 'of ACTUALS_BASE_URL) to read a summary of results from; ' + 300 'of ACTUALS_BASE_URL) to read a summary of results from; ' +
305 'defaults to %(default)s', 301 'defaults to %(default)s',
306 default='actual-results.json') 302 default='actual-results.json')
307 # TODO(epoger): Add test that exercises --add-new argument.
308 parser.add_argument('--add-new', action='store_true', 303 parser.add_argument('--add-new', action='store_true',
309 help='in addition to the standard behavior of ' + 304 help='in addition to the standard behavior of ' +
310 'updating expectations for failing tests, add ' + 305 'updating expectations for failing tests, add ' +
311 'expectations for tests which don\'t have expectations ' + 306 'expectations for tests which don\'t have expectations ' +
312 'yet.') 307 'yet.')
313 parser.add_argument('--builders', metavar='BUILDER', nargs='+', 308 parser.add_argument('--builders', metavar='BUILDER', nargs='+',
314 help='which platforms to rebaseline; ' + 309 help='which platforms to rebaseline; ' +
315 'if unspecified, rebaseline all platforms, same as ' + 310 'if unspecified, rebaseline all platforms, same as ' +
316 '"--builders %s"' % ' '.join(sorted(TEST_BUILDERS))) 311 '"--builders %s"' % ' '.join(sorted(TEST_BUILDERS)))
317 # TODO(epoger): Add test that exercises --configs argument. 312 # TODO(epoger): Add test that exercises --configs argument.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 expectations_input_filename=args.expectations_filename, 365 expectations_input_filename=args.expectations_filename,
371 expectations_output_filename=(args.expectations_filename_output or 366 expectations_output_filename=(args.expectations_filename_output or
372 args.expectations_filename), 367 args.expectations_filename),
373 tests=args.tests, configs=args.configs, 368 tests=args.tests, configs=args.configs,
374 actuals_base_url=args.actuals_base_url, 369 actuals_base_url=args.actuals_base_url,
375 actuals_filename=args.actuals_filename, 370 actuals_filename=args.actuals_filename,
376 exception_handler=exception_handler, 371 exception_handler=exception_handler,
377 add_new=args.add_new) 372 add_new=args.add_new)
378 try: 373 try:
379 rebaseliner.RebaselineSubdir(builder=builder) 374 rebaseliner.RebaselineSubdir(builder=builder)
380 except BaseException as e: 375 except BaseException:
381 exception_handler.RaiseExceptionOrContinue(e) 376 exception_handler.RaiseExceptionOrContinue()
382 else: 377 else:
383 exception_handler.RaiseExceptionOrContinue(_InternalException( 378 try:
384 'expectations_json_file %s not found' % expectations_json_file)) 379 raise _InternalException('expectations_json_file %s not found' %
380 expectations_json_file)
381 except BaseException:
rmistry 2013/09/03 17:09:35 Why is this catching BaseException instead of Exce
epoger 2013/09/03 18:01:33 I don't think it really matters. Got rid of the e
rmistry 2013/09/03 18:17:18 I think it does slightly matter because 'except Ba
382 exception_handler.RaiseExceptionOrContinue()
385 383
386 exception_handler.ReportAllFailures() 384 exception_handler.ReportAllFailures()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698