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