backend_unittest.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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 3// found in the LICENSE file. 4 5#include "base/basictypes.h" 6#include "base/file_util.h" 7#include "base/metrics/field_trial.h" 8#include "base/port.h" 9#include "base/strings/string_util.h" 10#include "base/strings/stringprintf.h" 11#include "base/third_party/dynamic_annotations/dynamic_annotations.h" 12#include "base/threading/platform_thread.h" 13#include "base/threading/thread_restrictions.h" 14#include "net/base/cache_type.h" 15#include "net/base/io_buffer.h" 16#include "net/base/net_errors.h" 17#include "net/base/test_completion_callback.h" 18#include "net/disk_cache/blockfile/backend_impl.h" 19#include "net/disk_cache/blockfile/entry_impl.h" 20#include "net/disk_cache/blockfile/experiments.h" 21#include "net/disk_cache/blockfile/histogram_macros.h" 22#include "net/disk_cache/blockfile/mapped_file.h" 23#include "net/disk_cache/cache_util.h" 24#include "net/disk_cache/disk_cache_test_base.h" 25#include "net/disk_cache/disk_cache_test_util.h" 26#include "net/disk_cache/memory/mem_backend_impl.h" 27#include "net/disk_cache/simple/simple_backend_impl.h" 28#include "net/disk_cache/simple/simple_entry_format.h" 29#include "net/disk_cache/simple/simple_test_util.h" 30#include "net/disk_cache/simple/simple_util.h" 31#include "net/disk_cache/tracing/tracing_cache_backend.h" 32#include "testing/gtest/include/gtest/gtest.h" 33 34#if defined(OS_WIN) 35#include "base/win/scoped_handle.h" 36#endif 37 38// Provide a BackendImpl object to macros from histogram_macros.h. 39#define CACHE_UMA_BACKEND_IMPL_OBJ backend_ 40 41using base::Time; 42 43namespace { 44 45const char kExistingEntryKey[] = "existing entry key"; 46 47scoped_ptr<disk_cache::BackendImpl> CreateExistingEntryCache( 48 const base::Thread& cache_thread, 49 base::FilePath& cache_path) { 50 net::TestCompletionCallback cb; 51 52 scoped_ptr<disk_cache::BackendImpl> cache(new disk_cache::BackendImpl( 53 cache_path, cache_thread.message_loop_proxy(), NULL)); 54 int rv = cache->Init(cb.callback()); 55 if (cb.GetResult(rv) != net::OK) 56 return scoped_ptr<disk_cache::BackendImpl>(); 57 58 disk_cache::Entry* entry = NULL; 59 rv = cache->CreateEntry(kExistingEntryKey, &entry, cb.callback()); 60 if (cb.GetResult(rv) != net::OK) 61 return scoped_ptr<disk_cache::BackendImpl>(); 62 entry->Close(); 63 64 return cache.Pass(); 65} 66 67} // namespace 68 69// Tests that can run with different types of caches. 70class DiskCacheBackendTest : public DiskCacheTestWithCache { 71 protected: 72 // Some utility methods: 73 74 // Perform IO operations on the cache until there is pending IO. 75 int GeneratePendingIO(net::TestCompletionCallback* cb); 76 77 // Adds 5 sparse entries. |doomed_start| and |doomed_end| if not NULL, 78 // will be filled with times, used by DoomEntriesSince and DoomEntriesBetween. 79 // There are 4 entries after doomed_start and 2 after doomed_end. 80 void InitSparseCache(base::Time* doomed_start, base::Time* doomed_end); 81 82 bool CreateSetOfRandomEntries(std::set<std::string>* key_pool); 83 bool EnumerateAndMatchKeys(int max_to_open, 84 void** iter, 85 std::set<std::string>* keys_to_match, 86 size_t* count); 87 88 // Actual tests: 89 void BackendBasics(); 90 void BackendKeying(); 91 void BackendShutdownWithPendingFileIO(bool fast); 92 void BackendShutdownWithPendingIO(bool fast); 93 void BackendShutdownWithPendingCreate(bool fast); 94 void BackendSetSize(); 95 void BackendLoad(); 96 void BackendChain(); 97 void BackendValidEntry(); 98 void BackendInvalidEntry(); 99 void BackendInvalidEntryRead(); 100 void BackendInvalidEntryWithLoad(); 101 void BackendTrimInvalidEntry(); 102 void BackendTrimInvalidEntry2(); 103 void BackendEnumerations(); 104 void BackendEnumerations2(); 105 void BackendInvalidEntryEnumeration(); 106 void BackendFixEnumerators(); 107 void BackendDoomRecent(); 108 void BackendDoomBetween(); 109 void BackendTransaction(const std::string& name, int num_entries, bool load); 110 void BackendRecoverInsert(); 111 void BackendRecoverRemove(); 112 void BackendRecoverWithEviction(); 113 void BackendInvalidEntry2(); 114 void BackendInvalidEntry3(); 115 void BackendInvalidEntry7(); 116 void BackendInvalidEntry8(); 117 void BackendInvalidEntry9(bool eviction); 118 void BackendInvalidEntry10(bool eviction); 119 void BackendInvalidEntry11(bool eviction); 120 void BackendTrimInvalidEntry12(); 121 void BackendDoomAll(); 122 void BackendDoomAll2(); 123 void BackendInvalidRankings(); 124 void BackendInvalidRankings2(); 125 void BackendDisable(); 126 void BackendDisable2(); 127 void BackendDisable3(); 128 void BackendDisable4(); 129 void TracingBackendBasics(); 130}; 131 132int DiskCacheBackendTest::GeneratePendingIO(net::TestCompletionCallback* cb) { 133 if (!use_current_thread_) { 134 ADD_FAILURE(); 135 return net::ERR_FAILED; 136 } 137 138 disk_cache::Entry* entry; 139 int rv = cache_->CreateEntry("some key", &entry, cb->callback()); 140 if (cb->GetResult(rv) != net::OK) 141 return net::ERR_CACHE_CREATE_FAILURE; 142 143 const int kSize = 25000; 144 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); 145 CacheTestFillBuffer(buffer->data(), kSize, false); 146 147 for (int i = 0; i < 10 * 1024 * 1024; i += 64 * 1024) { 148 // We are using the current thread as the cache thread because we want to 149 // be able to call directly this method to make sure that the OS (instead 150 // of us switching thread) is returning IO pending. 151 if (!simple_cache_mode_) { 152 rv = static_cast<disk_cache::EntryImpl*>(entry)->WriteDataImpl( 153 0, i, buffer.get(), kSize, cb->callback(), false); 154 } else { 155 rv = entry->WriteData(0, i, buffer.get(), kSize, cb->callback(), false); 156 } 157 158 if (rv == net::ERR_IO_PENDING) 159 break; 160 if (rv != kSize) 161 rv = net::ERR_FAILED; 162 } 163 164 // Don't call Close() to avoid going through the queue or we'll deadlock 165 // waiting for the operation to finish. 166 if (!simple_cache_mode_) 167 static_cast<disk_cache::EntryImpl*>(entry)->Release(); 168 else 169 entry->Close(); 170 171 return rv; 172} 173 174void DiskCacheBackendTest::InitSparseCache(base::Time* doomed_start, 175 base::Time* doomed_end) { 176 InitCache(); 177 178 const int kSize = 50; 179 // This must be greater then MemEntryImpl::kMaxSparseEntrySize. 180 const int kOffset = 10 + 1024 * 1024; 181 182 disk_cache::Entry* entry0 = NULL; 183 disk_cache::Entry* entry1 = NULL; 184 disk_cache::Entry* entry2 = NULL; 185 186 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); 187 CacheTestFillBuffer(buffer->data(), kSize, false); 188 189 ASSERT_EQ(net::OK, CreateEntry("zeroth", &entry0)); 190 ASSERT_EQ(kSize, WriteSparseData(entry0, 0, buffer.get(), kSize)); 191 ASSERT_EQ(kSize, 192 WriteSparseData(entry0, kOffset + kSize, buffer.get(), kSize)); 193 entry0->Close(); 194 195 FlushQueueForTest(); 196 AddDelay(); 197 if (doomed_start) 198 *doomed_start = base::Time::Now(); 199 200 // Order in rankings list: 201 // first_part1, first_part2, second_part1, second_part2 202 ASSERT_EQ(net::OK, CreateEntry("first", &entry1)); 203 ASSERT_EQ(kSize, WriteSparseData(entry1, 0, buffer.get(), kSize)); 204 ASSERT_EQ(kSize, 205 WriteSparseData(entry1, kOffset + kSize, buffer.get(), kSize)); 206 entry1->Close(); 207 208 ASSERT_EQ(net::OK, CreateEntry("second", &entry2)); 209 ASSERT_EQ(kSize, WriteSparseData(entry2, 0, buffer.get(), kSize)); 210 ASSERT_EQ(kSize, 211 WriteSparseData(entry2, kOffset + kSize, buffer.get(), kSize)); 212 entry2->Close(); 213 214 FlushQueueForTest(); 215 AddDelay(); 216 if (doomed_end) 217 *doomed_end = base::Time::Now(); 218 219 // Order in rankings list: 220 // third_part1, fourth_part1, third_part2, fourth_part2 221 disk_cache::Entry* entry3 = NULL; 222 disk_cache::Entry* entry4 = NULL; 223 ASSERT_EQ(net::OK, CreateEntry("third", &entry3)); 224 ASSERT_EQ(kSize, WriteSparseData(entry3, 0, buffer.get(), kSize)); 225 ASSERT_EQ(net::OK, CreateEntry("fourth", &entry4)); 226 ASSERT_EQ(kSize, WriteSparseData(entry4, 0, buffer.get(), kSize)); 227 ASSERT_EQ(kSize, 228 WriteSparseData(entry3, kOffset + kSize, buffer.get(), kSize)); 229 ASSERT_EQ(kSize, 230 WriteSparseData(entry4, kOffset + kSize, buffer.get(), kSize)); 231 entry3->Close(); 232 entry4->Close(); 233 234 FlushQueueForTest(); 235 AddDelay(); 236} 237 238// Creates entries based on random keys. Stores these keys in |key_pool|. 239bool DiskCacheBackendTest::CreateSetOfRandomEntries( 240 std::set<std::string>* key_pool) { 241 const int kNumEntries = 10; 242 243 for (int i = 0; i < kNumEntries; ++i) { 244 std::string key = GenerateKey(true); 245 disk_cache::Entry* entry; 246 if (CreateEntry(key, &entry) != net::OK) 247 return false; 248 key_pool->insert(key); 249 entry->Close(); 250 } 251 return key_pool->size() == implicit_cast<size_t>(cache_->GetEntryCount()); 252} 253 254// Performs iteration over the backend and checks that the keys of entries 255// opened are in |keys_to_match|, then erases them. Up to |max_to_open| entries 256// will be opened, if it is positive. Otherwise, iteration will continue until 257// OpenNextEntry stops returning net::OK. 258bool DiskCacheBackendTest::EnumerateAndMatchKeys( 259 int max_to_open, 260 void** iter, 261 std::set<std::string>* keys_to_match, 262 size_t* count) { 263 disk_cache::Entry* entry; 264 265 while (OpenNextEntry(iter, &entry) == net::OK) { 266 if (!entry) 267 return false; 268 EXPECT_EQ(1U, keys_to_match->erase(entry->GetKey())); 269 entry->Close(); 270 ++(*count); 271 if (max_to_open >= 0 && implicit_cast<int>(*count) >= max_to_open) 272 break; 273 }; 274 275 return true; 276} 277 278void DiskCacheBackendTest::BackendBasics() { 279 InitCache(); 280 disk_cache::Entry *entry1 = NULL, *entry2 = NULL; 281 EXPECT_NE(net::OK, OpenEntry("the first key", &entry1)); 282 ASSERT_EQ(net::OK, CreateEntry("the first key", &entry1)); 283 ASSERT_TRUE(NULL != entry1); 284 entry1->Close(); 285 entry1 = NULL; 286 287 ASSERT_EQ(net::OK, OpenEntry("the first key", &entry1)); 288 ASSERT_TRUE(NULL != entry1); 289 entry1->Close(); 290 entry1 = NULL; 291 292 EXPECT_NE(net::OK, CreateEntry("the first key", &entry1)); 293 ASSERT_EQ(net::OK, OpenEntry("the first key", &entry1)); 294 EXPECT_NE(net::OK, OpenEntry("some other key", &entry2)); 295 ASSERT_EQ(net::OK, CreateEntry("some other key", &entry2)); 296 ASSERT_TRUE(NULL != entry1); 297 ASSERT_TRUE(NULL != entry2); 298 EXPECT_EQ(2, cache_->GetEntryCount()); 299 300 disk_cache::Entry* entry3 = NULL; 301 ASSERT_EQ(net::OK, OpenEntry("some other key", &entry3)); 302 ASSERT_TRUE(NULL != entry3); 303 EXPECT_TRUE(entry2 == entry3); 304 EXPECT_EQ(2, cache_->GetEntryCount()); 305 306 EXPECT_EQ(net::OK, DoomEntry("some other key")); 307 EXPECT_EQ(1, cache_->GetEntryCount()); 308 entry1->Close(); 309 entry2->Close(); 310 entry3->Close(); 311 312 EXPECT_EQ(net::OK, DoomEntry("the first key")); 313 EXPECT_EQ(0, cache_->GetEntryCount()); 314 315 ASSERT_EQ(net::OK, CreateEntry("the first key", &entry1)); 316 ASSERT_EQ(net::OK, CreateEntry("some other key", &entry2)); 317 entry1->Doom(); 318 entry1->Close(); 319 EXPECT_EQ(net::OK, DoomEntry("some other key")); 320 EXPECT_EQ(0, cache_->GetEntryCount()); 321 entry2->Close(); 322} 323 324TEST_F(DiskCacheBackendTest, Basics) { 325 BackendBasics(); 326} 327 328TEST_F(DiskCacheBackendTest, NewEvictionBasics) { 329 SetNewEviction(); 330 BackendBasics(); 331} 332 333TEST_F(DiskCacheBackendTest, MemoryOnlyBasics) { 334 SetMemoryOnlyMode(); 335 BackendBasics(); 336} 337 338TEST_F(DiskCacheBackendTest, AppCacheBasics) { 339 SetCacheType(net::APP_CACHE); 340 BackendBasics(); 341} 342 343TEST_F(DiskCacheBackendTest, ShaderCacheBasics) { 344 SetCacheType(net::SHADER_CACHE); 345 BackendBasics(); 346} 347 348void DiskCacheBackendTest::BackendKeying() { 349 InitCache(); 350 const char* kName1 = "the first key"; 351 const char* kName2 = "the first Key"; 352 disk_cache::Entry *entry1, *entry2; 353 ASSERT_EQ(net::OK, CreateEntry(kName1, &entry1)); 354 355 ASSERT_EQ(net::OK, CreateEntry(kName2, &entry2)); 356 EXPECT_TRUE(entry1 != entry2) << "Case sensitive"; 357 entry2->Close(); 358 359 char buffer[30]; 360 base::strlcpy(buffer, kName1, arraysize(buffer)); 361 ASSERT_EQ(net::OK, OpenEntry(buffer, &entry2)); 362 EXPECT_TRUE(entry1 == entry2); 363 entry2->Close(); 364 365 base::strlcpy(buffer + 1, kName1, arraysize(buffer) - 1); 366 ASSERT_EQ(net::OK, OpenEntry(buffer + 1, &entry2)); 367 EXPECT_TRUE(entry1 == entry2); 368 entry2->Close(); 369 370 base::strlcpy(buffer + 3, kName1, arraysize(buffer) - 3); 371 ASSERT_EQ(net::OK, OpenEntry(buffer + 3, &entry2)); 372 EXPECT_TRUE(entry1 == entry2); 373 entry2->Close(); 374 375 // Now verify long keys. 376 char buffer2[20000]; 377 memset(buffer2, 's', sizeof(buffer2)); 378 buffer2[1023] = '\0'; 379 ASSERT_EQ(net::OK, CreateEntry(buffer2, &entry2)) << "key on block file"; 380 entry2->Close(); 381 382 buffer2[1023] = 'g'; 383 buffer2[19999] = '\0'; 384 ASSERT_EQ(net::OK, CreateEntry(buffer2, &entry2)) << "key on external file"; 385 entry2->Close(); 386 entry1->Close(); 387} 388 389TEST_F(DiskCacheBackendTest, Keying) { 390 BackendKeying(); 391} 392 393TEST_F(DiskCacheBackendTest, NewEvictionKeying) { 394 SetNewEviction(); 395 BackendKeying(); 396} 397 398TEST_F(DiskCacheBackendTest, MemoryOnlyKeying) { 399 SetMemoryOnlyMode(); 400 BackendKeying(); 401} 402 403TEST_F(DiskCacheBackendTest, AppCacheKeying) { 404 SetCacheType(net::APP_CACHE); 405 BackendKeying(); 406} 407 408TEST_F(DiskCacheBackendTest, ShaderCacheKeying) { 409 SetCacheType(net::SHADER_CACHE); 410 BackendKeying(); 411} 412 413TEST_F(DiskCacheTest, CreateBackend) { 414 net::TestCompletionCallback cb; 415 416 { 417 ASSERT_TRUE(CleanupCacheDir()); 418 base::Thread cache_thread("CacheThread"); 419 ASSERT_TRUE(cache_thread.StartWithOptions( 420 base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); 421 422 // Test the private factory method(s). 423 scoped_ptr<disk_cache::Backend> cache; 424 cache = disk_cache::MemBackendImpl::CreateBackend(0, NULL); 425 ASSERT_TRUE(cache.get()); 426 cache.reset(); 427 428 // Now test the public API. 429 int rv = 430 disk_cache::CreateCacheBackend(net::DISK_CACHE, 431 net::CACHE_BACKEND_DEFAULT, 432 cache_path_, 433 0, 434 false, 435 cache_thread.message_loop_proxy().get(), 436 NULL, 437 &cache, 438 cb.callback()); 439 ASSERT_EQ(net::OK, cb.GetResult(rv)); 440 ASSERT_TRUE(cache.get()); 441 cache.reset(); 442 443 rv = disk_cache::CreateCacheBackend(net::MEMORY_CACHE, 444 net::CACHE_BACKEND_DEFAULT, 445 base::FilePath(), 0, 446 false, NULL, NULL, &cache, 447 cb.callback()); 448 ASSERT_EQ(net::OK, cb.GetResult(rv)); 449 ASSERT_TRUE(cache.get()); 450 cache.reset(); 451 } 452 453 base::MessageLoop::current()->RunUntilIdle(); 454} 455 456// Tests that |BackendImpl| fails to initialize with a missing file. 457TEST_F(DiskCacheBackendTest, CreateBackend_MissingFile) { 458 ASSERT_TRUE(CopyTestCache("bad_entry")); 459 base::FilePath filename = cache_path_.AppendASCII("data_1"); 460 base::DeleteFile(filename, false); 461 base::Thread cache_thread("CacheThread"); 462 ASSERT_TRUE(cache_thread.StartWithOptions( 463 base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); 464 net::TestCompletionCallback cb; 465 466 bool prev = base::ThreadRestrictions::SetIOAllowed(false); 467 scoped_ptr<disk_cache::BackendImpl> cache(new disk_cache::BackendImpl( 468 cache_path_, cache_thread.message_loop_proxy().get(), NULL)); 469 int rv = cache->Init(cb.callback()); 470 EXPECT_EQ(net::ERR_FAILED, cb.GetResult(rv)); 471 base::ThreadRestrictions::SetIOAllowed(prev); 472 473 cache.reset(); 474 DisableIntegrityCheck(); 475} 476 477TEST_F(DiskCacheBackendTest, ExternalFiles) { 478 InitCache(); 479 // First, let's create a file on the folder. 480 base::FilePath filename = cache_path_.AppendASCII("f_000001"); 481 482 const int kSize = 50; 483 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize)); 484 CacheTestFillBuffer(buffer1->data(), kSize, false); 485 ASSERT_EQ(kSize, base::WriteFile(filename, buffer1->data(), kSize)); 486 487 // Now let's create a file with the cache. 488 disk_cache::Entry* entry; 489 ASSERT_EQ(net::OK, CreateEntry("key", &entry)); 490 ASSERT_EQ(0, WriteData(entry, 0, 20000, buffer1.get(), 0, false)); 491 entry->Close(); 492 493 // And verify that the first file is still there. 494 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize)); 495 ASSERT_EQ(kSize, base::ReadFile(filename, buffer2->data(), kSize)); 496 EXPECT_EQ(0, memcmp(buffer1->data(), buffer2->data(), kSize)); 497} 498 499// Tests that we deal with file-level pending operations at destruction time. 500void DiskCacheBackendTest::BackendShutdownWithPendingFileIO(bool fast) { 501 ASSERT_TRUE(CleanupCacheDir()); 502 uint32 flags = disk_cache::kNoBuffering; 503 if (!fast) 504 flags |= disk_cache::kNoRandom; 505 506 UseCurrentThread(); 507 CreateBackend(flags, NULL); 508 509 net::TestCompletionCallback cb; 510 int rv = GeneratePendingIO(&cb); 511 512 // The cache destructor will see one pending operation here. 513 cache_.reset(); 514 515 if (rv == net::ERR_IO_PENDING) { 516 if (fast || simple_cache_mode_) 517 EXPECT_FALSE(cb.have_result()); 518 else 519 EXPECT_TRUE(cb.have_result()); 520 } 521 522 base::MessageLoop::current()->RunUntilIdle(); 523 524#if !defined(OS_IOS) 525 // Wait for the actual operation to complete, or we'll keep a file handle that 526 // may cause issues later. Note that on iOS systems even though this test 527 // uses a single thread, the actual IO is posted to a worker thread and the 528 // cache destructor breaks the link to reach cb when the operation completes. 529 rv = cb.GetResult(rv); 530#endif 531} 532 533TEST_F(DiskCacheBackendTest, ShutdownWithPendingFileIO) { 534 BackendShutdownWithPendingFileIO(false); 535} 536 537// Here and below, tests that simulate crashes are not compiled in LeakSanitizer 538// builds because they contain a lot of intentional memory leaks. 539// The wrapper scripts used to run tests under Valgrind Memcheck will also 540// disable these tests. See: 541// tools/valgrind/gtest_exclude/net_unittests.gtest-memcheck.txt 542#if !defined(LEAK_SANITIZER) 543// We'll be leaking from this test. 544TEST_F(DiskCacheBackendTest, ShutdownWithPendingFileIO_Fast) { 545 // The integrity test sets kNoRandom so there's a version mismatch if we don't 546 // force new eviction. 547 SetNewEviction(); 548 BackendShutdownWithPendingFileIO(true); 549} 550#endif 551 552// See crbug.com/330074 553#if !defined(OS_IOS) 554// Tests that one cache instance is not affected by another one going away. 555TEST_F(DiskCacheBackendTest, MultipleInstancesWithPendingFileIO) { 556 base::ScopedTempDir store; 557 ASSERT_TRUE(store.CreateUniqueTempDir()); 558 559 net::TestCompletionCallback cb; 560 scoped_ptr<disk_cache::Backend> extra_cache; 561 int rv = disk_cache::CreateCacheBackend( 562 net::DISK_CACHE, net::CACHE_BACKEND_DEFAULT, store.path(), 0, 563 false, base::MessageLoopProxy::current().get(), NULL, 564 &extra_cache, cb.callback()); 565 ASSERT_EQ(net::OK, cb.GetResult(rv)); 566 ASSERT_TRUE(extra_cache.get() != NULL); 567 568 ASSERT_TRUE(CleanupCacheDir()); 569 SetNewEviction(); // Match the expected behavior for integrity verification. 570 UseCurrentThread(); 571 572 CreateBackend(disk_cache::kNoBuffering, NULL); 573 rv = GeneratePendingIO(&cb); 574 575 // cache_ has a pending operation, and extra_cache will go away. 576 extra_cache.reset(); 577 578 if (rv == net::ERR_IO_PENDING) 579 EXPECT_FALSE(cb.have_result()); 580 581 base::MessageLoop::current()->RunUntilIdle(); 582 583 // Wait for the actual operation to complete, or we'll keep a file handle that 584 // may cause issues later. 585 rv = cb.GetResult(rv); 586} 587#endif 588 589// Tests that we deal with background-thread pending operations. 590void DiskCacheBackendTest::BackendShutdownWithPendingIO(bool fast) { 591 net::TestCompletionCallback cb; 592 593 { 594 ASSERT_TRUE(CleanupCacheDir()); 595 base::Thread cache_thread("CacheThread"); 596 ASSERT_TRUE(cache_thread.StartWithOptions( 597 base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); 598 599 uint32 flags = disk_cache::kNoBuffering; 600 if (!fast) 601 flags |= disk_cache::kNoRandom; 602 603 CreateBackend(flags, &cache_thread); 604 605 disk_cache::Entry* entry; 606 int rv = cache_->CreateEntry("some key", &entry, cb.callback()); 607 ASSERT_EQ(net::OK, cb.GetResult(rv)); 608 609 entry->Close(); 610 611 // The cache destructor will see one pending operation here. 612 cache_.reset(); 613 } 614 615 base::MessageLoop::current()->RunUntilIdle(); 616} 617 618TEST_F(DiskCacheBackendTest, ShutdownWithPendingIO) { 619 BackendShutdownWithPendingIO(false); 620} 621 622#if !defined(LEAK_SANITIZER) 623// We'll be leaking from this test. 624TEST_F(DiskCacheBackendTest, ShutdownWithPendingIO_Fast) { 625 // The integrity test sets kNoRandom so there's a version mismatch if we don't 626 // force new eviction. 627 SetNewEviction(); 628 BackendShutdownWithPendingIO(true); 629} 630#endif 631 632// Tests that we deal with create-type pending operations. 633void DiskCacheBackendTest::BackendShutdownWithPendingCreate(bool fast) { 634 net::TestCompletionCallback cb; 635 636 { 637 ASSERT_TRUE(CleanupCacheDir()); 638 base::Thread cache_thread("CacheThread"); 639 ASSERT_TRUE(cache_thread.StartWithOptions( 640 base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); 641 642 disk_cache::BackendFlags flags = 643 fast ? disk_cache::kNone : disk_cache::kNoRandom; 644 CreateBackend(flags, &cache_thread); 645 646 disk_cache::Entry* entry; 647 int rv = cache_->CreateEntry("some key", &entry, cb.callback()); 648 ASSERT_EQ(net::ERR_IO_PENDING, rv); 649 650 cache_.reset(); 651 EXPECT_FALSE(cb.have_result()); 652 } 653 654 base::MessageLoop::current()->RunUntilIdle(); 655} 656 657TEST_F(DiskCacheBackendTest, ShutdownWithPendingCreate) { 658 BackendShutdownWithPendingCreate(false); 659} 660 661#if !defined(LEAK_SANITIZER) 662// We'll be leaking an entry from this test. 663TEST_F(DiskCacheBackendTest, ShutdownWithPendingCreate_Fast) { 664 // The integrity test sets kNoRandom so there's a version mismatch if we don't 665 // force new eviction. 666 SetNewEviction(); 667 BackendShutdownWithPendingCreate(true); 668} 669#endif 670 671// Disabled on android since this test requires cache creator to create 672// blockfile caches. 673#if !defined(OS_ANDROID) 674TEST_F(DiskCacheTest, TruncatedIndex) { 675 ASSERT_TRUE(CleanupCacheDir()); 676 base::FilePath index = cache_path_.AppendASCII("index"); 677 ASSERT_EQ(5, base::WriteFile(index, "hello", 5)); 678 679 base::Thread cache_thread("CacheThread"); 680 ASSERT_TRUE(cache_thread.StartWithOptions( 681 base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); 682 net::TestCompletionCallback cb; 683 684 scoped_ptr<disk_cache::Backend> backend; 685 int rv = 686 disk_cache::CreateCacheBackend(net::DISK_CACHE, 687 net::CACHE_BACKEND_BLOCKFILE, 688 cache_path_, 689 0, 690 false, 691 cache_thread.message_loop_proxy().get(), 692 NULL, 693 &backend, 694 cb.callback()); 695 ASSERT_NE(net::OK, cb.GetResult(rv)); 696 697 ASSERT_FALSE(backend); 698} 699#endif 700 701void DiskCacheBackendTest::BackendSetSize() { 702 const int cache_size = 0x10000; // 64 kB 703 SetMaxSize(cache_size); 704 InitCache(); 705 706 std::string first("some key"); 707 std::string second("something else"); 708 disk_cache::Entry* entry; 709 ASSERT_EQ(net::OK, CreateEntry(first, &entry)); 710 711 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(cache_size)); 712 memset(buffer->data(), 0, cache_size); 713 EXPECT_EQ(cache_size / 10, 714 WriteData(entry, 0, 0, buffer.get(), cache_size / 10, false)) 715 << "normal file"; 716 717 EXPECT_EQ(net::ERR_FAILED, 718 WriteData(entry, 1, 0, buffer.get(), cache_size / 5, false)) 719 << "file size above the limit"; 720 721 // By doubling the total size, we make this file cacheable. 722 SetMaxSize(cache_size * 2); 723 EXPECT_EQ(cache_size / 5, 724 WriteData(entry, 1, 0, buffer.get(), cache_size / 5, false)); 725 726 // Let's fill up the cache!. 727 SetMaxSize(cache_size * 10); 728 EXPECT_EQ(cache_size * 3 / 4, 729 WriteData(entry, 0, 0, buffer.get(), cache_size * 3 / 4, false)); 730 entry->Close(); 731 FlushQueueForTest(); 732 733 SetMaxSize(cache_size); 734 735 // The cache is 95% full. 736 737 ASSERT_EQ(net::OK, CreateEntry(second, &entry)); 738 EXPECT_EQ(cache_size / 10, 739 WriteData(entry, 0, 0, buffer.get(), cache_size / 10, false)); 740 741 disk_cache::Entry* entry2; 742 ASSERT_EQ(net::OK, CreateEntry("an extra key", &entry2)); 743 EXPECT_EQ(cache_size / 10, 744 WriteData(entry2, 0, 0, buffer.get(), cache_size / 10, false)); 745 entry2->Close(); // This will trigger the cache trim. 746 747 EXPECT_NE(net::OK, OpenEntry(first, &entry2)); 748 749 FlushQueueForTest(); // Make sure that we are done trimming the cache. 750 FlushQueueForTest(); // We may have posted two tasks to evict stuff. 751 752 entry->Close(); 753 ASSERT_EQ(net::OK, OpenEntry(second, &entry)); 754 EXPECT_EQ(cache_size / 10, entry->GetDataSize(0)); 755 entry->Close(); 756} 757 758TEST_F(DiskCacheBackendTest, SetSize) { 759 BackendSetSize(); 760} 761 762TEST_F(DiskCacheBackendTest, NewEvictionSetSize) { 763 SetNewEviction(); 764 BackendSetSize(); 765} 766 767TEST_F(DiskCacheBackendTest, MemoryOnlySetSize) { 768 SetMemoryOnlyMode(); 769 BackendSetSize(); 770} 771 772void DiskCacheBackendTest::BackendLoad() { 773 InitCache(); 774 int seed = static_cast<int>(Time::Now().ToInternalValue()); 775 srand(seed); 776 777 disk_cache::Entry* entries[100]; 778 for (int i = 0; i < 100; i++) { 779 std::string key = GenerateKey(true); 780 ASSERT_EQ(net::OK, CreateEntry(key, &entries[i])); 781 } 782 EXPECT_EQ(100, cache_->GetEntryCount()); 783 784 for (int i = 0; i < 100; i++) { 785 int source1 = rand() % 100; 786 int source2 = rand() % 100; 787 disk_cache::Entry* temp = entries[source1]; 788 entries[source1] = entries[source2]; 789 entries[source2] = temp; 790 } 791 792 for (int i = 0; i < 100; i++) { 793 disk_cache::Entry* entry; 794 ASSERT_EQ(net::OK, OpenEntry(entries[i]->GetKey(), &entry)); 795 EXPECT_TRUE(entry == entries[i]); 796 entry->Close(); 797 entries[i]->Doom(); 798 entries[i]->Close(); 799 } 800 FlushQueueForTest(); 801 EXPECT_EQ(0, cache_->GetEntryCount()); 802} 803 804TEST_F(DiskCacheBackendTest, Load) { 805 // Work with a tiny index table (16 entries) 806 SetMask(0xf); 807 SetMaxSize(0x100000); 808 BackendLoad(); 809} 810 811TEST_F(DiskCacheBackendTest, NewEvictionLoad) { 812 SetNewEviction(); 813 // Work with a tiny index table (16 entries) 814 SetMask(0xf); 815 SetMaxSize(0x100000); 816 BackendLoad(); 817} 818 819TEST_F(DiskCacheBackendTest, MemoryOnlyLoad) { 820 SetMaxSize(0x100000); 821 SetMemoryOnlyMode(); 822 BackendLoad(); 823} 824 825TEST_F(DiskCacheBackendTest, AppCacheLoad) { 826 SetCacheType(net::APP_CACHE); 827 // Work with a tiny index table (16 entries) 828 SetMask(0xf); 829 SetMaxSize(0x100000); 830 BackendLoad(); 831} 832 833TEST_F(DiskCacheBackendTest, ShaderCacheLoad) { 834 SetCacheType(net::SHADER_CACHE); 835 // Work with a tiny index table (16 entries) 836 SetMask(0xf); 837 SetMaxSize(0x100000); 838 BackendLoad(); 839} 840 841// Tests the chaining of an entry to the current head. 842void DiskCacheBackendTest::BackendChain() { 843 SetMask(0x1); // 2-entry table. 844 SetMaxSize(0x3000); // 12 kB. 845 InitCache(); 846 847 disk_cache::Entry* entry; 848 ASSERT_EQ(net::OK, CreateEntry("The first key", &entry)); 849 entry->Close(); 850 ASSERT_EQ(net::OK, CreateEntry("The Second key", &entry)); 851 entry->Close(); 852} 853 854TEST_F(DiskCacheBackendTest, Chain) { 855 BackendChain(); 856} 857 858TEST_F(DiskCacheBackendTest, NewEvictionChain) { 859 SetNewEviction(); 860 BackendChain(); 861} 862 863TEST_F(DiskCacheBackendTest, AppCacheChain) { 864 SetCacheType(net::APP_CACHE); 865 BackendChain(); 866} 867 868TEST_F(DiskCacheBackendTest, ShaderCacheChain) { 869 SetCacheType(net::SHADER_CACHE); 870 BackendChain(); 871} 872 873TEST_F(DiskCacheBackendTest, NewEvictionTrim) { 874 SetNewEviction(); 875 InitCache(); 876 877 disk_cache::Entry* entry; 878 for (int i = 0; i < 100; i++) { 879 std::string name(base::StringPrintf("Key %d", i)); 880 ASSERT_EQ(net::OK, CreateEntry(name, &entry)); 881 entry->Close(); 882 if (i < 90) { 883 // Entries 0 to 89 are in list 1; 90 to 99 are in list 0. 884 ASSERT_EQ(net::OK, OpenEntry(name, &entry)); 885 entry->Close(); 886 } 887 } 888 889 // The first eviction must come from list 1 (10% limit), the second must come 890 // from list 0. 891 TrimForTest(false); 892 EXPECT_NE(net::OK, OpenEntry("Key 0", &entry)); 893 TrimForTest(false); 894 EXPECT_NE(net::OK, OpenEntry("Key 90", &entry)); 895 896 // Double check that we still have the list tails. 897 ASSERT_EQ(net::OK, OpenEntry("Key 1", &entry)); 898 entry->Close(); 899 ASSERT_EQ(net::OK, OpenEntry("Key 91", &entry)); 900 entry->Close(); 901} 902 903// Before looking for invalid entries, let's check a valid entry. 904void DiskCacheBackendTest::BackendValidEntry() { 905 InitCache(); 906 907 std::string key("Some key"); 908 disk_cache::Entry* entry; 909 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 910 911 const int kSize = 50; 912 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize)); 913 memset(buffer1->data(), 0, kSize); 914 base::strlcpy(buffer1->data(), "And the data to save", kSize); 915 EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer1.get(), kSize, false)); 916 entry->Close(); 917 SimulateCrash(); 918 919 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 920 921 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize)); 922 memset(buffer2->data(), 0, kSize); 923 EXPECT_EQ(kSize, ReadData(entry, 0, 0, buffer2.get(), kSize)); 924 entry->Close(); 925 EXPECT_STREQ(buffer1->data(), buffer2->data()); 926} 927 928TEST_F(DiskCacheBackendTest, ValidEntry) { 929 BackendValidEntry(); 930} 931 932TEST_F(DiskCacheBackendTest, NewEvictionValidEntry) { 933 SetNewEviction(); 934 BackendValidEntry(); 935} 936 937// The same logic of the previous test (ValidEntry), but this time force the 938// entry to be invalid, simulating a crash in the middle. 939// We'll be leaking memory from this test. 940void DiskCacheBackendTest::BackendInvalidEntry() { 941 InitCache(); 942 943 std::string key("Some key"); 944 disk_cache::Entry* entry; 945 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 946 947 const int kSize = 50; 948 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); 949 memset(buffer->data(), 0, kSize); 950 base::strlcpy(buffer->data(), "And the data to save", kSize); 951 EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, false)); 952 SimulateCrash(); 953 954 EXPECT_NE(net::OK, OpenEntry(key, &entry)); 955 EXPECT_EQ(0, cache_->GetEntryCount()); 956} 957 958#if !defined(LEAK_SANITIZER) 959// We'll be leaking memory from this test. 960TEST_F(DiskCacheBackendTest, InvalidEntry) { 961 BackendInvalidEntry(); 962} 963 964// We'll be leaking memory from this test. 965TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry) { 966 SetNewEviction(); 967 BackendInvalidEntry(); 968} 969 970// We'll be leaking memory from this test. 971TEST_F(DiskCacheBackendTest, AppCacheInvalidEntry) { 972 SetCacheType(net::APP_CACHE); 973 BackendInvalidEntry(); 974} 975 976// We'll be leaking memory from this test. 977TEST_F(DiskCacheBackendTest, ShaderCacheInvalidEntry) { 978 SetCacheType(net::SHADER_CACHE); 979 BackendInvalidEntry(); 980} 981 982// Almost the same test, but this time crash the cache after reading an entry. 983// We'll be leaking memory from this test. 984void DiskCacheBackendTest::BackendInvalidEntryRead() { 985 InitCache(); 986 987 std::string key("Some key"); 988 disk_cache::Entry* entry; 989 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 990 991 const int kSize = 50; 992 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); 993 memset(buffer->data(), 0, kSize); 994 base::strlcpy(buffer->data(), "And the data to save", kSize); 995 EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, false)); 996 entry->Close(); 997 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 998 EXPECT_EQ(kSize, ReadData(entry, 0, 0, buffer.get(), kSize)); 999 1000 SimulateCrash(); 1001 1002 if (type_ == net::APP_CACHE) { 1003 // Reading an entry and crashing should not make it dirty. 1004 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 1005 EXPECT_EQ(1, cache_->GetEntryCount()); 1006 entry->Close(); 1007 } else { 1008 EXPECT_NE(net::OK, OpenEntry(key, &entry)); 1009 EXPECT_EQ(0, cache_->GetEntryCount()); 1010 } 1011} 1012 1013// We'll be leaking memory from this test. 1014TEST_F(DiskCacheBackendTest, InvalidEntryRead) { 1015 BackendInvalidEntryRead(); 1016} 1017 1018// We'll be leaking memory from this test. 1019TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntryRead) { 1020 SetNewEviction(); 1021 BackendInvalidEntryRead(); 1022} 1023 1024// We'll be leaking memory from this test. 1025TEST_F(DiskCacheBackendTest, AppCacheInvalidEntryRead) { 1026 SetCacheType(net::APP_CACHE); 1027 BackendInvalidEntryRead(); 1028} 1029 1030// We'll be leaking memory from this test. 1031TEST_F(DiskCacheBackendTest, ShaderCacheInvalidEntryRead) { 1032 SetCacheType(net::SHADER_CACHE); 1033 BackendInvalidEntryRead(); 1034} 1035 1036// We'll be leaking memory from this test. 1037void DiskCacheBackendTest::BackendInvalidEntryWithLoad() { 1038 // Work with a tiny index table (16 entries) 1039 SetMask(0xf); 1040 SetMaxSize(0x100000); 1041 InitCache(); 1042 1043 int seed = static_cast<int>(Time::Now().ToInternalValue()); 1044 srand(seed); 1045 1046 const int kNumEntries = 100; 1047 disk_cache::Entry* entries[kNumEntries]; 1048 for (int i = 0; i < kNumEntries; i++) { 1049 std::string key = GenerateKey(true); 1050 ASSERT_EQ(net::OK, CreateEntry(key, &entries[i])); 1051 } 1052 EXPECT_EQ(kNumEntries, cache_->GetEntryCount()); 1053 1054 for (int i = 0; i < kNumEntries; i++) { 1055 int source1 = rand() % kNumEntries; 1056 int source2 = rand() % kNumEntries; 1057 disk_cache::Entry* temp = entries[source1]; 1058 entries[source1] = entries[source2]; 1059 entries[source2] = temp; 1060 } 1061 1062 std::string keys[kNumEntries]; 1063 for (int i = 0; i < kNumEntries; i++) { 1064 keys[i] = entries[i]->GetKey(); 1065 if (i < kNumEntries / 2) 1066 entries[i]->Close(); 1067 } 1068 1069 SimulateCrash(); 1070 1071 for (int i = kNumEntries / 2; i < kNumEntries; i++) { 1072 disk_cache::Entry* entry; 1073 EXPECT_NE(net::OK, OpenEntry(keys[i], &entry)); 1074 } 1075 1076 for (int i = 0; i < kNumEntries / 2; i++) { 1077 disk_cache::Entry* entry; 1078 ASSERT_EQ(net::OK, OpenEntry(keys[i], &entry)); 1079 entry->Close(); 1080 } 1081 1082 EXPECT_EQ(kNumEntries / 2, cache_->GetEntryCount()); 1083} 1084 1085// We'll be leaking memory from this test. 1086TEST_F(DiskCacheBackendTest, InvalidEntryWithLoad) { 1087 BackendInvalidEntryWithLoad(); 1088} 1089 1090// We'll be leaking memory from this test. 1091TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntryWithLoad) { 1092 SetNewEviction(); 1093 BackendInvalidEntryWithLoad(); 1094} 1095 1096// We'll be leaking memory from this test. 1097TEST_F(DiskCacheBackendTest, AppCacheInvalidEntryWithLoad) { 1098 SetCacheType(net::APP_CACHE); 1099 BackendInvalidEntryWithLoad(); 1100} 1101 1102// We'll be leaking memory from this test. 1103TEST_F(DiskCacheBackendTest, ShaderCacheInvalidEntryWithLoad) { 1104 SetCacheType(net::SHADER_CACHE); 1105 BackendInvalidEntryWithLoad(); 1106} 1107 1108// We'll be leaking memory from this test. 1109void DiskCacheBackendTest::BackendTrimInvalidEntry() { 1110 const int kSize = 0x3000; // 12 kB 1111 SetMaxSize(kSize * 10); 1112 InitCache(); 1113 1114 std::string first("some key"); 1115 std::string second("something else"); 1116 disk_cache::Entry* entry; 1117 ASSERT_EQ(net::OK, CreateEntry(first, &entry)); 1118 1119 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); 1120 memset(buffer->data(), 0, kSize); 1121 EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, false)); 1122 1123 // Simulate a crash. 1124 SimulateCrash(); 1125 1126 ASSERT_EQ(net::OK, CreateEntry(second, &entry)); 1127 EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, false)); 1128 1129 EXPECT_EQ(2, cache_->GetEntryCount()); 1130 SetMaxSize(kSize); 1131 entry->Close(); // Trim the cache. 1132 FlushQueueForTest(); 1133 1134 // If we evicted the entry in less than 20mS, we have one entry in the cache; 1135 // if it took more than that, we posted a task and we'll delete the second 1136 // entry too. 1137 base::MessageLoop::current()->RunUntilIdle(); 1138 1139 // This may be not thread-safe in general, but for now it's OK so add some 1140 // ThreadSanitizer annotations to ignore data races on cache_. 1141 // See http://crbug.com/55970 1142 ANNOTATE_IGNORE_READS_BEGIN(); 1143 EXPECT_GE(1, cache_->GetEntryCount()); 1144 ANNOTATE_IGNORE_READS_END(); 1145 1146 EXPECT_NE(net::OK, OpenEntry(first, &entry)); 1147} 1148 1149// We'll be leaking memory from this test. 1150TEST_F(DiskCacheBackendTest, TrimInvalidEntry) { 1151 BackendTrimInvalidEntry(); 1152} 1153 1154// We'll be leaking memory from this test. 1155TEST_F(DiskCacheBackendTest, NewEvictionTrimInvalidEntry) { 1156 SetNewEviction(); 1157 BackendTrimInvalidEntry(); 1158} 1159 1160// We'll be leaking memory from this test. 1161void DiskCacheBackendTest::BackendTrimInvalidEntry2() { 1162 SetMask(0xf); // 16-entry table. 1163 1164 const int kSize = 0x3000; // 12 kB 1165 SetMaxSize(kSize * 40); 1166 InitCache(); 1167 1168 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); 1169 memset(buffer->data(), 0, kSize); 1170 disk_cache::Entry* entry; 1171 1172 // Writing 32 entries to this cache chains most of them. 1173 for (int i = 0; i < 32; i++) { 1174 std::string key(base::StringPrintf("some key %d", i)); 1175 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 1176 EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, false)); 1177 entry->Close(); 1178 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 1179 // Note that we are not closing the entries. 1180 } 1181 1182 // Simulate a crash. 1183 SimulateCrash(); 1184 1185 ASSERT_EQ(net::OK, CreateEntry("Something else", &entry)); 1186 EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, false)); 1187 1188 FlushQueueForTest(); 1189 EXPECT_EQ(33, cache_->GetEntryCount()); 1190 SetMaxSize(kSize); 1191 1192 // For the new eviction code, all corrupt entries are on the second list so 1193 // they are not going away that easy. 1194 if (new_eviction_) { 1195 EXPECT_EQ(net::OK, DoomAllEntries()); 1196 } 1197 1198 entry->Close(); // Trim the cache. 1199 FlushQueueForTest(); 1200 1201 // We may abort the eviction before cleaning up everything. 1202 base::MessageLoop::current()->RunUntilIdle(); 1203 FlushQueueForTest(); 1204 // If it's not clear enough: we may still have eviction tasks running at this 1205 // time, so the number of entries is changing while we read it. 1206 ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN(); 1207 EXPECT_GE(30, cache_->GetEntryCount()); 1208 ANNOTATE_IGNORE_READS_AND_WRITES_END(); 1209} 1210 1211// We'll be leaking memory from this test. 1212TEST_F(DiskCacheBackendTest, TrimInvalidEntry2) { 1213 BackendTrimInvalidEntry2(); 1214} 1215 1216// We'll be leaking memory from this test. 1217TEST_F(DiskCacheBackendTest, NewEvictionTrimInvalidEntry2) { 1218 SetNewEviction(); 1219 BackendTrimInvalidEntry2(); 1220} 1221#endif // !defined(LEAK_SANITIZER) 1222 1223void DiskCacheBackendTest::BackendEnumerations() { 1224 InitCache(); 1225 Time initial = Time::Now(); 1226 1227 const int kNumEntries = 100; 1228 for (int i = 0; i < kNumEntries; i++) { 1229 std::string key = GenerateKey(true); 1230 disk_cache::Entry* entry; 1231 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 1232 entry->Close(); 1233 } 1234 EXPECT_EQ(kNumEntries, cache_->GetEntryCount()); 1235 Time final = Time::Now(); 1236 1237 disk_cache::Entry* entry; 1238 void* iter = NULL; 1239 int count = 0; 1240 Time last_modified[kNumEntries]; 1241 Time last_used[kNumEntries]; 1242 while (OpenNextEntry(&iter, &entry) == net::OK) { 1243 ASSERT_TRUE(NULL != entry); 1244 if (count < kNumEntries) { 1245 last_modified[count] = entry->GetLastModified(); 1246 last_used[count] = entry->GetLastUsed(); 1247 EXPECT_TRUE(initial <= last_modified[count]); 1248 EXPECT_TRUE(final >= last_modified[count]); 1249 } 1250 1251 entry->Close(); 1252 count++; 1253 }; 1254 EXPECT_EQ(kNumEntries, count); 1255 1256 iter = NULL; 1257 count = 0; 1258 // The previous enumeration should not have changed the timestamps. 1259 while (OpenNextEntry(&iter, &entry) == net::OK) { 1260 ASSERT_TRUE(NULL != entry); 1261 if (count < kNumEntries) { 1262 EXPECT_TRUE(last_modified[count] == entry->GetLastModified()); 1263 EXPECT_TRUE(last_used[count] == entry->GetLastUsed()); 1264 } 1265 entry->Close(); 1266 count++; 1267 }; 1268 EXPECT_EQ(kNumEntries, count); 1269} 1270 1271TEST_F(DiskCacheBackendTest, Enumerations) { 1272 BackendEnumerations(); 1273} 1274 1275TEST_F(DiskCacheBackendTest, NewEvictionEnumerations) { 1276 SetNewEviction(); 1277 BackendEnumerations(); 1278} 1279 1280TEST_F(DiskCacheBackendTest, MemoryOnlyEnumerations) { 1281 SetMemoryOnlyMode(); 1282 BackendEnumerations(); 1283} 1284 1285TEST_F(DiskCacheBackendTest, ShaderCacheEnumerations) { 1286 SetCacheType(net::SHADER_CACHE); 1287 BackendEnumerations(); 1288} 1289 1290TEST_F(DiskCacheBackendTest, AppCacheEnumerations) { 1291 SetCacheType(net::APP_CACHE); 1292 BackendEnumerations(); 1293} 1294 1295// Verifies enumerations while entries are open. 1296void DiskCacheBackendTest::BackendEnumerations2() { 1297 InitCache(); 1298 const std::string first("first"); 1299 const std::string second("second"); 1300 disk_cache::Entry *entry1, *entry2; 1301 ASSERT_EQ(net::OK, CreateEntry(first, &entry1)); 1302 entry1->Close(); 1303 ASSERT_EQ(net::OK, CreateEntry(second, &entry2)); 1304 entry2->Close(); 1305 FlushQueueForTest(); 1306 1307 // Make sure that the timestamp is not the same. 1308 AddDelay(); 1309 ASSERT_EQ(net::OK, OpenEntry(second, &entry1)); 1310 void* iter = NULL; 1311 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry2)); 1312 EXPECT_EQ(entry2->GetKey(), second); 1313 1314 // Two entries and the iterator pointing at "first". 1315 entry1->Close(); 1316 entry2->Close(); 1317 1318 // The iterator should still be valid, so we should not crash. 1319 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry2)); 1320 EXPECT_EQ(entry2->GetKey(), first); 1321 entry2->Close(); 1322 cache_->EndEnumeration(&iter); 1323 1324 // Modify the oldest entry and get the newest element. 1325 ASSERT_EQ(net::OK, OpenEntry(first, &entry1)); 1326 EXPECT_EQ(0, WriteData(entry1, 0, 200, NULL, 0, false)); 1327 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry2)); 1328 if (type_ == net::APP_CACHE) { 1329 // The list is not updated. 1330 EXPECT_EQ(entry2->GetKey(), second); 1331 } else { 1332 EXPECT_EQ(entry2->GetKey(), first); 1333 } 1334 1335 entry1->Close(); 1336 entry2->Close(); 1337 cache_->EndEnumeration(&iter); 1338} 1339 1340TEST_F(DiskCacheBackendTest, Enumerations2) { 1341 BackendEnumerations2(); 1342} 1343 1344TEST_F(DiskCacheBackendTest, NewEvictionEnumerations2) { 1345 SetNewEviction(); 1346 BackendEnumerations2(); 1347} 1348 1349TEST_F(DiskCacheBackendTest, MemoryOnlyEnumerations2) { 1350 SetMemoryOnlyMode(); 1351 BackendEnumerations2(); 1352} 1353 1354TEST_F(DiskCacheBackendTest, AppCacheEnumerations2) { 1355 SetCacheType(net::APP_CACHE); 1356 BackendEnumerations2(); 1357} 1358 1359TEST_F(DiskCacheBackendTest, ShaderCacheEnumerations2) { 1360 SetCacheType(net::SHADER_CACHE); 1361 BackendEnumerations2(); 1362} 1363 1364// Verify that ReadData calls do not update the LRU cache 1365// when using the SHADER_CACHE type. 1366TEST_F(DiskCacheBackendTest, ShaderCacheEnumerationReadData) { 1367 SetCacheType(net::SHADER_CACHE); 1368 InitCache(); 1369 const std::string first("first"); 1370 const std::string second("second"); 1371 disk_cache::Entry *entry1, *entry2; 1372 const int kSize = 50; 1373 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize)); 1374 1375 ASSERT_EQ(net::OK, CreateEntry(first, &entry1)); 1376 memset(buffer1->data(), 0, kSize); 1377 base::strlcpy(buffer1->data(), "And the data to save", kSize); 1378 EXPECT_EQ(kSize, WriteData(entry1, 0, 0, buffer1.get(), kSize, false)); 1379 1380 ASSERT_EQ(net::OK, CreateEntry(second, &entry2)); 1381 entry2->Close(); 1382 1383 FlushQueueForTest(); 1384 1385 // Make sure that the timestamp is not the same. 1386 AddDelay(); 1387 1388 // Read from the last item in the LRU. 1389 EXPECT_EQ(kSize, ReadData(entry1, 0, 0, buffer1.get(), kSize)); 1390 entry1->Close(); 1391 1392 void* iter = NULL; 1393 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry2)); 1394 EXPECT_EQ(entry2->GetKey(), second); 1395 entry2->Close(); 1396 cache_->EndEnumeration(&iter); 1397} 1398 1399#if !defined(LEAK_SANITIZER) 1400// Verify handling of invalid entries while doing enumerations. 1401// We'll be leaking memory from this test. 1402void DiskCacheBackendTest::BackendInvalidEntryEnumeration() { 1403 InitCache(); 1404 1405 std::string key("Some key"); 1406 disk_cache::Entry *entry, *entry1, *entry2; 1407 ASSERT_EQ(net::OK, CreateEntry(key, &entry1)); 1408 1409 const int kSize = 50; 1410 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize)); 1411 memset(buffer1->data(), 0, kSize); 1412 base::strlcpy(buffer1->data(), "And the data to save", kSize); 1413 EXPECT_EQ(kSize, WriteData(entry1, 0, 0, buffer1.get(), kSize, false)); 1414 entry1->Close(); 1415 ASSERT_EQ(net::OK, OpenEntry(key, &entry1)); 1416 EXPECT_EQ(kSize, ReadData(entry1, 0, 0, buffer1.get(), kSize)); 1417 1418 std::string key2("Another key"); 1419 ASSERT_EQ(net::OK, CreateEntry(key2, &entry2)); 1420 entry2->Close(); 1421 ASSERT_EQ(2, cache_->GetEntryCount()); 1422 1423 SimulateCrash(); 1424 1425 void* iter = NULL; 1426 int count = 0; 1427 while (OpenNextEntry(&iter, &entry) == net::OK) { 1428 ASSERT_TRUE(NULL != entry); 1429 EXPECT_EQ(key2, entry->GetKey()); 1430 entry->Close(); 1431 count++; 1432 }; 1433 EXPECT_EQ(1, count); 1434 EXPECT_EQ(1, cache_->GetEntryCount()); 1435} 1436 1437// We'll be leaking memory from this test. 1438TEST_F(DiskCacheBackendTest, InvalidEntryEnumeration) { 1439 BackendInvalidEntryEnumeration(); 1440} 1441 1442// We'll be leaking memory from this test. 1443TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntryEnumeration) { 1444 SetNewEviction(); 1445 BackendInvalidEntryEnumeration(); 1446} 1447#endif // !defined(LEAK_SANITIZER) 1448 1449// Tests that if for some reason entries are modified close to existing cache 1450// iterators, we don't generate fatal errors or reset the cache. 1451void DiskCacheBackendTest::BackendFixEnumerators() { 1452 InitCache(); 1453 1454 int seed = static_cast<int>(Time::Now().ToInternalValue()); 1455 srand(seed); 1456 1457 const int kNumEntries = 10; 1458 for (int i = 0; i < kNumEntries; i++) { 1459 std::string key = GenerateKey(true); 1460 disk_cache::Entry* entry; 1461 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 1462 entry->Close(); 1463 } 1464 EXPECT_EQ(kNumEntries, cache_->GetEntryCount()); 1465 1466 disk_cache::Entry *entry1, *entry2; 1467 void* iter1 = NULL; 1468 void* iter2 = NULL; 1469 ASSERT_EQ(net::OK, OpenNextEntry(&iter1, &entry1)); 1470 ASSERT_TRUE(NULL != entry1); 1471 entry1->Close(); 1472 entry1 = NULL; 1473 1474 // Let's go to the middle of the list. 1475 for (int i = 0; i < kNumEntries / 2; i++) { 1476 if (entry1) 1477 entry1->Close(); 1478 ASSERT_EQ(net::OK, OpenNextEntry(&iter1, &entry1)); 1479 ASSERT_TRUE(NULL != entry1); 1480 1481 ASSERT_EQ(net::OK, OpenNextEntry(&iter2, &entry2)); 1482 ASSERT_TRUE(NULL != entry2); 1483 entry2->Close(); 1484 } 1485 1486 // Messing up with entry1 will modify entry2->next. 1487 entry1->Doom(); 1488 ASSERT_EQ(net::OK, OpenNextEntry(&iter2, &entry2)); 1489 ASSERT_TRUE(NULL != entry2); 1490 1491 // The link entry2->entry1 should be broken. 1492 EXPECT_NE(entry2->GetKey(), entry1->GetKey()); 1493 entry1->Close(); 1494 entry2->Close(); 1495 1496 // And the second iterator should keep working. 1497 ASSERT_EQ(net::OK, OpenNextEntry(&iter2, &entry2)); 1498 ASSERT_TRUE(NULL != entry2); 1499 entry2->Close(); 1500 1501 cache_->EndEnumeration(&iter1); 1502 cache_->EndEnumeration(&iter2); 1503} 1504 1505TEST_F(DiskCacheBackendTest, FixEnumerators) { 1506 BackendFixEnumerators(); 1507} 1508 1509TEST_F(DiskCacheBackendTest, NewEvictionFixEnumerators) { 1510 SetNewEviction(); 1511 BackendFixEnumerators(); 1512} 1513 1514void DiskCacheBackendTest::BackendDoomRecent() { 1515 InitCache(); 1516 1517 disk_cache::Entry *entry; 1518 ASSERT_EQ(net::OK, CreateEntry("first", &entry)); 1519 entry->Close(); 1520 ASSERT_EQ(net::OK, CreateEntry("second", &entry)); 1521 entry->Close(); 1522 FlushQueueForTest(); 1523 1524 AddDelay(); 1525 Time middle = Time::Now(); 1526 1527 ASSERT_EQ(net::OK, CreateEntry("third", &entry)); 1528 entry->Close(); 1529 ASSERT_EQ(net::OK, CreateEntry("fourth", &entry)); 1530 entry->Close(); 1531 FlushQueueForTest(); 1532 1533 AddDelay(); 1534 Time final = Time::Now(); 1535 1536 ASSERT_EQ(4, cache_->GetEntryCount()); 1537 EXPECT_EQ(net::OK, DoomEntriesSince(final)); 1538 ASSERT_EQ(4, cache_->GetEntryCount()); 1539 1540 EXPECT_EQ(net::OK, DoomEntriesSince(middle)); 1541 ASSERT_EQ(2, cache_->GetEntryCount()); 1542 1543 ASSERT_EQ(net::OK, OpenEntry("second", &entry)); 1544 entry->Close(); 1545} 1546 1547TEST_F(DiskCacheBackendTest, DoomRecent) { 1548 BackendDoomRecent(); 1549} 1550 1551TEST_F(DiskCacheBackendTest, NewEvictionDoomRecent) { 1552 SetNewEviction(); 1553 BackendDoomRecent(); 1554} 1555 1556TEST_F(DiskCacheBackendTest, MemoryOnlyDoomRecent) { 1557 SetMemoryOnlyMode(); 1558 BackendDoomRecent(); 1559} 1560 1561TEST_F(DiskCacheBackendTest, MemoryOnlyDoomEntriesSinceSparse) { 1562 SetMemoryOnlyMode(); 1563 base::Time start; 1564 InitSparseCache(&start, NULL); 1565 DoomEntriesSince(start); 1566 EXPECT_EQ(1, cache_->GetEntryCount()); 1567} 1568 1569TEST_F(DiskCacheBackendTest, DoomEntriesSinceSparse) { 1570 base::Time start; 1571 InitSparseCache(&start, NULL); 1572 DoomEntriesSince(start); 1573 // NOTE: BackendImpl counts child entries in its GetEntryCount(), while 1574 // MemBackendImpl does not. Thats why expected value differs here from 1575 // MemoryOnlyDoomEntriesSinceSparse. 1576 EXPECT_EQ(3, cache_->GetEntryCount()); 1577} 1578 1579TEST_F(DiskCacheBackendTest, MemoryOnlyDoomAllSparse) { 1580 SetMemoryOnlyMode(); 1581 InitSparseCache(NULL, NULL); 1582 EXPECT_EQ(net::OK, DoomAllEntries()); 1583 EXPECT_EQ(0, cache_->GetEntryCount()); 1584} 1585 1586TEST_F(DiskCacheBackendTest, DoomAllSparse) { 1587 InitSparseCache(NULL, NULL); 1588 EXPECT_EQ(net::OK, DoomAllEntries()); 1589 EXPECT_EQ(0, cache_->GetEntryCount()); 1590} 1591 1592void DiskCacheBackendTest::BackendDoomBetween() { 1593 InitCache(); 1594 1595 disk_cache::Entry *entry; 1596 ASSERT_EQ(net::OK, CreateEntry("first", &entry)); 1597 entry->Close(); 1598 FlushQueueForTest(); 1599 1600 AddDelay(); 1601 Time middle_start = Time::Now(); 1602 1603 ASSERT_EQ(net::OK, CreateEntry("second", &entry)); 1604 entry->Close(); 1605 ASSERT_EQ(net::OK, CreateEntry("third", &entry)); 1606 entry->Close(); 1607 FlushQueueForTest(); 1608 1609 AddDelay(); 1610 Time middle_end = Time::Now(); 1611 1612 ASSERT_EQ(net::OK, CreateEntry("fourth", &entry)); 1613 entry->Close(); 1614 ASSERT_EQ(net::OK, OpenEntry("fourth", &entry)); 1615 entry->Close(); 1616 FlushQueueForTest(); 1617 1618 AddDelay(); 1619 Time final = Time::Now(); 1620 1621 ASSERT_EQ(4, cache_->GetEntryCount()); 1622 EXPECT_EQ(net::OK, DoomEntriesBetween(middle_start, middle_end)); 1623 ASSERT_EQ(2, cache_->GetEntryCount()); 1624 1625 ASSERT_EQ(net::OK, OpenEntry("fourth", &entry)); 1626 entry->Close(); 1627 1628 EXPECT_EQ(net::OK, DoomEntriesBetween(middle_start, final)); 1629 ASSERT_EQ(1, cache_->GetEntryCount()); 1630 1631 ASSERT_EQ(net::OK, OpenEntry("first", &entry)); 1632 entry->Close(); 1633} 1634 1635TEST_F(DiskCacheBackendTest, DoomBetween) { 1636 BackendDoomBetween(); 1637} 1638 1639TEST_F(DiskCacheBackendTest, NewEvictionDoomBetween) { 1640 SetNewEviction(); 1641 BackendDoomBetween(); 1642} 1643 1644TEST_F(DiskCacheBackendTest, MemoryOnlyDoomBetween) { 1645 SetMemoryOnlyMode(); 1646 BackendDoomBetween(); 1647} 1648 1649TEST_F(DiskCacheBackendTest, MemoryOnlyDoomEntriesBetweenSparse) { 1650 SetMemoryOnlyMode(); 1651 base::Time start, end; 1652 InitSparseCache(&start, &end); 1653 DoomEntriesBetween(start, end); 1654 EXPECT_EQ(3, cache_->GetEntryCount()); 1655 1656 start = end; 1657 end = base::Time::Now(); 1658 DoomEntriesBetween(start, end); 1659 EXPECT_EQ(1, cache_->GetEntryCount()); 1660} 1661 1662TEST_F(DiskCacheBackendTest, DoomEntriesBetweenSparse) { 1663 base::Time start, end; 1664 InitSparseCache(&start, &end); 1665 DoomEntriesBetween(start, end); 1666 EXPECT_EQ(9, cache_->GetEntryCount()); 1667 1668 start = end; 1669 end = base::Time::Now(); 1670 DoomEntriesBetween(start, end); 1671 EXPECT_EQ(3, cache_->GetEntryCount()); 1672} 1673 1674void DiskCacheBackendTest::BackendTransaction(const std::string& name, 1675 int num_entries, bool load) { 1676 success_ = false; 1677 ASSERT_TRUE(CopyTestCache(name)); 1678 DisableFirstCleanup(); 1679 1680 uint32 mask; 1681 if (load) { 1682 mask = 0xf; 1683 SetMaxSize(0x100000); 1684 } else { 1685 // Clear the settings from the previous run. 1686 mask = 0; 1687 SetMaxSize(0); 1688 } 1689 SetMask(mask); 1690 1691 InitCache(); 1692 ASSERT_EQ(num_entries + 1, cache_->GetEntryCount()); 1693 1694 std::string key("the first key"); 1695 disk_cache::Entry* entry1; 1696 ASSERT_NE(net::OK, OpenEntry(key, &entry1)); 1697 1698 int actual = cache_->GetEntryCount(); 1699 if (num_entries != actual) { 1700 ASSERT_TRUE(load); 1701 // If there is a heavy load, inserting an entry will make another entry 1702 // dirty (on the hash bucket) so two entries are removed. 1703 ASSERT_EQ(num_entries - 1, actual); 1704 } 1705 1706 cache_.reset(); 1707 cache_impl_ = NULL; 1708 1709 ASSERT_TRUE(CheckCacheIntegrity(cache_path_, new_eviction_, mask)); 1710 success_ = true; 1711} 1712 1713void DiskCacheBackendTest::BackendRecoverInsert() { 1714 // Tests with an empty cache. 1715 BackendTransaction("insert_empty1", 0, false); 1716 ASSERT_TRUE(success_) << "insert_empty1"; 1717 BackendTransaction("insert_empty2", 0, false); 1718 ASSERT_TRUE(success_) << "insert_empty2"; 1719 BackendTransaction("insert_empty3", 0, false); 1720 ASSERT_TRUE(success_) << "insert_empty3"; 1721 1722 // Tests with one entry on the cache. 1723 BackendTransaction("insert_one1", 1, false); 1724 ASSERT_TRUE(success_) << "insert_one1"; 1725 BackendTransaction("insert_one2", 1, false); 1726 ASSERT_TRUE(success_) << "insert_one2"; 1727 BackendTransaction("insert_one3", 1, false); 1728 ASSERT_TRUE(success_) << "insert_one3"; 1729 1730 // Tests with one hundred entries on the cache, tiny index. 1731 BackendTransaction("insert_load1", 100, true); 1732 ASSERT_TRUE(success_) << "insert_load1"; 1733 BackendTransaction("insert_load2", 100, true); 1734 ASSERT_TRUE(success_) << "insert_load2"; 1735} 1736 1737TEST_F(DiskCacheBackendTest, RecoverInsert) { 1738 BackendRecoverInsert(); 1739} 1740 1741TEST_F(DiskCacheBackendTest, NewEvictionRecoverInsert) { 1742 SetNewEviction(); 1743 BackendRecoverInsert(); 1744} 1745 1746void DiskCacheBackendTest::BackendRecoverRemove() { 1747 // Removing the only element. 1748 BackendTransaction("remove_one1", 0, false); 1749 ASSERT_TRUE(success_) << "remove_one1"; 1750 BackendTransaction("remove_one2", 0, false); 1751 ASSERT_TRUE(success_) << "remove_one2"; 1752 BackendTransaction("remove_one3", 0, false); 1753 ASSERT_TRUE(success_) << "remove_one3"; 1754 1755 // Removing the head. 1756 BackendTransaction("remove_head1", 1, false); 1757 ASSERT_TRUE(success_) << "remove_head1"; 1758 BackendTransaction("remove_head2", 1, false); 1759 ASSERT_TRUE(success_) << "remove_head2"; 1760 BackendTransaction("remove_head3", 1, false); 1761 ASSERT_TRUE(success_) << "remove_head3"; 1762 1763 // Removing the tail. 1764 BackendTransaction("remove_tail1", 1, false); 1765 ASSERT_TRUE(success_) << "remove_tail1"; 1766 BackendTransaction("remove_tail2", 1, false); 1767 ASSERT_TRUE(success_) << "remove_tail2"; 1768 BackendTransaction("remove_tail3", 1, false); 1769 ASSERT_TRUE(success_) << "remove_tail3"; 1770 1771 // Removing with one hundred entries on the cache, tiny index. 1772 BackendTransaction("remove_load1", 100, true); 1773 ASSERT_TRUE(success_) << "remove_load1"; 1774 BackendTransaction("remove_load2", 100, true); 1775 ASSERT_TRUE(success_) << "remove_load2"; 1776 BackendTransaction("remove_load3", 100, true); 1777 ASSERT_TRUE(success_) << "remove_load3"; 1778 1779 // This case cannot be reverted. 1780 BackendTransaction("remove_one4", 0, false); 1781 ASSERT_TRUE(success_) << "remove_one4"; 1782 BackendTransaction("remove_head4", 1, false); 1783 ASSERT_TRUE(success_) << "remove_head4"; 1784} 1785 1786TEST_F(DiskCacheBackendTest, RecoverRemove) { 1787 BackendRecoverRemove(); 1788} 1789 1790TEST_F(DiskCacheBackendTest, NewEvictionRecoverRemove) { 1791 SetNewEviction(); 1792 BackendRecoverRemove(); 1793} 1794 1795void DiskCacheBackendTest::BackendRecoverWithEviction() { 1796 success_ = false; 1797 ASSERT_TRUE(CopyTestCache("insert_load1")); 1798 DisableFirstCleanup(); 1799 1800 SetMask(0xf); 1801 SetMaxSize(0x1000); 1802 1803 // We should not crash here. 1804 InitCache(); 1805 DisableIntegrityCheck(); 1806} 1807 1808TEST_F(DiskCacheBackendTest, RecoverWithEviction) { 1809 BackendRecoverWithEviction(); 1810} 1811 1812TEST_F(DiskCacheBackendTest, NewEvictionRecoverWithEviction) { 1813 SetNewEviction(); 1814 BackendRecoverWithEviction(); 1815} 1816 1817// Tests that the |BackendImpl| fails to start with the wrong cache version. 1818TEST_F(DiskCacheTest, WrongVersion) { 1819 ASSERT_TRUE(CopyTestCache("wrong_version")); 1820 base::Thread cache_thread("CacheThread"); 1821 ASSERT_TRUE(cache_thread.StartWithOptions( 1822 base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); 1823 net::TestCompletionCallback cb; 1824 1825 scoped_ptr<disk_cache::BackendImpl> cache(new disk_cache::BackendImpl( 1826 cache_path_, cache_thread.message_loop_proxy().get(), NULL)); 1827 int rv = cache->Init(cb.callback()); 1828 ASSERT_EQ(net::ERR_FAILED, cb.GetResult(rv)); 1829} 1830 1831class BadEntropyProvider : public base::FieldTrial::EntropyProvider { 1832 public: 1833 virtual ~BadEntropyProvider() {} 1834 1835 virtual double GetEntropyForTrial(const std::string& trial_name, 1836 uint32 randomization_seed) const OVERRIDE { 1837 return 0.5; 1838 } 1839}; 1840 1841// Tests that the disk cache successfully joins the control group, dropping the 1842// existing cache in favour of a new empty cache. 1843// Disabled on android since this test requires cache creator to create 1844// blockfile caches. 1845#if !defined(OS_ANDROID) 1846TEST_F(DiskCacheTest, SimpleCacheControlJoin) { 1847 base::Thread cache_thread("CacheThread"); 1848 ASSERT_TRUE(cache_thread.StartWithOptions( 1849 base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); 1850 1851 scoped_ptr<disk_cache::BackendImpl> cache = 1852 CreateExistingEntryCache(cache_thread, cache_path_); 1853 ASSERT_TRUE(cache.get()); 1854 cache.reset(); 1855 1856 // Instantiate the SimpleCacheTrial, forcing this run into the 1857 // ExperimentControl group. 1858 base::FieldTrialList field_trial_list(new BadEntropyProvider()); 1859 base::FieldTrialList::CreateFieldTrial("SimpleCacheTrial", 1860 "ExperimentControl"); 1861 net::TestCompletionCallback cb; 1862 scoped_ptr<disk_cache::Backend> base_cache; 1863 int rv = 1864 disk_cache::CreateCacheBackend(net::DISK_CACHE, 1865 net::CACHE_BACKEND_BLOCKFILE, 1866 cache_path_, 1867 0, 1868 true, 1869 cache_thread.message_loop_proxy().get(), 1870 NULL, 1871 &base_cache, 1872 cb.callback()); 1873 ASSERT_EQ(net::OK, cb.GetResult(rv)); 1874 EXPECT_EQ(0, base_cache->GetEntryCount()); 1875} 1876#endif 1877 1878// Tests that the disk cache can restart in the control group preserving 1879// existing entries. 1880TEST_F(DiskCacheTest, SimpleCacheControlRestart) { 1881 // Instantiate the SimpleCacheTrial, forcing this run into the 1882 // ExperimentControl group. 1883 base::FieldTrialList field_trial_list(new BadEntropyProvider()); 1884 base::FieldTrialList::CreateFieldTrial("SimpleCacheTrial", 1885 "ExperimentControl"); 1886 1887 base::Thread cache_thread("CacheThread"); 1888 ASSERT_TRUE(cache_thread.StartWithOptions( 1889 base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); 1890 1891 scoped_ptr<disk_cache::BackendImpl> cache = 1892 CreateExistingEntryCache(cache_thread, cache_path_); 1893 ASSERT_TRUE(cache.get()); 1894 1895 net::TestCompletionCallback cb; 1896 1897 const int kRestartCount = 5; 1898 for (int i = 0; i < kRestartCount; ++i) { 1899 cache.reset(new disk_cache::BackendImpl( 1900 cache_path_, cache_thread.message_loop_proxy(), NULL)); 1901 int rv = cache->Init(cb.callback()); 1902 ASSERT_EQ(net::OK, cb.GetResult(rv)); 1903 EXPECT_EQ(1, cache->GetEntryCount()); 1904 1905 disk_cache::Entry* entry = NULL; 1906 rv = cache->OpenEntry(kExistingEntryKey, &entry, cb.callback()); 1907 EXPECT_EQ(net::OK, cb.GetResult(rv)); 1908 EXPECT_TRUE(entry); 1909 entry->Close(); 1910 } 1911} 1912 1913// Tests that the disk cache can leave the control group preserving existing 1914// entries. 1915TEST_F(DiskCacheTest, SimpleCacheControlLeave) { 1916 base::Thread cache_thread("CacheThread"); 1917 ASSERT_TRUE(cache_thread.StartWithOptions( 1918 base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); 1919 1920 { 1921 // Instantiate the SimpleCacheTrial, forcing this run into the 1922 // ExperimentControl group. 1923 base::FieldTrialList field_trial_list(new BadEntropyProvider()); 1924 base::FieldTrialList::CreateFieldTrial("SimpleCacheTrial", 1925 "ExperimentControl"); 1926 1927 scoped_ptr<disk_cache::BackendImpl> cache = 1928 CreateExistingEntryCache(cache_thread, cache_path_); 1929 ASSERT_TRUE(cache.get()); 1930 } 1931 1932 // Instantiate the SimpleCacheTrial, forcing this run into the 1933 // ExperimentNo group. 1934 base::FieldTrialList field_trial_list(new BadEntropyProvider()); 1935 base::FieldTrialList::CreateFieldTrial("SimpleCacheTrial", "ExperimentNo"); 1936 net::TestCompletionCallback cb; 1937 1938 const int kRestartCount = 5; 1939 for (int i = 0; i < kRestartCount; ++i) { 1940 scoped_ptr<disk_cache::BackendImpl> cache(new disk_cache::BackendImpl( 1941 cache_path_, cache_thread.message_loop_proxy(), NULL)); 1942 int rv = cache->Init(cb.callback()); 1943 ASSERT_EQ(net::OK, cb.GetResult(rv)); 1944 EXPECT_EQ(1, cache->GetEntryCount()); 1945 1946 disk_cache::Entry* entry = NULL; 1947 rv = cache->OpenEntry(kExistingEntryKey, &entry, cb.callback()); 1948 EXPECT_EQ(net::OK, cb.GetResult(rv)); 1949 EXPECT_TRUE(entry); 1950 entry->Close(); 1951 } 1952} 1953 1954// Tests that the cache is properly restarted on recovery error. 1955// Disabled on android since this test requires cache creator to create 1956// blockfile caches. 1957#if !defined(OS_ANDROID) 1958TEST_F(DiskCacheBackendTest, DeleteOld) { 1959 ASSERT_TRUE(CopyTestCache("wrong_version")); 1960 SetNewEviction(); 1961 base::Thread cache_thread("CacheThread"); 1962 ASSERT_TRUE(cache_thread.StartWithOptions( 1963 base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); 1964 1965 net::TestCompletionCallback cb; 1966 bool prev = base::ThreadRestrictions::SetIOAllowed(false); 1967 base::FilePath path(cache_path_); 1968 int rv = 1969 disk_cache::CreateCacheBackend(net::DISK_CACHE, 1970 net::CACHE_BACKEND_BLOCKFILE, 1971 path, 1972 0, 1973 true, 1974 cache_thread.message_loop_proxy().get(), 1975 NULL, 1976 &cache_, 1977 cb.callback()); 1978 path.clear(); // Make sure path was captured by the previous call. 1979 ASSERT_EQ(net::OK, cb.GetResult(rv)); 1980 base::ThreadRestrictions::SetIOAllowed(prev); 1981 cache_.reset(); 1982 EXPECT_TRUE(CheckCacheIntegrity(cache_path_, new_eviction_, mask_)); 1983} 1984#endif 1985 1986// We want to be able to deal with messed up entries on disk. 1987void DiskCacheBackendTest::BackendInvalidEntry2() { 1988 ASSERT_TRUE(CopyTestCache("bad_entry")); 1989 DisableFirstCleanup(); 1990 InitCache(); 1991 1992 disk_cache::Entry *entry1, *entry2; 1993 ASSERT_EQ(net::OK, OpenEntry("the first key", &entry1)); 1994 EXPECT_NE(net::OK, OpenEntry("some other key", &entry2)); 1995 entry1->Close(); 1996 1997 // CheckCacheIntegrity will fail at this point. 1998 DisableIntegrityCheck(); 1999} 2000 2001TEST_F(DiskCacheBackendTest, InvalidEntry2) { 2002 BackendInvalidEntry2(); 2003} 2004 2005TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry2) { 2006 SetNewEviction(); 2007 BackendInvalidEntry2(); 2008} 2009 2010// Tests that we don't crash or hang when enumerating this cache. 2011void DiskCacheBackendTest::BackendInvalidEntry3() { 2012 SetMask(0x1); // 2-entry table. 2013 SetMaxSize(0x3000); // 12 kB. 2014 DisableFirstCleanup(); 2015 InitCache(); 2016 2017 disk_cache::Entry* entry; 2018 void* iter = NULL; 2019 while (OpenNextEntry(&iter, &entry) == net::OK) { 2020 entry->Close(); 2021 } 2022} 2023 2024TEST_F(DiskCacheBackendTest, InvalidEntry3) { 2025 ASSERT_TRUE(CopyTestCache("dirty_entry3")); 2026 BackendInvalidEntry3(); 2027} 2028 2029TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry3) { 2030 ASSERT_TRUE(CopyTestCache("dirty_entry4")); 2031 SetNewEviction(); 2032 BackendInvalidEntry3(); 2033 DisableIntegrityCheck(); 2034} 2035 2036// Test that we handle a dirty entry on the LRU list, already replaced with 2037// the same key, and with hash collisions. 2038TEST_F(DiskCacheBackendTest, InvalidEntry4) { 2039 ASSERT_TRUE(CopyTestCache("dirty_entry3")); 2040 SetMask(0x1); // 2-entry table. 2041 SetMaxSize(0x3000); // 12 kB. 2042 DisableFirstCleanup(); 2043 InitCache(); 2044 2045 TrimForTest(false); 2046} 2047 2048// Test that we handle a dirty entry on the deleted list, already replaced with 2049// the same key, and with hash collisions. 2050TEST_F(DiskCacheBackendTest, InvalidEntry5) { 2051 ASSERT_TRUE(CopyTestCache("dirty_entry4")); 2052 SetNewEviction(); 2053 SetMask(0x1); // 2-entry table. 2054 SetMaxSize(0x3000); // 12 kB. 2055 DisableFirstCleanup(); 2056 InitCache(); 2057 2058 TrimDeletedListForTest(false); 2059} 2060 2061TEST_F(DiskCacheBackendTest, InvalidEntry6) { 2062 ASSERT_TRUE(CopyTestCache("dirty_entry5")); 2063 SetMask(0x1); // 2-entry table. 2064 SetMaxSize(0x3000); // 12 kB. 2065 DisableFirstCleanup(); 2066 InitCache(); 2067 2068 // There is a dirty entry (but marked as clean) at the end, pointing to a 2069 // deleted entry through the hash collision list. We should not re-insert the 2070 // deleted entry into the index table. 2071 2072 TrimForTest(false); 2073 // The cache should be clean (as detected by CheckCacheIntegrity). 2074} 2075 2076// Tests that we don't hang when there is a loop on the hash collision list. 2077// The test cache could be a result of bug 69135. 2078TEST_F(DiskCacheBackendTest, BadNextEntry1) { 2079 ASSERT_TRUE(CopyTestCache("list_loop2")); 2080 SetMask(0x1); // 2-entry table. 2081 SetMaxSize(0x3000); // 12 kB. 2082 DisableFirstCleanup(); 2083 InitCache(); 2084 2085 // The second entry points at itselft, and the first entry is not accessible 2086 // though the index, but it is at the head of the LRU. 2087 2088 disk_cache::Entry* entry; 2089 ASSERT_EQ(net::OK, CreateEntry("The first key", &entry)); 2090 entry->Close(); 2091 2092 TrimForTest(false); 2093 TrimForTest(false); 2094 ASSERT_EQ(net::OK, OpenEntry("The first key", &entry)); 2095 entry->Close(); 2096 EXPECT_EQ(1, cache_->GetEntryCount()); 2097} 2098 2099// Tests that we don't hang when there is a loop on the hash collision list. 2100// The test cache could be a result of bug 69135. 2101TEST_F(DiskCacheBackendTest, BadNextEntry2) { 2102 ASSERT_TRUE(CopyTestCache("list_loop3")); 2103 SetMask(0x1); // 2-entry table. 2104 SetMaxSize(0x3000); // 12 kB. 2105 DisableFirstCleanup(); 2106 InitCache(); 2107 2108 // There is a wide loop of 5 entries. 2109 2110 disk_cache::Entry* entry; 2111 ASSERT_NE(net::OK, OpenEntry("Not present key", &entry)); 2112} 2113 2114TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry6) { 2115 ASSERT_TRUE(CopyTestCache("bad_rankings3")); 2116 DisableFirstCleanup(); 2117 SetNewEviction(); 2118 InitCache(); 2119 2120 // The second entry is dirty, but removing it should not corrupt the list. 2121 disk_cache::Entry* entry; 2122 ASSERT_NE(net::OK, OpenEntry("the second key", &entry)); 2123 ASSERT_EQ(net::OK, OpenEntry("the first key", &entry)); 2124 2125 // This should not delete the cache. 2126 entry->Doom(); 2127 FlushQueueForTest(); 2128 entry->Close(); 2129 2130 ASSERT_EQ(net::OK, OpenEntry("some other key", &entry)); 2131 entry->Close(); 2132} 2133 2134// Tests handling of corrupt entries by keeping the rankings node around, with 2135// a fatal failure. 2136void DiskCacheBackendTest::BackendInvalidEntry7() { 2137 const int kSize = 0x3000; // 12 kB. 2138 SetMaxSize(kSize * 10); 2139 InitCache(); 2140 2141 std::string first("some key"); 2142 std::string second("something else"); 2143 disk_cache::Entry* entry; 2144 ASSERT_EQ(net::OK, CreateEntry(first, &entry)); 2145 entry->Close(); 2146 ASSERT_EQ(net::OK, CreateEntry(second, &entry)); 2147 2148 // Corrupt this entry. 2149 disk_cache::EntryImpl* entry_impl = 2150 static_cast<disk_cache::EntryImpl*>(entry); 2151 2152 entry_impl->rankings()->Data()->next = 0; 2153 entry_impl->rankings()->Store(); 2154 entry->Close(); 2155 FlushQueueForTest(); 2156 EXPECT_EQ(2, cache_->GetEntryCount()); 2157 2158 // This should detect the bad entry. 2159 EXPECT_NE(net::OK, OpenEntry(second, &entry)); 2160 EXPECT_EQ(1, cache_->GetEntryCount()); 2161 2162 // We should delete the cache. The list still has a corrupt node. 2163 void* iter = NULL; 2164 EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry)); 2165 FlushQueueForTest(); 2166 EXPECT_EQ(0, cache_->GetEntryCount()); 2167} 2168 2169TEST_F(DiskCacheBackendTest, InvalidEntry7) { 2170 BackendInvalidEntry7(); 2171} 2172 2173TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry7) { 2174 SetNewEviction(); 2175 BackendInvalidEntry7(); 2176} 2177 2178// Tests handling of corrupt entries by keeping the rankings node around, with 2179// a non fatal failure. 2180void DiskCacheBackendTest::BackendInvalidEntry8() { 2181 const int kSize = 0x3000; // 12 kB 2182 SetMaxSize(kSize * 10); 2183 InitCache(); 2184 2185 std::string first("some key"); 2186 std::string second("something else"); 2187 disk_cache::Entry* entry; 2188 ASSERT_EQ(net::OK, CreateEntry(first, &entry)); 2189 entry->Close(); 2190 ASSERT_EQ(net::OK, CreateEntry(second, &entry)); 2191 2192 // Corrupt this entry. 2193 disk_cache::EntryImpl* entry_impl = 2194 static_cast<disk_cache::EntryImpl*>(entry); 2195 2196 entry_impl->rankings()->Data()->contents = 0; 2197 entry_impl->rankings()->Store(); 2198 entry->Close(); 2199 FlushQueueForTest(); 2200 EXPECT_EQ(2, cache_->GetEntryCount()); 2201 2202 // This should detect the bad entry. 2203 EXPECT_NE(net::OK, OpenEntry(second, &entry)); 2204 EXPECT_EQ(1, cache_->GetEntryCount()); 2205 2206 // We should not delete the cache. 2207 void* iter = NULL; 2208 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry)); 2209 entry->Close(); 2210 EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry)); 2211 EXPECT_EQ(1, cache_->GetEntryCount()); 2212} 2213 2214TEST_F(DiskCacheBackendTest, InvalidEntry8) { 2215 BackendInvalidEntry8(); 2216} 2217 2218TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry8) { 2219 SetNewEviction(); 2220 BackendInvalidEntry8(); 2221} 2222 2223// Tests handling of corrupt entries detected by enumerations. Note that these 2224// tests (xx9 to xx11) are basically just going though slightly different 2225// codepaths so they are tighlty coupled with the code, but that is better than 2226// not testing error handling code. 2227void DiskCacheBackendTest::BackendInvalidEntry9(bool eviction) { 2228 const int kSize = 0x3000; // 12 kB. 2229 SetMaxSize(kSize * 10); 2230 InitCache(); 2231 2232 std::string first("some key"); 2233 std::string second("something else"); 2234 disk_cache::Entry* entry; 2235 ASSERT_EQ(net::OK, CreateEntry(first, &entry)); 2236 entry->Close(); 2237 ASSERT_EQ(net::OK, CreateEntry(second, &entry)); 2238 2239 // Corrupt this entry. 2240 disk_cache::EntryImpl* entry_impl = 2241 static_cast<disk_cache::EntryImpl*>(entry); 2242 2243 entry_impl->entry()->Data()->state = 0xbad; 2244 entry_impl->entry()->Store(); 2245 entry->Close(); 2246 FlushQueueForTest(); 2247 EXPECT_EQ(2, cache_->GetEntryCount()); 2248 2249 if (eviction) { 2250 TrimForTest(false); 2251 EXPECT_EQ(1, cache_->GetEntryCount()); 2252 TrimForTest(false); 2253 EXPECT_EQ(1, cache_->GetEntryCount()); 2254 } else { 2255 // We should detect the problem through the list, but we should not delete 2256 // the entry, just fail the iteration. 2257 void* iter = NULL; 2258 EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry)); 2259 2260 // Now a full iteration will work, and return one entry. 2261 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry)); 2262 entry->Close(); 2263 EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry)); 2264 2265 // This should detect what's left of the bad entry. 2266 EXPECT_NE(net::OK, OpenEntry(second, &entry)); 2267 EXPECT_EQ(2, cache_->GetEntryCount()); 2268 } 2269 DisableIntegrityCheck(); 2270} 2271 2272TEST_F(DiskCacheBackendTest, InvalidEntry9) { 2273 BackendInvalidEntry9(false); 2274} 2275 2276TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry9) { 2277 SetNewEviction(); 2278 BackendInvalidEntry9(false); 2279} 2280 2281TEST_F(DiskCacheBackendTest, TrimInvalidEntry9) { 2282 BackendInvalidEntry9(true); 2283} 2284 2285TEST_F(DiskCacheBackendTest, NewEvictionTrimInvalidEntry9) { 2286 SetNewEviction(); 2287 BackendInvalidEntry9(true); 2288} 2289 2290// Tests handling of corrupt entries detected by enumerations. 2291void DiskCacheBackendTest::BackendInvalidEntry10(bool eviction) { 2292 const int kSize = 0x3000; // 12 kB. 2293 SetMaxSize(kSize * 10); 2294 SetNewEviction(); 2295 InitCache(); 2296 2297 std::string first("some key"); 2298 std::string second("something else"); 2299 disk_cache::Entry* entry; 2300 ASSERT_EQ(net::OK, CreateEntry(first, &entry)); 2301 entry->Close(); 2302 ASSERT_EQ(net::OK, OpenEntry(first, &entry)); 2303 EXPECT_EQ(0, WriteData(entry, 0, 200, NULL, 0, false)); 2304 entry->Close(); 2305 ASSERT_EQ(net::OK, CreateEntry(second, &entry)); 2306 2307 // Corrupt this entry. 2308 disk_cache::EntryImpl* entry_impl = 2309 static_cast<disk_cache::EntryImpl*>(entry); 2310 2311 entry_impl->entry()->Data()->state = 0xbad; 2312 entry_impl->entry()->Store(); 2313 entry->Close(); 2314 ASSERT_EQ(net::OK, CreateEntry("third", &entry)); 2315 entry->Close(); 2316 EXPECT_EQ(3, cache_->GetEntryCount()); 2317 2318 // We have: 2319 // List 0: third -> second (bad). 2320 // List 1: first. 2321 2322 if (eviction) { 2323 // Detection order: second -> first -> third. 2324 TrimForTest(false); 2325 EXPECT_EQ(3, cache_->GetEntryCount()); 2326 TrimForTest(false); 2327 EXPECT_EQ(2, cache_->GetEntryCount()); 2328 TrimForTest(false); 2329 EXPECT_EQ(1, cache_->GetEntryCount()); 2330 } else { 2331 // Detection order: third -> second -> first. 2332 // We should detect the problem through the list, but we should not delete 2333 // the entry. 2334 void* iter = NULL; 2335 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry)); 2336 entry->Close(); 2337 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry)); 2338 EXPECT_EQ(first, entry->GetKey()); 2339 entry->Close(); 2340 EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry)); 2341 } 2342 DisableIntegrityCheck(); 2343} 2344 2345TEST_F(DiskCacheBackendTest, InvalidEntry10) { 2346 BackendInvalidEntry10(false); 2347} 2348 2349TEST_F(DiskCacheBackendTest, TrimInvalidEntry10) { 2350 BackendInvalidEntry10(true); 2351} 2352 2353// Tests handling of corrupt entries detected by enumerations. 2354void DiskCacheBackendTest::BackendInvalidEntry11(bool eviction) { 2355 const int kSize = 0x3000; // 12 kB. 2356 SetMaxSize(kSize * 10); 2357 SetNewEviction(); 2358 InitCache(); 2359 2360 std::string first("some key"); 2361 std::string second("something else"); 2362 disk_cache::Entry* entry; 2363 ASSERT_EQ(net::OK, CreateEntry(first, &entry)); 2364 entry->Close(); 2365 ASSERT_EQ(net::OK, OpenEntry(first, &entry)); 2366 EXPECT_EQ(0, WriteData(entry, 0, 200, NULL, 0, false)); 2367 entry->Close(); 2368 ASSERT_EQ(net::OK, CreateEntry(second, &entry)); 2369 entry->Close(); 2370 ASSERT_EQ(net::OK, OpenEntry(second, &entry)); 2371 EXPECT_EQ(0, WriteData(entry, 0, 200, NULL, 0, false)); 2372 2373 // Corrupt this entry. 2374 disk_cache::EntryImpl* entry_impl = 2375 static_cast<disk_cache::EntryImpl*>(entry); 2376 2377 entry_impl->entry()->Data()->state = 0xbad; 2378 entry_impl->entry()->Store(); 2379 entry->Close(); 2380 ASSERT_EQ(net::OK, CreateEntry("third", &entry)); 2381 entry->Close(); 2382 FlushQueueForTest(); 2383 EXPECT_EQ(3, cache_->GetEntryCount()); 2384 2385 // We have: 2386 // List 0: third. 2387 // List 1: second (bad) -> first. 2388 2389 if (eviction) { 2390 // Detection order: third -> first -> second. 2391 TrimForTest(false); 2392 EXPECT_EQ(2, cache_->GetEntryCount()); 2393 TrimForTest(false); 2394 EXPECT_EQ(1, cache_->GetEntryCount()); 2395 TrimForTest(false); 2396 EXPECT_EQ(1, cache_->GetEntryCount()); 2397 } else { 2398 // Detection order: third -> second. 2399 // We should detect the problem through the list, but we should not delete 2400 // the entry, just fail the iteration. 2401 void* iter = NULL; 2402 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry)); 2403 entry->Close(); 2404 EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry)); 2405 2406 // Now a full iteration will work, and return two entries. 2407 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry)); 2408 entry->Close(); 2409 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry)); 2410 entry->Close(); 2411 EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry)); 2412 } 2413 DisableIntegrityCheck(); 2414} 2415 2416TEST_F(DiskCacheBackendTest, InvalidEntry11) { 2417 BackendInvalidEntry11(false); 2418} 2419 2420TEST_F(DiskCacheBackendTest, TrimInvalidEntry11) { 2421 BackendInvalidEntry11(true); 2422} 2423 2424// Tests handling of corrupt entries in the middle of a long eviction run. 2425void DiskCacheBackendTest::BackendTrimInvalidEntry12() { 2426 const int kSize = 0x3000; // 12 kB 2427 SetMaxSize(kSize * 10); 2428 InitCache(); 2429 2430 std::string first("some key"); 2431 std::string second("something else"); 2432 disk_cache::Entry* entry; 2433 ASSERT_EQ(net::OK, CreateEntry(first, &entry)); 2434 entry->Close(); 2435 ASSERT_EQ(net::OK, CreateEntry(second, &entry)); 2436 2437 // Corrupt this entry. 2438 disk_cache::EntryImpl* entry_impl = 2439 static_cast<disk_cache::EntryImpl*>(entry); 2440 2441 entry_impl->entry()->Data()->state = 0xbad; 2442 entry_impl->entry()->Store(); 2443 entry->Close(); 2444 ASSERT_EQ(net::OK, CreateEntry("third", &entry)); 2445 entry->Close(); 2446 ASSERT_EQ(net::OK, CreateEntry("fourth", &entry)); 2447 TrimForTest(true); 2448 EXPECT_EQ(1, cache_->GetEntryCount()); 2449 entry->Close(); 2450 DisableIntegrityCheck(); 2451} 2452 2453TEST_F(DiskCacheBackendTest, TrimInvalidEntry12) { 2454 BackendTrimInvalidEntry12(); 2455} 2456 2457TEST_F(DiskCacheBackendTest, NewEvictionTrimInvalidEntry12) { 2458 SetNewEviction(); 2459 BackendTrimInvalidEntry12(); 2460} 2461 2462// We want to be able to deal with messed up entries on disk. 2463void DiskCacheBackendTest::BackendInvalidRankings2() { 2464 ASSERT_TRUE(CopyTestCache("bad_rankings")); 2465 DisableFirstCleanup(); 2466 InitCache(); 2467 2468 disk_cache::Entry *entry1, *entry2; 2469 EXPECT_NE(net::OK, OpenEntry("the first key", &entry1)); 2470 ASSERT_EQ(net::OK, OpenEntry("some other key", &entry2)); 2471 entry2->Close(); 2472 2473 // CheckCacheIntegrity will fail at this point. 2474 DisableIntegrityCheck(); 2475} 2476 2477TEST_F(DiskCacheBackendTest, InvalidRankings2) { 2478 BackendInvalidRankings2(); 2479} 2480 2481TEST_F(DiskCacheBackendTest, NewEvictionInvalidRankings2) { 2482 SetNewEviction(); 2483 BackendInvalidRankings2(); 2484} 2485 2486// If the LRU is corrupt, we delete the cache. 2487void DiskCacheBackendTest::BackendInvalidRankings() { 2488 disk_cache::Entry* entry; 2489 void* iter = NULL; 2490 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry)); 2491 entry->Close(); 2492 EXPECT_EQ(2, cache_->GetEntryCount()); 2493 2494 EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry)); 2495 FlushQueueForTest(); // Allow the restart to finish. 2496 EXPECT_EQ(0, cache_->GetEntryCount()); 2497} 2498 2499TEST_F(DiskCacheBackendTest, InvalidRankingsSuccess) { 2500 ASSERT_TRUE(CopyTestCache("bad_rankings")); 2501 DisableFirstCleanup(); 2502 InitCache(); 2503 BackendInvalidRankings(); 2504} 2505 2506TEST_F(DiskCacheBackendTest, NewEvictionInvalidRankingsSuccess) { 2507 ASSERT_TRUE(CopyTestCache("bad_rankings")); 2508 DisableFirstCleanup(); 2509 SetNewEviction(); 2510 InitCache(); 2511 BackendInvalidRankings(); 2512} 2513 2514TEST_F(DiskCacheBackendTest, InvalidRankingsFailure) { 2515 ASSERT_TRUE(CopyTestCache("bad_rankings")); 2516 DisableFirstCleanup(); 2517 InitCache(); 2518 SetTestMode(); // Fail cache reinitialization. 2519 BackendInvalidRankings(); 2520} 2521 2522TEST_F(DiskCacheBackendTest, NewEvictionInvalidRankingsFailure) { 2523 ASSERT_TRUE(CopyTestCache("bad_rankings")); 2524 DisableFirstCleanup(); 2525 SetNewEviction(); 2526 InitCache(); 2527 SetTestMode(); // Fail cache reinitialization. 2528 BackendInvalidRankings(); 2529} 2530 2531// If the LRU is corrupt and we have open entries, we disable the cache. 2532void DiskCacheBackendTest::BackendDisable() { 2533 disk_cache::Entry *entry1, *entry2; 2534 void* iter = NULL; 2535 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry1)); 2536 2537 EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry2)); 2538 EXPECT_EQ(0, cache_->GetEntryCount()); 2539 EXPECT_NE(net::OK, CreateEntry("Something new", &entry2)); 2540 2541 entry1->Close(); 2542 FlushQueueForTest(); // Flushing the Close posts a task to restart the cache. 2543 FlushQueueForTest(); // This one actually allows that task to complete. 2544 2545 EXPECT_EQ(0, cache_->GetEntryCount()); 2546} 2547 2548TEST_F(DiskCacheBackendTest, DisableSuccess) { 2549 ASSERT_TRUE(CopyTestCache("bad_rankings")); 2550 DisableFirstCleanup(); 2551 InitCache(); 2552 BackendDisable(); 2553} 2554 2555TEST_F(DiskCacheBackendTest, NewEvictionDisableSuccess) { 2556 ASSERT_TRUE(CopyTestCache("bad_rankings")); 2557 DisableFirstCleanup(); 2558 SetNewEviction(); 2559 InitCache(); 2560 BackendDisable(); 2561} 2562 2563TEST_F(DiskCacheBackendTest, DisableFailure) { 2564 ASSERT_TRUE(CopyTestCache("bad_rankings")); 2565 DisableFirstCleanup(); 2566 InitCache(); 2567 SetTestMode(); // Fail cache reinitialization. 2568 BackendDisable(); 2569} 2570 2571TEST_F(DiskCacheBackendTest, NewEvictionDisableFailure) { 2572 ASSERT_TRUE(CopyTestCache("bad_rankings")); 2573 DisableFirstCleanup(); 2574 SetNewEviction(); 2575 InitCache(); 2576 SetTestMode(); // Fail cache reinitialization. 2577 BackendDisable(); 2578} 2579 2580// This is another type of corruption on the LRU; disable the cache. 2581void DiskCacheBackendTest::BackendDisable2() { 2582 EXPECT_EQ(8, cache_->GetEntryCount()); 2583 2584 disk_cache::Entry* entry; 2585 void* iter = NULL; 2586 int count = 0; 2587 while (OpenNextEntry(&iter, &entry) == net::OK) { 2588 ASSERT_TRUE(NULL != entry); 2589 entry->Close(); 2590 count++; 2591 ASSERT_LT(count, 9); 2592 }; 2593 2594 FlushQueueForTest(); 2595 EXPECT_EQ(0, cache_->GetEntryCount()); 2596} 2597 2598TEST_F(DiskCacheBackendTest, DisableSuccess2) { 2599 ASSERT_TRUE(CopyTestCache("list_loop")); 2600 DisableFirstCleanup(); 2601 InitCache(); 2602 BackendDisable2(); 2603} 2604 2605TEST_F(DiskCacheBackendTest, NewEvictionDisableSuccess2) { 2606 ASSERT_TRUE(CopyTestCache("list_loop")); 2607 DisableFirstCleanup(); 2608 SetNewEviction(); 2609 InitCache(); 2610 BackendDisable2(); 2611} 2612 2613TEST_F(DiskCacheBackendTest, DisableFailure2) { 2614 ASSERT_TRUE(CopyTestCache("list_loop")); 2615 DisableFirstCleanup(); 2616 InitCache(); 2617 SetTestMode(); // Fail cache reinitialization. 2618 BackendDisable2(); 2619} 2620 2621TEST_F(DiskCacheBackendTest, NewEvictionDisableFailure2) { 2622 ASSERT_TRUE(CopyTestCache("list_loop")); 2623 DisableFirstCleanup(); 2624 SetNewEviction(); 2625 InitCache(); 2626 SetTestMode(); // Fail cache reinitialization. 2627 BackendDisable2(); 2628} 2629 2630// If the index size changes when we disable the cache, we should not crash. 2631void DiskCacheBackendTest::BackendDisable3() { 2632 disk_cache::Entry *entry1, *entry2; 2633 void* iter = NULL; 2634 EXPECT_EQ(2, cache_->GetEntryCount()); 2635 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry1)); 2636 entry1->Close(); 2637 2638 EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry2)); 2639 FlushQueueForTest(); 2640 2641 ASSERT_EQ(net::OK, CreateEntry("Something new", &entry2)); 2642 entry2->Close(); 2643 2644 EXPECT_EQ(1, cache_->GetEntryCount()); 2645} 2646 2647TEST_F(DiskCacheBackendTest, DisableSuccess3) { 2648 ASSERT_TRUE(CopyTestCache("bad_rankings2")); 2649 DisableFirstCleanup(); 2650 SetMaxSize(20 * 1024 * 1024); 2651 InitCache(); 2652 BackendDisable3(); 2653} 2654 2655TEST_F(DiskCacheBackendTest, NewEvictionDisableSuccess3) { 2656 ASSERT_TRUE(CopyTestCache("bad_rankings2")); 2657 DisableFirstCleanup(); 2658 SetMaxSize(20 * 1024 * 1024); 2659 SetNewEviction(); 2660 InitCache(); 2661 BackendDisable3(); 2662} 2663 2664// If we disable the cache, already open entries should work as far as possible. 2665void DiskCacheBackendTest::BackendDisable4() { 2666 disk_cache::Entry *entry1, *entry2, *entry3, *entry4; 2667 void* iter = NULL; 2668 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry1)); 2669 2670 char key2[2000]; 2671 char key3[20000]; 2672 CacheTestFillBuffer(key2, sizeof(key2), true); 2673 CacheTestFillBuffer(key3, sizeof(key3), true); 2674 key2[sizeof(key2) - 1] = '\0'; 2675 key3[sizeof(key3) - 1] = '\0'; 2676 ASSERT_EQ(net::OK, CreateEntry(key2, &entry2)); 2677 ASSERT_EQ(net::OK, CreateEntry(key3, &entry3)); 2678 2679 const int kBufSize = 20000; 2680 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kBufSize)); 2681 memset(buf->data(), 0, kBufSize); 2682 EXPECT_EQ(100, WriteData(entry2, 0, 0, buf.get(), 100, false)); 2683 EXPECT_EQ(kBufSize, WriteData(entry3, 0, 0, buf.get(), kBufSize, false)); 2684 2685 // This line should disable the cache but not delete it. 2686 EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry4)); 2687 EXPECT_EQ(0, cache_->GetEntryCount()); 2688 2689 EXPECT_NE(net::OK, CreateEntry("cache is disabled", &entry4)); 2690 2691 EXPECT_EQ(100, ReadData(entry2, 0, 0, buf.get(), 100)); 2692 EXPECT_EQ(100, WriteData(entry2, 0, 0, buf.get(), 100, false)); 2693 EXPECT_EQ(100, WriteData(entry2, 1, 0, buf.get(), 100, false)); 2694 2695 EXPECT_EQ(kBufSize, ReadData(entry3, 0, 0, buf.get(), kBufSize)); 2696 EXPECT_EQ(kBufSize, WriteData(entry3, 0, 0, buf.get(), kBufSize, false)); 2697 EXPECT_EQ(kBufSize, WriteData(entry3, 1, 0, buf.get(), kBufSize, false)); 2698 2699 std::string key = entry2->GetKey(); 2700 EXPECT_EQ(sizeof(key2) - 1, key.size()); 2701 key = entry3->GetKey(); 2702 EXPECT_EQ(sizeof(key3) - 1, key.size()); 2703 2704 entry1->Close(); 2705 entry2->Close(); 2706 entry3->Close(); 2707 FlushQueueForTest(); // Flushing the Close posts a task to restart the cache. 2708 FlushQueueForTest(); // This one actually allows that task to complete. 2709 2710 EXPECT_EQ(0, cache_->GetEntryCount()); 2711} 2712 2713TEST_F(DiskCacheBackendTest, DisableSuccess4) { 2714 ASSERT_TRUE(CopyTestCache("bad_rankings")); 2715 DisableFirstCleanup(); 2716 InitCache(); 2717 BackendDisable4(); 2718} 2719 2720TEST_F(DiskCacheBackendTest, NewEvictionDisableSuccess4) { 2721 ASSERT_TRUE(CopyTestCache("bad_rankings")); 2722 DisableFirstCleanup(); 2723 SetNewEviction(); 2724 InitCache(); 2725 BackendDisable4(); 2726} 2727 2728TEST_F(DiskCacheTest, Backend_UsageStatsTimer) { 2729 MessageLoopHelper helper; 2730 2731 ASSERT_TRUE(CleanupCacheDir()); 2732 scoped_ptr<disk_cache::BackendImpl> cache; 2733 cache.reset(new disk_cache::BackendImpl( 2734 cache_path_, base::MessageLoopProxy::current().get(), NULL)); 2735 ASSERT_TRUE(NULL != cache.get()); 2736 cache->SetUnitTestMode(); 2737 ASSERT_EQ(net::OK, cache->SyncInit()); 2738 2739 // Wait for a callback that never comes... about 2 secs :). The message loop 2740 // has to run to allow invocation of the usage timer. 2741 helper.WaitUntilCacheIoFinished(1); 2742} 2743 2744TEST_F(DiskCacheBackendTest, TimerNotCreated) { 2745 ASSERT_TRUE(CopyTestCache("wrong_version")); 2746 2747 scoped_ptr<disk_cache::BackendImpl> cache; 2748 cache.reset(new disk_cache::BackendImpl( 2749 cache_path_, base::MessageLoopProxy::current().get(), NULL)); 2750 ASSERT_TRUE(NULL != cache.get()); 2751 cache->SetUnitTestMode(); 2752 ASSERT_NE(net::OK, cache->SyncInit()); 2753 2754 ASSERT_TRUE(NULL == cache->GetTimerForTest()); 2755 2756 DisableIntegrityCheck(); 2757} 2758 2759TEST_F(DiskCacheBackendTest, Backend_UsageStats) { 2760 InitCache(); 2761 disk_cache::Entry* entry; 2762 ASSERT_EQ(net::OK, CreateEntry("key", &entry)); 2763 entry->Close(); 2764 FlushQueueForTest(); 2765 2766 disk_cache::StatsItems stats; 2767 cache_->GetStats(&stats); 2768 EXPECT_FALSE(stats.empty()); 2769 2770 disk_cache::StatsItems::value_type hits("Create hit", "0x1"); 2771 EXPECT_EQ(1, std::count(stats.begin(), stats.end(), hits)); 2772 2773 cache_.reset(); 2774 2775 // Now open the cache and verify that the stats are still there. 2776 DisableFirstCleanup(); 2777 InitCache(); 2778 EXPECT_EQ(1, cache_->GetEntryCount()); 2779 2780 stats.clear(); 2781 cache_->GetStats(&stats); 2782 EXPECT_FALSE(stats.empty()); 2783 2784 EXPECT_EQ(1, std::count(stats.begin(), stats.end(), hits)); 2785} 2786 2787void DiskCacheBackendTest::BackendDoomAll() { 2788 InitCache(); 2789 2790 disk_cache::Entry *entry1, *entry2; 2791 ASSERT_EQ(net::OK, CreateEntry("first", &entry1)); 2792 ASSERT_EQ(net::OK, CreateEntry("second", &entry2)); 2793 entry1->Close(); 2794 entry2->Close(); 2795 2796 ASSERT_EQ(net::OK, CreateEntry("third", &entry1)); 2797 ASSERT_EQ(net::OK, CreateEntry("fourth", &entry2)); 2798 2799 ASSERT_EQ(4, cache_->GetEntryCount()); 2800 EXPECT_EQ(net::OK, DoomAllEntries()); 2801 ASSERT_EQ(0, cache_->GetEntryCount()); 2802 2803 // We should stop posting tasks at some point (if we post any). 2804 base::MessageLoop::current()->RunUntilIdle(); 2805 2806 disk_cache::Entry *entry3, *entry4; 2807 EXPECT_NE(net::OK, OpenEntry("third", &entry3)); 2808 ASSERT_EQ(net::OK, CreateEntry("third", &entry3)); 2809 ASSERT_EQ(net::OK, CreateEntry("fourth", &entry4)); 2810 2811 EXPECT_EQ(net::OK, DoomAllEntries()); 2812 ASSERT_EQ(0, cache_->GetEntryCount()); 2813 2814 entry1->Close(); 2815 entry2->Close(); 2816 entry3->Doom(); // The entry should be already doomed, but this must work. 2817 entry3->Close(); 2818 entry4->Close(); 2819 2820 // Now try with all references released. 2821 ASSERT_EQ(net::OK, CreateEntry("third", &entry1)); 2822 ASSERT_EQ(net::OK, CreateEntry("fourth", &entry2)); 2823 entry1->Close(); 2824 entry2->Close(); 2825 2826 ASSERT_EQ(2, cache_->GetEntryCount()); 2827 EXPECT_EQ(net::OK, DoomAllEntries()); 2828 ASSERT_EQ(0, cache_->GetEntryCount()); 2829 2830 EXPECT_EQ(net::OK, DoomAllEntries()); 2831} 2832 2833TEST_F(DiskCacheBackendTest, DoomAll) { 2834 BackendDoomAll(); 2835} 2836 2837TEST_F(DiskCacheBackendTest, NewEvictionDoomAll) { 2838 SetNewEviction(); 2839 BackendDoomAll(); 2840} 2841 2842TEST_F(DiskCacheBackendTest, MemoryOnlyDoomAll) { 2843 SetMemoryOnlyMode(); 2844 BackendDoomAll(); 2845} 2846 2847TEST_F(DiskCacheBackendTest, AppCacheOnlyDoomAll) { 2848 SetCacheType(net::APP_CACHE); 2849 BackendDoomAll(); 2850} 2851 2852TEST_F(DiskCacheBackendTest, ShaderCacheOnlyDoomAll) { 2853 SetCacheType(net::SHADER_CACHE); 2854 BackendDoomAll(); 2855} 2856 2857// If the index size changes when we doom the cache, we should not crash. 2858void DiskCacheBackendTest::BackendDoomAll2() { 2859 EXPECT_EQ(2, cache_->GetEntryCount()); 2860 EXPECT_EQ(net::OK, DoomAllEntries()); 2861 2862 disk_cache::Entry* entry; 2863 ASSERT_EQ(net::OK, CreateEntry("Something new", &entry)); 2864 entry->Close(); 2865 2866 EXPECT_EQ(1, cache_->GetEntryCount()); 2867} 2868 2869TEST_F(DiskCacheBackendTest, DoomAll2) { 2870 ASSERT_TRUE(CopyTestCache("bad_rankings2")); 2871 DisableFirstCleanup(); 2872 SetMaxSize(20 * 1024 * 1024); 2873 InitCache(); 2874 BackendDoomAll2(); 2875} 2876 2877TEST_F(DiskCacheBackendTest, NewEvictionDoomAll2) { 2878 ASSERT_TRUE(CopyTestCache("bad_rankings2")); 2879 DisableFirstCleanup(); 2880 SetMaxSize(20 * 1024 * 1024); 2881 SetNewEviction(); 2882 InitCache(); 2883 BackendDoomAll2(); 2884} 2885 2886// We should be able to create the same entry on multiple simultaneous instances 2887// of the cache. 2888TEST_F(DiskCacheTest, MultipleInstances) { 2889 base::ScopedTempDir store1, store2; 2890 ASSERT_TRUE(store1.CreateUniqueTempDir()); 2891 ASSERT_TRUE(store2.CreateUniqueTempDir()); 2892 2893 base::Thread cache_thread("CacheThread"); 2894 ASSERT_TRUE(cache_thread.StartWithOptions( 2895 base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); 2896 net::TestCompletionCallback cb; 2897 2898 const int kNumberOfCaches = 2; 2899 scoped_ptr<disk_cache::Backend> cache[kNumberOfCaches]; 2900 2901 int rv = 2902 disk_cache::CreateCacheBackend(net::DISK_CACHE, 2903 net::CACHE_BACKEND_DEFAULT, 2904 store1.path(), 2905 0, 2906 false, 2907 cache_thread.message_loop_proxy().get(), 2908 NULL, 2909 &cache[0], 2910 cb.callback()); 2911 ASSERT_EQ(net::OK, cb.GetResult(rv)); 2912 rv = disk_cache::CreateCacheBackend(net::MEDIA_CACHE, 2913 net::CACHE_BACKEND_DEFAULT, 2914 store2.path(), 2915 0, 2916 false, 2917 cache_thread.message_loop_proxy().get(), 2918 NULL, 2919 &cache[1], 2920 cb.callback()); 2921 ASSERT_EQ(net::OK, cb.GetResult(rv)); 2922 2923 ASSERT_TRUE(cache[0].get() != NULL && cache[1].get() != NULL); 2924 2925 std::string key("the first key"); 2926 disk_cache::Entry* entry; 2927 for (int i = 0; i < kNumberOfCaches; i++) { 2928 rv = cache[i]->CreateEntry(key, &entry, cb.callback()); 2929 ASSERT_EQ(net::OK, cb.GetResult(rv)); 2930 entry->Close(); 2931 } 2932} 2933 2934// Test the six regions of the curve that determines the max cache size. 2935TEST_F(DiskCacheTest, AutomaticMaxSize) { 2936 using disk_cache::kDefaultCacheSize; 2937 int64 large_size = kDefaultCacheSize; 2938 2939 // Region 1: expected = available * 0.8 2940 EXPECT_EQ((kDefaultCacheSize - 1) * 8 / 10, 2941 disk_cache::PreferredCacheSize(large_size - 1)); 2942 EXPECT_EQ(kDefaultCacheSize * 8 / 10, 2943 disk_cache::PreferredCacheSize(large_size)); 2944 EXPECT_EQ(kDefaultCacheSize - 1, 2945 disk_cache::PreferredCacheSize(large_size * 10 / 8 - 1)); 2946 2947 // Region 2: expected = default_size 2948 EXPECT_EQ(kDefaultCacheSize, 2949 disk_cache::PreferredCacheSize(large_size * 10 / 8)); 2950 EXPECT_EQ(kDefaultCacheSize, 2951 disk_cache::PreferredCacheSize(large_size * 10 - 1)); 2952 2953 // Region 3: expected = available * 0.1 2954 EXPECT_EQ(kDefaultCacheSize, 2955 disk_cache::PreferredCacheSize(large_size * 10)); 2956 EXPECT_EQ((kDefaultCacheSize * 25 - 1) / 10, 2957 disk_cache::PreferredCacheSize(large_size * 25 - 1)); 2958 2959 // Region 4: expected = default_size * 2.5 2960 EXPECT_EQ(kDefaultCacheSize * 25 / 10, 2961 disk_cache::PreferredCacheSize(large_size * 25)); 2962 EXPECT_EQ(kDefaultCacheSize * 25 / 10, 2963 disk_cache::PreferredCacheSize(large_size * 100 - 1)); 2964 EXPECT_EQ(kDefaultCacheSize * 25 / 10, 2965 disk_cache::PreferredCacheSize(large_size * 100)); 2966 EXPECT_EQ(kDefaultCacheSize * 25 / 10, 2967 disk_cache::PreferredCacheSize(large_size * 250 - 1)); 2968 2969 // Region 5: expected = available * 0.1 2970 int64 largest_size = kDefaultCacheSize * 4; 2971 EXPECT_EQ(kDefaultCacheSize * 25 / 10, 2972 disk_cache::PreferredCacheSize(large_size * 250)); 2973 EXPECT_EQ(largest_size - 1, 2974 disk_cache::PreferredCacheSize(largest_size * 100 - 1)); 2975 2976 // Region 6: expected = largest possible size 2977 EXPECT_EQ(largest_size, 2978 disk_cache::PreferredCacheSize(largest_size * 100)); 2979 EXPECT_EQ(largest_size, 2980 disk_cache::PreferredCacheSize(largest_size * 10000)); 2981} 2982 2983// Tests that we can "migrate" a running instance from one experiment group to 2984// another. 2985TEST_F(DiskCacheBackendTest, Histograms) { 2986 InitCache(); 2987 disk_cache::BackendImpl* backend_ = cache_impl_; // Needed be the macro. 2988 2989 for (int i = 1; i < 3; i++) { 2990 CACHE_UMA(HOURS, "FillupTime", i, 28); 2991 } 2992} 2993 2994// Make sure that we keep the total memory used by the internal buffers under 2995// control. 2996TEST_F(DiskCacheBackendTest, TotalBuffersSize1) { 2997 InitCache(); 2998 std::string key("the first key"); 2999 disk_cache::Entry* entry; 3000 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 3001 3002 const int kSize = 200; 3003 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); 3004 CacheTestFillBuffer(buffer->data(), kSize, true); 3005 3006 for (int i = 0; i < 10; i++) { 3007 SCOPED_TRACE(i); 3008 // Allocate 2MB for this entry. 3009 EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, true)); 3010 EXPECT_EQ(kSize, WriteData(entry, 1, 0, buffer.get(), kSize, true)); 3011 EXPECT_EQ(kSize, 3012 WriteData(entry, 0, 1024 * 1024, buffer.get(), kSize, false)); 3013 EXPECT_EQ(kSize, 3014 WriteData(entry, 1, 1024 * 1024, buffer.get(), kSize, false)); 3015 3016 // Delete one of the buffers and truncate the other. 3017 EXPECT_EQ(0, WriteData(entry, 0, 0, buffer.get(), 0, true)); 3018 EXPECT_EQ(0, WriteData(entry, 1, 10, buffer.get(), 0, true)); 3019 3020 // Delete the second buffer, writing 10 bytes to disk. 3021 entry->Close(); 3022 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 3023 } 3024 3025 entry->Close(); 3026 EXPECT_EQ(0, cache_impl_->GetTotalBuffersSize()); 3027} 3028 3029// This test assumes at least 150MB of system memory. 3030TEST_F(DiskCacheBackendTest, TotalBuffersSize2) { 3031 InitCache(); 3032 3033 const int kOneMB = 1024 * 1024; 3034 EXPECT_TRUE(cache_impl_->IsAllocAllowed(0, kOneMB)); 3035 EXPECT_EQ(kOneMB, cache_impl_->GetTotalBuffersSize()); 3036 3037 EXPECT_TRUE(cache_impl_->IsAllocAllowed(0, kOneMB)); 3038 EXPECT_EQ(kOneMB * 2, cache_impl_->GetTotalBuffersSize()); 3039 3040 EXPECT_TRUE(cache_impl_->IsAllocAllowed(0, kOneMB)); 3041 EXPECT_EQ(kOneMB * 3, cache_impl_->GetTotalBuffersSize()); 3042 3043 cache_impl_->BufferDeleted(kOneMB); 3044 EXPECT_EQ(kOneMB * 2, cache_impl_->GetTotalBuffersSize()); 3045 3046 // Check the upper limit. 3047 EXPECT_FALSE(cache_impl_->IsAllocAllowed(0, 30 * kOneMB)); 3048 3049 for (int i = 0; i < 30; i++) 3050 cache_impl_->IsAllocAllowed(0, kOneMB); // Ignore the result. 3051 3052 EXPECT_FALSE(cache_impl_->IsAllocAllowed(0, kOneMB)); 3053} 3054 3055// Tests that sharing of external files works and we are able to delete the 3056// files when we need to. 3057TEST_F(DiskCacheBackendTest, FileSharing) { 3058 InitCache(); 3059 3060 disk_cache::Addr address(0x80000001); 3061 ASSERT_TRUE(cache_impl_->CreateExternalFile(&address)); 3062 base::FilePath name = cache_impl_->GetFileName(address); 3063 3064 scoped_refptr<disk_cache::File> file(new disk_cache::File(false)); 3065 file->Init(name); 3066 3067#if defined(OS_WIN) 3068 DWORD sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; 3069 DWORD access = GENERIC_READ | GENERIC_WRITE; 3070 base::win::ScopedHandle file2(CreateFile( 3071 name.value().c_str(), access, sharing, NULL, OPEN_EXISTING, 0, NULL)); 3072 EXPECT_FALSE(file2.IsValid()); 3073 3074 sharing |= FILE_SHARE_DELETE; 3075 file2.Set(CreateFile(name.value().c_str(), access, sharing, NULL, 3076 OPEN_EXISTING, 0, NULL)); 3077 EXPECT_TRUE(file2.IsValid()); 3078#endif 3079 3080 EXPECT_TRUE(base::DeleteFile(name, false)); 3081 3082 // We should be able to use the file. 3083 const int kSize = 200; 3084 char buffer1[kSize]; 3085 char buffer2[kSize]; 3086 memset(buffer1, 't', kSize); 3087 memset(buffer2, 0, kSize); 3088 EXPECT_TRUE(file->Write(buffer1, kSize, 0)); 3089 EXPECT_TRUE(file->Read(buffer2, kSize, 0)); 3090 EXPECT_EQ(0, memcmp(buffer1, buffer2, kSize)); 3091 3092 EXPECT_TRUE(disk_cache::DeleteCacheFile(name)); 3093} 3094 3095TEST_F(DiskCacheBackendTest, UpdateRankForExternalCacheHit) { 3096 InitCache(); 3097 3098 disk_cache::Entry* entry; 3099 3100 for (int i = 0; i < 2; ++i) { 3101 std::string key = base::StringPrintf("key%d", i); 3102 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 3103 entry->Close(); 3104 } 3105 3106 // Ping the oldest entry. 3107 cache_->OnExternalCacheHit("key0"); 3108 3109 TrimForTest(false); 3110 3111 // Make sure the older key remains. 3112 EXPECT_EQ(1, cache_->GetEntryCount()); 3113 ASSERT_EQ(net::OK, OpenEntry("key0", &entry)); 3114 entry->Close(); 3115} 3116 3117TEST_F(DiskCacheBackendTest, ShaderCacheUpdateRankForExternalCacheHit) { 3118 SetCacheType(net::SHADER_CACHE); 3119 InitCache(); 3120 3121 disk_cache::Entry* entry; 3122 3123 for (int i = 0; i < 2; ++i) { 3124 std::string key = base::StringPrintf("key%d", i); 3125 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 3126 entry->Close(); 3127 } 3128 3129 // Ping the oldest entry. 3130 cache_->OnExternalCacheHit("key0"); 3131 3132 TrimForTest(false); 3133 3134 // Make sure the older key remains. 3135 EXPECT_EQ(1, cache_->GetEntryCount()); 3136 ASSERT_EQ(net::OK, OpenEntry("key0", &entry)); 3137 entry->Close(); 3138} 3139 3140void DiskCacheBackendTest::TracingBackendBasics() { 3141 InitCache(); 3142 cache_.reset(new disk_cache::TracingCacheBackend(cache_.Pass())); 3143 cache_impl_ = NULL; 3144 EXPECT_EQ(net::DISK_CACHE, cache_->GetCacheType()); 3145 if (!simple_cache_mode_) { 3146 EXPECT_EQ(0, cache_->GetEntryCount()); 3147 } 3148 3149 net::TestCompletionCallback cb; 3150 disk_cache::Entry* entry = NULL; 3151 EXPECT_NE(net::OK, OpenEntry("key", &entry)); 3152 EXPECT_TRUE(NULL == entry); 3153 3154 ASSERT_EQ(net::OK, CreateEntry("key", &entry)); 3155 EXPECT_TRUE(NULL != entry); 3156 3157 disk_cache::Entry* same_entry = NULL; 3158 ASSERT_EQ(net::OK, OpenEntry("key", &same_entry)); 3159 EXPECT_TRUE(NULL != same_entry); 3160 3161 if (!simple_cache_mode_) { 3162 EXPECT_EQ(1, cache_->GetEntryCount()); 3163 } 3164 entry->Close(); 3165 entry = NULL; 3166 same_entry->Close(); 3167 same_entry = NULL; 3168} 3169 3170TEST_F(DiskCacheBackendTest, TracingBackendBasics) { 3171 TracingBackendBasics(); 3172} 3173 3174// The Simple Cache backend requires a few guarantees from the filesystem like 3175// atomic renaming of recently open files. Those guarantees are not provided in 3176// general on Windows. 3177#if defined(OS_POSIX) 3178 3179TEST_F(DiskCacheBackendTest, SimpleCacheShutdownWithPendingCreate) { 3180 SetCacheType(net::APP_CACHE); 3181 SetSimpleCacheMode(); 3182 BackendShutdownWithPendingCreate(false); 3183} 3184 3185TEST_F(DiskCacheBackendTest, SimpleCacheShutdownWithPendingFileIO) { 3186 SetCacheType(net::APP_CACHE); 3187 SetSimpleCacheMode(); 3188 BackendShutdownWithPendingFileIO(false); 3189} 3190 3191TEST_F(DiskCacheBackendTest, SimpleCacheBasics) { 3192 SetSimpleCacheMode(); 3193 BackendBasics(); 3194} 3195 3196TEST_F(DiskCacheBackendTest, SimpleCacheAppCacheBasics) { 3197 SetCacheType(net::APP_CACHE); 3198 SetSimpleCacheMode(); 3199 BackendBasics(); 3200} 3201 3202TEST_F(DiskCacheBackendTest, SimpleCacheKeying) { 3203 SetSimpleCacheMode(); 3204 BackendKeying(); 3205} 3206 3207TEST_F(DiskCacheBackendTest, SimpleCacheAppCacheKeying) { 3208 SetSimpleCacheMode(); 3209 SetCacheType(net::APP_CACHE); 3210 BackendKeying(); 3211} 3212 3213TEST_F(DiskCacheBackendTest, DISABLED_SimpleCacheSetSize) { 3214 SetSimpleCacheMode(); 3215 BackendSetSize(); 3216} 3217 3218// MacOS has a default open file limit of 256 files, which is incompatible with 3219// this simple cache test. 3220#if defined(OS_MACOSX) 3221#define SIMPLE_MAYBE_MACOS(TestName) DISABLED_ ## TestName 3222#else 3223#define SIMPLE_MAYBE_MACOS(TestName) TestName 3224#endif 3225 3226TEST_F(DiskCacheBackendTest, SIMPLE_MAYBE_MACOS(SimpleCacheLoad)) { 3227 SetMaxSize(0x100000); 3228 SetSimpleCacheMode(); 3229 BackendLoad(); 3230} 3231 3232TEST_F(DiskCacheBackendTest, SIMPLE_MAYBE_MACOS(SimpleCacheAppCacheLoad)) { 3233 SetCacheType(net::APP_CACHE); 3234 SetSimpleCacheMode(); 3235 SetMaxSize(0x100000); 3236 BackendLoad(); 3237} 3238 3239TEST_F(DiskCacheBackendTest, SimpleDoomRecent) { 3240 SetSimpleCacheMode(); 3241 BackendDoomRecent(); 3242} 3243 3244// crbug.com/330926, crbug.com/370677 3245TEST_F(DiskCacheBackendTest, DISABLED_SimpleDoomBetween) { 3246 SetSimpleCacheMode(); 3247 BackendDoomBetween(); 3248} 3249 3250TEST_F(DiskCacheBackendTest, SimpleCacheDoomAll) { 3251 SetSimpleCacheMode(); 3252 BackendDoomAll(); 3253} 3254 3255TEST_F(DiskCacheBackendTest, SimpleCacheAppCacheOnlyDoomAll) { 3256 SetCacheType(net::APP_CACHE); 3257 SetSimpleCacheMode(); 3258 BackendDoomAll(); 3259} 3260 3261TEST_F(DiskCacheBackendTest, SimpleCacheTracingBackendBasics) { 3262 SetSimpleCacheMode(); 3263 TracingBackendBasics(); 3264 // TODO(pasko): implement integrity checking on the Simple Backend. 3265 DisableIntegrityCheck(); 3266} 3267 3268TEST_F(DiskCacheBackendTest, SimpleCacheOpenMissingFile) { 3269 SetSimpleCacheMode(); 3270 InitCache(); 3271 3272 const char* key = "the first key"; 3273 disk_cache::Entry* entry = NULL; 3274 3275 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 3276 ASSERT_TRUE(entry != NULL); 3277 entry->Close(); 3278 entry = NULL; 3279 3280 // To make sure the file creation completed we need to call open again so that 3281 // we block until it actually created the files. 3282 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 3283 ASSERT_TRUE(entry != NULL); 3284 entry->Close(); 3285 entry = NULL; 3286 3287 // Delete one of the files in the entry. 3288 base::FilePath to_delete_file = cache_path_.AppendASCII( 3289 disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0)); 3290 EXPECT_TRUE(base::PathExists(to_delete_file)); 3291 EXPECT_TRUE(disk_cache::DeleteCacheFile(to_delete_file)); 3292 3293 // Failing to open the entry should delete the rest of these files. 3294 ASSERT_EQ(net::ERR_FAILED, OpenEntry(key, &entry)); 3295 3296 // Confirm the rest of the files are gone. 3297 for (int i = 1; i < disk_cache::kSimpleEntryFileCount; ++i) { 3298 base::FilePath should_be_gone_file(cache_path_.AppendASCII( 3299 disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, i))); 3300 EXPECT_FALSE(base::PathExists(should_be_gone_file)); 3301 } 3302} 3303 3304TEST_F(DiskCacheBackendTest, SimpleCacheOpenBadFile) { 3305 SetSimpleCacheMode(); 3306 InitCache(); 3307 3308 const char* key = "the first key"; 3309 disk_cache::Entry* entry = NULL; 3310 3311 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 3312 disk_cache::Entry* null = NULL; 3313 ASSERT_NE(null, entry); 3314 entry->Close(); 3315 entry = NULL; 3316 3317 // To make sure the file creation completed we need to call open again so that 3318 // we block until it actually created the files. 3319 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 3320 ASSERT_NE(null, entry); 3321 entry->Close(); 3322 entry = NULL; 3323 3324 // Write an invalid header for stream 0 and stream 1. 3325 base::FilePath entry_file1_path = cache_path_.AppendASCII( 3326 disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0)); 3327 3328 disk_cache::SimpleFileHeader header; 3329 header.initial_magic_number = GG_UINT64_C(0xbadf00d); 3330 EXPECT_EQ( 3331 implicit_cast<int>(sizeof(header)), 3332 base::WriteFile(entry_file1_path, reinterpret_cast<char*>(&header), 3333 sizeof(header))); 3334 ASSERT_EQ(net::ERR_FAILED, OpenEntry(key, &entry)); 3335} 3336 3337// Tests that the Simple Cache Backend fails to initialize with non-matching 3338// file structure on disk. 3339TEST_F(DiskCacheBackendTest, SimpleCacheOverBlockfileCache) { 3340 // Create a cache structure with the |BackendImpl|. 3341 InitCache(); 3342 disk_cache::Entry* entry; 3343 const int kSize = 50; 3344 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); 3345 CacheTestFillBuffer(buffer->data(), kSize, false); 3346 ASSERT_EQ(net::OK, CreateEntry("key", &entry)); 3347 ASSERT_EQ(0, WriteData(entry, 0, 0, buffer.get(), 0, false)); 3348 entry->Close(); 3349 cache_.reset(); 3350 3351 // Check that the |SimpleBackendImpl| does not favor this structure. 3352 base::Thread cache_thread("CacheThread"); 3353 ASSERT_TRUE(cache_thread.StartWithOptions( 3354 base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); 3355 disk_cache::SimpleBackendImpl* simple_cache = 3356 new disk_cache::SimpleBackendImpl(cache_path_, 3357 0, 3358 net::DISK_CACHE, 3359 cache_thread.message_loop_proxy().get(), 3360 NULL); 3361 net::TestCompletionCallback cb; 3362 int rv = simple_cache->Init(cb.callback()); 3363 EXPECT_NE(net::OK, cb.GetResult(rv)); 3364 delete simple_cache; 3365 DisableIntegrityCheck(); 3366} 3367 3368// Tests that the |BackendImpl| refuses to initialize on top of the files 3369// generated by the Simple Cache Backend. 3370TEST_F(DiskCacheBackendTest, BlockfileCacheOverSimpleCache) { 3371 // Create a cache structure with the |SimpleBackendImpl|. 3372 SetSimpleCacheMode(); 3373 InitCache(); 3374 disk_cache::Entry* entry; 3375 const int kSize = 50; 3376 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); 3377 CacheTestFillBuffer(buffer->data(), kSize, false); 3378 ASSERT_EQ(net::OK, CreateEntry("key", &entry)); 3379 ASSERT_EQ(0, WriteData(entry, 0, 0, buffer.get(), 0, false)); 3380 entry->Close(); 3381 cache_.reset(); 3382 3383 // Check that the |BackendImpl| does not favor this structure. 3384 base::Thread cache_thread("CacheThread"); 3385 ASSERT_TRUE(cache_thread.StartWithOptions( 3386 base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); 3387 disk_cache::BackendImpl* cache = new disk_cache::BackendImpl( 3388 cache_path_, base::MessageLoopProxy::current().get(), NULL); 3389 cache->SetUnitTestMode(); 3390 net::TestCompletionCallback cb; 3391 int rv = cache->Init(cb.callback()); 3392 EXPECT_NE(net::OK, cb.GetResult(rv)); 3393 delete cache; 3394 DisableIntegrityCheck(); 3395} 3396 3397TEST_F(DiskCacheBackendTest, SimpleCacheFixEnumerators) { 3398 SetSimpleCacheMode(); 3399 BackendFixEnumerators(); 3400} 3401 3402// Tests basic functionality of the SimpleBackend implementation of the 3403// enumeration API. 3404TEST_F(DiskCacheBackendTest, SimpleCacheEnumerationBasics) { 3405 SetSimpleCacheMode(); 3406 InitCache(); 3407 std::set<std::string> key_pool; 3408 ASSERT_TRUE(CreateSetOfRandomEntries(&key_pool)); 3409 3410 // Check that enumeration returns all entries. 3411 std::set<std::string> keys_to_match(key_pool); 3412 void* iter = NULL; 3413 size_t count = 0; 3414 ASSERT_TRUE(EnumerateAndMatchKeys(-1, &iter, &keys_to_match, &count)); 3415 cache_->EndEnumeration(&iter); 3416 EXPECT_EQ(key_pool.size(), count); 3417 EXPECT_TRUE(keys_to_match.empty()); 3418 3419 // Check that opening entries does not affect enumeration. 3420 keys_to_match = key_pool; 3421 iter = NULL; 3422 count = 0; 3423 disk_cache::Entry* entry_opened_before; 3424 ASSERT_EQ(net::OK, OpenEntry(*(key_pool.begin()), &entry_opened_before)); 3425 ASSERT_TRUE(EnumerateAndMatchKeys(key_pool.size()/2, 3426 &iter, 3427 &keys_to_match, 3428 &count)); 3429 3430 disk_cache::Entry* entry_opened_middle; 3431 ASSERT_EQ(net::OK, 3432 OpenEntry(*(keys_to_match.begin()), &entry_opened_middle)); 3433 ASSERT_TRUE(EnumerateAndMatchKeys(-1, &iter, &keys_to_match, &count)); 3434 cache_->EndEnumeration(&iter); 3435 entry_opened_before->Close(); 3436 entry_opened_middle->Close(); 3437 3438 EXPECT_EQ(key_pool.size(), count); 3439 EXPECT_TRUE(keys_to_match.empty()); 3440} 3441 3442// Tests that the enumerations are not affected by dooming an entry in the 3443// middle. 3444TEST_F(DiskCacheBackendTest, SimpleCacheEnumerationWhileDoomed) { 3445 SetSimpleCacheMode(); 3446 InitCache(); 3447 std::set<std::string> key_pool; 3448 ASSERT_TRUE(CreateSetOfRandomEntries(&key_pool)); 3449 3450 // Check that enumeration returns all entries but the doomed one. 3451 std::set<std::string> keys_to_match(key_pool); 3452 void* iter = NULL; 3453 size_t count = 0; 3454 ASSERT_TRUE(EnumerateAndMatchKeys(key_pool.size()/2, 3455 &iter, 3456 &keys_to_match, 3457 &count)); 3458 3459 std::string key_to_delete = *(keys_to_match.begin()); 3460 DoomEntry(key_to_delete); 3461 keys_to_match.erase(key_to_delete); 3462 key_pool.erase(key_to_delete); 3463 ASSERT_TRUE(EnumerateAndMatchKeys(-1, &iter, &keys_to_match, &count)); 3464 cache_->EndEnumeration(&iter); 3465 3466 EXPECT_EQ(key_pool.size(), count); 3467 EXPECT_TRUE(keys_to_match.empty()); 3468} 3469 3470// Tests that enumerations are not affected by corrupt files. 3471TEST_F(DiskCacheBackendTest, SimpleCacheEnumerationCorruption) { 3472 SetSimpleCacheMode(); 3473 InitCache(); 3474 std::set<std::string> key_pool; 3475 ASSERT_TRUE(CreateSetOfRandomEntries(&key_pool)); 3476 3477 // Create a corrupt entry. The write/read sequence ensures that the entry will 3478 // have been created before corrupting the platform files, in the case of 3479 // optimistic operations. 3480 const std::string key = "the key"; 3481 disk_cache::Entry* corrupted_entry; 3482 3483 ASSERT_EQ(net::OK, CreateEntry(key, &corrupted_entry)); 3484 ASSERT_TRUE(corrupted_entry); 3485 const int kSize = 50; 3486 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); 3487 CacheTestFillBuffer(buffer->data(), kSize, false); 3488 ASSERT_EQ(kSize, 3489 WriteData(corrupted_entry, 0, 0, buffer.get(), kSize, false)); 3490 ASSERT_EQ(kSize, ReadData(corrupted_entry, 0, 0, buffer.get(), kSize)); 3491 corrupted_entry->Close(); 3492 3493 EXPECT_TRUE(disk_cache::simple_util::CreateCorruptFileForTests( 3494 key, cache_path_)); 3495 EXPECT_EQ(key_pool.size() + 1, 3496 implicit_cast<size_t>(cache_->GetEntryCount())); 3497 3498 // Check that enumeration returns all entries but the corrupt one. 3499 std::set<std::string> keys_to_match(key_pool); 3500 void* iter = NULL; 3501 size_t count = 0; 3502 ASSERT_TRUE(EnumerateAndMatchKeys(-1, &iter, &keys_to_match, &count)); 3503 cache_->EndEnumeration(&iter); 3504 3505 EXPECT_EQ(key_pool.size(), count); 3506 EXPECT_TRUE(keys_to_match.empty()); 3507} 3508 3509#endif // defined(OS_POSIX) 3510