| 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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 dm_bht_set_read_cb(bht_.get(), dm_bht_zeroread_callback); | 111 dm_bht_set_read_cb(bht_.get(), dm_bht_zeroread_callback); |
| 112 EXPECT_EQ(0, dm_bht_compute(bht_.get(), NULL)); | 112 EXPECT_EQ(0, dm_bht_compute(bht_.get(), NULL)); |
| 113 EXPECT_EQ(0, dm_bht_sync(bht_.get(), reinterpret_cast<void *>(this))); | 113 EXPECT_EQ(0, dm_bht_sync(bht_.get(), reinterpret_cast<void *>(this))); |
| 114 u8 digest[1024]; | 114 u8 digest[1024]; |
| 115 dm_bht_root_hexdigest(bht_.get(), digest, sizeof(digest)); | 115 dm_bht_root_hexdigest(bht_.get(), digest, sizeof(digest)); |
| 116 LOG(INFO) << "MemoryBhtTest root is " << digest; | 116 LOG(INFO) << "MemoryBhtTest root is " << digest; |
| 117 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); | 117 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); |
| 118 // bht is now dead and mbht_ is a prepared hash image | 118 // bht is now dead and mbht_ is a prepared hash image |
| 119 | 119 |
| 120 NewBht(depth, total_blocks, digest_algorithm); | 120 NewBht(depth, total_blocks, digest_algorithm); |
| 121 |
| 122 // Load the tree from the pre-populated hash data |
| 123 for (blocks = 0; blocks < total_blocks; blocks += bht_->node_count) { |
| 124 EXPECT_GE(dm_bht_populate(bht_.get(), |
| 125 reinterpret_cast<void *>(this), |
| 126 blocks), |
| 127 DM_BHT_ENTRY_REQUESTED); |
| 128 // Since we're testing synchronously, a second run through should yield |
| 129 // READY. |
| 130 EXPECT_GE(dm_bht_populate(bht_.get(), |
| 131 reinterpret_cast<void *>(this), |
| 132 blocks), |
| 133 DM_BHT_ENTRY_READY); |
| 134 } |
| 121 } | 135 } |
| 122 | 136 |
| 123 scoped_ptr<struct dm_bht> bht_; | 137 scoped_ptr<struct dm_bht> bht_; |
| 124 scoped_array<u8> hash_data_; | 138 scoped_array<u8> hash_data_; |
| 125 sector_t sectors_; | 139 sector_t sectors_; |
| 126 }; | 140 }; |
| 127 | 141 |
| 128 TEST_F(MemoryBhtTest, CreateThenVerifyOk) { | 142 TEST_F(MemoryBhtTest, CreateThenVerifyOk) { |
| 129 static const unsigned int total_blocks = 16384; | 143 static const unsigned int total_blocks = 16384; |
| 130 SetupBht(2, total_blocks, "sha256"); | |
| 131 // Set the root hash for a 0-filled image | 144 // Set the root hash for a 0-filled image |
| 132 static const char kRootDigest[] = | 145 static const char kRootDigest[] = |
| 133 "45d65d6f9e5a962f4d80b5f1bd7a918152251c27bdad8c5f52b590c129833372"; | 146 "45d65d6f9e5a962f4d80b5f1bd7a918152251c27bdad8c5f52b590c129833372"; |
| 134 dm_bht_set_root_hexdigest(bht_.get(), | |
| 135 reinterpret_cast<const u8 *>(kRootDigest)); | |
| 136 | |
| 137 // This should match what dm_bht_store_block computed earlier. | 147 // This should match what dm_bht_store_block computed earlier. |
| 138 static const char kZeroDigest[] = | 148 static const char kZeroDigest[] = |
| 139 "ad7facb2586fc6e966c004d7d1d16b024f5805ff7cb47c7a85dabd8b48892ca7"; | 149 "ad7facb2586fc6e966c004d7d1d16b024f5805ff7cb47c7a85dabd8b48892ca7"; |
| 140 u8 digest[(sizeof(kZeroDigest) - 1) >> 1]; | 150 u8 digest[(sizeof(kZeroDigest) - 1) >> 1]; |
| 141 // TODO(wad) write a test for hex_to_bin and bin_to_hex | 151 // TODO(wad) write a test for hex_to_bin and bin_to_hex |
| 142 unsigned int digest_size = strlen(kZeroDigest) >> 1; | 152 unsigned int digest_size = strlen(kZeroDigest) >> 1; |
| 153 |
| 143 dm_bht_hex_to_bin(digest, | 154 dm_bht_hex_to_bin(digest, |
| 144 reinterpret_cast<const u8 *>(kZeroDigest), | 155 reinterpret_cast<const u8 *>(kZeroDigest), |
| 145 digest_size); | 156 digest_size); |
| 146 | 157 |
| 147 // Load the tree from the pre-populated hash data | 158 SetupBht(2, total_blocks, "sha256"); |
| 159 dm_bht_set_root_hexdigest(bht_.get(), |
| 160 reinterpret_cast<const u8 *>(kRootDigest)); |
| 161 |
| 148 for (unsigned int blocks = 0; blocks < total_blocks; ++blocks) { | 162 for (unsigned int blocks = 0; blocks < total_blocks; ++blocks) { |
| 149 if ((blocks % bht_->node_count) == 0) { | |
| 150 EXPECT_GE(dm_bht_populate(bht_.get(), | |
| 151 reinterpret_cast<void *>(this), | |
| 152 blocks), | |
| 153 DM_BHT_ENTRY_REQUESTED); | |
| 154 // Since we're testing synchronously, a second run through should yield | |
| 155 // READY. | |
| 156 EXPECT_GE(dm_bht_populate(bht_.get(), | |
| 157 reinterpret_cast<void *>(this), | |
| 158 blocks), | |
| 159 DM_BHT_ENTRY_READY); | |
| 160 } | |
| 161 LOG(INFO) << "verifying block: " << blocks; | 163 LOG(INFO) << "verifying block: " << blocks; |
| 162 EXPECT_EQ(0, dm_bht_verify_block(bht_.get(), blocks, digest, digest_size)); | 164 EXPECT_EQ(0, dm_bht_verify_block(bht_.get(), blocks, digest, digest_size)); |
| 163 } | 165 } |
| 164 | 166 |
| 165 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); | 167 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); |
| 166 } | 168 } |
| 167 | 169 |
| 168 TEST_F(MemoryBhtTest, CreateThenVerifyMultipleLevels) { | 170 TEST_F(MemoryBhtTest, CreateThenVerifyMultipleLevels) { |
| 169 static const unsigned int total_blocks = 16384; | 171 static const unsigned int total_blocks = 16384; |
| 170 SetupBht(4, total_blocks, "sha256"); | |
| 171 // Set the root hash for a 0-filled image | 172 // Set the root hash for a 0-filled image |
| 172 static const char kRootDigest[] = | 173 static const char kRootDigest[] = |
| 173 "c86619624d3456f711dbb94d4ad79a4b029f6fd3b5a4a90b155c856bf5b3409b"; | 174 "c86619624d3456f711dbb94d4ad79a4b029f6fd3b5a4a90b155c856bf5b3409b"; |
| 174 dm_bht_set_root_hexdigest(bht_.get(), | |
| 175 reinterpret_cast<const u8 *>(kRootDigest)); | |
| 176 | |
| 177 // This should match what dm_bht_store_block computed earlier. | 175 // This should match what dm_bht_store_block computed earlier. |
| 178 static const char kZeroDigest[] = | 176 static const char kZeroDigest[] = |
| 179 "ad7facb2586fc6e966c004d7d1d16b024f5805ff7cb47c7a85dabd8b48892ca7"; | 177 "ad7facb2586fc6e966c004d7d1d16b024f5805ff7cb47c7a85dabd8b48892ca7"; |
| 180 u8 digest[(sizeof(kZeroDigest) - 1) >> 1]; | 178 u8 digest[(sizeof(kZeroDigest) - 1) >> 1]; |
| 181 // TODO(wad) write a test for hex_to_bin and bin_to_hex | 179 // TODO(wad) write a test for hex_to_bin and bin_to_hex |
| 182 unsigned int digest_size = strlen(kZeroDigest) >> 1; | 180 unsigned int digest_size = strlen(kZeroDigest) >> 1; |
| 181 |
| 183 dm_bht_hex_to_bin(digest, | 182 dm_bht_hex_to_bin(digest, |
| 184 reinterpret_cast<const u8 *>(kZeroDigest), | 183 reinterpret_cast<const u8 *>(kZeroDigest), |
| 185 digest_size); | 184 digest_size); |
| 186 | 185 |
| 187 // Load the tree from the pre-populated hash data | 186 SetupBht(4, total_blocks, "sha256"); |
| 188 for (unsigned int blocks = 0; blocks < total_blocks; blocks++) { | 187 dm_bht_set_root_hexdigest(bht_.get(), |
| 189 if ((blocks % bht_->node_count) == 0) { | 188 reinterpret_cast<const u8 *>(kRootDigest)); |
| 190 EXPECT_GE(dm_bht_populate(bht_.get(), | 189 |
| 191 reinterpret_cast<void *>(this), | 190 for (unsigned int blocks = 0; blocks < total_blocks; ++blocks) { |
| 192 blocks), | |
| 193 DM_BHT_ENTRY_REQUESTED); | |
| 194 // Since we're testing synchronously, a second run through should yield | |
| 195 // READY. | |
| 196 EXPECT_GE(dm_bht_populate(bht_.get(), | |
| 197 reinterpret_cast<void *>(this), | |
| 198 blocks), | |
| 199 DM_BHT_ENTRY_READY); | |
| 200 } | |
| 201 LOG(INFO) << "verifying block: " << blocks; | 191 LOG(INFO) << "verifying block: " << blocks; |
| 202 EXPECT_EQ(0, dm_bht_verify_block(bht_.get(), blocks, digest, digest_size)); | 192 EXPECT_EQ(0, dm_bht_verify_block(bht_.get(), blocks, digest, digest_size)); |
| 203 } | 193 } |
| 204 | 194 |
| 205 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); | 195 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); |
| 206 } | 196 } |
| 207 | 197 |
| 208 TEST_F(MemoryBhtTest, CreateThenVerifyBad) { | 198 TEST_F(MemoryBhtTest, CreateThenVerifyBad) { |
| 209 static const unsigned int total_blocks = 16384; | 199 static const unsigned int total_blocks = 16384; |
| 210 SetupBht(2, total_blocks, "sha256"); | 200 SetupBht(2, total_blocks, "sha256"); |
| 211 // Set the root hash for a 0-filled image | 201 // Set the root hash for a 0-filled image |
| 212 static const char kRootDigest[] = | 202 static const char kRootDigest[] = |
| 213 "45d65d6f9e5a962f4d80b5f1bd7a918152251c27bdad8c5f52b590c129833372"; | 203 "45d65d6f9e5a962f4d80b5f1bd7a918152251c27bdad8c5f52b590c129833372"; |
| 214 dm_bht_set_root_hexdigest(bht_.get(), | 204 dm_bht_set_root_hexdigest(bht_.get(), |
| 215 reinterpret_cast<const u8 *>(kRootDigest)); | 205 reinterpret_cast<const u8 *>(kRootDigest)); |
| 216 | 206 |
| 217 // Load the tree from the pre-populated hash data | |
| 218 for (unsigned int blocks = 0; blocks < total_blocks; blocks++) { | |
| 219 if ((blocks % bht_->node_count) == 0) { | |
| 220 EXPECT_GE(dm_bht_populate(bht_.get(), | |
| 221 reinterpret_cast<void *>(this), | |
| 222 blocks), | |
| 223 DM_BHT_ENTRY_REQUESTED); | |
| 224 // Since we're testing synchronously, a second run through should yield | |
| 225 // READY. | |
| 226 EXPECT_GE(dm_bht_populate(bht_.get(), | |
| 227 reinterpret_cast<void *>(this), | |
| 228 blocks), | |
| 229 DM_BHT_ENTRY_READY); | |
| 230 } | |
| 231 } | |
| 232 // TODO(wad) add tests for partial tree validity/verification | 207 // TODO(wad) add tests for partial tree validity/verification |
| 233 | 208 |
| 234 // Corrupt one block value | 209 // Corrupt one block value |
| 235 static const unsigned int kBadBlock = 256; | 210 static const unsigned int kBadBlock = 256; |
| 236 u8 data[PAGE_SIZE]; | 211 u8 data[PAGE_SIZE]; |
| 237 memset(reinterpret_cast<void *>(data), 'A', sizeof(data)); | 212 memset(reinterpret_cast<void *>(data), 'A', sizeof(data)); |
| 238 EXPECT_EQ(dm_bht_store_block(bht_.get(), kBadBlock, data), 0); | 213 EXPECT_EQ(dm_bht_store_block(bht_.get(), kBadBlock, data), 0); |
| 239 | 214 |
| 240 // This should match what dm_bht_store_block computed earlier. | 215 // This should match what dm_bht_store_block computed earlier. |
| 241 static const char kZeroDigest[] = | 216 static const char kZeroDigest[] = |
| (...skipping 22 matching lines...) Expand all Loading... |
| 264 EXPECT_EQ(dm_bht_verify_block(bht_.get(), kBadBlock - 1, digest, digest_size), | 239 EXPECT_EQ(dm_bht_verify_block(bht_.get(), kBadBlock - 1, digest, digest_size), |
| 265 0); | 240 0); |
| 266 | 241 |
| 267 // Same for the next entry | 242 // Same for the next entry |
| 268 EXPECT_EQ(dm_bht_verify_block(bht_.get(), kBadBlock + bht_->node_count, | 243 EXPECT_EQ(dm_bht_verify_block(bht_.get(), kBadBlock + bht_->node_count, |
| 269 digest, digest_size), | 244 digest, digest_size), |
| 270 0); | 245 0); |
| 271 | 246 |
| 272 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); | 247 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); |
| 273 } | 248 } |
| OLD | NEW |