Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(191)

Side by Side Diff: gm/gm_expectations.cpp

Issue 15883004: GM: create GmResultDigest that encapsulates digest type ("bitmap-64bitMD5") and value (12345) (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: add_isValid Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « gm/gm_expectations.h ('k') | gm/gmmain.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 // These constants must be kept in sync with the JSONKEY_ constants in 14 // These constants must be kept in sync with the JSONKEY_ constants in
15 // display_json_results.py ! 15 // display_json_results.py !
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_ActualResults_AnyStatus_BitmapHash[] = "bitmap-64bit MD5";
22 21
23 const static char kJsonKey_ExpectedResults[] = "expected-results"; 22 const static char kJsonKey_ExpectedResults[] = "expected-results";
24 const static char kJsonKey_ExpectedResults_AllowedBitmapHashes[] = "allowed-bitm ap-64bitMD5s"; 23 const static char kJsonKey_ExpectedResults_AllowedDigests[] = "allowed-digests";
25 const static char kJsonKey_ExpectedResults_IgnoreFailure[] = "ignore-f ailure"; 24 const static char kJsonKey_ExpectedResults_IgnoreFailure[] = "ignore-failure";
25
26 // Types of result hashes we support in the JSON file.
27 const static char kJsonKey_Hashtype_Bitmap_64bitMD5[] = "bitmap-64bitMD5";
28
26 29
27 namespace skiagm { 30 namespace skiagm {
28 31
29 void gm_fprintf(FILE *stream, const char format[], ...) { 32 void gm_fprintf(FILE *stream, const char format[], ...) {
30 va_list args; 33 va_list args;
31 va_start(args, format); 34 va_start(args, format);
32 fprintf(stream, "GM: "); 35 fprintf(stream, "GM: ");
33 vfprintf(stream, format, args); 36 vfprintf(stream, format, args);
34 va_end(args); 37 va_end(args);
35 } 38 }
36 39
37 SkString SkPathJoin(const char *rootPath, const char *relativePath) { 40 SkString SkPathJoin(const char *rootPath, const char *relativePath) {
38 SkString result(rootPath); 41 SkString result(rootPath);
39 if (!result.endsWith(SkPATH_SEPARATOR)) { 42 if (!result.endsWith(SkPATH_SEPARATOR)) {
40 result.appendUnichar(SkPATH_SEPARATOR); 43 result.appendUnichar(SkPATH_SEPARATOR);
41 } 44 }
42 result.append(relativePath); 45 result.append(relativePath);
43 return result; 46 return result;
44 } 47 }
45 48
46 // TODO(epoger): This currently assumes that the result SkHashDigest was
47 // generated as an SkHashDigest of an SkBitmap. We'll need to allow for oth er
48 // hash types to cover non-bitmaps.
49 Json::Value ActualResultAsJsonValue(const SkHashDigest& result) {
50 Json::Value jsonValue;
51 jsonValue[kJsonKey_ActualResults_AnyStatus_BitmapHash] = asJsonValue(res ult);
52 return jsonValue;
53 }
54
55 Json::Value CreateJsonTree(Json::Value expectedResults, 49 Json::Value CreateJsonTree(Json::Value expectedResults,
56 Json::Value actualResultsFailed, 50 Json::Value actualResultsFailed,
57 Json::Value actualResultsFailureIgnored, 51 Json::Value actualResultsFailureIgnored,
58 Json::Value actualResultsNoComparison, 52 Json::Value actualResultsNoComparison,
59 Json::Value actualResultsSucceeded) { 53 Json::Value actualResultsSucceeded) {
60 Json::Value actualResults; 54 Json::Value actualResults;
61 actualResults[kJsonKey_ActualResults_Failed] = actualResultsFailed; 55 actualResults[kJsonKey_ActualResults_Failed] = actualResultsFailed;
62 actualResults[kJsonKey_ActualResults_FailureIgnored] = actualResultsFail ureIgnored; 56 actualResults[kJsonKey_ActualResults_FailureIgnored] = actualResultsFail ureIgnored;
63 actualResults[kJsonKey_ActualResults_NoComparison] = actualResultsNoComp arison; 57 actualResults[kJsonKey_ActualResults_NoComparison] = actualResultsNoComp arison;
64 actualResults[kJsonKey_ActualResults_Succeeded] = actualResultsSucceeded ; 58 actualResults[kJsonKey_ActualResults_Succeeded] = actualResultsSucceeded ;
65 Json::Value root; 59 Json::Value root;
66 root[kJsonKey_ActualResults] = actualResults; 60 root[kJsonKey_ActualResults] = actualResults;
67 root[kJsonKey_ExpectedResults] = expectedResults; 61 root[kJsonKey_ExpectedResults] = expectedResults;
68 return root; 62 return root;
69 } 63 }
70 64
71 65
66 // GmResultDigest class...
67
68 GmResultDigest::GmResultDigest(const SkBitmap &bitmap) {
69 fIsValid = SkBitmapHasher::ComputeDigest(bitmap, &fHashDigest);
70 }
71
72 GmResultDigest::GmResultDigest(const Json::Value &jsonTypeValuePair) {
73 fIsValid = false;
74 if (!jsonTypeValuePair.isArray()) {
75 gm_fprintf(stderr, "found non-array json value when parsing GmResult Digest: %s\n",
76 jsonTypeValuePair.toStyledString().c_str());
77 DEBUGFAIL_SEE_STDERR;
78 } else if (2 != jsonTypeValuePair.size()) {
79 gm_fprintf(stderr, "found json array with wrong size when parsing Gm ResultDigest: %s\n",
80 jsonTypeValuePair.toStyledString().c_str());
81 DEBUGFAIL_SEE_STDERR;
82 } else {
83 // TODO(epoger): The current implementation assumes that the
84 // result digest is always of type kJsonKey_Hashtype_Bitmap_64bitMD5
85 Json::Value jsonHashValue = jsonTypeValuePair[1];
86 if (!jsonHashValue.isIntegral()) {
87 gm_fprintf(stderr,
88 "found non-integer jsonHashValue when parsing GmResul tDigest: %s\n",
89 jsonTypeValuePair.toStyledString().c_str());
90 DEBUGFAIL_SEE_STDERR;
91 } else {
92 fHashDigest = jsonHashValue.asUInt64();
93 fIsValid = true;
94 }
95 }
96 }
97
98 bool GmResultDigest::isValid() const {
99 return fIsValid;
100 }
101
102 bool GmResultDigest::equals(const GmResultDigest &other) const {
103 // TODO(epoger): The current implementation assumes that this
104 // and other are always of type kJsonKey_Hashtype_Bitmap_64bitMD5
105 return (this->fIsValid && other.fIsValid && (this->fHashDigest == other. fHashDigest));
106 }
107
108 Json::Value GmResultDigest::asJsonTypeValuePair() const {
109 // TODO(epoger): The current implementation assumes that the
110 // result digest is always of type kJsonKey_Hashtype_Bitmap_64bitMD5
111 Json::Value jsonTypeValuePair;
112 if (fIsValid) {
113 jsonTypeValuePair.append(Json::Value(kJsonKey_Hashtype_Bitmap_64bitM D5));
114 jsonTypeValuePair.append(Json::UInt64(fHashDigest));
115 } else {
116 jsonTypeValuePair.append(Json::Value("INVALID"));
117 }
118 return jsonTypeValuePair;
119 }
120
121
72 // Expectations class... 122 // Expectations class...
73 123
74 Expectations::Expectations(bool ignoreFailure) { 124 Expectations::Expectations(bool ignoreFailure) {
75 fIgnoreFailure = ignoreFailure; 125 fIgnoreFailure = ignoreFailure;
76 } 126 }
77 127
78 Expectations::Expectations(const SkBitmap& bitmap, bool ignoreFailure) { 128 Expectations::Expectations(const SkBitmap& bitmap, bool ignoreFailure) {
79 fBitmap = bitmap; 129 fBitmap = bitmap;
80 fIgnoreFailure = ignoreFailure; 130 fIgnoreFailure = ignoreFailure;
81 SkHashDigest digest; 131 fAllowedResultDigests.push_back(GmResultDigest(bitmap));
82 // TODO(epoger): Better handling for error returned by ComputeDigest()?
83 // For now, we just report a digest of 0 in error cases, like before.
84 if (!SkBitmapHasher::ComputeDigest(bitmap, &digest)) {
85 digest = 0;
86 }
87 fAllowedBitmapChecksums.push_back() = digest;
88 } 132 }
89 133
90 Expectations::Expectations(Json::Value jsonElement) { 134 Expectations::Expectations(Json::Value jsonElement) {
91 if (jsonElement.empty()) { 135 if (jsonElement.empty()) {
92 fIgnoreFailure = kDefaultIgnoreFailure; 136 fIgnoreFailure = kDefaultIgnoreFailure;
93 } else { 137 } else {
94 Json::Value ignoreFailure = jsonElement[kJsonKey_ExpectedResults_Ign oreFailure]; 138 Json::Value ignoreFailure = jsonElement[kJsonKey_ExpectedResults_Ign oreFailure];
95 if (ignoreFailure.isNull()) { 139 if (ignoreFailure.isNull()) {
96 fIgnoreFailure = kDefaultIgnoreFailure; 140 fIgnoreFailure = kDefaultIgnoreFailure;
97 } else if (!ignoreFailure.isBool()) { 141 } else if (!ignoreFailure.isBool()) {
98 gm_fprintf(stderr, "found non-boolean json value" 142 gm_fprintf(stderr, "found non-boolean json value"
99 " for key '%s' in element '%s'\n", 143 " for key '%s' in element '%s'\n",
100 kJsonKey_ExpectedResults_IgnoreFailure, 144 kJsonKey_ExpectedResults_IgnoreFailure,
101 jsonElement.toStyledString().c_str()); 145 jsonElement.toStyledString().c_str());
102 DEBUGFAIL_SEE_STDERR; 146 DEBUGFAIL_SEE_STDERR;
103 fIgnoreFailure = kDefaultIgnoreFailure; 147 fIgnoreFailure = kDefaultIgnoreFailure;
104 } else { 148 } else {
105 fIgnoreFailure = ignoreFailure.asBool(); 149 fIgnoreFailure = ignoreFailure.asBool();
106 } 150 }
107 151
108 Json::Value allowedChecksums = 152 Json::Value allowedDigests = jsonElement[kJsonKey_ExpectedResults_Al lowedDigests];
109 jsonElement[kJsonKey_ExpectedResults_AllowedBitmapHashes]; 153 if (allowedDigests.isNull()) {
110 if (allowedChecksums.isNull()) { 154 // ok, we'll just assume there aren't any AllowedDigests to comp are against
111 // ok, we'll just assume there aren't any expected checksums to compare against 155 } else if (!allowedDigests.isArray()) {
112 } else if (!allowedChecksums.isArray()) {
113 gm_fprintf(stderr, "found non-array json value" 156 gm_fprintf(stderr, "found non-array json value"
114 " for key '%s' in element '%s'\n", 157 " for key '%s' in element '%s'\n",
115 kJsonKey_ExpectedResults_AllowedBitmapHashes, 158 kJsonKey_ExpectedResults_AllowedDigests,
116 jsonElement.toStyledString().c_str()); 159 jsonElement.toStyledString().c_str());
117 DEBUGFAIL_SEE_STDERR; 160 DEBUGFAIL_SEE_STDERR;
118 } else { 161 } else {
119 for (Json::ArrayIndex i=0; i<allowedChecksums.size(); i++) { 162 for (Json::ArrayIndex i=0; i<allowedDigests.size(); i++) {
120 Json::Value checksumElement = allowedChecksums[i]; 163 fAllowedResultDigests.push_back(GmResultDigest(allowedDigest s[i]));
121 if (!checksumElement.isIntegral()) {
122 gm_fprintf(stderr, "found non-integer checksum"
123 " in json element '%s'\n",
124 jsonElement.toStyledString().c_str());
125 DEBUGFAIL_SEE_STDERR;
126 } else {
127 fAllowedBitmapChecksums.push_back() = asChecksum(checksu mElement);
128 }
129 } 164 }
130 } 165 }
131 } 166 }
132 } 167 }
133 168
134 bool Expectations::match(Checksum actualChecksum) const { 169 bool Expectations::match(GmResultDigest actualGmResultDigest) const {
135 for (int i=0; i < this->fAllowedBitmapChecksums.count(); i++) { 170 for (int i=0; i < this->fAllowedResultDigests.count(); i++) {
136 Checksum allowedChecksum = this->fAllowedBitmapChecksums[i]; 171 GmResultDigest allowedResultDigest = this->fAllowedResultDigests[i];
137 if (allowedChecksum == actualChecksum) { 172 if (allowedResultDigest.equals(actualGmResultDigest)) {
138 return true; 173 return true;
139 } 174 }
140 } 175 }
141 return false; 176 return false;
142 } 177 }
143 178
144 Json::Value Expectations::asJsonValue() const { 179 Json::Value Expectations::asJsonValue() const {
145 Json::Value allowedChecksumArray; 180 Json::Value allowedDigestArray;
146 if (!this->fAllowedBitmapChecksums.empty()) { 181 if (!this->fAllowedResultDigests.empty()) {
147 for (int i=0; i < this->fAllowedBitmapChecksums.count(); i++) { 182 for (int i=0; i < this->fAllowedResultDigests.count(); i++) {
148 Checksum allowedChecksum = this->fAllowedBitmapChecksums[i]; 183 allowedDigestArray.append(this->fAllowedResultDigests[i].asJsonT ypeValuePair());
149 allowedChecksumArray.append(Json::UInt64(allowedChecksum));
150 } 184 }
151 } 185 }
152 186
153 Json::Value jsonValue; 187 Json::Value jsonExpectations;
154 jsonValue[kJsonKey_ExpectedResults_AllowedBitmapHashes] = allowedChecksu mArray; 188 jsonExpectations[kJsonKey_ExpectedResults_AllowedDigests] = allowedDiges tArray;
155 jsonValue[kJsonKey_ExpectedResults_IgnoreFailure] = this->ignoreFailure( ); 189 jsonExpectations[kJsonKey_ExpectedResults_IgnoreFailure] = this->ignore Failure();
156 return jsonValue; 190 return jsonExpectations;
157 } 191 }
158 192
159 193
160 // IndividualImageExpectationsSource class... 194 // IndividualImageExpectationsSource class...
161 195
162 Expectations IndividualImageExpectationsSource::get(const char *testName) { 196 Expectations IndividualImageExpectationsSource::get(const char *testName) {
163 SkString path = SkPathJoin(fRootDir.c_str(), testName); 197 SkString path = SkPathJoin(fRootDir.c_str(), testName);
164 SkBitmap referenceBitmap; 198 SkBitmap referenceBitmap;
165 bool decodedReferenceBitmap = 199 bool decodedReferenceBitmap =
166 SkImageDecoder::DecodeFile(path.c_str(), &referenceBitmap, 200 SkImageDecoder::DecodeFile(path.c_str(), &referenceBitmap,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 Json::Reader reader; 258 Json::Reader reader;
225 if (!reader.parse(bytes, bytes+size, *jsonRoot)) { 259 if (!reader.parse(bytes, bytes+size, *jsonRoot)) {
226 gm_fprintf(stderr, "error parsing JSON file %s\n", jsonPath); 260 gm_fprintf(stderr, "error parsing JSON file %s\n", jsonPath);
227 DEBUGFAIL_SEE_STDERR; 261 DEBUGFAIL_SEE_STDERR;
228 return false; 262 return false;
229 } 263 }
230 return true; 264 return true;
231 } 265 }
232 266
233 } 267 }
OLDNEW
« no previous file with comments | « gm/gm_expectations.h ('k') | gm/gmmain.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698