| OLD | NEW |
| 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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 'Test-Win7-ShuttleA-HD2000-x86-Debug', | 84 'Test-Win7-ShuttleA-HD2000-x86-Debug', |
| 85 'Test-Win7-ShuttleA-HD2000-x86-Debug-ANGLE', | 85 'Test-Win7-ShuttleA-HD2000-x86-Debug-ANGLE', |
| 86 'Test-Win7-ShuttleA-HD2000-x86-Debug-DirectWrite', | 86 'Test-Win7-ShuttleA-HD2000-x86-Debug-DirectWrite', |
| 87 'Test-Win7-ShuttleA-HD2000-x86-Release', | 87 'Test-Win7-ShuttleA-HD2000-x86-Release', |
| 88 'Test-Win7-ShuttleA-HD2000-x86-Release-ANGLE', | 88 'Test-Win7-ShuttleA-HD2000-x86-Release-ANGLE', |
| 89 'Test-Win7-ShuttleA-HD2000-x86-Release-DirectWrite', | 89 'Test-Win7-ShuttleA-HD2000-x86-Release-DirectWrite', |
| 90 'Test-Win7-ShuttleA-HD2000-x86_64-Debug', | 90 'Test-Win7-ShuttleA-HD2000-x86_64-Debug', |
| 91 'Test-Win7-ShuttleA-HD2000-x86_64-Release', | 91 'Test-Win7-ShuttleA-HD2000-x86_64-Release', |
| 92 ] | 92 ] |
| 93 | 93 |
| 94 # TODO: Get this from builder_name_schema in buildbot. |
| 95 TRYBOT_SUFFIX = '-Trybot' |
| 96 |
| 97 |
| 94 class _InternalException(Exception): | 98 class _InternalException(Exception): |
| 95 pass | 99 pass |
| 96 | 100 |
| 97 class ExceptionHandler(object): | 101 class ExceptionHandler(object): |
| 98 """ Object that handles exceptions, either raising them immediately or | 102 """ Object that handles exceptions, either raising them immediately or |
| 99 collecting them to display later on.""" | 103 collecting them to display later on.""" |
| 100 | 104 |
| 101 # params: | 105 # params: |
| 102 def __init__(self, keep_going_on_failure=False): | 106 def __init__(self, keep_going_on_failure=False): |
| 103 """ | 107 """ |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 # notes: free-form text notes to add to all updated expectations | 167 # notes: free-form text notes to add to all updated expectations |
| 164 # mark_unreviewed: if True, mark these expectations as NOT having been | 168 # mark_unreviewed: if True, mark these expectations as NOT having been |
| 165 # reviewed by a human; otherwise, leave that field blank. | 169 # reviewed by a human; otherwise, leave that field blank. |
| 166 # Currently, there is no way to make this script mark | 170 # Currently, there is no way to make this script mark |
| 167 # expectations as reviewed-by-human=True. | 171 # expectations as reviewed-by-human=True. |
| 168 # TODO(epoger): Add that capability to a review tool. | 172 # TODO(epoger): Add that capability to a review tool. |
| 169 def __init__(self, expectations_root, expectations_input_filename, | 173 def __init__(self, expectations_root, expectations_input_filename, |
| 170 expectations_output_filename, actuals_base_url, | 174 expectations_output_filename, actuals_base_url, |
| 171 actuals_filename, exception_handler, | 175 actuals_filename, exception_handler, |
| 172 tests=None, configs=None, add_new=False, bugs=None, notes=None, | 176 tests=None, configs=None, add_new=False, bugs=None, notes=None, |
| 173 mark_unreviewed=None): | 177 mark_unreviewed=None, from_trybot=False): |
| 174 self._expectations_root = expectations_root | 178 self._expectations_root = expectations_root |
| 175 self._expectations_input_filename = expectations_input_filename | 179 self._expectations_input_filename = expectations_input_filename |
| 176 self._expectations_output_filename = expectations_output_filename | 180 self._expectations_output_filename = expectations_output_filename |
| 177 self._tests = tests | 181 self._tests = tests |
| 178 self._configs = configs | 182 self._configs = configs |
| 179 self._actuals_base_url = actuals_base_url | 183 self._actuals_base_url = actuals_base_url |
| 180 self._actuals_filename = actuals_filename | 184 self._actuals_filename = actuals_filename |
| 181 self._exception_handler = exception_handler | 185 self._exception_handler = exception_handler |
| 182 self._add_new = add_new | 186 self._add_new = add_new |
| 183 self._bugs = bugs | 187 self._bugs = bugs |
| 184 self._notes = notes | 188 self._notes = notes |
| 185 self._mark_unreviewed = mark_unreviewed | 189 self._mark_unreviewed = mark_unreviewed |
| 186 self._image_filename_re = re.compile(gm_json.IMAGE_FILENAME_PATTERN) | 190 self._image_filename_re = re.compile(gm_json.IMAGE_FILENAME_PATTERN) |
| 187 self._using_svn = os.path.isdir(os.path.join(expectations_root, '.svn')) | 191 self._using_svn = os.path.isdir(os.path.join(expectations_root, '.svn')) |
| 192 self._from_trybot = from_trybot |
| 188 | 193 |
| 189 # Executes subprocess.call(cmd). | 194 # Executes subprocess.call(cmd). |
| 190 # Raises an Exception if the command fails. | 195 # Raises an Exception if the command fails. |
| 191 def _Call(self, cmd): | 196 def _Call(self, cmd): |
| 192 if subprocess.call(cmd) != 0: | 197 if subprocess.call(cmd) != 0: |
| 193 raise _InternalException('error running command: ' + ' '.join(cmd)) | 198 raise _InternalException('error running command: ' + ' '.join(cmd)) |
| 194 | 199 |
| 195 # Returns the full contents of filepath, as a single string. | 200 # Returns the full contents of filepath, as a single string. |
| 196 # If filepath looks like a URL, try to read it that way instead of as | 201 # If filepath looks like a URL, try to read it that way instead of as |
| 197 # a path on local storage. | 202 # a path on local storage. |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 return results_to_return | 252 return results_to_return |
| 248 | 253 |
| 249 # Rebaseline all tests/types we specified in the constructor, | 254 # Rebaseline all tests/types we specified in the constructor, |
| 250 # within this builder's subdirectory in expectations/gm . | 255 # within this builder's subdirectory in expectations/gm . |
| 251 # | 256 # |
| 252 # params: | 257 # params: |
| 253 # builder : e.g. 'Test-Win7-ShuttleA-HD2000-x86-Release' | 258 # builder : e.g. 'Test-Win7-ShuttleA-HD2000-x86-Release' |
| 254 def RebaselineSubdir(self, builder): | 259 def RebaselineSubdir(self, builder): |
| 255 # Read in the actual result summary, and extract all the tests whose | 260 # Read in the actual result summary, and extract all the tests whose |
| 256 # results we need to update. | 261 # results we need to update. |
| 257 actuals_url = '/'.join([self._actuals_base_url, | 262 results_builder = str(builder) |
| 258 builder, self._actuals_filename]) | 263 if self._from_trybot: |
| 264 results_builder = results_builder + TRYBOT_SUFFIX |
| 265 actuals_url = '/'.join([self._actuals_base_url, results_builder, |
| 266 self._actuals_filename]) |
| 259 # Only update results for tests that are currently failing. | 267 # Only update results for tests that are currently failing. |
| 260 # We don't want to rewrite results for tests that are already succeeding, | 268 # We don't want to rewrite results for tests that are already succeeding, |
| 261 # because we don't want to add annotation fields (such as | 269 # because we don't want to add annotation fields (such as |
| 262 # JSONKEY_EXPECTEDRESULTS_BUGS) except for tests whose expectations we | 270 # JSONKEY_EXPECTEDRESULTS_BUGS) except for tests whose expectations we |
| 263 # are actually modifying. | 271 # are actually modifying. |
| 264 sections = [gm_json.JSONKEY_ACTUALRESULTS_FAILED] | 272 sections = [gm_json.JSONKEY_ACTUALRESULTS_FAILED] |
| 265 if self._add_new: | 273 if self._add_new: |
| 266 sections.append(gm_json.JSONKEY_ACTUALRESULTS_NOCOMPARISON) | 274 sections.append(gm_json.JSONKEY_ACTUALRESULTS_NOCOMPARISON) |
| 267 results_to_update = self._GetActualResults(json_url=actuals_url, | 275 results_to_update = self._GetActualResults(json_url=actuals_url, |
| 268 sections=sections) | 276 sections=sections) |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 parser.add_argument('--tests', metavar='TEST', nargs='+', | 388 parser.add_argument('--tests', metavar='TEST', nargs='+', |
| 381 help=('which tests to rebaseline, e.g. ' | 389 help=('which tests to rebaseline, e.g. ' |
| 382 '"--tests aaclip bigmatrix", as a filter over the ' | 390 '"--tests aaclip bigmatrix", as a filter over the ' |
| 383 'full set of results in ACTUALS_FILENAME; if ' | 391 'full set of results in ACTUALS_FILENAME; if ' |
| 384 'unspecified, rebaseline *all* tests that are ' | 392 'unspecified, rebaseline *all* tests that are ' |
| 385 'available.')) | 393 'available.')) |
| 386 parser.add_argument('--unreviewed', action='store_true', | 394 parser.add_argument('--unreviewed', action='store_true', |
| 387 help=('mark all expectations modified by this run as ' | 395 help=('mark all expectations modified by this run as ' |
| 388 '"%s": False' % | 396 '"%s": False' % |
| 389 gm_json.JSONKEY_EXPECTEDRESULTS_REVIEWED)) | 397 gm_json.JSONKEY_EXPECTEDRESULTS_REVIEWED)) |
| 398 parser.add_argument('--from-trybot', action='store_true', |
| 399 help=('pull the actual-results.json file from the ' |
| 400 'corresponding trybot, rather than the main builder')) |
| 390 args = parser.parse_args() | 401 args = parser.parse_args() |
| 391 exception_handler = ExceptionHandler( | 402 exception_handler = ExceptionHandler( |
| 392 keep_going_on_failure=args.keep_going_on_failure) | 403 keep_going_on_failure=args.keep_going_on_failure) |
| 393 if args.builders: | 404 if args.builders: |
| 394 builders = args.builders | 405 builders = args.builders |
| 395 missing_json_is_fatal = True | 406 missing_json_is_fatal = True |
| 396 else: | 407 else: |
| 397 builders = sorted(TEST_BUILDERS) | 408 builders = sorted(TEST_BUILDERS) |
| 398 missing_json_is_fatal = False | 409 missing_json_is_fatal = False |
| 399 for builder in builders: | 410 for builder in builders: |
| 400 if not builder in TEST_BUILDERS: | 411 if not builder in TEST_BUILDERS: |
| 401 raise Exception(('unrecognized builder "%s"; ' + | 412 raise Exception(('unrecognized builder "%s"; ' + |
| 402 'should be one of %s') % ( | 413 'should be one of %s') % ( |
| 403 builder, TEST_BUILDERS)) | 414 builder, TEST_BUILDERS)) |
| 404 | 415 |
| 405 expectations_json_file = os.path.join(args.expectations_root, builder, | 416 expectations_json_file = os.path.join(args.expectations_root, builder, |
| 406 args.expectations_filename) | 417 args.expectations_filename) |
| 407 if os.path.isfile(expectations_json_file): | 418 if os.path.isfile(expectations_json_file): |
| 408 rebaseliner = JsonRebaseliner( | 419 rebaseliner = JsonRebaseliner( |
| 409 expectations_root=args.expectations_root, | 420 expectations_root=args.expectations_root, |
| 410 expectations_input_filename=args.expectations_filename, | 421 expectations_input_filename=args.expectations_filename, |
| 411 expectations_output_filename=(args.expectations_filename_output or | 422 expectations_output_filename=(args.expectations_filename_output or |
| 412 args.expectations_filename), | 423 args.expectations_filename), |
| 413 tests=args.tests, configs=args.configs, | 424 tests=args.tests, configs=args.configs, |
| 414 actuals_base_url=args.actuals_base_url, | 425 actuals_base_url=args.actuals_base_url, |
| 415 actuals_filename=args.actuals_filename, | 426 actuals_filename=args.actuals_filename, |
| 416 exception_handler=exception_handler, | 427 exception_handler=exception_handler, |
| 417 add_new=args.add_new, bugs=args.bugs, notes=args.notes, | 428 add_new=args.add_new, bugs=args.bugs, notes=args.notes, |
| 418 mark_unreviewed=args.unreviewed) | 429 mark_unreviewed=args.unreviewed, |
| 430 from_trybot=args.from_trybot) |
| 419 try: | 431 try: |
| 420 rebaseliner.RebaselineSubdir(builder=builder) | 432 rebaseliner.RebaselineSubdir(builder=builder) |
| 421 except: | 433 except: |
| 422 exception_handler.RaiseExceptionOrContinue() | 434 exception_handler.RaiseExceptionOrContinue() |
| 423 else: | 435 else: |
| 424 try: | 436 try: |
| 425 raise _InternalException('expectations_json_file %s not found' % | 437 raise _InternalException('expectations_json_file %s not found' % |
| 426 expectations_json_file) | 438 expectations_json_file) |
| 427 except: | 439 except: |
| 428 exception_handler.RaiseExceptionOrContinue() | 440 exception_handler.RaiseExceptionOrContinue() |
| 429 | 441 |
| 430 exception_handler.ReportAllFailures() | 442 exception_handler.ReportAllFailures() |
| OLD | NEW |