OLD | NEW |
---|---|
1 // Copyright (C) 2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (C) 2010 The Chromium OS Authors. All rights reserved. |
2 // Use of this source code is governed by the GPL v2 license that can | 2 // Use of this source code is governed by the GPL v2 license that can |
3 // be found in the LICENSE file. | 3 // be found in the LICENSE file. |
4 // | 4 // |
5 // Basic unittesting of dm-bht using google-gtest. | 5 // Basic unittesting of dm-bht using google-gtest. |
6 | 6 |
7 #include <base/basictypes.h> | 7 #include <base/basictypes.h> |
8 #include <base/logging.h> | 8 #include <base/logging.h> |
9 #include <base/scoped_ptr.h> | 9 #include <base/scoped_ptr.h> |
10 #include <gtest/gtest.h> | 10 #include <gtest/gtest.h> |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
100 hash_data_.reset(new u8[to_bytes(sectors_)]); | 100 hash_data_.reset(new u8[to_bytes(sectors_)]); |
101 } | 101 } |
102 dm_bht_set_write_cb(bht_.get(), MemoryBhtTest::WriteCallback); | 102 dm_bht_set_write_cb(bht_.get(), MemoryBhtTest::WriteCallback); |
103 dm_bht_set_read_cb(bht_.get(), MemoryBhtTest::ReadCallback); | 103 dm_bht_set_read_cb(bht_.get(), MemoryBhtTest::ReadCallback); |
104 } | 104 } |
105 void SetupBht(const unsigned int depth, | 105 void SetupBht(const unsigned int depth, |
106 const unsigned int total_blocks, | 106 const unsigned int total_blocks, |
107 const char *digest_algorithm) { | 107 const char *digest_algorithm) { |
108 NewBht(depth, total_blocks, digest_algorithm); | 108 NewBht(depth, total_blocks, digest_algorithm); |
109 | 109 |
110 u8 data[PAGE_SIZE]; | 110 u8 data[PAGE_SIZE] = { 0 }; |
111 // Store all the block hashes of blocks of 0. | |
112 memset(reinterpret_cast<void *>(data), 0, sizeof(data)); | |
113 unsigned int blocks = total_blocks; | 111 unsigned int blocks = total_blocks; |
114 do { | 112 do { |
115 EXPECT_EQ(dm_bht_store_block(bht_.get(), blocks - 1, data), 0); | 113 EXPECT_EQ(dm_bht_store_block(bht_.get(), blocks - 1, data), 0); |
116 } while (--blocks > 0); | 114 } while (--blocks > 0); |
117 | 115 |
118 dm_bht_set_read_cb(bht_.get(), dm_bht_zeroread_callback); | 116 dm_bht_set_read_cb(bht_.get(), dm_bht_zeroread_callback); |
119 EXPECT_EQ(0, dm_bht_compute(bht_.get(), NULL)); | 117 EXPECT_EQ(0, dm_bht_compute(bht_.get(), NULL)); |
120 EXPECT_EQ(0, dm_bht_sync(bht_.get(), reinterpret_cast<void *>(this))); | 118 EXPECT_EQ(0, dm_bht_sync(bht_.get(), reinterpret_cast<void *>(this))); |
121 u8 digest[1024]; | 119 u8 digest[1024]; |
122 dm_bht_root_hexdigest(bht_.get(), digest, sizeof(digest)); | 120 dm_bht_root_hexdigest(bht_.get(), digest, sizeof(digest)); |
(...skipping 21 matching lines...) Expand all Loading... | |
144 scoped_ptr<struct dm_bht> bht_; | 142 scoped_ptr<struct dm_bht> bht_; |
145 scoped_array<u8> hash_data_; | 143 scoped_array<u8> hash_data_; |
146 sector_t sectors_; | 144 sector_t sectors_; |
147 }; | 145 }; |
148 | 146 |
149 TEST_F(MemoryBhtTest, CreateThenVerifyOk) { | 147 TEST_F(MemoryBhtTest, CreateThenVerifyOk) { |
150 static const unsigned int total_blocks = 16384; | 148 static const unsigned int total_blocks = 16384; |
151 // Set the root hash for a 0-filled image | 149 // Set the root hash for a 0-filled image |
152 static const char kRootDigest[] = | 150 static const char kRootDigest[] = |
153 "45d65d6f9e5a962f4d80b5f1bd7a918152251c27bdad8c5f52b590c129833372"; | 151 "45d65d6f9e5a962f4d80b5f1bd7a918152251c27bdad8c5f52b590c129833372"; |
154 // This should match what dm_bht_store_block computed earlier. | 152 // A page of all zeros |
155 static const char kZeroDigest[] = | 153 static const char kZeroPage[PAGE_SIZE] = { 0 }; |
156 "ad7facb2586fc6e966c004d7d1d16b024f5805ff7cb47c7a85dabd8b48892ca7"; | |
157 u8 digest[(sizeof(kZeroDigest) - 1) >> 1]; | |
158 // TODO(wad) write a test for hex_to_bin and bin_to_hex | |
159 unsigned int digest_size = strlen(kZeroDigest) >> 1; | |
160 | |
161 dm_bht_hex_to_bin(digest, | |
162 reinterpret_cast<const u8 *>(kZeroDigest), | |
163 digest_size); | |
164 | 154 |
165 SetupBht(2, total_blocks, "sha256"); | 155 SetupBht(2, total_blocks, "sha256"); |
166 dm_bht_set_root_hexdigest(bht_.get(), | 156 dm_bht_set_root_hexdigest(bht_.get(), |
167 reinterpret_cast<const u8 *>(kRootDigest)); | 157 reinterpret_cast<const u8 *>(kRootDigest)); |
168 | 158 |
169 for (unsigned int blocks = 0; blocks < total_blocks; ++blocks) { | 159 for (unsigned int blocks = 0; blocks < total_blocks; ++blocks) { |
170 DLOG(INFO) << "verifying block: " << blocks; | 160 DLOG(INFO) << "verifying block: " << blocks; |
171 EXPECT_EQ(0, dm_bht_verify_block(bht_.get(), blocks, digest, digest_size)); | 161 EXPECT_EQ(0, dm_bht_verify_block(bht_.get(), blocks, kZeroPage)); |
172 } | 162 } |
173 | 163 |
174 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); | 164 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); |
175 } | 165 } |
176 | 166 |
177 TEST_F(MemoryBhtTest, CreateThenVerifyMultipleLevels) { | 167 TEST_F(MemoryBhtTest, CreateThenVerifyMultipleLevels) { |
178 static const unsigned int total_blocks = 16384; | 168 static const unsigned int total_blocks = 16384; |
179 // Set the root hash for a 0-filled image | 169 // Set the root hash for a 0-filled image |
180 static const char kRootDigest[] = | 170 static const char kRootDigest[] = |
181 "c86619624d3456f711dbb94d4ad79a4b029f6fd3b5a4a90b155c856bf5b3409b"; | 171 "c86619624d3456f711dbb94d4ad79a4b029f6fd3b5a4a90b155c856bf5b3409b"; |
182 // This should match what dm_bht_store_block computed earlier. | 172 // A page of all zeros |
183 static const char kZeroDigest[] = | 173 static const char kZeroPage[PAGE_SIZE] = { 0 }; |
184 "ad7facb2586fc6e966c004d7d1d16b024f5805ff7cb47c7a85dabd8b48892ca7"; | |
185 u8 digest[(sizeof(kZeroDigest) - 1) >> 1]; | |
186 // TODO(wad) write a test for hex_to_bin and bin_to_hex | |
187 unsigned int digest_size = strlen(kZeroDigest) >> 1; | |
188 | |
189 dm_bht_hex_to_bin(digest, | |
190 reinterpret_cast<const u8 *>(kZeroDigest), | |
191 digest_size); | |
192 | 174 |
193 SetupBht(4, total_blocks, "sha256"); | 175 SetupBht(4, total_blocks, "sha256"); |
194 dm_bht_set_root_hexdigest(bht_.get(), | 176 dm_bht_set_root_hexdigest(bht_.get(), |
195 reinterpret_cast<const u8 *>(kRootDigest)); | 177 reinterpret_cast<const u8 *>(kRootDigest)); |
196 | 178 |
197 for (unsigned int blocks = 0; blocks < total_blocks; ++blocks) { | 179 for (unsigned int blocks = 0; blocks < total_blocks; ++blocks) { |
198 DLOG(INFO) << "verifying block: " << blocks; | 180 DLOG(INFO) << "verifying block: " << blocks; |
199 EXPECT_EQ(0, dm_bht_verify_block(bht_.get(), blocks, digest, digest_size)); | 181 EXPECT_EQ(0, dm_bht_verify_block(bht_.get(), blocks, kZeroPage)); |
200 } | 182 } |
201 | 183 |
202 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); | 184 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); |
203 } | 185 } |
204 | 186 |
205 TEST_F(MemoryBhtTest, CreateThenVerifyOddCount) { | 187 TEST_F(MemoryBhtTest, CreateThenVerifyOddCount) { |
206 static const unsigned int total_blocks = 16383; | 188 static const unsigned int total_blocks = 16383; |
207 // Set the root hash for a 0-filled image | 189 // Set the root hash for a 0-filled image |
208 static const char kRootDigest[] = | 190 static const char kRootDigest[] = |
209 "c78d187c430465bd7831fe4908247b6ab5107e3a826d933b71e85aa9a932e03c"; | 191 "c78d187c430465bd7831fe4908247b6ab5107e3a826d933b71e85aa9a932e03c"; |
210 // This should match what dm_bht_store_block computed earlier. | 192 // A page of all zeros |
211 static const char kZeroDigest[] = | 193 static const char kZeroPage[PAGE_SIZE] = { 0 }; |
212 "ad7facb2586fc6e966c004d7d1d16b024f5805ff7cb47c7a85dabd8b48892ca7"; | |
213 u8 digest[(sizeof(kZeroDigest) - 1) >> 1]; | |
214 // TODO(wad) write a test for hex_to_bin and bin_to_hex | |
215 unsigned int digest_size = strlen(kZeroDigest) >> 1; | |
216 | |
217 dm_bht_hex_to_bin(digest, | |
218 reinterpret_cast<const u8 *>(kZeroDigest), | |
219 digest_size); | |
220 | 194 |
221 SetupBht(4, total_blocks, "sha256"); | 195 SetupBht(4, total_blocks, "sha256"); |
222 dm_bht_set_root_hexdigest(bht_.get(), | 196 dm_bht_set_root_hexdigest(bht_.get(), |
223 reinterpret_cast<const u8 *>(kRootDigest)); | 197 reinterpret_cast<const u8 *>(kRootDigest)); |
224 | 198 |
225 for (unsigned int blocks = 0; blocks < total_blocks; ++blocks) { | 199 for (unsigned int blocks = 0; blocks < total_blocks; ++blocks) { |
226 DLOG(INFO) << "verifying block: " << blocks; | 200 DLOG(INFO) << "verifying block: " << blocks; |
227 EXPECT_EQ(0, dm_bht_verify_block(bht_.get(), blocks, digest, digest_size)); | 201 EXPECT_EQ(0, dm_bht_verify_block(bht_.get(), blocks, kZeroPage)); |
228 } | 202 } |
229 | 203 |
230 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); | 204 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); |
231 } | 205 } |
232 | 206 |
233 TEST_F(MemoryBhtTest, CreateThenVerifyBad) { | 207 TEST_F(MemoryBhtTest, CreateThenVerifyBad) { |
234 static const unsigned int total_blocks = 16384; | 208 static const unsigned int total_blocks = 384; |
235 SetupBht(2, total_blocks, "sha256"); | 209 SetupBht(2, total_blocks, "sha256"); |
236 // Set the root hash for a 0-filled image | 210 // Set the root hash for a 0-filled image |
237 static const char kRootDigest[] = | 211 static const char kRootDigest[] = |
238 "45d65d6f9e5a962f4d80b5f1bd7a918152251c27bdad8c5f52b590c129833372"; | 212 "45d65d6f9e5a962f4d80b5f1bd7a918152251c27bdad8c5f52b590c129833372"; |
239 dm_bht_set_root_hexdigest(bht_.get(), | 213 dm_bht_set_root_hexdigest(bht_.get(), |
240 reinterpret_cast<const u8 *>(kRootDigest)); | 214 reinterpret_cast<const u8 *>(kRootDigest)); |
215 // A corrupt page | |
216 static const u8 kBadPage[PAGE_SIZE] = { 'A' }; | |
241 | 217 |
242 // TODO(wad) add tests for partial tree validity/verification | 218 EXPECT_LT(dm_bht_verify_block(bht_.get(), 0, kBadPage), 0); |
243 | 219 EXPECT_LT(dm_bht_verify_block(bht_.get(), 127, kBadPage), 0); |
244 // Corrupt one block value | 220 EXPECT_LT(dm_bht_verify_block(bht_.get(), 128, kBadPage), 0); |
245 static const unsigned int kBadBlock = 256; | 221 EXPECT_LT(dm_bht_verify_block(bht_.get(), 255, kBadPage), 0); |
246 u8 data[PAGE_SIZE]; | 222 EXPECT_LT(dm_bht_verify_block(bht_.get(), 256, kBadPage), 0); |
Will Drewry
2011/03/16 16:53:37
This test no longer matches the initial test funct
| |
247 memset(reinterpret_cast<void *>(data), 'A', sizeof(data)); | 223 EXPECT_LT(dm_bht_verify_block(bht_.get(), 383, kBadPage), 0); |
248 EXPECT_EQ(dm_bht_store_block(bht_.get(), kBadBlock, data), 0); | |
249 | |
250 // This should match what dm_bht_store_block computed earlier. | |
251 static const char kZeroDigest[] = | |
252 "ad7facb2586fc6e966c004d7d1d16b024f5805ff7cb47c7a85dabd8b48892ca7"; | |
253 u8 digest[(sizeof(kZeroDigest) - 1) >> 1]; | |
254 // TODO(wad) write a test for hex_to_bin and bin_to_hex | |
255 unsigned int digest_size = strlen(kZeroDigest) >> 1; | |
256 dm_bht_hex_to_bin(digest, | |
257 reinterpret_cast<const u8 *>(kZeroDigest), | |
258 digest_size); | |
259 | |
260 // Attempt to verify both the bad block and all the neighbors. | |
261 EXPECT_LT(dm_bht_verify_block(bht_.get(), kBadBlock + 1, digest, digest_size), | |
262 0); | |
263 | |
264 EXPECT_LT(dm_bht_verify_block(bht_.get(), kBadBlock + 2, digest, digest_size), | |
265 0); | |
266 | |
267 EXPECT_LT(dm_bht_verify_block(bht_.get(), kBadBlock + (bht_->node_count / 2), | |
268 digest, digest_size), | |
269 0); | |
270 | |
271 EXPECT_LT(dm_bht_verify_block(bht_.get(), kBadBlock, digest, digest_size), 0); | |
272 | |
273 // Verify that the prior entry is untouched and still safe | |
274 EXPECT_EQ(dm_bht_verify_block(bht_.get(), kBadBlock - 1, digest, digest_size), | |
275 0); | |
276 | |
277 // Same for the next entry | |
278 EXPECT_EQ(dm_bht_verify_block(bht_.get(), kBadBlock + bht_->node_count, | |
279 digest, digest_size), | |
280 0); | |
281 | 224 |
282 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); | 225 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); |
283 } | 226 } |
OLD | NEW |