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 |