| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 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 "SkBitmapHasher.h" | 9 #include "SkBitmapHasher.h" |
| 10 #include "SkImageDecoder.h" | 10 #include "SkImageDecoder.h" |
| 11 | 11 |
| 12 #define DEBUGFAIL_SEE_STDERR SkDEBUGFAIL("see stderr for message") | 12 #define DEBUGFAIL_SEE_STDERR SkDEBUGFAIL("see stderr for message") |
| 13 | 13 |
| 14 // See gm_json.py for descriptions of each of these JSON keys. | 14 // See gm_json.py for descriptions of each of these JSON keys. |
| 15 // These constants must be kept in sync with the ones in that Python file! | 15 // These constants must be kept in sync with the ones in that Python file! |
| 16 const static char kJsonKey_ActualResults[] = "actual-results"; | 16 const static char kJsonKey_ActualResults[] = "actual-results"; |
| 17 const static char kJsonKey_ActualResults_Failed[] = "failed"; | 17 const static char kJsonKey_ActualResults_Failed[] = "failed"; |
| 18 const static char kJsonKey_ActualResults_FailureIgnored[]= "failure-ignored"; | 18 const static char kJsonKey_ActualResults_FailureIgnored[]= "failure-ignored"; |
| 19 const static char kJsonKey_ActualResults_NoComparison[] = "no-comparison"; | 19 const static char kJsonKey_ActualResults_NoComparison[] = "no-comparison"; |
| 20 const static char kJsonKey_ActualResults_Succeeded[] = "succeeded"; | 20 const static char kJsonKey_ActualResults_Succeeded[] = "succeeded"; |
| 21 const static char kJsonKey_ExpectedResults[] = "expected-results"; | 21 const static char kJsonKey_ExpectedResults[] = "expected-results"; |
| 22 const static char kJsonKey_ExpectedResults_AllowedDigests[] = "allowed-digests"; | 22 const static char kJsonKey_ExpectedResults_AllowedDigests[] = "allowed-digests"; |
| 23 const static char kJsonKey_ExpectedResults_IgnoreFailure[] = "ignore-failure"; | 23 const static char kJsonKey_ExpectedResults_IgnoreFailure[] = "ignore-failure"; |
| 24 | 24 |
| 25 // Types of result hashes we support in the JSON file. | 25 // Types of result hashes we support in the JSON file. |
| 26 const static char kJsonKey_Hashtype_Bitmap_64bitMD5[] = "bitmap-64bitMD5"; | 26 const static char kJsonKey_Hashtype_Bitmap_64bitMD5[] = "bitmap-64bitMD5"; |
| 27 | 27 |
| 28 | 28 |
| 29 namespace skiagm { | 29 namespace skiagm { |
| 30 void gm_fprintf(FILE *stream, const char format[], ...) { | |
| 31 va_list args; | |
| 32 va_start(args, format); | |
| 33 fprintf(stream, "GM: "); | |
| 34 vfprintf(stream, format, args); | |
| 35 #ifdef SK_BUILD_FOR_WIN | |
| 36 if (stderr == stream || stdout == stream) { | |
| 37 fflush(stream); | |
| 38 } | |
| 39 #endif | |
| 40 va_end(args); | |
| 41 } | |
| 42 | 30 |
| 43 Json::Value CreateJsonTree(Json::Value expectedResults, | 31 Json::Value CreateJsonTree(Json::Value expectedResults, |
| 44 Json::Value actualResultsFailed, | 32 Json::Value actualResultsFailed, |
| 45 Json::Value actualResultsFailureIgnored, | 33 Json::Value actualResultsFailureIgnored, |
| 46 Json::Value actualResultsNoComparison, | 34 Json::Value actualResultsNoComparison, |
| 47 Json::Value actualResultsSucceeded) { | 35 Json::Value actualResultsSucceeded) { |
| 48 Json::Value actualResults; | 36 Json::Value actualResults; |
| 49 actualResults[kJsonKey_ActualResults_Failed] = actualResultsFailed; | 37 actualResults[kJsonKey_ActualResults_Failed] = actualResultsFailed; |
| 50 actualResults[kJsonKey_ActualResults_FailureIgnored] = actualResultsFail
ureIgnored; | 38 actualResults[kJsonKey_ActualResults_FailureIgnored] = actualResultsFail
ureIgnored; |
| 51 actualResults[kJsonKey_ActualResults_NoComparison] = actualResultsNoComp
arison; | 39 actualResults[kJsonKey_ActualResults_NoComparison] = actualResultsNoComp
arison; |
| 52 actualResults[kJsonKey_ActualResults_Succeeded] = actualResultsSucceeded
; | 40 actualResults[kJsonKey_ActualResults_Succeeded] = actualResultsSucceeded
; |
| 53 Json::Value root; | 41 Json::Value root; |
| 54 root[kJsonKey_ActualResults] = actualResults; | 42 root[kJsonKey_ActualResults] = actualResults; |
| 55 root[kJsonKey_ExpectedResults] = expectedResults; | 43 root[kJsonKey_ExpectedResults] = expectedResults; |
| 56 return root; | 44 return root; |
| 57 } | 45 } |
| 58 | 46 |
| 59 | 47 |
| 60 // GmResultDigest class... | 48 // GmResultDigest class... |
| 61 | 49 |
| 62 GmResultDigest::GmResultDigest(const SkBitmap &bitmap) { | 50 GmResultDigest::GmResultDigest(const SkBitmap &bitmap) { |
| 63 fIsValid = SkBitmapHasher::ComputeDigest(bitmap, &fHashDigest); | 51 fIsValid = SkBitmapHasher::ComputeDigest(bitmap, &fHashDigest); |
| 64 } | 52 } |
| 65 | 53 |
| 66 GmResultDigest::GmResultDigest(const Json::Value &jsonTypeValuePair) { | 54 GmResultDigest::GmResultDigest(const Json::Value &jsonTypeValuePair) { |
| 67 fIsValid = false; | 55 fIsValid = false; |
| 68 if (!jsonTypeValuePair.isArray()) { | 56 if (!jsonTypeValuePair.isArray()) { |
| 69 gm_fprintf(stderr, "found non-array json value when parsing GmResult
Digest: %s\n", | 57 SkDebugf("found non-array json value when parsing GmResultDigest: %s
\n", |
| 70 jsonTypeValuePair.toStyledString().c_str()); | 58 jsonTypeValuePair.toStyledString().c_str()); |
| 71 DEBUGFAIL_SEE_STDERR; | 59 DEBUGFAIL_SEE_STDERR; |
| 72 } else if (2 != jsonTypeValuePair.size()) { | 60 } else if (2 != jsonTypeValuePair.size()) { |
| 73 gm_fprintf(stderr, "found json array with wrong size when parsing Gm
ResultDigest: %s\n", | 61 SkDebugf("found json array with wrong size when parsing GmResultDige
st: %s\n", |
| 74 jsonTypeValuePair.toStyledString().c_str()); | 62 jsonTypeValuePair.toStyledString().c_str()); |
| 75 DEBUGFAIL_SEE_STDERR; | 63 DEBUGFAIL_SEE_STDERR; |
| 76 } else { | 64 } else { |
| 77 // TODO(epoger): The current implementation assumes that the | 65 // TODO(epoger): The current implementation assumes that the |
| 78 // result digest is always of type kJsonKey_Hashtype_Bitmap_64bitMD5 | 66 // result digest is always of type kJsonKey_Hashtype_Bitmap_64bitMD5 |
| 79 Json::Value jsonHashValue = jsonTypeValuePair[1]; | 67 Json::Value jsonHashValue = jsonTypeValuePair[1]; |
| 80 if (!jsonHashValue.isIntegral()) { | 68 if (!jsonHashValue.isIntegral()) { |
| 81 gm_fprintf(stderr, | 69 SkDebugf("found non-integer jsonHashValue when parsing GmResultD
igest: %s\n", |
| 82 "found non-integer jsonHashValue when parsing GmResul
tDigest: %s\n", | 70 jsonTypeValuePair.toStyledString().c_str()); |
| 83 jsonTypeValuePair.toStyledString().c_str()); | |
| 84 DEBUGFAIL_SEE_STDERR; | 71 DEBUGFAIL_SEE_STDERR; |
| 85 } else { | 72 } else { |
| 86 fHashDigest = jsonHashValue.asUInt64(); | 73 fHashDigest = jsonHashValue.asUInt64(); |
| 87 fIsValid = true; | 74 fIsValid = true; |
| 88 } | 75 } |
| 89 } | 76 } |
| 90 } | 77 } |
| 91 | 78 |
| 92 bool GmResultDigest::isValid() const { | 79 bool GmResultDigest::isValid() const { |
| 93 return fIsValid; | 80 return fIsValid; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 } | 133 } |
| 147 | 134 |
| 148 Expectations::Expectations(Json::Value jsonElement) { | 135 Expectations::Expectations(Json::Value jsonElement) { |
| 149 if (jsonElement.empty()) { | 136 if (jsonElement.empty()) { |
| 150 fIgnoreFailure = kDefaultIgnoreFailure; | 137 fIgnoreFailure = kDefaultIgnoreFailure; |
| 151 } else { | 138 } else { |
| 152 Json::Value ignoreFailure = jsonElement[kJsonKey_ExpectedResults_Ign
oreFailure]; | 139 Json::Value ignoreFailure = jsonElement[kJsonKey_ExpectedResults_Ign
oreFailure]; |
| 153 if (ignoreFailure.isNull()) { | 140 if (ignoreFailure.isNull()) { |
| 154 fIgnoreFailure = kDefaultIgnoreFailure; | 141 fIgnoreFailure = kDefaultIgnoreFailure; |
| 155 } else if (!ignoreFailure.isBool()) { | 142 } else if (!ignoreFailure.isBool()) { |
| 156 gm_fprintf(stderr, "found non-boolean json value" | 143 SkDebugf("found non-boolean json value for key '%s' in element '
%s'\n", |
| 157 " for key '%s' in element '%s'\n", | 144 kJsonKey_ExpectedResults_IgnoreFailure, |
| 158 kJsonKey_ExpectedResults_IgnoreFailure, | 145 jsonElement.toStyledString().c_str()); |
| 159 jsonElement.toStyledString().c_str()); | |
| 160 DEBUGFAIL_SEE_STDERR; | 146 DEBUGFAIL_SEE_STDERR; |
| 161 fIgnoreFailure = kDefaultIgnoreFailure; | 147 fIgnoreFailure = kDefaultIgnoreFailure; |
| 162 } else { | 148 } else { |
| 163 fIgnoreFailure = ignoreFailure.asBool(); | 149 fIgnoreFailure = ignoreFailure.asBool(); |
| 164 } | 150 } |
| 165 | 151 |
| 166 Json::Value allowedDigests = jsonElement[kJsonKey_ExpectedResults_Al
lowedDigests]; | 152 Json::Value allowedDigests = jsonElement[kJsonKey_ExpectedResults_Al
lowedDigests]; |
| 167 if (allowedDigests.isNull()) { | 153 if (allowedDigests.isNull()) { |
| 168 // ok, we'll just assume there aren't any AllowedDigests to comp
are against | 154 // ok, we'll just assume there aren't any AllowedDigests to comp
are against |
| 169 } else if (!allowedDigests.isArray()) { | 155 } else if (!allowedDigests.isArray()) { |
| 170 gm_fprintf(stderr, "found non-array json value" | 156 SkDebugf("found non-array json value for key '%s' in element '%s
'\n", |
| 171 " for key '%s' in element '%s'\n", | 157 kJsonKey_ExpectedResults_AllowedDigests, |
| 172 kJsonKey_ExpectedResults_AllowedDigests, | 158 jsonElement.toStyledString().c_str()); |
| 173 jsonElement.toStyledString().c_str()); | |
| 174 DEBUGFAIL_SEE_STDERR; | 159 DEBUGFAIL_SEE_STDERR; |
| 175 } else { | 160 } else { |
| 176 for (Json::ArrayIndex i=0; i<allowedDigests.size(); i++) { | 161 for (Json::ArrayIndex i=0; i<allowedDigests.size(); i++) { |
| 177 fAllowedResultDigests.push_back(GmResultDigest(allowedDigest
s[i])); | 162 fAllowedResultDigests.push_back(GmResultDigest(allowedDigest
s[i])); |
| 178 } | 163 } |
| 179 } | 164 } |
| 180 } | 165 } |
| 181 } | 166 } |
| 182 | 167 |
| 183 bool Expectations::match(GmResultDigest actualGmResultDigest) const { | 168 bool Expectations::match(GmResultDigest actualGmResultDigest) const { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 } | 233 } |
| 249 bytesRemaining -= bytesReadThisTime; | 234 bytesRemaining -= bytesReadThisTime; |
| 250 bufPtr += bytesReadThisTime; | 235 bufPtr += bytesReadThisTime; |
| 251 } | 236 } |
| 252 return SkData::NewFromMalloc(bufStart, maxBytes - bytesRemaining); | 237 return SkData::NewFromMalloc(bufStart, maxBytes - bytesRemaining); |
| 253 } | 238 } |
| 254 | 239 |
| 255 /*static*/ bool JsonExpectationsSource::Parse(const char *jsonPath, Json::Va
lue *jsonRoot) { | 240 /*static*/ bool JsonExpectationsSource::Parse(const char *jsonPath, Json::Va
lue *jsonRoot) { |
| 256 SkFILEStream inFile(jsonPath); | 241 SkFILEStream inFile(jsonPath); |
| 257 if (!inFile.isValid()) { | 242 if (!inFile.isValid()) { |
| 258 gm_fprintf(stderr, "unable to read JSON file %s\n", jsonPath); | 243 SkDebugf("unable to read JSON file %s\n", jsonPath); |
| 259 DEBUGFAIL_SEE_STDERR; | 244 DEBUGFAIL_SEE_STDERR; |
| 260 return false; | 245 return false; |
| 261 } | 246 } |
| 262 | 247 |
| 263 SkAutoDataUnref dataRef(ReadFileIntoSkData(inFile)); | 248 SkAutoDataUnref dataRef(ReadFileIntoSkData(inFile)); |
| 264 if (NULL == dataRef.get()) { | 249 if (NULL == dataRef.get()) { |
| 265 gm_fprintf(stderr, "error reading JSON file %s\n", jsonPath); | 250 SkDebugf("error reading JSON file %s\n", jsonPath); |
| 266 DEBUGFAIL_SEE_STDERR; | 251 DEBUGFAIL_SEE_STDERR; |
| 267 return false; | 252 return false; |
| 268 } | 253 } |
| 269 | 254 |
| 270 const char *bytes = reinterpret_cast<const char *>(dataRef.get()->data()
); | 255 const char *bytes = reinterpret_cast<const char *>(dataRef.get()->data()
); |
| 271 size_t size = dataRef.get()->size(); | 256 size_t size = dataRef.get()->size(); |
| 272 Json::Reader reader; | 257 Json::Reader reader; |
| 273 if (!reader.parse(bytes, bytes+size, *jsonRoot)) { | 258 if (!reader.parse(bytes, bytes+size, *jsonRoot)) { |
| 274 gm_fprintf(stderr, "error parsing JSON file %s\n", jsonPath); | 259 SkDebugf("error parsing JSON file %s\n", jsonPath); |
| 275 DEBUGFAIL_SEE_STDERR; | 260 DEBUGFAIL_SEE_STDERR; |
| 276 return false; | 261 return false; |
| 277 } | 262 } |
| 278 return true; | 263 return true; |
| 279 } | 264 } |
| 280 | 265 |
| 281 } | 266 } |
| OLD | NEW |