| 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 * TODO(epoger): Combine this with tools/image_expectations.cpp, or eliminate on
e of the two. | 7 * TODO(epoger): Combine this with tools/image_expectations.cpp, or eliminate on
e of the two. |
| 8 */ | 8 */ |
| 9 | 9 |
| 10 #include "gm_expectations.h" | 10 #include "gm_expectations.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 const static char kJsonKey_ExpectedResults[] = "expected-results"; | 24 const static char kJsonKey_ExpectedResults[] = "expected-results"; |
| 25 const static char kJsonKey_ExpectedResults_AllowedDigests[] = "allowed-digests"; | 25 const static char kJsonKey_ExpectedResults_AllowedDigests[] = "allowed-digests"; |
| 26 const static char kJsonKey_ExpectedResults_IgnoreFailure[] = "ignore-failure"; | 26 const static char kJsonKey_ExpectedResults_IgnoreFailure[] = "ignore-failure"; |
| 27 | 27 |
| 28 // Types of result hashes we support in the JSON file. | 28 // Types of result hashes we support in the JSON file. |
| 29 const static char kJsonKey_Hashtype_Bitmap_64bitMD5[] = "bitmap-64bitMD5"; | 29 const static char kJsonKey_Hashtype_Bitmap_64bitMD5[] = "bitmap-64bitMD5"; |
| 30 | 30 |
| 31 | 31 |
| 32 namespace skiagm { | 32 namespace skiagm { |
| 33 | 33 |
| 34 #ifdef SK_BUILD_JSON_WRITER | |
| 35 Json::Value CreateJsonTree(Json::Value expectedResults, | 34 Json::Value CreateJsonTree(Json::Value expectedResults, |
| 36 Json::Value actualResultsFailed, | 35 Json::Value actualResultsFailed, |
| 37 Json::Value actualResultsFailureIgnored, | 36 Json::Value actualResultsFailureIgnored, |
| 38 Json::Value actualResultsNoComparison, | 37 Json::Value actualResultsNoComparison, |
| 39 Json::Value actualResultsSucceeded) { | 38 Json::Value actualResultsSucceeded) { |
| 40 Json::Value actualResults; | 39 Json::Value actualResults; |
| 41 actualResults[kJsonKey_ActualResults_Failed] = actualResultsFailed; | 40 actualResults[kJsonKey_ActualResults_Failed] = actualResultsFailed; |
| 42 actualResults[kJsonKey_ActualResults_FailureIgnored] = actualResultsFail
ureIgnored; | 41 actualResults[kJsonKey_ActualResults_FailureIgnored] = actualResultsFail
ureIgnored; |
| 43 actualResults[kJsonKey_ActualResults_NoComparison] = actualResultsNoComp
arison; | 42 actualResults[kJsonKey_ActualResults_NoComparison] = actualResultsNoComp
arison; |
| 44 actualResults[kJsonKey_ActualResults_Succeeded] = actualResultsSucceeded
; | 43 actualResults[kJsonKey_ActualResults_Succeeded] = actualResultsSucceeded
; |
| 45 Json::Value root; | 44 Json::Value root; |
| 46 root[kJsonKey_ActualResults] = actualResults; | 45 root[kJsonKey_ActualResults] = actualResults; |
| 47 root[kJsonKey_ExpectedResults] = expectedResults; | 46 root[kJsonKey_ExpectedResults] = expectedResults; |
| 48 return root; | 47 return root; |
| 49 } | 48 } |
| 50 #endif | |
| 51 | 49 |
| 52 // GmResultDigest class... | 50 // GmResultDigest class... |
| 53 | 51 |
| 54 GmResultDigest::GmResultDigest(const SkBitmap &bitmap) { | 52 GmResultDigest::GmResultDigest(const SkBitmap &bitmap) { |
| 55 fIsValid = SkBitmapHasher::ComputeDigest(bitmap, &fHashDigest); | 53 fIsValid = SkBitmapHasher::ComputeDigest(bitmap, &fHashDigest); |
| 56 } | 54 } |
| 57 | 55 |
| 58 #ifdef SK_BUILD_JSON_WRITER | |
| 59 GmResultDigest::GmResultDigest(const Json::Value &jsonTypeValuePair) { | 56 GmResultDigest::GmResultDigest(const Json::Value &jsonTypeValuePair) { |
| 60 fIsValid = false; | 57 fIsValid = false; |
| 61 if (!jsonTypeValuePair.isArray()) { | 58 if (!jsonTypeValuePair.isArray()) { |
| 62 SkDebugf("found non-array json value when parsing GmResultDigest: %s
\n", | 59 SkDebugf("found non-array json value when parsing GmResultDigest: %s
\n", |
| 63 jsonTypeValuePair.toStyledString().c_str()); | 60 jsonTypeValuePair.toStyledString().c_str()); |
| 64 DEBUGFAIL_SEE_STDERR; | 61 DEBUGFAIL_SEE_STDERR; |
| 65 } else if (2 != jsonTypeValuePair.size()) { | 62 } else if (2 != jsonTypeValuePair.size()) { |
| 66 SkDebugf("found json array with wrong size when parsing GmResultDige
st: %s\n", | 63 SkDebugf("found json array with wrong size when parsing GmResultDige
st: %s\n", |
| 67 jsonTypeValuePair.toStyledString().c_str()); | 64 jsonTypeValuePair.toStyledString().c_str()); |
| 68 DEBUGFAIL_SEE_STDERR; | 65 DEBUGFAIL_SEE_STDERR; |
| 69 } else { | 66 } else { |
| 70 // TODO(epoger): The current implementation assumes that the | 67 // TODO(epoger): The current implementation assumes that the |
| 71 // result digest is always of type kJsonKey_Hashtype_Bitmap_64bitMD5 | 68 // result digest is always of type kJsonKey_Hashtype_Bitmap_64bitMD5 |
| 72 Json::Value jsonHashValue = jsonTypeValuePair[1]; | 69 Json::Value jsonHashValue = jsonTypeValuePair[1]; |
| 73 if (!jsonHashValue.isIntegral()) { | 70 if (!jsonHashValue.isIntegral()) { |
| 74 SkDebugf("found non-integer jsonHashValue when parsing GmResultD
igest: %s\n", | 71 SkDebugf("found non-integer jsonHashValue when parsing GmResultD
igest: %s\n", |
| 75 jsonTypeValuePair.toStyledString().c_str()); | 72 jsonTypeValuePair.toStyledString().c_str()); |
| 76 DEBUGFAIL_SEE_STDERR; | 73 DEBUGFAIL_SEE_STDERR; |
| 77 } else { | 74 } else { |
| 78 fHashDigest = jsonHashValue.asUInt64(); | 75 fHashDigest = jsonHashValue.asUInt64(); |
| 79 fIsValid = true; | 76 fIsValid = true; |
| 80 } | 77 } |
| 81 } | 78 } |
| 82 } | 79 } |
| 83 #endif | |
| 84 | 80 |
| 85 bool GmResultDigest::isValid() const { | 81 bool GmResultDigest::isValid() const { |
| 86 return fIsValid; | 82 return fIsValid; |
| 87 } | 83 } |
| 88 | 84 |
| 89 bool GmResultDigest::equals(const GmResultDigest &other) const { | 85 bool GmResultDigest::equals(const GmResultDigest &other) const { |
| 90 // TODO(epoger): The current implementation assumes that this | 86 // TODO(epoger): The current implementation assumes that this |
| 91 // and other are always of type kJsonKey_Hashtype_Bitmap_64bitMD5 | 87 // and other are always of type kJsonKey_Hashtype_Bitmap_64bitMD5 |
| 92 return (this->fIsValid && other.fIsValid && (this->fHashDigest == other.
fHashDigest)); | 88 return (this->fIsValid && other.fIsValid && (this->fHashDigest == other.
fHashDigest)); |
| 93 } | 89 } |
| 94 | 90 |
| 95 #ifdef SK_BUILD_JSON_WRITER | |
| 96 Json::Value GmResultDigest::asJsonTypeValuePair() const { | 91 Json::Value GmResultDigest::asJsonTypeValuePair() const { |
| 97 // TODO(epoger): The current implementation assumes that the | 92 // TODO(epoger): The current implementation assumes that the |
| 98 // result digest is always of type kJsonKey_Hashtype_Bitmap_64bitMD5 | 93 // result digest is always of type kJsonKey_Hashtype_Bitmap_64bitMD5 |
| 99 Json::Value jsonTypeValuePair; | 94 Json::Value jsonTypeValuePair; |
| 100 if (fIsValid) { | 95 if (fIsValid) { |
| 101 jsonTypeValuePair.append(Json::Value(kJsonKey_Hashtype_Bitmap_64bitM
D5)); | 96 jsonTypeValuePair.append(Json::Value(kJsonKey_Hashtype_Bitmap_64bitM
D5)); |
| 102 jsonTypeValuePair.append(Json::UInt64(fHashDigest)); | 97 jsonTypeValuePair.append(Json::UInt64(fHashDigest)); |
| 103 } else { | 98 } else { |
| 104 jsonTypeValuePair.append(Json::Value("INVALID")); | 99 jsonTypeValuePair.append(Json::Value("INVALID")); |
| 105 } | 100 } |
| 106 return jsonTypeValuePair; | 101 return jsonTypeValuePair; |
| 107 } | 102 } |
| 108 #endif | |
| 109 | 103 |
| 110 SkString GmResultDigest::getHashType() const { | 104 SkString GmResultDigest::getHashType() const { |
| 111 // TODO(epoger): The current implementation assumes that the | 105 // TODO(epoger): The current implementation assumes that the |
| 112 // result digest is always of type kJsonKey_Hashtype_Bitmap_64bitMD5 | 106 // result digest is always of type kJsonKey_Hashtype_Bitmap_64bitMD5 |
| 113 return SkString(kJsonKey_Hashtype_Bitmap_64bitMD5); | 107 return SkString(kJsonKey_Hashtype_Bitmap_64bitMD5); |
| 114 } | 108 } |
| 115 | 109 |
| 116 SkString GmResultDigest::getDigestValue() const { | 110 SkString GmResultDigest::getDigestValue() const { |
| 117 // TODO(epoger): The current implementation assumes that the | 111 // TODO(epoger): The current implementation assumes that the |
| 118 // result digest is always of type kJsonKey_Hashtype_Bitmap_64bitMD5 | 112 // result digest is always of type kJsonKey_Hashtype_Bitmap_64bitMD5 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 133 fIgnoreFailure = ignoreFailure; | 127 fIgnoreFailure = ignoreFailure; |
| 134 fAllowedResultDigests.push_back(GmResultDigest(bitmap)); | 128 fAllowedResultDigests.push_back(GmResultDigest(bitmap)); |
| 135 } | 129 } |
| 136 | 130 |
| 137 Expectations::Expectations(const BitmapAndDigest& bitmapAndDigest) { | 131 Expectations::Expectations(const BitmapAndDigest& bitmapAndDigest) { |
| 138 fBitmap = bitmapAndDigest.fBitmap; | 132 fBitmap = bitmapAndDigest.fBitmap; |
| 139 fIgnoreFailure = false; | 133 fIgnoreFailure = false; |
| 140 fAllowedResultDigests.push_back(bitmapAndDigest.fDigest); | 134 fAllowedResultDigests.push_back(bitmapAndDigest.fDigest); |
| 141 } | 135 } |
| 142 | 136 |
| 143 #ifdef SK_BUILD_JSON_WRITER | |
| 144 Expectations::Expectations(Json::Value jsonElement) { | 137 Expectations::Expectations(Json::Value jsonElement) { |
| 145 if (jsonElement.empty()) { | 138 if (jsonElement.empty()) { |
| 146 fIgnoreFailure = kDefaultIgnoreFailure; | 139 fIgnoreFailure = kDefaultIgnoreFailure; |
| 147 } else { | 140 } else { |
| 148 Json::Value ignoreFailure = jsonElement[kJsonKey_ExpectedResults_Ign
oreFailure]; | 141 Json::Value ignoreFailure = jsonElement[kJsonKey_ExpectedResults_Ign
oreFailure]; |
| 149 if (ignoreFailure.isNull()) { | 142 if (ignoreFailure.isNull()) { |
| 150 fIgnoreFailure = kDefaultIgnoreFailure; | 143 fIgnoreFailure = kDefaultIgnoreFailure; |
| 151 } else if (!ignoreFailure.isBool()) { | 144 } else if (!ignoreFailure.isBool()) { |
| 152 SkDebugf("found non-boolean json value for key '%s' in element '
%s'\n", | 145 SkDebugf("found non-boolean json value for key '%s' in element '
%s'\n", |
| 153 kJsonKey_ExpectedResults_IgnoreFailure, | 146 kJsonKey_ExpectedResults_IgnoreFailure, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 166 kJsonKey_ExpectedResults_AllowedDigests, | 159 kJsonKey_ExpectedResults_AllowedDigests, |
| 167 jsonElement.toStyledString().c_str()); | 160 jsonElement.toStyledString().c_str()); |
| 168 DEBUGFAIL_SEE_STDERR; | 161 DEBUGFAIL_SEE_STDERR; |
| 169 } else { | 162 } else { |
| 170 for (Json::ArrayIndex i=0; i<allowedDigests.size(); i++) { | 163 for (Json::ArrayIndex i=0; i<allowedDigests.size(); i++) { |
| 171 fAllowedResultDigests.push_back(GmResultDigest(allowedDigest
s[i])); | 164 fAllowedResultDigests.push_back(GmResultDigest(allowedDigest
s[i])); |
| 172 } | 165 } |
| 173 } | 166 } |
| 174 } | 167 } |
| 175 } | 168 } |
| 176 #endif | |
| 177 | 169 |
| 178 bool Expectations::match(GmResultDigest actualGmResultDigest) const { | 170 bool Expectations::match(GmResultDigest actualGmResultDigest) const { |
| 179 for (int i=0; i < this->fAllowedResultDigests.count(); i++) { | 171 for (int i=0; i < this->fAllowedResultDigests.count(); i++) { |
| 180 GmResultDigest allowedResultDigest = this->fAllowedResultDigests[i]; | 172 GmResultDigest allowedResultDigest = this->fAllowedResultDigests[i]; |
| 181 if (allowedResultDigest.equals(actualGmResultDigest)) { | 173 if (allowedResultDigest.equals(actualGmResultDigest)) { |
| 182 return true; | 174 return true; |
| 183 } | 175 } |
| 184 } | 176 } |
| 185 return false; | 177 return false; |
| 186 } | 178 } |
| 187 | 179 |
| 188 #ifdef SK_BUILD_JSON_WRITER | |
| 189 Json::Value Expectations::asJsonValue() const { | 180 Json::Value Expectations::asJsonValue() const { |
| 190 Json::Value allowedDigestArray; | 181 Json::Value allowedDigestArray; |
| 191 if (!this->fAllowedResultDigests.empty()) { | 182 if (!this->fAllowedResultDigests.empty()) { |
| 192 for (int i=0; i < this->fAllowedResultDigests.count(); i++) { | 183 for (int i=0; i < this->fAllowedResultDigests.count(); i++) { |
| 193 allowedDigestArray.append(this->fAllowedResultDigests[i].asJsonT
ypeValuePair()); | 184 allowedDigestArray.append(this->fAllowedResultDigests[i].asJsonT
ypeValuePair()); |
| 194 } | 185 } |
| 195 } | 186 } |
| 196 | 187 |
| 197 Json::Value jsonExpectations; | 188 Json::Value jsonExpectations; |
| 198 jsonExpectations[kJsonKey_ExpectedResults_AllowedDigests] = allowedDiges
tArray; | 189 jsonExpectations[kJsonKey_ExpectedResults_AllowedDigests] = allowedDiges
tArray; |
| 199 jsonExpectations[kJsonKey_ExpectedResults_IgnoreFailure] = this->ignore
Failure(); | 190 jsonExpectations[kJsonKey_ExpectedResults_IgnoreFailure] = this->ignore
Failure(); |
| 200 return jsonExpectations; | 191 return jsonExpectations; |
| 201 } | 192 } |
| 202 #endif | |
| 203 | 193 |
| 204 // IndividualImageExpectationsSource class... | 194 // IndividualImageExpectationsSource class... |
| 205 | 195 |
| 206 Expectations IndividualImageExpectationsSource::get(const char *testName) co
nst { | 196 Expectations IndividualImageExpectationsSource::get(const char *testName) co
nst { |
| 207 SkString path = SkOSPath::SkPathJoin(fRootDir.c_str(), testName); | 197 SkString path = SkOSPath::SkPathJoin(fRootDir.c_str(), testName); |
| 208 SkBitmap referenceBitmap; | 198 SkBitmap referenceBitmap; |
| 209 bool decodedReferenceBitmap = | 199 bool decodedReferenceBitmap = |
| 210 SkImageDecoder::DecodeFile(path.c_str(), &referenceBitmap, kN32_SkCo
lorType, | 200 SkImageDecoder::DecodeFile(path.c_str(), &referenceBitmap, kN32_SkCo
lorType, |
| 211 SkImageDecoder::kDecodePixels_Mode, NULL)
; | 201 SkImageDecoder::kDecodePixels_Mode, NULL)
; |
| 212 if (decodedReferenceBitmap) { | 202 if (decodedReferenceBitmap) { |
| 213 return Expectations(referenceBitmap); | 203 return Expectations(referenceBitmap); |
| 214 } else { | 204 } else { |
| 215 return Expectations(); | 205 return Expectations(); |
| 216 } | 206 } |
| 217 } | 207 } |
| 218 | 208 |
| 219 | 209 |
| 220 #ifdef SK_BUILD_JSON_WRITER | |
| 221 // JsonExpectationsSource class... | 210 // JsonExpectationsSource class... |
| 222 | 211 |
| 223 JsonExpectationsSource::JsonExpectationsSource(const char *jsonPath) { | 212 JsonExpectationsSource::JsonExpectationsSource(const char *jsonPath) { |
| 224 Parse(jsonPath, &fJsonRoot); | 213 Parse(jsonPath, &fJsonRoot); |
| 225 fJsonExpectedResults = fJsonRoot[kJsonKey_ExpectedResults]; | 214 fJsonExpectedResults = fJsonRoot[kJsonKey_ExpectedResults]; |
| 226 } | 215 } |
| 227 | 216 |
| 228 Expectations JsonExpectationsSource::get(const char *testName) const { | 217 Expectations JsonExpectationsSource::get(const char *testName) const { |
| 229 return Expectations(fJsonExpectedResults[testName]); | 218 return Expectations(fJsonExpectedResults[testName]); |
| 230 } | 219 } |
| 231 | 220 |
| 232 /*static*/ bool JsonExpectationsSource::Parse(const char *jsonPath, Json::Va
lue *jsonRoot) { | 221 /*static*/ bool JsonExpectationsSource::Parse(const char *jsonPath, Json::Va
lue *jsonRoot) { |
| 233 SkAutoDataUnref dataRef(SkData::NewFromFileName(jsonPath)); | 222 SkAutoDataUnref dataRef(SkData::NewFromFileName(jsonPath)); |
| 234 if (NULL == dataRef.get()) { | 223 if (NULL == dataRef.get()) { |
| 235 SkDebugf("error reading JSON file %s\n", jsonPath); | 224 SkDebugf("error reading JSON file %s\n", jsonPath); |
| 236 DEBUGFAIL_SEE_STDERR; | 225 DEBUGFAIL_SEE_STDERR; |
| 237 return false; | 226 return false; |
| 238 } | 227 } |
| 239 | 228 |
| 240 const char *bytes = reinterpret_cast<const char *>(dataRef.get()->data()
); | 229 const char *bytes = reinterpret_cast<const char *>(dataRef.get()->data()
); |
| 241 size_t size = dataRef.get()->size(); | 230 size_t size = dataRef.get()->size(); |
| 242 Json::Reader reader; | 231 Json::Reader reader; |
| 243 if (!reader.parse(bytes, bytes+size, *jsonRoot)) { | 232 if (!reader.parse(bytes, bytes+size, *jsonRoot)) { |
| 244 SkDebugf("error parsing JSON file %s\n", jsonPath); | 233 SkDebugf("error parsing JSON file %s\n", jsonPath); |
| 245 DEBUGFAIL_SEE_STDERR; | 234 DEBUGFAIL_SEE_STDERR; |
| 246 return false; | 235 return false; |
| 247 } | 236 } |
| 248 return true; | 237 return true; |
| 249 } | 238 } |
| 250 #endif | |
| 251 } | 239 } |
| OLD | NEW |