OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "net/disk_cache/backend_tests.h" |
| 6 |
| 7 #include <string> |
| 8 |
| 9 #include "base/strings/string_util.h" |
| 10 #include "base/strings/stringprintf.h" |
| 11 #include "net/base/io_buffer.h" |
| 12 #include "net/base/net_errors.h" |
| 13 #include "net/base/test_completion_callback.h" |
| 14 #include "base/time/time.h" |
| 15 #include "net/disk_cache/disk_cache.h" |
| 16 #include "net/disk_cache/disk_cache_test.h" |
| 17 #include "net/disk_cache/disk_cache_test_util.h" |
| 18 |
| 19 using base::Time; |
| 20 |
| 21 namespace disk_cache { |
| 22 |
| 23 namespace { |
| 24 |
| 25 TEST_P(DiskCacheBackendTest, BackendBasics) { |
| 26 InitCache(); |
| 27 disk_cache::Entry *entry1 = NULL, *entry2 = NULL; |
| 28 EXPECT_NE(net::OK, OpenEntry("the first key", &entry1)); |
| 29 ASSERT_EQ(net::OK, CreateEntry("the first key", &entry1)); |
| 30 ASSERT_TRUE(NULL != entry1); |
| 31 entry1->Close(); |
| 32 entry1 = NULL; |
| 33 |
| 34 ASSERT_EQ(net::OK, OpenEntry("the first key", &entry1)); |
| 35 ASSERT_TRUE(NULL != entry1); |
| 36 entry1->Close(); |
| 37 entry1 = NULL; |
| 38 |
| 39 EXPECT_NE(net::OK, CreateEntry("the first key", &entry1)); |
| 40 ASSERT_EQ(net::OK, OpenEntry("the first key", &entry1)); |
| 41 EXPECT_NE(net::OK, OpenEntry("some other key", &entry2)); |
| 42 ASSERT_EQ(net::OK, CreateEntry("some other key", &entry2)); |
| 43 ASSERT_TRUE(NULL != entry1); |
| 44 ASSERT_TRUE(NULL != entry2); |
| 45 EXPECT_EQ(2, cache()->GetEntryCount()); |
| 46 |
| 47 disk_cache::Entry* entry3 = NULL; |
| 48 ASSERT_EQ(net::OK, OpenEntry("some other key", &entry3)); |
| 49 ASSERT_TRUE(NULL != entry3); |
| 50 EXPECT_TRUE(entry2 == entry3); |
| 51 EXPECT_EQ(2, cache()->GetEntryCount()); |
| 52 |
| 53 EXPECT_EQ(net::OK, DoomEntry("some other key")); |
| 54 EXPECT_EQ(1, cache()->GetEntryCount()); |
| 55 entry1->Close(); |
| 56 entry2->Close(); |
| 57 entry3->Close(); |
| 58 |
| 59 EXPECT_EQ(net::OK, DoomEntry("the first key")); |
| 60 EXPECT_EQ(0, cache()->GetEntryCount()); |
| 61 |
| 62 ASSERT_EQ(net::OK, CreateEntry("the first key", &entry1)); |
| 63 ASSERT_EQ(net::OK, CreateEntry("some other key", &entry2)); |
| 64 entry1->Doom(); |
| 65 entry1->Close(); |
| 66 EXPECT_EQ(net::OK, DoomEntry("some other key")); |
| 67 EXPECT_EQ(0, cache()->GetEntryCount()); |
| 68 entry2->Close(); |
| 69 } |
| 70 |
| 71 TEST_P(DiskCacheBackendTest, Keying) { |
| 72 InitCache(); |
| 73 const char* kName1 = "the first key"; |
| 74 const char* kName2 = "the first Key"; |
| 75 disk_cache::Entry *entry1, *entry2; |
| 76 ASSERT_EQ(net::OK, CreateEntry(kName1, &entry1)); |
| 77 |
| 78 ASSERT_EQ(net::OK, CreateEntry(kName2, &entry2)); |
| 79 EXPECT_TRUE(entry1 != entry2) << "Case sensitive"; |
| 80 entry2->Close(); |
| 81 |
| 82 char buffer[30]; |
| 83 base::strlcpy(buffer, kName1, arraysize(buffer)); |
| 84 ASSERT_EQ(net::OK, OpenEntry(buffer, &entry2)); |
| 85 EXPECT_TRUE(entry1 == entry2); |
| 86 entry2->Close(); |
| 87 |
| 88 base::strlcpy(buffer + 1, kName1, arraysize(buffer) - 1); |
| 89 ASSERT_EQ(net::OK, OpenEntry(buffer + 1, &entry2)); |
| 90 EXPECT_TRUE(entry1 == entry2); |
| 91 entry2->Close(); |
| 92 |
| 93 base::strlcpy(buffer + 3, kName1, arraysize(buffer) - 3); |
| 94 ASSERT_EQ(net::OK, OpenEntry(buffer + 3, &entry2)); |
| 95 EXPECT_TRUE(entry1 == entry2); |
| 96 entry2->Close(); |
| 97 |
| 98 // Now verify long keys. |
| 99 char buffer2[20000]; |
| 100 memset(buffer2, 's', sizeof(buffer2)); |
| 101 buffer2[1023] = '\0'; |
| 102 ASSERT_EQ(net::OK, CreateEntry(buffer2, &entry2)) << "key on block file"; |
| 103 entry2->Close(); |
| 104 |
| 105 buffer2[1023] = 'g'; |
| 106 buffer2[19999] = '\0'; |
| 107 ASSERT_EQ(net::OK, CreateEntry(buffer2, &entry2)) << "key on external file"; |
| 108 entry2->Close(); |
| 109 entry1->Close(); |
| 110 } |
| 111 |
| 112 // XYZZY make less lame |
| 113 TEST_P(DiskCacheTest, CreateBackend) { |
| 114 net::TestCompletionCallback cb; |
| 115 |
| 116 { |
| 117 scoped_ptr<disk_cache::Backend> cache; |
| 118 |
| 119 base::Thread cache_thread("CacheThread"); |
| 120 ASSERT_TRUE(cache_thread.StartWithOptions( |
| 121 base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); |
| 122 |
| 123 // Now test the public API. |
| 124 int rv = |
| 125 disk_cache::CreateCacheBackend(net::DISK_CACHE, |
| 126 net::CACHE_BACKEND_DEFAULT, |
| 127 cache_path(), |
| 128 0, |
| 129 false, |
| 130 cache_thread.message_loop_proxy().get(), |
| 131 NULL, |
| 132 &cache, |
| 133 cb.callback()); |
| 134 ASSERT_EQ(net::OK, cb.GetResult(rv)); |
| 135 ASSERT_TRUE(cache.get()); |
| 136 cache.reset(); |
| 137 |
| 138 rv = disk_cache::CreateCacheBackend(net::MEMORY_CACHE, |
| 139 net::CACHE_BACKEND_DEFAULT, |
| 140 base::FilePath(), 0, |
| 141 false, NULL, NULL, &cache, |
| 142 cb.callback()); |
| 143 ASSERT_EQ(net::OK, cb.GetResult(rv)); |
| 144 ASSERT_TRUE(cache.get()); |
| 145 cache.reset(); |
| 146 } |
| 147 |
| 148 base::MessageLoop::current()->RunUntilIdle(); |
| 149 } |
| 150 |
| 151 TEST_P(DiskCacheBackendTest, SetSize) { |
| 152 const int cache_size = 0x10000; |
| 153 SetMaxSize(cache_size); |
| 154 InitCache(); |
| 155 |
| 156 std::string first("some key"); |
| 157 std::string second("something else"); |
| 158 disk_cache::Entry* entry; |
| 159 ASSERT_EQ(net::OK, CreateEntry(first, &entry)); |
| 160 |
| 161 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(cache_size)); |
| 162 memset(buffer->data(), 0, cache_size); |
| 163 EXPECT_EQ(cache_size / 10, |
| 164 WriteData(entry, 0, 0, buffer.get(), cache_size / 10, false)) |
| 165 << "normal file"; |
| 166 |
| 167 EXPECT_EQ(net::ERR_FAILED, |
| 168 WriteData(entry, 1, 0, buffer.get(), cache_size / 5, false)) |
| 169 << "file size above the limit"; |
| 170 |
| 171 // By doubling the total size, we make this file cacheable. |
| 172 SetMaxSize(cache_size * 2); |
| 173 EXPECT_EQ(cache_size / 5, |
| 174 WriteData(entry, 1, 0, buffer.get(), cache_size / 5, false)); |
| 175 |
| 176 // Let's fill up the cache!. |
| 177 SetMaxSize(cache_size * 10); |
| 178 EXPECT_EQ(cache_size * 3 / 4, |
| 179 WriteData(entry, 0, 0, buffer.get(), cache_size * 3 / 4, false)); |
| 180 entry->Close(); |
| 181 FlushQueueForTest(); |
| 182 |
| 183 SetMaxSize(cache_size); |
| 184 |
| 185 // The cache is 95% full. |
| 186 |
| 187 ASSERT_EQ(net::OK, CreateEntry(second, &entry)); |
| 188 EXPECT_EQ(cache_size / 10, |
| 189 WriteData(entry, 0, 0, buffer.get(), cache_size / 10, false)); |
| 190 |
| 191 disk_cache::Entry* entry2; |
| 192 ASSERT_EQ(net::OK, CreateEntry("an extra key", &entry2)); |
| 193 EXPECT_EQ(cache_size / 10, |
| 194 WriteData(entry2, 0, 0, buffer.get(), cache_size / 10, false)); |
| 195 entry2->Close(); // This will trigger the cache trim. |
| 196 |
| 197 EXPECT_NE(net::OK, OpenEntry(first, &entry2)); |
| 198 |
| 199 FlushQueueForTest(); // Make sure that we are done trimming the cache. |
| 200 FlushQueueForTest(); // We may have posted two tasks to evict stuff. |
| 201 |
| 202 entry->Close(); |
| 203 ASSERT_EQ(net::OK, OpenEntry(second, &entry)); |
| 204 EXPECT_EQ(cache_size / 10, entry->GetDataSize(0)); |
| 205 entry->Close(); |
| 206 } |
| 207 |
| 208 TEST_P(DiskCacheBackendTest, BackendLoad) { |
| 209 // TODO(gavinp) mask?? ugh. |
| 210 SetMaxSize(0x100000); |
| 211 InitCache(); |
| 212 int seed = static_cast<int>(Time::Now().ToInternalValue()); |
| 213 srand(seed); |
| 214 |
| 215 disk_cache::Entry* entries[100]; |
| 216 for (int i = 0; i < 100; i++) { |
| 217 std::string key = GenerateKey(true); |
| 218 ASSERT_EQ(net::OK, CreateEntry(key, &entries[i])); |
| 219 } |
| 220 EXPECT_EQ(100, cache()->GetEntryCount()); |
| 221 |
| 222 for (int i = 0; i < 100; i++) { |
| 223 int source1 = rand() % 100; |
| 224 int source2 = rand() % 100; |
| 225 disk_cache::Entry* temp = entries[source1]; |
| 226 entries[source1] = entries[source2]; |
| 227 entries[source2] = temp; |
| 228 } |
| 229 |
| 230 for (int i = 0; i < 100; i++) { |
| 231 disk_cache::Entry* entry; |
| 232 ASSERT_EQ(net::OK, OpenEntry(entries[i]->GetKey(), &entry)); |
| 233 EXPECT_TRUE(entry == entries[i]); |
| 234 entry->Close(); |
| 235 entries[i]->Doom(); |
| 236 entries[i]->Close(); |
| 237 } |
| 238 FlushQueueForTest(); |
| 239 EXPECT_EQ(0, cache()->GetEntryCount()); |
| 240 } |
| 241 |
| 242 TEST_P(DiskCacheBackendTest, DoomRecent) { |
| 243 InitCache(); |
| 244 |
| 245 disk_cache::Entry *entry; |
| 246 ASSERT_EQ(net::OK, CreateEntry("first", &entry)); |
| 247 entry->Close(); |
| 248 ASSERT_EQ(net::OK, CreateEntry("second", &entry)); |
| 249 entry->Close(); |
| 250 FlushQueueForTest(); |
| 251 |
| 252 AddDelay(); |
| 253 Time middle = Time::Now(); |
| 254 |
| 255 ASSERT_EQ(net::OK, CreateEntry("third", &entry)); |
| 256 entry->Close(); |
| 257 ASSERT_EQ(net::OK, CreateEntry("fourth", &entry)); |
| 258 entry->Close(); |
| 259 FlushQueueForTest(); |
| 260 |
| 261 AddDelay(); |
| 262 Time final = Time::Now(); |
| 263 |
| 264 ASSERT_EQ(4, cache()->GetEntryCount()); |
| 265 EXPECT_EQ(net::OK, DoomEntriesSince(final)); |
| 266 ASSERT_EQ(4, cache()->GetEntryCount()); |
| 267 |
| 268 EXPECT_EQ(net::OK, DoomEntriesSince(middle)); |
| 269 ASSERT_EQ(2, cache()->GetEntryCount()); |
| 270 |
| 271 ASSERT_EQ(net::OK, OpenEntry("second", &entry)); |
| 272 entry->Close(); |
| 273 } |
| 274 |
| 275 void InitSparseCache(DiskCacheTest* test, |
| 276 base::Time* doomed_start, |
| 277 base::Time* doomed_end) { |
| 278 test->InitCache(); |
| 279 |
| 280 const int kSize = 50; |
| 281 // This must be greater then MemEntryImpl::kMaxSparseEntrySize. |
| 282 const int kOffset = 10 + 1024 * 1024; |
| 283 |
| 284 disk_cache::Entry* entry0 = NULL; |
| 285 disk_cache::Entry* entry1 = NULL; |
| 286 disk_cache::Entry* entry2 = NULL; |
| 287 |
| 288 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); |
| 289 CacheTestFillBuffer(buffer->data(), kSize, false); |
| 290 |
| 291 ASSERT_EQ(net::OK, test->CreateEntry("zeroth", &entry0)); |
| 292 ASSERT_EQ(kSize, test->WriteSparseData(entry0, 0, buffer.get(), kSize)); |
| 293 ASSERT_EQ(kSize, |
| 294 test->WriteSparseData(entry0, kOffset + kSize, buffer.get(), kSize))
; |
| 295 entry0->Close(); |
| 296 |
| 297 test->FlushQueueForTest(); |
| 298 test->AddDelay(); |
| 299 if (doomed_start) |
| 300 *doomed_start = base::Time::Now(); |
| 301 |
| 302 // Order in rankings list: |
| 303 // first_part1, first_part2, second_part1, second_part2 |
| 304 ASSERT_EQ(net::OK, test->CreateEntry("first", &entry1)); |
| 305 ASSERT_EQ(kSize, test->WriteSparseData(entry1, 0, buffer.get(), kSize)); |
| 306 ASSERT_EQ(kSize, |
| 307 test->WriteSparseData(entry1, kOffset + kSize, buffer.get(), kSize))
; |
| 308 entry1->Close(); |
| 309 |
| 310 ASSERT_EQ(net::OK, test->CreateEntry("second", &entry2)); |
| 311 ASSERT_EQ(kSize, test->WriteSparseData(entry2, 0, buffer.get(), kSize)); |
| 312 ASSERT_EQ(kSize, |
| 313 test->WriteSparseData(entry2, kOffset + kSize, buffer.get(), kSize))
; |
| 314 entry2->Close(); |
| 315 |
| 316 test->FlushQueueForTest(); |
| 317 test->AddDelay(); |
| 318 if (doomed_end) |
| 319 *doomed_end = base::Time::Now(); |
| 320 test->AddDelay(); |
| 321 |
| 322 // Order in rankings list: |
| 323 // third_part1, fourth_part1, third_part2, fourth_part2 |
| 324 disk_cache::Entry* entry3 = NULL; |
| 325 disk_cache::Entry* entry4 = NULL; |
| 326 ASSERT_EQ(net::OK, test->CreateEntry("third", &entry3)); |
| 327 ASSERT_EQ(kSize, test->WriteSparseData(entry3, 0, buffer.get(), kSize)); |
| 328 ASSERT_EQ(net::OK, test->CreateEntry("fourth", &entry4)); |
| 329 ASSERT_EQ(kSize, test->WriteSparseData(entry4, 0, buffer.get(), kSize)); |
| 330 ASSERT_EQ(kSize, |
| 331 test->WriteSparseData(entry3, kOffset + kSize, buffer.get(), kSize))
; |
| 332 ASSERT_EQ(kSize, |
| 333 test->WriteSparseData(entry4, kOffset + kSize, buffer.get(), kSize))
; |
| 334 entry3->Close(); |
| 335 entry4->Close(); |
| 336 |
| 337 test->FlushQueueForTest(); |
| 338 test->AddDelay(); |
| 339 } |
| 340 |
| 341 TEST_P(DiskCacheBackendTest, DoomEntriesSinceSparse) { |
| 342 base::Time start; |
| 343 InitSparseCache(this, &start, NULL); |
| 344 DoomEntriesSince(start); |
| 345 if (traits()->EntryCountIncludesSparseRanges()) |
| 346 EXPECT_EQ(3, cache()->GetEntryCount()); |
| 347 else |
| 348 EXPECT_EQ(1, cache()->GetEntryCount()); |
| 349 } |
| 350 |
| 351 TEST_P(DiskCacheBackendTest, DoomAllSparse) { |
| 352 InitSparseCache(this, NULL, NULL); |
| 353 EXPECT_EQ(net::OK, DoomAllEntries()); |
| 354 EXPECT_EQ(0, cache()->GetEntryCount()); |
| 355 } |
| 356 |
| 357 TEST_P(DiskCacheBackendTest, DoomBetween) { |
| 358 InitCache(); |
| 359 |
| 360 disk_cache::Entry *entry; |
| 361 ASSERT_EQ(net::OK, CreateEntry("first", &entry)); |
| 362 entry->Close(); |
| 363 FlushQueueForTest(); |
| 364 |
| 365 AddDelay(); |
| 366 Time middle_start = Time::Now(); |
| 367 |
| 368 ASSERT_EQ(net::OK, CreateEntry("second", &entry)); |
| 369 entry->Close(); |
| 370 ASSERT_EQ(net::OK, CreateEntry("third", &entry)); |
| 371 entry->Close(); |
| 372 FlushQueueForTest(); |
| 373 |
| 374 AddDelay(); |
| 375 Time middle_end = Time::Now(); |
| 376 AddDelay(); |
| 377 |
| 378 ASSERT_EQ(net::OK, CreateEntry("fourth", &entry)); |
| 379 entry->Close(); |
| 380 ASSERT_EQ(net::OK, OpenEntry("fourth", &entry)); |
| 381 entry->Close(); |
| 382 FlushQueueForTest(); |
| 383 |
| 384 AddDelay(); |
| 385 Time final = Time::Now(); |
| 386 |
| 387 ASSERT_EQ(4, cache()->GetEntryCount()); |
| 388 EXPECT_EQ(net::OK, DoomEntriesBetween(middle_start, middle_end)); |
| 389 ASSERT_EQ(2, cache()->GetEntryCount()); |
| 390 |
| 391 ASSERT_EQ(net::OK, OpenEntry("fourth", &entry)); |
| 392 entry->Close(); |
| 393 |
| 394 EXPECT_EQ(net::OK, DoomEntriesBetween(middle_start, final)); |
| 395 ASSERT_EQ(1, cache()->GetEntryCount()); |
| 396 |
| 397 ASSERT_EQ(net::OK, OpenEntry("first", &entry)); |
| 398 entry->Close(); |
| 399 } |
| 400 |
| 401 TEST_P(DiskCacheBackendTest, DoomEntriesBetweenSparse) { |
| 402 base::Time start, end; |
| 403 InitSparseCache(this, &start, &end); |
| 404 DoomEntriesBetween(start, end); |
| 405 if (traits()->EntryCountIncludesSparseRanges()) |
| 406 EXPECT_EQ(9, cache()->GetEntryCount()); |
| 407 else |
| 408 EXPECT_EQ(3, cache()->GetEntryCount()); |
| 409 |
| 410 start = end; |
| 411 end = base::Time::Now(); |
| 412 DoomEntriesBetween(start, end); |
| 413 if (traits()->EntryCountIncludesSparseRanges()) |
| 414 EXPECT_EQ(3, cache()->GetEntryCount()); |
| 415 else |
| 416 EXPECT_EQ(1, cache()->GetEntryCount()); |
| 417 } |
| 418 |
| 419 |
| 420 TEST_P(DiskCacheBackendTest, DoomAll) { |
| 421 InitCache(); |
| 422 |
| 423 disk_cache::Entry *entry1, *entry2; |
| 424 ASSERT_EQ(net::OK, CreateEntry("first", &entry1)); |
| 425 ASSERT_EQ(net::OK, CreateEntry("second", &entry2)); |
| 426 entry1->Close(); |
| 427 entry2->Close(); |
| 428 |
| 429 ASSERT_EQ(net::OK, CreateEntry("third", &entry1)); |
| 430 ASSERT_EQ(net::OK, CreateEntry("fourth", &entry2)); |
| 431 |
| 432 ASSERT_EQ(4, cache()->GetEntryCount()); |
| 433 EXPECT_EQ(net::OK, DoomAllEntries()); |
| 434 ASSERT_EQ(0, cache()->GetEntryCount()); |
| 435 |
| 436 // We should stop posting tasks at some point (if we post any). |
| 437 base::MessageLoop::current()->RunUntilIdle(); |
| 438 |
| 439 disk_cache::Entry *entry3, *entry4; |
| 440 EXPECT_NE(net::OK, OpenEntry("third", &entry3)); |
| 441 ASSERT_EQ(net::OK, CreateEntry("third", &entry3)); |
| 442 ASSERT_EQ(net::OK, CreateEntry("fourth", &entry4)); |
| 443 |
| 444 EXPECT_EQ(net::OK, DoomAllEntries()); |
| 445 ASSERT_EQ(0, cache()->GetEntryCount()); |
| 446 |
| 447 entry1->Close(); |
| 448 entry2->Close(); |
| 449 entry3->Doom(); // The entry should be already doomed, but this must work. |
| 450 entry3->Close(); |
| 451 entry4->Close(); |
| 452 |
| 453 // Now try with all references released. |
| 454 ASSERT_EQ(net::OK, CreateEntry("third", &entry1)); |
| 455 ASSERT_EQ(net::OK, CreateEntry("fourth", &entry2)); |
| 456 entry1->Close(); |
| 457 entry2->Close(); |
| 458 |
| 459 ASSERT_EQ(2, cache()->GetEntryCount()); |
| 460 EXPECT_EQ(net::OK, DoomAllEntries()); |
| 461 ASSERT_EQ(0, cache()->GetEntryCount()); |
| 462 |
| 463 EXPECT_EQ(net::OK, DoomAllEntries()); |
| 464 } |
| 465 |
| 466 } // namespace |
| 467 |
| 468 } // namespace disk_cache |
OLD | NEW |