OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 #include "Test.h" | 8 #include "Test.h" |
9 | 9 |
10 #include "SkChecksum.h" | 10 #include "SkChecksum.h" |
11 | 11 |
12 // Word size that is large enough to hold results of any checksum type. | 12 // Word size that is large enough to hold results of any checksum type. |
13 typedef uint64_t checksum_result; | 13 typedef uint64_t checksum_result; |
14 | 14 |
15 namespace skiatest { | 15 namespace skiatest { |
16 class ChecksumTestClass : public Test { | 16 class ChecksumTestClass : public Test { |
17 public: | 17 public: |
18 static Test* Factory(void*) {return SkNEW(ChecksumTestClass); } | 18 static Test* Factory(void*) {return SkNEW(ChecksumTestClass); } |
19 protected: | 19 protected: |
20 virtual void onGetName(SkString* name) { name->set("Checksum"); } | 20 virtual void onGetName(SkString* name) { name->set("Checksum"); } |
21 virtual void onRun(Reporter* reporter) { | 21 virtual void onRun(Reporter* reporter) { |
22 this->fReporter = reporter; | 22 this->fReporter = reporter; |
23 RunTest(); | 23 RunTest(); |
24 } | 24 } |
25 private: | 25 private: |
26 enum Algorithm { | 26 enum Algorithm { |
27 kSkChecksum | 27 kSkChecksum, |
| 28 kMurmur3, |
28 }; | 29 }; |
29 | 30 |
30 // Call Compute(data, size) on the appropriate checksum algorithm, | 31 // Call Compute(data, size) on the appropriate checksum algorithm, |
31 // depending on this->fWhichAlgorithm. | 32 // depending on this->fWhichAlgorithm. |
32 checksum_result ComputeChecksum(const char *data, size_t size) { | 33 checksum_result ComputeChecksum(const char *data, size_t size) { |
33 switch(fWhichAlgorithm) { | 34 switch(fWhichAlgorithm) { |
34 case kSkChecksum: | 35 case kSkChecksum: |
35 REPORTER_ASSERT_MESSAGE(fReporter, | 36 REPORTER_ASSERT_MESSAGE(fReporter, |
36 reinterpret_cast<uintptr_t>(data) % 4 ==
0, | 37 reinterpret_cast<uintptr_t>(data) % 4 ==
0, |
37 "test data pointer is not 32-bit aligned
"); | 38 "test data pointer is not 32-bit aligned
"); |
38 REPORTER_ASSERT_MESSAGE(fReporter, SkIsAlign4(size), | 39 REPORTER_ASSERT_MESSAGE(fReporter, SkIsAlign4(size), |
39 "test data size is not 32-bit aligned"); | 40 "test data size is not 32-bit aligned"); |
40 return SkChecksum::Compute(reinterpret_cast<const uint32_t *>(da
ta), size); | 41 return SkChecksum::Compute(reinterpret_cast<const uint32_t *>(da
ta), size); |
| 42 case kMurmur3: |
| 43 REPORTER_ASSERT_MESSAGE(fReporter, |
| 44 reinterpret_cast<uintptr_t>(data) % 4 ==
0, |
| 45 "test data pointer is not 32-bit aligned
"); |
| 46 REPORTER_ASSERT_MESSAGE(fReporter, SkIsAlign4(size), |
| 47 "test data size is not 32-bit aligned"); |
| 48 return SkChecksum::Murmur3(reinterpret_cast<const uint32_t *>(da
ta), size); |
41 default: | 49 default: |
42 SkString message("fWhichAlgorithm has unknown value "); | 50 SkString message("fWhichAlgorithm has unknown value "); |
43 message.appendf("%d", fWhichAlgorithm); | 51 message.appendf("%d", fWhichAlgorithm); |
44 fReporter->reportFailed(message); | 52 fReporter->reportFailed(message); |
45 } | 53 } |
46 // we never get here | 54 // we never get here |
47 return 0; | 55 return 0; |
48 } | 56 } |
49 | 57 |
50 // Confirm that the checksum algorithm (specified by fWhichAlgorithm) | 58 // Confirm that the checksum algorithm (specified by fWhichAlgorithm) |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 char* start = reinterpret_cast<char *>(storage.get()); | 99 char* start = reinterpret_cast<char *>(storage.get()); |
92 char* ptr = start; | 100 char* ptr = start; |
93 for (size_t i = 0; i < len; ++i) { | 101 for (size_t i = 0; i < len; ++i) { |
94 *ptr++ = ((seed+i) & 0x7f); | 102 *ptr++ = ((seed+i) & 0x7f); |
95 } | 103 } |
96 checksum_result result = ComputeChecksum(start, len); | 104 checksum_result result = ComputeChecksum(start, len); |
97 return result; | 105 return result; |
98 } | 106 } |
99 | 107 |
100 void RunTest() { | 108 void RunTest() { |
101 // Test self-consistency of checksum algorithms. | 109 const Algorithm algorithms[] = { kSkChecksum, kMurmur3 }; |
102 fWhichAlgorithm = kSkChecksum; | 110 for (size_t i = 0; i < SK_ARRAY_COUNT(algorithms); i++) { |
103 TestChecksumSelfConsistency(128); | 111 fWhichAlgorithm = algorithms[i]; |
104 | 112 |
105 // Test checksum results that should be consistent across | 113 // Test self-consistency of checksum algorithms. |
106 // versions and platforms. | 114 TestChecksumSelfConsistency(128); |
107 fWhichAlgorithm = kSkChecksum; | |
108 REPORTER_ASSERT(fReporter, ComputeChecksum(NULL, 0) == 0); | |
109 | 115 |
110 // TODO: note the weakness exposed by these collisions... | 116 // Test checksum results that should be consistent across |
111 // We need to improve the SkChecksum algorithm. | 117 // versions and platforms. |
112 // We would prefer that these asserts FAIL! | 118 REPORTER_ASSERT(fReporter, ComputeChecksum(NULL, 0) == 0); |
113 // Filed as https://code.google.com/p/skia/issues/detail?id=981 | 119 |
114 // ('SkChecksum algorithm allows for way too many collisions') | 120 const bool colision1 = GetTestDataChecksum(128) == GetTestDataCh
ecksum(256); |
115 fWhichAlgorithm = kSkChecksum; | 121 const bool colision2 = GetTestDataChecksum(132) == GetTestDataCh
ecksum(260); |
116 REPORTER_ASSERT(fReporter, | 122 if (fWhichAlgorithm == kSkChecksum) { |
117 GetTestDataChecksum(128) == GetTestDataChecksum(256)); | 123 // TODO: note the weakness exposed by these collisions... |
118 REPORTER_ASSERT(fReporter, | 124 // We need to improve the SkChecksum algorithm. |
119 GetTestDataChecksum(132) == GetTestDataChecksum(260)); | 125 // We would prefer that these asserts FAIL! |
| 126 // Filed as https://code.google.com/p/skia/issues/detail?id=
981 |
| 127 // ('SkChecksum algorithm allows for way too many collisions
') |
| 128 REPORTER_ASSERT(fReporter, colision1); |
| 129 REPORTER_ASSERT(fReporter, colision2); |
| 130 } else { |
| 131 REPORTER_ASSERT(fReporter, !colision1); |
| 132 REPORTER_ASSERT(fReporter, !colision2); |
| 133 } |
| 134 } |
120 } | 135 } |
121 | 136 |
122 Reporter* fReporter; | 137 Reporter* fReporter; |
123 Algorithm fWhichAlgorithm; | 138 Algorithm fWhichAlgorithm; |
124 }; | 139 }; |
125 | 140 |
126 static TestRegistry gReg(ChecksumTestClass::Factory); | 141 static TestRegistry gReg(ChecksumTestClass::Factory); |
127 } | 142 } |
OLD | NEW |