| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 | 2 |
| 3 """ | 3 """ |
| 4 Copyright 2013 Google Inc. | 4 Copyright 2013 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 Repackage expected/actual GM results as needed by our HTML rebaseline viewer. | 9 Repackage expected/actual GM results as needed by our HTML rebaseline viewer. |
| 10 """ | 10 """ |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 | 98 |
| 99 Note that this will NOT update the results stored in self._results[] ; | 99 Note that this will NOT update the results stored in self._results[] ; |
| 100 in order to see those updates, you must instantiate a new | 100 in order to see those updates, you must instantiate a new |
| 101 ExpectationComparisons object based on the (now updated) files on disk. | 101 ExpectationComparisons object based on the (now updated) files on disk. |
| 102 | 102 |
| 103 Args: | 103 Args: |
| 104 modifications: a list of dictionaries, one for each expectation to update: | 104 modifications: a list of dictionaries, one for each expectation to update: |
| 105 | 105 |
| 106 [ | 106 [ |
| 107 { | 107 { |
| 108 imagepair.KEY__EXPECTATIONS_DATA: { | 108 imagepair.KEY__IMAGEPAIRS__EXPECTATIONS: { |
| 109 results.KEY__EXPECTATIONS__BUGS: [123, 456], | 109 results.KEY__EXPECTATIONS__BUGS: [123, 456], |
| 110 results.KEY__EXPECTATIONS__IGNOREFAILURE: false, | 110 results.KEY__EXPECTATIONS__IGNOREFAILURE: false, |
| 111 results.KEY__EXPECTATIONS__REVIEWED: true, | 111 results.KEY__EXPECTATIONS__REVIEWED: true, |
| 112 }, | 112 }, |
| 113 imagepair.KEY__EXTRA_COLUMN_VALUES: { | 113 imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS: { |
| 114 results.KEY__EXTRACOLUMN__BUILDER: 'Test-Mac10.6-MacMini4.1-GeFor
ce320M-x86-Debug', | 114 results.KEY__EXTRACOLUMNS__BUILDER: 'Test-Mac10.6-MacMini4.1-GeFo
rce320M-x86-Debug', |
| 115 results.KEY__EXTRACOLUMN__CONFIG: '8888', | 115 results.KEY__EXTRACOLUMNS__CONFIG: '8888', |
| 116 results.KEY__EXTRACOLUMN__TEST: 'bigmatrix', | 116 results.KEY__EXTRACOLUMNS__TEST: 'bigmatrix', |
| 117 }, | 117 }, |
| 118 results.KEY__NEW_IMAGE_URL: 'bitmap-64bitMD5/bigmatrix/108944080240
79689926.png', | 118 results.KEY__IMAGEPAIRS__IMAGE_B_URL: 'bitmap-64bitMD5/bigmatrix/10
894408024079689926.png', |
| 119 }, | 119 }, |
| 120 ... | 120 ... |
| 121 ] | 121 ] |
| 122 | 122 |
| 123 """ | 123 """ |
| 124 expected_builder_dicts = self._read_builder_dicts_from_root( | 124 expected_builder_dicts = self._read_builder_dicts_from_root( |
| 125 self._expected_root) | 125 self._expected_root) |
| 126 for mod in modifications: | 126 for mod in modifications: |
| 127 image_name = results.IMAGE_FILENAME_FORMATTER % ( | 127 image_name = results.IMAGE_FILENAME_FORMATTER % ( |
| 128 mod[imagepair.KEY__EXTRA_COLUMN_VALUES] | 128 mod[imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS] |
| 129 [results.KEY__EXTRACOLUMN__TEST], | 129 [results.KEY__EXTRACOLUMNS__TEST], |
| 130 mod[imagepair.KEY__EXTRA_COLUMN_VALUES] | 130 mod[imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS] |
| 131 [results.KEY__EXTRACOLUMN__CONFIG]) | 131 [results.KEY__EXTRACOLUMNS__CONFIG]) |
| 132 _, hash_type, hash_digest = gm_json.SplitGmRelativeUrl( | 132 _, hash_type, hash_digest = gm_json.SplitGmRelativeUrl( |
| 133 mod[results.KEY__NEW_IMAGE_URL]) | 133 mod[imagepair.KEY__IMAGEPAIRS__IMAGE_B_URL]) |
| 134 allowed_digests = [[hash_type, int(hash_digest)]] | 134 allowed_digests = [[hash_type, int(hash_digest)]] |
| 135 new_expectations = { | 135 new_expectations = { |
| 136 gm_json.JSONKEY_EXPECTEDRESULTS_ALLOWEDDIGESTS: allowed_digests, | 136 gm_json.JSONKEY_EXPECTEDRESULTS_ALLOWEDDIGESTS: allowed_digests, |
| 137 } | 137 } |
| 138 for field in EXPECTATION_FIELDS_PASSED_THRU_VERBATIM: | 138 for field in EXPECTATION_FIELDS_PASSED_THRU_VERBATIM: |
| 139 value = mod[imagepair.KEY__EXPECTATIONS_DATA].get(field) | 139 value = mod[imagepair.KEY__IMAGEPAIRS__EXPECTATIONS].get(field) |
| 140 if value is not None: | 140 if value is not None: |
| 141 new_expectations[field] = value | 141 new_expectations[field] = value |
| 142 builder_dict = expected_builder_dicts[ | 142 builder_dict = expected_builder_dicts[ |
| 143 mod[imagepair.KEY__EXTRA_COLUMN_VALUES] | 143 mod[imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS] |
| 144 [results.KEY__EXTRACOLUMN__BUILDER]] | 144 [results.KEY__EXTRACOLUMNS__BUILDER]] |
| 145 builder_expectations = builder_dict.get(gm_json.JSONKEY_EXPECTEDRESULTS) | 145 builder_expectations = builder_dict.get(gm_json.JSONKEY_EXPECTEDRESULTS) |
| 146 if not builder_expectations: | 146 if not builder_expectations: |
| 147 builder_expectations = {} | 147 builder_expectations = {} |
| 148 builder_dict[gm_json.JSONKEY_EXPECTEDRESULTS] = builder_expectations | 148 builder_dict[gm_json.JSONKEY_EXPECTEDRESULTS] = builder_expectations |
| 149 builder_expectations[image_name] = new_expectations | 149 builder_expectations[image_name] = new_expectations |
| 150 ExpectationComparisons._write_dicts_to_root( | 150 ExpectationComparisons._write_dicts_to_root( |
| 151 expected_builder_dicts, self._expected_root) | 151 expected_builder_dicts, self._expected_root) |
| 152 | 152 |
| 153 @staticmethod | 153 @staticmethod |
| 154 def _write_dicts_to_root(meta_dict, root, pattern='*.json'): | 154 def _write_dicts_to_root(meta_dict, root, pattern='*.json'): |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 self._expected_root) | 209 self._expected_root) |
| 210 | 210 |
| 211 all_image_pairs = imagepairset.ImagePairSet( | 211 all_image_pairs = imagepairset.ImagePairSet( |
| 212 descriptions=IMAGEPAIR_SET_DESCRIPTIONS, | 212 descriptions=IMAGEPAIR_SET_DESCRIPTIONS, |
| 213 diff_base_url=self._diff_base_url) | 213 diff_base_url=self._diff_base_url) |
| 214 failing_image_pairs = imagepairset.ImagePairSet( | 214 failing_image_pairs = imagepairset.ImagePairSet( |
| 215 descriptions=IMAGEPAIR_SET_DESCRIPTIONS, | 215 descriptions=IMAGEPAIR_SET_DESCRIPTIONS, |
| 216 diff_base_url=self._diff_base_url) | 216 diff_base_url=self._diff_base_url) |
| 217 | 217 |
| 218 all_image_pairs.ensure_extra_column_values_in_summary( | 218 all_image_pairs.ensure_extra_column_values_in_summary( |
| 219 column_id=results.KEY__EXTRACOLUMN__RESULT_TYPE, values=[ | 219 column_id=results.KEY__EXTRACOLUMNS__RESULT_TYPE, values=[ |
| 220 results.KEY__RESULT_TYPE__FAILED, | 220 results.KEY__RESULT_TYPE__FAILED, |
| 221 results.KEY__RESULT_TYPE__FAILUREIGNORED, | 221 results.KEY__RESULT_TYPE__FAILUREIGNORED, |
| 222 results.KEY__RESULT_TYPE__NOCOMPARISON, | 222 results.KEY__RESULT_TYPE__NOCOMPARISON, |
| 223 results.KEY__RESULT_TYPE__SUCCEEDED, | 223 results.KEY__RESULT_TYPE__SUCCEEDED, |
| 224 ]) | 224 ]) |
| 225 failing_image_pairs.ensure_extra_column_values_in_summary( | 225 failing_image_pairs.ensure_extra_column_values_in_summary( |
| 226 column_id=results.KEY__EXTRACOLUMN__RESULT_TYPE, values=[ | 226 column_id=results.KEY__EXTRACOLUMNS__RESULT_TYPE, values=[ |
| 227 results.KEY__RESULT_TYPE__FAILED, | 227 results.KEY__RESULT_TYPE__FAILED, |
| 228 results.KEY__RESULT_TYPE__FAILUREIGNORED, | 228 results.KEY__RESULT_TYPE__FAILUREIGNORED, |
| 229 results.KEY__RESULT_TYPE__NOCOMPARISON, | 229 results.KEY__RESULT_TYPE__NOCOMPARISON, |
| 230 ]) | 230 ]) |
| 231 | 231 |
| 232 # Only consider builders we have both expected and actual results for. | 232 # Only consider builders we have both expected and actual results for. |
| 233 # Fixes http://skbug.com/2486 ('rebaseline_server shows actual results | 233 # Fixes http://skbug.com/2486 ('rebaseline_server shows actual results |
| 234 # (but not expectations) for Test-Ubuntu12-ShuttleA-NoGPU-x86_64-Debug | 234 # (but not expectations) for Test-Ubuntu12-ShuttleA-NoGPU-x86_64-Debug |
| 235 # builder') | 235 # builder') |
| 236 actual_builder_set = set(actual_builder_dicts.keys()) | 236 actual_builder_set = set(actual_builder_dicts.keys()) |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 # rendering mode even though we don't have explicit expectations | 291 # rendering mode even though we don't have explicit expectations |
| 292 # for the test (the implicit expectation is that it must | 292 # for the test (the implicit expectation is that it must |
| 293 # render the same in all rendering modes). | 293 # render the same in all rendering modes). |
| 294 # | 294 # |
| 295 # Don't log type 1, because it is common. | 295 # Don't log type 1, because it is common. |
| 296 # Log other types, because they are rare and we should know about | 296 # Log other types, because they are rare and we should know about |
| 297 # them, but don't throw an exception, because we need to keep our | 297 # them, but don't throw an exception, because we need to keep our |
| 298 # tools working in the meanwhile! | 298 # tools working in the meanwhile! |
| 299 if result_type != results.KEY__RESULT_TYPE__NOCOMPARISON: | 299 if result_type != results.KEY__RESULT_TYPE__NOCOMPARISON: |
| 300 logging.warning('No expectations found for test: %s' % { | 300 logging.warning('No expectations found for test: %s' % { |
| 301 results.KEY__EXTRACOLUMN__BUILDER: builder, | 301 results.KEY__EXTRACOLUMNS__BUILDER: builder, |
| 302 results.KEY__EXTRACOLUMN__RESULT_TYPE: result_type, | 302 results.KEY__EXTRACOLUMNS__RESULT_TYPE: result_type, |
| 303 'image_name': image_name, | 303 'image_name': image_name, |
| 304 }) | 304 }) |
| 305 | 305 |
| 306 # If this test was recently rebaselined, it will remain in | 306 # If this test was recently rebaselined, it will remain in |
| 307 # the 'failed' set of actuals until all the bots have | 307 # the 'failed' set of actuals until all the bots have |
| 308 # cycled (although the expectations have indeed been set | 308 # cycled (although the expectations have indeed been set |
| 309 # from the most recent actuals). Treat these as successes | 309 # from the most recent actuals). Treat these as successes |
| 310 # instead of failures. | 310 # instead of failures. |
| 311 # | 311 # |
| 312 # TODO(epoger): Do we need to do something similar in | 312 # TODO(epoger): Do we need to do something similar in |
| 313 # other cases, such as when we have recently marked a test | 313 # other cases, such as when we have recently marked a test |
| 314 # as ignoreFailure but it still shows up in the 'failed' | 314 # as ignoreFailure but it still shows up in the 'failed' |
| 315 # category? Maybe we should not rely on the result_type | 315 # category? Maybe we should not rely on the result_type |
| 316 # categories recorded within the gm_actuals AT ALL, and | 316 # categories recorded within the gm_actuals AT ALL, and |
| 317 # instead evaluate the result_type ourselves based on what | 317 # instead evaluate the result_type ourselves based on what |
| 318 # we see in expectations vs actual checksum? | 318 # we see in expectations vs actual checksum? |
| 319 # See related http://skbug.com/2514 ('rebaseline_server: apply | 319 # See related http://skbug.com/2514 ('rebaseline_server: apply |
| 320 # ignored-tests.txt within rebaseline_server, not just on the bots') | 320 # ignored-tests.txt within rebaseline_server, not just on the bots') |
| 321 if expected_image_relative_url == actual_image_relative_url: | 321 if expected_image_relative_url == actual_image_relative_url: |
| 322 updated_result_type = results.KEY__RESULT_TYPE__SUCCEEDED | 322 updated_result_type = results.KEY__RESULT_TYPE__SUCCEEDED |
| 323 else: | 323 else: |
| 324 updated_result_type = result_type | 324 updated_result_type = result_type |
| 325 extra_columns_dict = { | 325 extra_columns_dict = { |
| 326 results.KEY__EXTRACOLUMN__RESULT_TYPE: updated_result_type, | 326 results.KEY__EXTRACOLUMNS__RESULT_TYPE: updated_result_type, |
| 327 results.KEY__EXTRACOLUMN__BUILDER: builder, | 327 results.KEY__EXTRACOLUMNS__BUILDER: builder, |
| 328 results.KEY__EXTRACOLUMN__TEST: test, | 328 results.KEY__EXTRACOLUMNS__TEST: test, |
| 329 results.KEY__EXTRACOLUMN__CONFIG: config, | 329 results.KEY__EXTRACOLUMNS__CONFIG: config, |
| 330 } | 330 } |
| 331 try: | 331 try: |
| 332 image_pair = imagepair.ImagePair( | 332 image_pair = imagepair.ImagePair( |
| 333 image_diff_db=self._image_diff_db, | 333 image_diff_db=self._image_diff_db, |
| 334 base_url=gm_json.GM_ACTUALS_ROOT_HTTP_URL, | 334 base_url=gm_json.GM_ACTUALS_ROOT_HTTP_URL, |
| 335 imageA_relative_url=expected_image_relative_url, | 335 imageA_relative_url=expected_image_relative_url, |
| 336 imageB_relative_url=actual_image_relative_url, | 336 imageB_relative_url=actual_image_relative_url, |
| 337 expectations=expectations_dict, | 337 expectations=expectations_dict, |
| 338 extra_columns=extra_columns_dict) | 338 extra_columns=extra_columns_dict) |
| 339 all_image_pairs.add_image_pair(image_pair) | 339 all_image_pairs.add_image_pair(image_pair) |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 results_obj = ExpectationComparisons(actuals_root=args.actuals, | 378 results_obj = ExpectationComparisons(actuals_root=args.actuals, |
| 379 expected_root=args.expectations, | 379 expected_root=args.expectations, |
| 380 generated_images_root=args.workdir) | 380 generated_images_root=args.workdir) |
| 381 gm_json.WriteToFile( | 381 gm_json.WriteToFile( |
| 382 results_obj.get_packaged_results_of_type(results_type=args.results), | 382 results_obj.get_packaged_results_of_type(results_type=args.results), |
| 383 args.outfile) | 383 args.outfile) |
| 384 | 384 |
| 385 | 385 |
| 386 if __name__ == '__main__': | 386 if __name__ == '__main__': |
| 387 main() | 387 main() |
| OLD | NEW |