OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/file_util.h" | 5 #include "base/file_util.h" |
6 #include "net/disk_cache/block_files.h" | 6 #include "net/disk_cache/block_files.h" |
7 #include "net/disk_cache/disk_cache.h" | 7 #include "net/disk_cache/disk_cache.h" |
8 #include "net/disk_cache/disk_cache_test_base.h" | 8 #include "net/disk_cache/disk_cache_test_base.h" |
9 #include "net/disk_cache/disk_cache_test_util.h" | 9 #include "net/disk_cache/disk_cache_test_util.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
(...skipping 15 matching lines...) Expand all Loading... |
26 | 26 |
27 } // namespace; | 27 } // namespace; |
28 | 28 |
29 namespace disk_cache { | 29 namespace disk_cache { |
30 | 30 |
31 TEST_F(DiskCacheTest, BlockFiles_Grow) { | 31 TEST_F(DiskCacheTest, BlockFiles_Grow) { |
32 ASSERT_TRUE(CleanupCacheDir()); | 32 ASSERT_TRUE(CleanupCacheDir()); |
33 ASSERT_TRUE(file_util::CreateDirectory(cache_path_)); | 33 ASSERT_TRUE(file_util::CreateDirectory(cache_path_)); |
34 | 34 |
35 BlockFiles files(cache_path_); | 35 BlockFiles files(cache_path_); |
36 ASSERT_TRUE(files.Init(true)); | 36 ASSERT_TRUE(files.Init(true, kFirstAdditionalBlockFile)); |
37 | 37 |
38 const int kMaxSize = 35000; | 38 const int kMaxSize = 35000; |
39 Addr address[kMaxSize]; | 39 Addr address[kMaxSize]; |
40 | 40 |
41 // Fill up the 32-byte block file (use three files). | 41 // Fill up the 32-byte block file (use three files). |
42 for (int i = 0; i < kMaxSize; i++) { | 42 for (int i = 0; i < kMaxSize; i++) { |
43 EXPECT_TRUE(files.CreateBlock(RANKINGS, 4, &address[i])); | 43 EXPECT_TRUE(files.CreateBlock(RANKINGS, 4, &address[i])); |
44 } | 44 } |
45 EXPECT_EQ(6, NumberOfFiles(cache_path_)); | 45 EXPECT_EQ(6, NumberOfFiles(cache_path_)); |
46 | 46 |
47 // Make sure we don't keep adding files. | 47 // Make sure we don't keep adding files. |
48 for (int i = 0; i < kMaxSize * 4; i += 2) { | 48 for (int i = 0; i < kMaxSize * 4; i += 2) { |
49 int target = i % kMaxSize; | 49 int target = i % kMaxSize; |
50 files.DeleteBlock(address[target], false); | 50 files.DeleteBlock(address[target], false); |
51 EXPECT_TRUE(files.CreateBlock(RANKINGS, 4, &address[target])); | 51 EXPECT_TRUE(files.CreateBlock(RANKINGS, 4, &address[target])); |
52 } | 52 } |
53 EXPECT_EQ(6, NumberOfFiles(cache_path_)); | 53 EXPECT_EQ(6, NumberOfFiles(cache_path_)); |
54 } | 54 } |
55 | 55 |
56 // We should be able to delete empty block files. | 56 // We should be able to delete empty block files. |
57 TEST_F(DiskCacheTest, BlockFiles_Shrink) { | 57 TEST_F(DiskCacheTest, BlockFiles_Shrink) { |
58 ASSERT_TRUE(CleanupCacheDir()); | 58 ASSERT_TRUE(CleanupCacheDir()); |
59 ASSERT_TRUE(file_util::CreateDirectory(cache_path_)); | 59 ASSERT_TRUE(file_util::CreateDirectory(cache_path_)); |
60 | 60 |
61 BlockFiles files(cache_path_); | 61 BlockFiles files(cache_path_); |
62 ASSERT_TRUE(files.Init(true)); | 62 ASSERT_TRUE(files.Init(true, kFirstAdditionalBlockFile)); |
63 | 63 |
64 const int kMaxSize = 35000; | 64 const int kMaxSize = 35000; |
65 Addr address[kMaxSize]; | 65 Addr address[kMaxSize]; |
66 | 66 |
67 // Fill up the 32-byte block file (use three files). | 67 // Fill up the 32-byte block file (use three files). |
68 for (int i = 0; i < kMaxSize; i++) { | 68 for (int i = 0; i < kMaxSize; i++) { |
69 EXPECT_TRUE(files.CreateBlock(RANKINGS, 4, &address[i])); | 69 EXPECT_TRUE(files.CreateBlock(RANKINGS, 4, &address[i])); |
70 } | 70 } |
71 | 71 |
72 // Now delete all the blocks, so that we can delete the two extra files. | 72 // Now delete all the blocks, so that we can delete the two extra files. |
73 for (int i = 0; i < kMaxSize; i++) { | 73 for (int i = 0; i < kMaxSize; i++) { |
74 files.DeleteBlock(address[i], false); | 74 files.DeleteBlock(address[i], false); |
75 } | 75 } |
76 EXPECT_EQ(4, NumberOfFiles(cache_path_)); | 76 EXPECT_EQ(4, NumberOfFiles(cache_path_)); |
77 } | 77 } |
78 | 78 |
79 // Handling of block files not properly closed. | 79 // Handling of block files not properly closed. |
80 TEST_F(DiskCacheTest, BlockFiles_Recover) { | 80 TEST_F(DiskCacheTest, BlockFiles_Recover) { |
81 ASSERT_TRUE(CleanupCacheDir()); | 81 ASSERT_TRUE(CleanupCacheDir()); |
82 ASSERT_TRUE(file_util::CreateDirectory(cache_path_)); | 82 ASSERT_TRUE(file_util::CreateDirectory(cache_path_)); |
83 | 83 |
84 BlockFiles files(cache_path_); | 84 BlockFiles files(cache_path_); |
85 ASSERT_TRUE(files.Init(true)); | 85 ASSERT_TRUE(files.Init(true, kFirstAdditionalBlockFile)); |
86 | 86 |
87 const int kNumEntries = 2000; | 87 const int kNumEntries = 2000; |
88 CacheAddr entries[kNumEntries]; | 88 CacheAddr entries[kNumEntries]; |
89 | 89 |
90 int seed = static_cast<int>(Time::Now().ToInternalValue()); | 90 int seed = static_cast<int>(Time::Now().ToInternalValue()); |
91 srand(seed); | 91 srand(seed); |
92 for (int i = 0; i < kNumEntries; i++) { | 92 for (int i = 0; i < kNumEntries; i++) { |
93 Addr address(0); | 93 Addr address(0); |
94 int size = (rand() % 4) + 1; | 94 int size = (rand() % 4) + 1; |
95 EXPECT_TRUE(files.CreateBlock(RANKINGS, size, &address)); | 95 EXPECT_TRUE(files.CreateBlock(RANKINGS, size, &address)); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 int empty_3 = header->empty[2]; | 128 int empty_3 = header->empty[2]; |
129 int empty_4 = header->empty[3]; | 129 int empty_4 = header->empty[3]; |
130 | 130 |
131 // Corrupt the file. | 131 // Corrupt the file. |
132 header->max_entries = header->empty[0] = 0; | 132 header->max_entries = header->empty[0] = 0; |
133 header->empty[1] = header->empty[2] = header->empty[3] = 0; | 133 header->empty[1] = header->empty[2] = header->empty[3] = 0; |
134 header->updating = -1; | 134 header->updating = -1; |
135 | 135 |
136 files.CloseFiles(); | 136 files.CloseFiles(); |
137 | 137 |
138 ASSERT_TRUE(files.Init(false)); | 138 ASSERT_TRUE(files.Init(false, kFirstAdditionalBlockFile)); |
139 | 139 |
140 // The file must have been fixed. | 140 // The file must have been fixed. |
141 file = files.GetFile(address); | 141 file = files.GetFile(address); |
142 ASSERT_TRUE(NULL != file); | 142 ASSERT_TRUE(NULL != file); |
143 | 143 |
144 header = reinterpret_cast<BlockFileHeader*>(file->buffer()); | 144 header = reinterpret_cast<BlockFileHeader*>(file->buffer()); |
145 ASSERT_TRUE(NULL != header); | 145 ASSERT_TRUE(NULL != header); |
146 | 146 |
147 ASSERT_EQ(0, header->updating); | 147 ASSERT_EQ(0, header->updating); |
148 | 148 |
149 EXPECT_EQ(max_entries, header->max_entries); | 149 EXPECT_EQ(max_entries, header->max_entries); |
150 EXPECT_EQ(empty_1, header->empty[0]); | 150 EXPECT_EQ(empty_1, header->empty[0]); |
151 EXPECT_EQ(empty_2, header->empty[1]); | 151 EXPECT_EQ(empty_2, header->empty[1]); |
152 EXPECT_EQ(empty_3, header->empty[2]); | 152 EXPECT_EQ(empty_3, header->empty[2]); |
153 EXPECT_EQ(empty_4, header->empty[3]); | 153 EXPECT_EQ(empty_4, header->empty[3]); |
154 } | 154 } |
155 | 155 |
156 // Handling of truncated files. | 156 // Handling of truncated files. |
157 TEST_F(DiskCacheTest, BlockFiles_ZeroSizeFile) { | 157 TEST_F(DiskCacheTest, BlockFiles_ZeroSizeFile) { |
158 ASSERT_TRUE(CleanupCacheDir()); | 158 ASSERT_TRUE(CleanupCacheDir()); |
159 ASSERT_TRUE(file_util::CreateDirectory(cache_path_)); | 159 ASSERT_TRUE(file_util::CreateDirectory(cache_path_)); |
160 | 160 |
161 BlockFiles files(cache_path_); | 161 BlockFiles files(cache_path_); |
162 ASSERT_TRUE(files.Init(true)); | 162 ASSERT_TRUE(files.Init(true, kFirstAdditionalBlockFile)); |
163 | 163 |
164 base::FilePath filename = files.Name(0); | 164 base::FilePath filename = files.HeaderName(0); |
165 files.CloseFiles(); | 165 files.CloseFiles(); |
166 // Truncate one of the files. | 166 // Truncate one of the files. |
167 { | 167 { |
168 scoped_refptr<File> file(new File); | 168 scoped_refptr<File> file(new File); |
169 ASSERT_TRUE(file->Init(filename)); | 169 ASSERT_TRUE(file->Init(filename)); |
170 EXPECT_TRUE(file->SetLength(0)); | 170 EXPECT_TRUE(file->SetLength(0)); |
171 } | 171 } |
172 | 172 |
173 // Initializing should fail, not crash. | 173 // Initializing should fail, not crash. |
174 ASSERT_FALSE(files.Init(false)); | 174 ASSERT_FALSE(files.Init(false, kFirstAdditionalBlockFile)); |
175 } | 175 } |
176 | 176 |
177 // Handling of truncated files (non empty). | 177 // Handling of truncated files (non empty). |
178 TEST_F(DiskCacheTest, BlockFiles_TruncatedFile) { | 178 TEST_F(DiskCacheTest, BlockFiles_TruncatedFile) { |
179 ASSERT_TRUE(CleanupCacheDir()); | 179 ASSERT_TRUE(CleanupCacheDir()); |
180 ASSERT_TRUE(file_util::CreateDirectory(cache_path_)); | 180 ASSERT_TRUE(file_util::CreateDirectory(cache_path_)); |
181 | 181 |
182 BlockFiles files(cache_path_); | 182 BlockFiles files(cache_path_); |
183 ASSERT_TRUE(files.Init(true)); | 183 ASSERT_TRUE(files.Init(true, kFirstAdditionalBlockFile)); |
184 Addr address; | 184 Addr address; |
185 EXPECT_TRUE(files.CreateBlock(RANKINGS, 2, &address)); | 185 EXPECT_TRUE(files.CreateBlock(RANKINGS, 2, &address)); |
186 | 186 |
187 base::FilePath filename = files.Name(0); | 187 base::FilePath filename = files.HeaderName(0); |
188 files.CloseFiles(); | 188 files.CloseFiles(); |
189 // Truncate one of the files. | 189 // Truncate one of the files. |
190 { | 190 { |
191 scoped_refptr<File> file(new File); | 191 scoped_refptr<File> file(new File); |
192 ASSERT_TRUE(file->Init(filename)); | 192 ASSERT_TRUE(file->Init(filename)); |
193 EXPECT_TRUE(file->SetLength(15000)); | 193 EXPECT_TRUE(file->SetLength(15000)); |
194 } | 194 } |
195 | 195 |
196 // Initializing should fail, not crash. | 196 // Initializing should fail, not crash. |
197 ASSERT_FALSE(files.Init(false)); | 197 ASSERT_FALSE(files.Init(false, kFirstAdditionalBlockFile)); |
198 } | 198 } |
199 | 199 |
200 // Tests detection of out of sync counters. | 200 // Tests detection of out of sync counters. |
201 TEST_F(DiskCacheTest, BlockFiles_Counters) { | 201 TEST_F(DiskCacheTest, BlockFiles_Counters) { |
202 ASSERT_TRUE(CleanupCacheDir()); | 202 ASSERT_TRUE(CleanupCacheDir()); |
203 ASSERT_TRUE(file_util::CreateDirectory(cache_path_)); | 203 ASSERT_TRUE(file_util::CreateDirectory(cache_path_)); |
204 | 204 |
205 BlockFiles files(cache_path_); | 205 BlockFiles files(cache_path_); |
206 ASSERT_TRUE(files.Init(true)); | 206 ASSERT_TRUE(files.Init(true, kFirstAdditionalBlockFile)); |
207 | 207 |
208 // Create a block of size 2. | 208 // Create a block of size 2. |
209 Addr address(0); | 209 Addr address(0); |
210 EXPECT_TRUE(files.CreateBlock(RANKINGS, 2, &address)); | 210 EXPECT_TRUE(files.CreateBlock(RANKINGS, 2, &address)); |
211 | 211 |
212 MappedFile* file = files.GetFile(address); | 212 MappedFile* file = files.GetFile(address); |
213 ASSERT_TRUE(NULL != file); | 213 ASSERT_TRUE(NULL != file); |
214 | 214 |
215 BlockFileHeader* header = reinterpret_cast<BlockFileHeader*>(file->buffer()); | 215 BlockFileHeader* header = reinterpret_cast<BlockFileHeader*>(file->buffer()); |
216 ASSERT_TRUE(NULL != header); | 216 ASSERT_TRUE(NULL != header); |
217 ASSERT_EQ(0, header->updating); | 217 ASSERT_EQ(0, header->updating); |
218 | 218 |
219 // Alter the counters so that the free space doesn't add up. | 219 // Alter the counters so that the free space doesn't add up. |
220 header->empty[2] = 50; // 50 free blocks of size 3. | 220 header->empty[2] = 50; // 50 free blocks of size 3. |
221 files.CloseFiles(); | 221 files.CloseFiles(); |
222 | 222 |
223 ASSERT_TRUE(files.Init(false)); | 223 ASSERT_TRUE(files.Init(false, kFirstAdditionalBlockFile)); |
224 file = files.GetFile(address); | 224 file = files.GetFile(address); |
225 ASSERT_TRUE(NULL != file); | 225 ASSERT_TRUE(NULL != file); |
226 header = reinterpret_cast<BlockFileHeader*>(file->buffer()); | 226 header = reinterpret_cast<BlockFileHeader*>(file->buffer()); |
227 ASSERT_TRUE(NULL != header); | 227 ASSERT_TRUE(NULL != header); |
228 | 228 |
229 // The file must have been fixed. | 229 // The file must have been fixed. |
230 ASSERT_EQ(0, header->empty[2]); | 230 ASSERT_EQ(0, header->empty[2]); |
231 | 231 |
232 // Change the number of entries. | 232 // Change the number of entries. |
233 header->num_entries = 3; | 233 header->num_entries = 3; |
234 header->updating = 1; | 234 header->updating = 1; |
235 files.CloseFiles(); | 235 files.CloseFiles(); |
236 | 236 |
237 ASSERT_TRUE(files.Init(false)); | 237 ASSERT_TRUE(files.Init(false, kFirstAdditionalBlockFile)); |
238 file = files.GetFile(address); | 238 file = files.GetFile(address); |
239 ASSERT_TRUE(NULL != file); | 239 ASSERT_TRUE(NULL != file); |
240 header = reinterpret_cast<BlockFileHeader*>(file->buffer()); | 240 header = reinterpret_cast<BlockFileHeader*>(file->buffer()); |
241 ASSERT_TRUE(NULL != header); | 241 ASSERT_TRUE(NULL != header); |
242 | 242 |
243 // The file must have been "fixed". | 243 // The file must have been "fixed". |
244 ASSERT_EQ(2, header->num_entries); | 244 ASSERT_EQ(2, header->num_entries); |
245 | 245 |
246 // Change the number of entries. | 246 // Change the number of entries. |
247 header->num_entries = -1; | 247 header->num_entries = -1; |
248 header->updating = 1; | 248 header->updating = 1; |
249 files.CloseFiles(); | 249 files.CloseFiles(); |
250 | 250 |
251 // Detect the error. | 251 // Detect the error. |
252 ASSERT_FALSE(files.Init(false)); | 252 ASSERT_FALSE(files.Init(false, kFirstAdditionalBlockFile)); |
253 } | 253 } |
254 | 254 |
255 // An invalid file can be detected after init. | 255 // An invalid file can be detected after init. |
256 TEST_F(DiskCacheTest, BlockFiles_InvalidFile) { | 256 TEST_F(DiskCacheTest, BlockFiles_InvalidFile) { |
257 ASSERT_TRUE(CleanupCacheDir()); | 257 ASSERT_TRUE(CleanupCacheDir()); |
258 ASSERT_TRUE(file_util::CreateDirectory(cache_path_)); | 258 ASSERT_TRUE(file_util::CreateDirectory(cache_path_)); |
259 | 259 |
260 BlockFiles files(cache_path_); | 260 BlockFiles files(cache_path_); |
261 ASSERT_TRUE(files.Init(true)); | 261 ASSERT_TRUE(files.Init(true, kFirstAdditionalBlockFile)); |
262 | 262 |
263 // Let's access block 10 of file 5. (There is no file). | 263 // Let's access block 10 of file 5. (There is no file). |
264 Addr addr(BLOCK_256, 1, 5, 10); | 264 Addr addr(BLOCK_256, 1, 5, 10); |
265 EXPECT_TRUE(NULL == files.GetFile(addr)); | 265 EXPECT_TRUE(NULL == files.GetFile(addr)); |
266 | 266 |
267 // Let's create an invalid file. | 267 // Let's create an invalid file. |
268 base::FilePath filename(files.Name(5)); | 268 base::FilePath filename(files.HeaderName(5)); |
269 char header[kBlockHeaderSize]; | 269 char header[kBlockHeaderSize]; |
270 memset(header, 'a', kBlockHeaderSize); | 270 memset(header, 'a', kBlockHeaderSize); |
271 EXPECT_EQ(kBlockHeaderSize, | 271 EXPECT_EQ(kBlockHeaderSize, |
272 file_util::WriteFile(filename, header, kBlockHeaderSize)); | 272 file_util::WriteFile(filename, header, kBlockHeaderSize)); |
273 | 273 |
274 EXPECT_TRUE(NULL == files.GetFile(addr)); | 274 EXPECT_TRUE(NULL == files.GetFile(addr)); |
275 | 275 |
276 // The file should not have been changed (it is still invalid). | 276 // The file should not have been changed (it is still invalid). |
277 EXPECT_TRUE(NULL == files.GetFile(addr)); | 277 EXPECT_TRUE(NULL == files.GetFile(addr)); |
278 } | 278 } |
279 | 279 |
280 // Tests that we generate the correct file stats. | 280 // Tests that we generate the correct file stats. |
281 TEST_F(DiskCacheTest, BlockFiles_Stats) { | 281 TEST_F(DiskCacheTest, BlockFiles_Stats) { |
282 ASSERT_TRUE(CopyTestCache("remove_load1")); | 282 ASSERT_TRUE(CopyTestCache("remove_load1")); |
283 | 283 |
284 BlockFiles files(cache_path_); | 284 BlockFiles files(cache_path_); |
285 ASSERT_TRUE(files.Init(false)); | 285 ASSERT_TRUE(files.Init(false, kFirstAdditionalBlockFile)); |
286 int used, load; | 286 int used, load; |
287 | 287 |
288 files.GetFileStats(0, &used, &load); | 288 files.GetFileStats(0, &used, &load); |
289 EXPECT_EQ(101, used); | 289 EXPECT_EQ(101, used); |
290 EXPECT_EQ(9, load); | 290 EXPECT_EQ(9, load); |
291 | 291 |
292 files.GetFileStats(1, &used, &load); | 292 files.GetFileStats(1, &used, &load); |
293 EXPECT_EQ(203, used); | 293 EXPECT_EQ(203, used); |
294 EXPECT_EQ(19, load); | 294 EXPECT_EQ(19, load); |
295 | 295 |
296 files.GetFileStats(2, &used, &load); | 296 files.GetFileStats(2, &used, &load); |
297 EXPECT_EQ(0, used); | 297 EXPECT_EQ(0, used); |
298 EXPECT_EQ(0, load); | 298 EXPECT_EQ(0, load); |
299 } | 299 } |
300 | 300 |
301 // Tests that we add and remove blocks correctly. | 301 // Tests that we add and remove blocks correctly. |
302 TEST_F(DiskCacheTest, AllocationMap) { | 302 TEST_F(DiskCacheTest, AllocationMap) { |
303 ASSERT_TRUE(CleanupCacheDir()); | 303 ASSERT_TRUE(CleanupCacheDir()); |
304 ASSERT_TRUE(file_util::CreateDirectory(cache_path_)); | 304 ASSERT_TRUE(file_util::CreateDirectory(cache_path_)); |
305 | 305 |
306 BlockFiles files(cache_path_); | 306 BlockFiles files(cache_path_); |
307 ASSERT_TRUE(files.Init(true)); | 307 ASSERT_TRUE(files.Init(true, kFirstAdditionalBlockFile)); |
308 | 308 |
309 // Create a bunch of entries. | 309 // Create a bunch of entries. |
310 const int kSize = 100; | 310 const int kSize = 100; |
311 Addr address[kSize]; | 311 Addr address[kSize]; |
312 for (int i = 0; i < kSize; i++) { | 312 for (int i = 0; i < kSize; i++) { |
313 SCOPED_TRACE(i); | 313 SCOPED_TRACE(i); |
314 int block_size = i % 4 + 1; | 314 int block_size = i % 4 + 1; |
315 EXPECT_TRUE(files.CreateBlock(BLOCK_1K, block_size, &address[i])); | 315 EXPECT_TRUE(files.CreateBlock(BLOCK_1K, block_size, &address[i])); |
316 EXPECT_EQ(BLOCK_1K, address[i].file_type()); | 316 EXPECT_EQ(BLOCK_1K, address[i].file_type()); |
317 EXPECT_EQ(block_size, address[i].num_blocks()); | 317 EXPECT_EQ(block_size, address[i].num_blocks()); |
(...skipping 22 matching lines...) Expand all Loading... |
340 } | 340 } |
341 | 341 |
342 // The allocation map should be empty. | 342 // The allocation map should be empty. |
343 for (int i =0; i < 50; i++) { | 343 for (int i =0; i < 50; i++) { |
344 SCOPED_TRACE(i); | 344 SCOPED_TRACE(i); |
345 EXPECT_EQ(0, buffer[i]); | 345 EXPECT_EQ(0, buffer[i]); |
346 } | 346 } |
347 } | 347 } |
348 | 348 |
349 } // namespace disk_cache | 349 } // namespace disk_cache |
OLD | NEW |