Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "gm_expectations.h" | 8 #include "gm_expectations.h" |
| 9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
| 10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 97 static SkTArray<SkString, false> gMissingCodecs; | 97 static SkTArray<SkString, false> gMissingCodecs; |
| 98 static SkTArray<SkString, false> gDecodeFailures; | 98 static SkTArray<SkString, false> gDecodeFailures; |
| 99 static SkTArray<SkString, false> gEncodeFailures; | 99 static SkTArray<SkString, false> gEncodeFailures; |
| 100 static SkTArray<SkString, false> gSuccessfulDecodes; | 100 static SkTArray<SkString, false> gSuccessfulDecodes; |
| 101 static SkTArray<SkString, false> gSuccessfulSubsetDecodes; | 101 static SkTArray<SkString, false> gSuccessfulSubsetDecodes; |
| 102 static SkTArray<SkString, false> gFailedSubsetDecodes; | 102 static SkTArray<SkString, false> gFailedSubsetDecodes; |
| 103 // Files/subsets that do not have expectations. Not reported as a failure of the test so | 103 // Files/subsets that do not have expectations. Not reported as a failure of the test so |
| 104 // the bots will not turn red with each new image test. | 104 // the bots will not turn red with each new image test. |
| 105 static SkTArray<SkString, false> gMissingExpectations; | 105 static SkTArray<SkString, false> gMissingExpectations; |
| 106 static SkTArray<SkString, false> gMissingSubsetExpectations; | 106 static SkTArray<SkString, false> gMissingSubsetExpectations; |
| 107 // For files that are expected to fail. | |
| 108 static SkTArray<SkString, false> gKnownFailures; | |
| 107 | 109 |
| 108 static SkBitmap::Config gPrefConfig(SkBitmap::kNo_Config); | 110 static SkBitmap::Config gPrefConfig(SkBitmap::kNo_Config); |
| 109 | 111 |
| 110 // Expections read from a file specified by readExpectationsPath. The expectatio ns must have been | 112 // Expections read from a file specified by readExpectationsPath. The expectatio ns must have been |
| 111 // previously written using createExpectationsPath. | 113 // previously written using createExpectationsPath. |
| 112 SkAutoTUnref<skiagm::JsonExpectationsSource> gJsonExpectations; | 114 SkAutoTUnref<skiagm::JsonExpectationsSource> gJsonExpectations; |
| 113 | 115 |
| 114 static bool write_bitmap(const char outName[], const SkBitmap& bm) { | 116 static bool write_bitmap(const char outName[], const SkBitmap& bm) { |
| 115 if (SkImageEncoder::EncodeFile(outName, bm, SkImageEncoder::kPNG_Type, 100)) { | 117 if (SkImageEncoder::EncodeFile(outName, bm, SkImageEncoder::kPNG_Type, 100)) { |
| 116 return true; | 118 return true; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 181 static void write_expectations(const SkBitmap& bitmap, const char* filename) { | 183 static void write_expectations(const SkBitmap& bitmap, const char* filename) { |
| 182 if (!FLAGS_createExpectationsPath.isEmpty()) { | 184 if (!FLAGS_createExpectationsPath.isEmpty()) { |
| 183 // Creates an Expectations object, and add it to the list to write. | 185 // Creates an Expectations object, and add it to the list to write. |
| 184 skiagm::Expectations expectation(bitmap); | 186 skiagm::Expectations expectation(bitmap); |
| 185 Json::Value value = expectation.asJsonValue(); | 187 Json::Value value = expectation.asJsonValue(); |
| 186 gExpectationsToWrite[filename] = value; | 188 gExpectationsToWrite[filename] = value; |
| 187 } | 189 } |
| 188 } | 190 } |
| 189 | 191 |
| 190 /** | 192 /** |
| 191 * Return true if this filename is a known failure, and therefore a failure | |
| 192 * to decode should be ignored. | |
| 193 */ | |
| 194 static bool expect_to_fail(const char* filename) { | |
| 195 if (NULL == gJsonExpectations.get()) { | |
| 196 return false; | |
| 197 } | |
| 198 skiagm::Expectations jsExpectations = gJsonExpectations->get(filename); | |
| 199 return jsExpectations.ignoreFailure(); | |
| 200 } | |
| 201 | |
| 202 /** | |
| 203 * Compare against an expectation for this filename, if there is one. | 193 * Compare against an expectation for this filename, if there is one. |
| 204 * @param digest GmResultDigest, computed from the decoded bitmap, to compare t o the | 194 * @param digest GmResultDigest, computed from the decoded bitmap, to compare t o the |
| 205 * expectation. | 195 * expectation. |
| 206 * @param filename String used to find the expected value. | 196 * @param filename String used to find the expected value. |
| 207 * @param failureArray Array to add a failure message to on failure. | 197 * @param failureArray Array to add a failure message to on failure. |
| 208 * @param missingArray Array to add missing expectation to on failure. | 198 * @param missingArray Array to add missing expectation to on failure. |
|
epoger
2013/10/15 15:31:03
maybe instead...
@param missingArray Array to add
scroggo
2013/10/15 19:50:59
Done.
| |
| 209 * @return bool True in any of these cases: | 199 * @return bool True in any of these cases: |
| 210 * - the bitmap matches the expectation. | 200 * - the bitmap matches the expectation. |
| 211 * False in any of these cases: | 201 * False in any of these cases: |
| 212 * - there is no expectations file. | 202 * - there is no expectations file. |
| 213 * - there is an expectations file, but no expectation for this bitmap. | 203 * - there is an expectations file, but no expectation for this bitmap. |
| 214 * - there is an expectation for this bitmap, but it did not ma tch. | 204 * - there is an expectation for this bitmap, but it did not ma tch. |
| 215 * - expectation could not be computed from the bitmap. | 205 * - expectation could not be computed from the bitmap. |
| 216 */ | 206 */ |
| 217 static bool compare_to_expectations_if_necessary(const skiagm::GmResultDigest& d igest, | 207 static bool compare_to_expectations_if_necessary(const skiagm::GmResultDigest& d igest, |
| 218 const char* filename, | 208 const char* filename, |
| 219 SkTArray<SkString, false>* fail ureArray, | 209 SkTArray<SkString, false>* fail ureArray, |
| 220 SkTArray<SkString, false>* miss ingArray) { | 210 SkTArray<SkString, false>* miss ingArray) { |
| 221 if (!digest.isValid()) { | 211 if (!digest.isValid()) { |
| 222 if (failureArray != NULL) { | 212 if (failureArray != NULL) { |
| 223 failureArray->push_back().printf("decoded %s, but could not create a GmResultDigest.", | 213 failureArray->push_back().printf("decoded %s, but could not create a GmResultDigest.", |
| 224 filename); | 214 filename); |
| 225 } | 215 } |
| 226 return false; | 216 return false; |
| 227 } | 217 } |
| 228 | 218 |
| 229 if (NULL == gJsonExpectations.get()) { | 219 if (NULL == gJsonExpectations.get()) { |
| 230 return false; | 220 return false; |
| 231 } | 221 } |
| 232 | 222 |
| 233 skiagm::Expectations jsExpectation = gJsonExpectations->get(filename); | 223 skiagm::Expectations jsExpectation = gJsonExpectations->get(filename); |
| 234 if (jsExpectation.empty()) { | 224 if (jsExpectation.empty()) { |
| 235 if (missingArray != NULL) { | 225 if (missingArray != NULL) { |
| 236 missingArray->push_back().printf("decoded %s, but could not find exp ectation.", | 226 missingArray->push_back().printf("decoded %s, but could not find exp ectation.", |
|
epoger
2013/10/15 15:31:03
Why are failureArray and missingArray passed as pa
scroggo
2013/10/15 19:50:59
Good question. The first two are passed as paramet
| |
| 237 filename); | 227 filename); |
| 238 } | 228 } |
| 239 return false; | 229 return false; |
| 240 } | 230 } |
| 241 | 231 |
| 242 if (jsExpectation.match(digest)) { | 232 if (jsExpectation.match(digest)) { |
| 243 return true; | 233 return true; |
| 244 } | 234 } |
| 245 | 235 |
| 246 if (failureArray != NULL) { | 236 if (jsExpectation.ignoreFailure()) { |
| 237 gKnownFailures.push_back().printf("%s does not match expectation, but th is is known.", | |
|
epoger
2013/10/15 15:31:03
You can handle this in a separate CL if you like (
scroggo
2013/10/15 19:50:59
Added a FIXME (up by the declaration of the arrays
| |
| 238 filename); | |
| 239 } else if (failureArray != NULL) { | |
| 247 failureArray->push_back().printf("decoded %s, but the result does not ma tch " | 240 failureArray->push_back().printf("decoded %s, but the result does not ma tch " |
| 248 "expectations.", | 241 "expectations.", |
| 249 filename); | 242 filename); |
| 250 } | 243 } |
| 251 return false; | 244 return false; |
| 252 } | 245 } |
| 253 | 246 |
| 254 /** | 247 /** |
| 255 * Helper function to write a bitmap subset to a file. Only called if subsets w ere created | 248 * Helper function to write a bitmap subset to a file. Only called if subsets w ere created |
| 256 * and a writePath was provided. Creates a subdirectory called 'subsets' and wr ites a PNG to | 249 * and a writePath was provided. Creates a subdirectory called 'subsets' and wr ites a PNG to |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 403 codec->setSkipWritingZeroes(FLAGS_skip); | 396 codec->setSkipWritingZeroes(FLAGS_skip); |
| 404 codec->setSampleSize(FLAGS_sampleSize); | 397 codec->setSampleSize(FLAGS_sampleSize); |
| 405 stream.rewind(); | 398 stream.rewind(); |
| 406 | 399 |
| 407 // Create a string representing just the filename itself, for use in json ex pectations. | 400 // Create a string representing just the filename itself, for use in json ex pectations. |
| 408 SkString basename = SkOSPath::SkBasename(srcPath); | 401 SkString basename = SkOSPath::SkBasename(srcPath); |
| 409 const char* filename = basename.c_str(); | 402 const char* filename = basename.c_str(); |
| 410 | 403 |
| 411 if (!codec->decode(&stream, &bitmap, gPrefConfig, | 404 if (!codec->decode(&stream, &bitmap, gPrefConfig, |
| 412 SkImageDecoder::kDecodePixels_Mode)) { | 405 SkImageDecoder::kDecodePixels_Mode)) { |
| 413 if (expect_to_fail(filename)) { | 406 if (NULL != gJsonExpectations.get()) { |
| 414 gSuccessfulDecodes.push_back().appendf( | 407 skiagm::Expectations jsExpectations = gJsonExpectations->get(filenam e); |
| 415 "failed to decode %s, which is a known failure.", srcPath); | 408 if (jsExpectations.ignoreFailure()) { |
| 416 } else { | 409 // This is a known failure. |
| 417 gDecodeFailures.push_back().set(srcPath); | 410 gKnownFailures.push_back().appendf( |
| 411 "failed to decode %s, which is a known failure.", srcPath); | |
| 412 return; | |
| 413 } | |
| 414 if (jsExpectations.empty()) { | |
| 415 // This is a failure, but it is a new file. Mark it as missing, with | |
| 416 // a note that it should be marked failing. | |
| 417 gMissingExpectations.push_back().appendf( | |
| 418 "new file %s (with no expectations) FAILED to decode.", srcP ath); | |
| 419 return; | |
| 420 } | |
| 418 } | 421 } |
| 422 | |
| 423 // If there was a failure, and either there was no expectations file, or | |
| 424 // the expectations file listed a valid expectation, report the failure. | |
| 425 gDecodeFailures.push_back().set(srcPath); | |
| 419 return; | 426 return; |
| 420 } | 427 } |
| 421 | 428 |
| 422 // Test decoding just the bounds. The bounds should always match. | 429 // Test decoding just the bounds. The bounds should always match. |
| 423 { | 430 { |
| 424 stream.rewind(); | 431 stream.rewind(); |
| 425 SkBitmap dim; | 432 SkBitmap dim; |
| 426 if (!codec->decode(&stream, &dim, SkImageDecoder::kDecodeBounds_Mode)) { | 433 if (!codec->decode(&stream, &dim, SkImageDecoder::kDecodeBounds_Mode)) { |
| 427 SkString failure = SkStringPrintf("failed to decode bounds for %s", srcPath); | 434 SkString failure = SkStringPrintf("failed to decode bounds for %s", srcPath); |
| 428 gDecodeFailures.push_back() = failure; | 435 gDecodeFailures.push_back() = failure; |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 709 failed |= print_strings("Failed to encode", gEncodeFailures); | 716 failed |= print_strings("Failed to encode", gEncodeFailures); |
| 710 print_strings("Decoded", gSuccessfulDecodes); | 717 print_strings("Decoded", gSuccessfulDecodes); |
| 711 print_strings("Missing expectations", gMissingExpectations); | 718 print_strings("Missing expectations", gMissingExpectations); |
| 712 | 719 |
| 713 if (FLAGS_testSubsetDecoding) { | 720 if (FLAGS_testSubsetDecoding) { |
| 714 failed |= print_strings("Failed subset decodes", gFailedSubsetDecodes); | 721 failed |= print_strings("Failed subset decodes", gFailedSubsetDecodes); |
| 715 print_strings("Decoded subsets", gSuccessfulSubsetDecodes); | 722 print_strings("Decoded subsets", gSuccessfulSubsetDecodes); |
| 716 print_strings("Missing subset expectations", gMissingSubsetExpectations) ; | 723 print_strings("Missing subset expectations", gMissingSubsetExpectations) ; |
| 717 } | 724 } |
| 718 | 725 |
| 726 print_strings("Known failures", gKnownFailures); | |
| 727 | |
| 719 return failed ? -1 : 0; | 728 return failed ? -1 : 0; |
| 720 } | 729 } |
| 721 | 730 |
| 722 #if !defined SK_BUILD_FOR_IOS | 731 #if !defined SK_BUILD_FOR_IOS |
| 723 int main(int argc, char * const argv[]) { | 732 int main(int argc, char * const argv[]) { |
| 724 return tool_main(argc, (char**) argv); | 733 return tool_main(argc, (char**) argv); |
| 725 } | 734 } |
| 726 #endif | 735 #endif |
| OLD | NEW |