Home | History | Annotate | Download | only in disk_cache
      1 // Copyright (c) 2011 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/string_util.h"
      8 #include "base/stringprintf.h"
      9 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
     10 #include "base/threading/platform_thread.h"
     11 #include "net/base/io_buffer.h"
     12 #include "net/base/net_errors.h"
     13 #include "net/base/test_completion_callback.h"
     14 #include "net/disk_cache/backend_impl.h"
     15 #include "net/disk_cache/cache_util.h"
     16 #include "net/disk_cache/disk_cache_test_base.h"
     17 #include "net/disk_cache/disk_cache_test_util.h"
     18 #include "net/disk_cache/histogram_macros.h"
     19 #include "net/disk_cache/mapped_file.h"
     20 #include "net/disk_cache/mem_backend_impl.h"
     21 #include "testing/gtest/include/gtest/gtest.h"
     22 
     23 #if defined(OS_WIN)
     24 #include "base/win/scoped_handle.h"
     25 #endif
     26 
     27 using base::Time;
     28 
     29 // Tests that can run with different types of caches.
     30 class DiskCacheBackendTest : public DiskCacheTestWithCache {
     31  protected:
     32   void BackendBasics();
     33   void BackendKeying();
     34   void BackendSetSize();
     35   void BackendLoad();
     36   void BackendValidEntry();
     37   void BackendInvalidEntry();
     38   void BackendInvalidEntryRead();
     39   void BackendInvalidEntryWithLoad();
     40   void BackendTrimInvalidEntry();
     41   void BackendTrimInvalidEntry2();
     42   void BackendEnumerations();
     43   void BackendEnumerations2();
     44   void BackendInvalidEntryEnumeration();
     45   void BackendFixEnumerators();
     46   void BackendDoomRecent();
     47   void BackendDoomBetween();
     48   void BackendTransaction(const std::string& name, int num_entries, bool load);
     49   void BackendRecoverInsert();
     50   void BackendRecoverRemove();
     51   void BackendRecoverWithEviction();
     52   void BackendInvalidEntry2();
     53   void BackendInvalidEntry3();
     54   void BackendNotMarkedButDirty(const std::string& name);
     55   void BackendDoomAll();
     56   void BackendDoomAll2();
     57   void BackendInvalidRankings();
     58   void BackendInvalidRankings2();
     59   void BackendDisable();
     60   void BackendDisable2();
     61   void BackendDisable3();
     62   void BackendDisable4();
     63 };
     64 
     65 void DiskCacheBackendTest::BackendBasics() {
     66   InitCache();
     67   disk_cache::Entry *entry1 = NULL, *entry2 = NULL;
     68   EXPECT_NE(net::OK, OpenEntry("the first key", &entry1));
     69   ASSERT_EQ(net::OK, CreateEntry("the first key", &entry1));
     70   ASSERT_TRUE(NULL != entry1);
     71   entry1->Close();
     72   entry1 = NULL;
     73 
     74   ASSERT_EQ(net::OK, OpenEntry("the first key", &entry1));
     75   ASSERT_TRUE(NULL != entry1);
     76   entry1->Close();
     77   entry1 = NULL;
     78 
     79   EXPECT_NE(net::OK, CreateEntry("the first key", &entry1));
     80   ASSERT_EQ(net::OK, OpenEntry("the first key", &entry1));
     81   EXPECT_NE(net::OK, OpenEntry("some other key", &entry2));
     82   ASSERT_EQ(net::OK, CreateEntry("some other key", &entry2));
     83   ASSERT_TRUE(NULL != entry1);
     84   ASSERT_TRUE(NULL != entry2);
     85   EXPECT_EQ(2, cache_->GetEntryCount());
     86 
     87   disk_cache::Entry* entry3 = NULL;
     88   ASSERT_EQ(net::OK, OpenEntry("some other key", &entry3));
     89   ASSERT_TRUE(NULL != entry3);
     90   EXPECT_TRUE(entry2 == entry3);
     91   EXPECT_EQ(2, cache_->GetEntryCount());
     92 
     93   EXPECT_EQ(net::OK, DoomEntry("some other key"));
     94   EXPECT_EQ(1, cache_->GetEntryCount());
     95   entry1->Close();
     96   entry2->Close();
     97   entry3->Close();
     98 
     99   EXPECT_EQ(net::OK, DoomEntry("the first key"));
    100   EXPECT_EQ(0, cache_->GetEntryCount());
    101 
    102   ASSERT_EQ(net::OK, CreateEntry("the first key", &entry1));
    103   ASSERT_EQ(net::OK, CreateEntry("some other key", &entry2));
    104   entry1->Doom();
    105   entry1->Close();
    106   EXPECT_EQ(net::OK, DoomEntry("some other key"));
    107   EXPECT_EQ(0, cache_->GetEntryCount());
    108   entry2->Close();
    109 }
    110 
    111 TEST_F(DiskCacheBackendTest, Basics) {
    112   BackendBasics();
    113 }
    114 
    115 TEST_F(DiskCacheBackendTest, NewEvictionBasics) {
    116   SetNewEviction();
    117   BackendBasics();
    118 }
    119 
    120 TEST_F(DiskCacheBackendTest, MemoryOnlyBasics) {
    121   SetMemoryOnlyMode();
    122   BackendBasics();
    123 }
    124 
    125 TEST_F(DiskCacheBackendTest, AppCacheBasics) {
    126   SetCacheType(net::APP_CACHE);
    127   BackendBasics();
    128 }
    129 
    130 void DiskCacheBackendTest::BackendKeying() {
    131   InitCache();
    132   const char* kName1 = "the first key";
    133   const char* kName2 = "the first Key";
    134   disk_cache::Entry *entry1, *entry2;
    135   ASSERT_EQ(net::OK, CreateEntry(kName1, &entry1));
    136 
    137   ASSERT_EQ(net::OK, CreateEntry(kName2, &entry2));
    138   EXPECT_TRUE(entry1 != entry2) << "Case sensitive";
    139   entry2->Close();
    140 
    141   char buffer[30];
    142   base::strlcpy(buffer, kName1, arraysize(buffer));
    143   ASSERT_EQ(net::OK, OpenEntry(buffer, &entry2));
    144   EXPECT_TRUE(entry1 == entry2);
    145   entry2->Close();
    146 
    147   base::strlcpy(buffer + 1, kName1, arraysize(buffer) - 1);
    148   ASSERT_EQ(net::OK, OpenEntry(buffer + 1, &entry2));
    149   EXPECT_TRUE(entry1 == entry2);
    150   entry2->Close();
    151 
    152   base::strlcpy(buffer + 3,  kName1, arraysize(buffer) - 3);
    153   ASSERT_EQ(net::OK, OpenEntry(buffer + 3, &entry2));
    154   EXPECT_TRUE(entry1 == entry2);
    155   entry2->Close();
    156 
    157   // Now verify long keys.
    158   char buffer2[20000];
    159   memset(buffer2, 's', sizeof(buffer2));
    160   buffer2[1023] = '\0';
    161   ASSERT_EQ(net::OK, CreateEntry(buffer2, &entry2)) << "key on block file";
    162   entry2->Close();
    163 
    164   buffer2[1023] = 'g';
    165   buffer2[19999] = '\0';
    166   ASSERT_EQ(net::OK, CreateEntry(buffer2, &entry2)) << "key on external file";
    167   entry2->Close();
    168   entry1->Close();
    169 }
    170 
    171 TEST_F(DiskCacheBackendTest, Keying) {
    172   BackendKeying();
    173 }
    174 
    175 TEST_F(DiskCacheBackendTest, NewEvictionKeying) {
    176   SetNewEviction();
    177   BackendKeying();
    178 }
    179 
    180 TEST_F(DiskCacheBackendTest, MemoryOnlyKeying) {
    181   SetMemoryOnlyMode();
    182   BackendKeying();
    183 }
    184 
    185 TEST_F(DiskCacheBackendTest, AppCacheKeying) {
    186   SetCacheType(net::APP_CACHE);
    187   BackendKeying();
    188 }
    189 
    190 TEST_F(DiskCacheTest, CreateBackend) {
    191   TestCompletionCallback cb;
    192 
    193   {
    194     FilePath path = GetCacheFilePath();
    195     ASSERT_TRUE(DeleteCache(path));
    196     base::Thread cache_thread("CacheThread");
    197     ASSERT_TRUE(cache_thread.StartWithOptions(
    198                     base::Thread::Options(MessageLoop::TYPE_IO, 0)));
    199 
    200     // Test the private factory methods.
    201     disk_cache::Backend* cache = NULL;
    202     int rv = disk_cache::BackendImpl::CreateBackend(
    203                  path, false, 0, net::DISK_CACHE, disk_cache::kNoRandom,
    204                  cache_thread.message_loop_proxy(), NULL, &cache, &cb);
    205     ASSERT_EQ(net::OK, cb.GetResult(rv));
    206     ASSERT_TRUE(cache);
    207     delete cache;
    208 
    209     cache = disk_cache::MemBackendImpl::CreateBackend(0, NULL);
    210     ASSERT_TRUE(cache);
    211     delete cache;
    212     cache = NULL;
    213 
    214     // Now test the public API.
    215     rv = disk_cache::CreateCacheBackend(net::DISK_CACHE, path, 0, false,
    216                                         cache_thread.message_loop_proxy(),
    217                                         NULL, &cache, &cb);
    218     ASSERT_EQ(net::OK, cb.GetResult(rv));
    219     ASSERT_TRUE(cache);
    220     delete cache;
    221     cache = NULL;
    222 
    223     rv = disk_cache::CreateCacheBackend(net::MEMORY_CACHE, FilePath(), 0, false,
    224                                         NULL, NULL, &cache, &cb);
    225     ASSERT_EQ(net::OK, cb.GetResult(rv));
    226     ASSERT_TRUE(cache);
    227     delete cache;
    228   }
    229 
    230   MessageLoop::current()->RunAllPending();
    231 }
    232 
    233 TEST_F(DiskCacheBackendTest, ExternalFiles) {
    234   InitCache();
    235   // First, let's create a file on the folder.
    236   FilePath filename = GetCacheFilePath().AppendASCII("f_000001");
    237 
    238   const int kSize = 50;
    239   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
    240   CacheTestFillBuffer(buffer1->data(), kSize, false);
    241   ASSERT_EQ(kSize, file_util::WriteFile(filename, buffer1->data(), kSize));
    242 
    243   // Now let's create a file with the cache.
    244   disk_cache::Entry* entry;
    245   ASSERT_EQ(net::OK, CreateEntry("key", &entry));
    246   ASSERT_EQ(0, WriteData(entry, 0, 20000, buffer1, 0, false));
    247   entry->Close();
    248 
    249   // And verify that the first file is still there.
    250   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize));
    251   ASSERT_EQ(kSize, file_util::ReadFile(filename, buffer2->data(), kSize));
    252   EXPECT_EQ(0, memcmp(buffer1->data(), buffer2->data(), kSize));
    253 }
    254 
    255 // Tests that we deal with file-level pending operations at destruction time.
    256 TEST_F(DiskCacheTest, ShutdownWithPendingIO) {
    257   TestCompletionCallback cb;
    258 
    259   {
    260     FilePath path = GetCacheFilePath();
    261     ASSERT_TRUE(DeleteCache(path));
    262     base::Thread cache_thread("CacheThread");
    263     ASSERT_TRUE(cache_thread.StartWithOptions(
    264                     base::Thread::Options(MessageLoop::TYPE_IO, 0)));
    265 
    266     disk_cache::Backend* cache;
    267     int rv = disk_cache::BackendImpl::CreateBackend(
    268                  path, false, 0, net::DISK_CACHE, disk_cache::kNoRandom,
    269                  base::MessageLoopProxy::CreateForCurrentThread(), NULL,
    270                  &cache, &cb);
    271     ASSERT_EQ(net::OK, cb.GetResult(rv));
    272 
    273     disk_cache::EntryImpl* entry;
    274     rv = cache->CreateEntry("some key",
    275                             reinterpret_cast<disk_cache::Entry**>(&entry), &cb);
    276     ASSERT_EQ(net::OK, cb.GetResult(rv));
    277 
    278     const int kSize = 25000;
    279     scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
    280     CacheTestFillBuffer(buffer->data(), kSize, false);
    281 
    282     for (int i = 0; i < 10 * 1024 * 1024; i += 64 * 1024) {
    283       // We are using the current thread as the cache thread because we want to
    284       // be able to call directly this method to make sure that the OS (instead
    285       // of us switching thread) is returning IO pending.
    286       rv = entry->WriteDataImpl(0, i, buffer, kSize, &cb, false);
    287       if (rv == net::ERR_IO_PENDING)
    288         break;
    289       EXPECT_EQ(kSize, rv);
    290     }
    291 
    292     // Don't call Close() to avoid going through the queue or we'll deadlock
    293     // waiting for the operation to finish.
    294     entry->Release();
    295 
    296     // The cache destructor will see one pending operation here.
    297     delete cache;
    298 
    299     if (rv == net::ERR_IO_PENDING) {
    300       EXPECT_TRUE(cb.have_result());
    301     }
    302   }
    303 
    304   MessageLoop::current()->RunAllPending();
    305 }
    306 
    307 // Tests that we deal with background-thread pending operations.
    308 TEST_F(DiskCacheTest, ShutdownWithPendingIO2) {
    309   TestCompletionCallback cb;
    310 
    311   {
    312     FilePath path = GetCacheFilePath();
    313     ASSERT_TRUE(DeleteCache(path));
    314     base::Thread cache_thread("CacheThread");
    315     ASSERT_TRUE(cache_thread.StartWithOptions(
    316                     base::Thread::Options(MessageLoop::TYPE_IO, 0)));
    317 
    318     disk_cache::Backend* cache;
    319     int rv = disk_cache::BackendImpl::CreateBackend(
    320                  path, false, 0, net::DISK_CACHE, disk_cache::kNoRandom,
    321                  cache_thread.message_loop_proxy(), NULL, &cache, &cb);
    322     ASSERT_EQ(net::OK, cb.GetResult(rv));
    323 
    324     disk_cache::Entry* entry;
    325     rv = cache->CreateEntry("some key", &entry, &cb);
    326     ASSERT_EQ(net::OK, cb.GetResult(rv));
    327 
    328     const int kSize = 25000;
    329     scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
    330     CacheTestFillBuffer(buffer->data(), kSize, false);
    331 
    332     rv = entry->WriteData(0, 0, buffer, kSize, &cb, false);
    333     EXPECT_EQ(net::ERR_IO_PENDING, rv);
    334 
    335     entry->Close();
    336 
    337     // The cache destructor will see two pending operations here.
    338     delete cache;
    339   }
    340 
    341   MessageLoop::current()->RunAllPending();
    342 }
    343 
    344 TEST_F(DiskCacheTest, TruncatedIndex) {
    345   FilePath path = GetCacheFilePath();
    346   ASSERT_TRUE(DeleteCache(path));
    347   FilePath index = path.AppendASCII("index");
    348   ASSERT_EQ(5, file_util::WriteFile(index, "hello", 5));
    349 
    350   base::Thread cache_thread("CacheThread");
    351   ASSERT_TRUE(cache_thread.StartWithOptions(
    352                   base::Thread::Options(MessageLoop::TYPE_IO, 0)));
    353   TestCompletionCallback cb;
    354 
    355   disk_cache::Backend* backend = NULL;
    356   int rv = disk_cache::BackendImpl::CreateBackend(
    357                path, false, 0, net::DISK_CACHE, disk_cache::kNone,
    358                cache_thread.message_loop_proxy(), NULL, &backend, &cb);
    359   ASSERT_NE(net::OK, cb.GetResult(rv));
    360 
    361   ASSERT_TRUE(backend == NULL);
    362   delete backend;
    363 }
    364 
    365 void DiskCacheBackendTest::BackendSetSize() {
    366   SetDirectMode();
    367   const int cache_size = 0x10000;  // 64 kB
    368   SetMaxSize(cache_size);
    369   InitCache();
    370 
    371   std::string first("some key");
    372   std::string second("something else");
    373   disk_cache::Entry* entry;
    374   ASSERT_EQ(net::OK, CreateEntry(first, &entry));
    375 
    376   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(cache_size));
    377   memset(buffer->data(), 0, cache_size);
    378   EXPECT_EQ(cache_size / 10, WriteData(entry, 0, 0, buffer, cache_size / 10,
    379                                        false)) << "normal file";
    380 
    381   EXPECT_EQ(net::ERR_FAILED, WriteData(entry, 1, 0, buffer, cache_size / 5,
    382                                        false)) << "file size above the limit";
    383 
    384   // By doubling the total size, we make this file cacheable.
    385   SetMaxSize(cache_size * 2);
    386   EXPECT_EQ(cache_size / 5, WriteData(entry, 1, 0, buffer, cache_size / 5,
    387                                       false));
    388 
    389   // Let's fill up the cache!.
    390   SetMaxSize(cache_size * 10);
    391   EXPECT_EQ(cache_size * 3 / 4, WriteData(entry, 0, 0, buffer,
    392                                           cache_size * 3 / 4, false));
    393   entry->Close();
    394   FlushQueueForTest();
    395 
    396   SetMaxSize(cache_size);
    397 
    398   // The cache is 95% full.
    399 
    400   ASSERT_EQ(net::OK, CreateEntry(second, &entry));
    401   EXPECT_EQ(cache_size / 10, WriteData(entry, 0, 0, buffer, cache_size / 10,
    402                                        false));
    403 
    404   disk_cache::Entry* entry2;
    405   ASSERT_EQ(net::OK, CreateEntry("an extra key", &entry2));
    406   EXPECT_EQ(cache_size / 10, WriteData(entry2, 0, 0, buffer, cache_size / 10,
    407                                        false));
    408   entry2->Close();  // This will trigger the cache trim.
    409 
    410   EXPECT_NE(net::OK, OpenEntry(first, &entry2));
    411 
    412   FlushQueueForTest();  // Make sure that we are done trimming the cache.
    413   FlushQueueForTest();  // We may have posted two tasks to evict stuff.
    414 
    415   entry->Close();
    416   ASSERT_EQ(net::OK, OpenEntry(second, &entry));
    417   EXPECT_EQ(cache_size / 10, entry->GetDataSize(0));
    418   entry->Close();
    419 }
    420 
    421 TEST_F(DiskCacheBackendTest, SetSize) {
    422   BackendSetSize();
    423 }
    424 
    425 TEST_F(DiskCacheBackendTest, NewEvictionSetSize) {
    426   SetNewEviction();
    427   BackendSetSize();
    428 }
    429 
    430 TEST_F(DiskCacheBackendTest, MemoryOnlySetSize) {
    431   SetMemoryOnlyMode();
    432   BackendSetSize();
    433 }
    434 
    435 void DiskCacheBackendTest::BackendLoad() {
    436   InitCache();
    437   int seed = static_cast<int>(Time::Now().ToInternalValue());
    438   srand(seed);
    439 
    440   disk_cache::Entry* entries[100];
    441   for (int i = 0; i < 100; i++) {
    442     std::string key = GenerateKey(true);
    443     ASSERT_EQ(net::OK, CreateEntry(key, &entries[i]));
    444   }
    445   EXPECT_EQ(100, cache_->GetEntryCount());
    446 
    447   for (int i = 0; i < 100; i++) {
    448     int source1 = rand() % 100;
    449     int source2 = rand() % 100;
    450     disk_cache::Entry* temp = entries[source1];
    451     entries[source1] = entries[source2];
    452     entries[source2] = temp;
    453   }
    454 
    455   for (int i = 0; i < 100; i++) {
    456     disk_cache::Entry* entry;
    457     ASSERT_EQ(net::OK, OpenEntry(entries[i]->GetKey(), &entry));
    458     EXPECT_TRUE(entry == entries[i]);
    459     entry->Close();
    460     entries[i]->Doom();
    461     entries[i]->Close();
    462   }
    463   FlushQueueForTest();
    464   EXPECT_EQ(0, cache_->GetEntryCount());
    465 }
    466 
    467 TEST_F(DiskCacheBackendTest, Load) {
    468   // Work with a tiny index table (16 entries)
    469   SetMask(0xf);
    470   SetMaxSize(0x100000);
    471   BackendLoad();
    472 }
    473 
    474 TEST_F(DiskCacheBackendTest, NewEvictionLoad) {
    475   SetNewEviction();
    476   // Work with a tiny index table (16 entries)
    477   SetMask(0xf);
    478   SetMaxSize(0x100000);
    479   BackendLoad();
    480 }
    481 
    482 TEST_F(DiskCacheBackendTest, MemoryOnlyLoad) {
    483   // Work with a tiny index table (16 entries)
    484   SetMaxSize(0x100000);
    485   SetMemoryOnlyMode();
    486   BackendLoad();
    487 }
    488 
    489 TEST_F(DiskCacheBackendTest, AppCacheLoad) {
    490   SetCacheType(net::APP_CACHE);
    491   // Work with a tiny index table (16 entries)
    492   SetMask(0xf);
    493   SetMaxSize(0x100000);
    494   BackendLoad();
    495 }
    496 
    497 TEST_F(DiskCacheBackendTest, NewEvictionTrim) {
    498   SetNewEviction();
    499   SetDirectMode();
    500   InitCache();
    501 
    502   disk_cache::Entry* entry;
    503   for (int i = 0; i < 100; i++) {
    504     std::string name(StringPrintf("Key %d", i));
    505     ASSERT_EQ(net::OK, CreateEntry(name, &entry));
    506     entry->Close();
    507     if (i < 90) {
    508       // Entries 0 to 89 are in list 1; 90 to 99 are in list 0.
    509       ASSERT_EQ(net::OK, OpenEntry(name, &entry));
    510       entry->Close();
    511     }
    512   }
    513 
    514   // The first eviction must come from list 1 (10% limit), the second must come
    515   // from list 0.
    516   TrimForTest(false);
    517   EXPECT_NE(net::OK, OpenEntry("Key 0", &entry));
    518   TrimForTest(false);
    519   EXPECT_NE(net::OK, OpenEntry("Key 90", &entry));
    520 
    521   // Double check that we still have the list tails.
    522   ASSERT_EQ(net::OK, OpenEntry("Key 1", &entry));
    523   entry->Close();
    524   ASSERT_EQ(net::OK, OpenEntry("Key 91", &entry));
    525   entry->Close();
    526 }
    527 
    528 // Before looking for invalid entries, let's check a valid entry.
    529 void DiskCacheBackendTest::BackendValidEntry() {
    530   SetDirectMode();
    531   InitCache();
    532 
    533   std::string key("Some key");
    534   disk_cache::Entry* entry;
    535   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
    536 
    537   const int kSize = 50;
    538   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
    539   memset(buffer1->data(), 0, kSize);
    540   base::strlcpy(buffer1->data(), "And the data to save", kSize);
    541   EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer1, kSize, false));
    542   entry->Close();
    543   SimulateCrash();
    544 
    545   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
    546 
    547   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize));
    548   memset(buffer2->data(), 0, kSize);
    549   EXPECT_EQ(kSize, ReadData(entry, 0, 0, buffer2, kSize));
    550   entry->Close();
    551   EXPECT_STREQ(buffer1->data(), buffer2->data());
    552 }
    553 
    554 TEST_F(DiskCacheBackendTest, ValidEntry) {
    555   BackendValidEntry();
    556 }
    557 
    558 TEST_F(DiskCacheBackendTest, NewEvictionValidEntry) {
    559   SetNewEviction();
    560   BackendValidEntry();
    561 }
    562 
    563 // The same logic of the previous test (ValidEntry), but this time force the
    564 // entry to be invalid, simulating a crash in the middle.
    565 // We'll be leaking memory from this test.
    566 void DiskCacheBackendTest::BackendInvalidEntry() {
    567   // Use the implementation directly... we need to simulate a crash.
    568   SetDirectMode();
    569   InitCache();
    570 
    571   std::string key("Some key");
    572   disk_cache::Entry* entry;
    573   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
    574 
    575   const int kSize = 50;
    576   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
    577   memset(buffer->data(), 0, kSize);
    578   base::strlcpy(buffer->data(), "And the data to save", kSize);
    579   EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer, kSize, false));
    580   SimulateCrash();
    581 
    582   EXPECT_NE(net::OK, OpenEntry(key, &entry));
    583   EXPECT_EQ(0, cache_->GetEntryCount());
    584 }
    585 
    586 // This and the other intentionally leaky tests below are excluded from
    587 // purify and valgrind runs by naming them in the files
    588 //   net/data/purify/net_unittests.exe.gtest.txt and
    589 //   net/data/valgrind/net_unittests.gtest.txt
    590 // The scripts tools/{purify,valgrind}/chrome_tests.sh
    591 // read those files and pass the appropriate --gtest_filter to net_unittests.
    592 TEST_F(DiskCacheBackendTest, InvalidEntry) {
    593   BackendInvalidEntry();
    594 }
    595 
    596 // We'll be leaking memory from this test.
    597 TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry) {
    598   SetNewEviction();
    599   BackendInvalidEntry();
    600 }
    601 
    602 // We'll be leaking memory from this test.
    603 TEST_F(DiskCacheBackendTest, AppCacheInvalidEntry) {
    604   SetCacheType(net::APP_CACHE);
    605   BackendInvalidEntry();
    606 }
    607 
    608 // Almost the same test, but this time crash the cache after reading an entry.
    609 // We'll be leaking memory from this test.
    610 void DiskCacheBackendTest::BackendInvalidEntryRead() {
    611   // Use the implementation directly... we need to simulate a crash.
    612   SetDirectMode();
    613   InitCache();
    614 
    615   std::string key("Some key");
    616   disk_cache::Entry* entry;
    617   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
    618 
    619   const int kSize = 50;
    620   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
    621   memset(buffer->data(), 0, kSize);
    622   base::strlcpy(buffer->data(), "And the data to save", kSize);
    623   EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer, kSize, false));
    624   entry->Close();
    625   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
    626   EXPECT_EQ(kSize, ReadData(entry, 0, 0, buffer, kSize));
    627 
    628   SimulateCrash();
    629 
    630   if (type_ == net::APP_CACHE) {
    631     // Reading an entry and crashing should not make it dirty.
    632     ASSERT_EQ(net::OK, OpenEntry(key, &entry));
    633     EXPECT_EQ(1, cache_->GetEntryCount());
    634     entry->Close();
    635   } else {
    636     EXPECT_NE(net::OK, OpenEntry(key, &entry));
    637     EXPECT_EQ(0, cache_->GetEntryCount());
    638   }
    639 }
    640 
    641 // We'll be leaking memory from this test.
    642 TEST_F(DiskCacheBackendTest, InvalidEntryRead) {
    643   BackendInvalidEntryRead();
    644 }
    645 
    646 // We'll be leaking memory from this test.
    647 TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntryRead) {
    648   SetNewEviction();
    649   BackendInvalidEntryRead();
    650 }
    651 
    652 // We'll be leaking memory from this test.
    653 TEST_F(DiskCacheBackendTest, AppCacheInvalidEntryRead) {
    654   SetCacheType(net::APP_CACHE);
    655   BackendInvalidEntryRead();
    656 }
    657 
    658 // We'll be leaking memory from this test.
    659 void DiskCacheBackendTest::BackendInvalidEntryWithLoad() {
    660   // Work with a tiny index table (16 entries)
    661   SetMask(0xf);
    662   SetMaxSize(0x100000);
    663   InitCache();
    664 
    665   int seed = static_cast<int>(Time::Now().ToInternalValue());
    666   srand(seed);
    667 
    668   const int kNumEntries = 100;
    669   disk_cache::Entry* entries[kNumEntries];
    670   for (int i = 0; i < kNumEntries; i++) {
    671     std::string key = GenerateKey(true);
    672     ASSERT_EQ(net::OK, CreateEntry(key, &entries[i]));
    673   }
    674   EXPECT_EQ(kNumEntries, cache_->GetEntryCount());
    675 
    676   for (int i = 0; i < kNumEntries; i++) {
    677     int source1 = rand() % kNumEntries;
    678     int source2 = rand() % kNumEntries;
    679     disk_cache::Entry* temp = entries[source1];
    680     entries[source1] = entries[source2];
    681     entries[source2] = temp;
    682   }
    683 
    684   std::string keys[kNumEntries];
    685   for (int i = 0; i < kNumEntries; i++) {
    686     keys[i] = entries[i]->GetKey();
    687     if (i < kNumEntries / 2)
    688       entries[i]->Close();
    689   }
    690 
    691   SimulateCrash();
    692 
    693   for (int i = kNumEntries / 2; i < kNumEntries; i++) {
    694     disk_cache::Entry* entry;
    695     EXPECT_NE(net::OK, OpenEntry(keys[i], &entry));
    696   }
    697 
    698   for (int i = 0; i < kNumEntries / 2; i++) {
    699     disk_cache::Entry* entry;
    700     EXPECT_EQ(net::OK, OpenEntry(keys[i], &entry));
    701     entry->Close();
    702   }
    703 
    704   EXPECT_EQ(kNumEntries / 2, cache_->GetEntryCount());
    705 }
    706 
    707 // We'll be leaking memory from this test.
    708 TEST_F(DiskCacheBackendTest, InvalidEntryWithLoad) {
    709   BackendInvalidEntryWithLoad();
    710 }
    711 
    712 // We'll be leaking memory from this test.
    713 TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntryWithLoad) {
    714   SetNewEviction();
    715   BackendInvalidEntryWithLoad();
    716 }
    717 
    718 // We'll be leaking memory from this test.
    719 TEST_F(DiskCacheBackendTest, AppCacheInvalidEntryWithLoad) {
    720   SetCacheType(net::APP_CACHE);
    721   BackendInvalidEntryWithLoad();
    722 }
    723 
    724 // We'll be leaking memory from this test.
    725 void DiskCacheBackendTest::BackendTrimInvalidEntry() {
    726   // Use the implementation directly... we need to simulate a crash.
    727   SetDirectMode();
    728 
    729   const int kSize = 0x3000;  // 12 kB
    730   SetMaxSize(kSize * 10);
    731   InitCache();
    732 
    733   std::string first("some key");
    734   std::string second("something else");
    735   disk_cache::Entry* entry;
    736   ASSERT_EQ(net::OK, CreateEntry(first, &entry));
    737 
    738   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
    739   memset(buffer->data(), 0, kSize);
    740   EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer, kSize, false));
    741 
    742   // Simulate a crash.
    743   SimulateCrash();
    744 
    745   ASSERT_EQ(net::OK, CreateEntry(second, &entry));
    746   EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer, kSize, false));
    747 
    748   EXPECT_EQ(2, cache_->GetEntryCount());
    749   SetMaxSize(kSize);
    750   entry->Close();  // Trim the cache.
    751   FlushQueueForTest();
    752 
    753   // If we evicted the entry in less than 20mS, we have one entry in the cache;
    754   // if it took more than that, we posted a task and we'll delete the second
    755   // entry too.
    756   MessageLoop::current()->RunAllPending();
    757 
    758   // This may be not thread-safe in general, but for now it's OK so add some
    759   // ThreadSanitizer annotations to ignore data races on cache_.
    760   // See http://crbug.com/55970
    761   ANNOTATE_IGNORE_READS_BEGIN();
    762   EXPECT_GE(1, cache_->GetEntryCount());
    763   ANNOTATE_IGNORE_READS_END();
    764 
    765   EXPECT_NE(net::OK, OpenEntry(first, &entry));
    766 }
    767 
    768 // We'll be leaking memory from this test.
    769 TEST_F(DiskCacheBackendTest, TrimInvalidEntry) {
    770   BackendTrimInvalidEntry();
    771 }
    772 
    773 // We'll be leaking memory from this test.
    774 TEST_F(DiskCacheBackendTest, NewEvictionTrimInvalidEntry) {
    775   SetNewEviction();
    776   BackendTrimInvalidEntry();
    777 }
    778 
    779 // We'll be leaking memory from this test.
    780 void DiskCacheBackendTest::BackendTrimInvalidEntry2() {
    781   // Use the implementation directly... we need to simulate a crash.
    782   SetDirectMode();
    783   SetMask(0xf);  // 16-entry table.
    784 
    785   const int kSize = 0x3000;  // 12 kB
    786   SetMaxSize(kSize * 40);
    787   InitCache();
    788 
    789   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
    790   memset(buffer->data(), 0, kSize);
    791   disk_cache::Entry* entry;
    792 
    793   // Writing 32 entries to this cache chains most of them.
    794   for (int i = 0; i < 32; i++) {
    795     std::string key(base::StringPrintf("some key %d", i));
    796     ASSERT_EQ(net::OK, CreateEntry(key, &entry));
    797     EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer, kSize, false));
    798     entry->Close();
    799     ASSERT_EQ(net::OK, OpenEntry(key, &entry));
    800     // Note that we are not closing the entries.
    801   }
    802 
    803   // Simulate a crash.
    804   SimulateCrash();
    805 
    806   ASSERT_EQ(net::OK, CreateEntry("Something else", &entry));
    807   EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer, kSize, false));
    808 
    809   EXPECT_EQ(33, cache_->GetEntryCount());
    810   SetMaxSize(kSize);
    811 
    812   // For the new eviction code, all corrupt entries are on the second list so
    813   // they are not going away that easy.
    814   if (new_eviction_) {
    815     EXPECT_EQ(net::OK, DoomAllEntries());
    816   }
    817 
    818   entry->Close();  // Trim the cache.
    819   FlushQueueForTest();
    820 
    821   // We may abort the eviction before cleaning up everything.
    822   MessageLoop::current()->RunAllPending();
    823   EXPECT_GE(30, cache_->GetEntryCount());
    824 }
    825 
    826 // We'll be leaking memory from this test.
    827 TEST_F(DiskCacheBackendTest, TrimInvalidEntry2) {
    828   BackendTrimInvalidEntry2();
    829 }
    830 
    831 // We'll be leaking memory from this test.
    832 TEST_F(DiskCacheBackendTest, NewEvictionTrimInvalidEntry2) {
    833   SetNewEviction();
    834   BackendTrimInvalidEntry2();
    835 }
    836 
    837 void DiskCacheBackendTest::BackendEnumerations() {
    838   InitCache();
    839   Time initial = Time::Now();
    840   int seed = static_cast<int>(initial.ToInternalValue());
    841   srand(seed);
    842 
    843   const int kNumEntries = 100;
    844   for (int i = 0; i < kNumEntries; i++) {
    845     std::string key = GenerateKey(true);
    846     disk_cache::Entry* entry;
    847     ASSERT_EQ(net::OK, CreateEntry(key, &entry));
    848     entry->Close();
    849   }
    850   EXPECT_EQ(kNumEntries, cache_->GetEntryCount());
    851   Time final = Time::Now();
    852 
    853   disk_cache::Entry* entry;
    854   void* iter = NULL;
    855   int count = 0;
    856   Time last_modified[kNumEntries];
    857   Time last_used[kNumEntries];
    858   while (OpenNextEntry(&iter, &entry) == net::OK) {
    859     ASSERT_TRUE(NULL != entry);
    860     if (count < kNumEntries) {
    861       last_modified[count] = entry->GetLastModified();
    862       last_used[count] = entry->GetLastUsed();
    863       EXPECT_TRUE(initial <= last_modified[count]);
    864       EXPECT_TRUE(final >= last_modified[count]);
    865     }
    866 
    867     entry->Close();
    868     count++;
    869   };
    870   EXPECT_EQ(kNumEntries, count);
    871 
    872   iter = NULL;
    873   count = 0;
    874   // The previous enumeration should not have changed the timestamps.
    875   while (OpenNextEntry(&iter, &entry) == net::OK) {
    876     ASSERT_TRUE(NULL != entry);
    877     if (count < kNumEntries) {
    878       EXPECT_TRUE(last_modified[count] == entry->GetLastModified());
    879       EXPECT_TRUE(last_used[count] == entry->GetLastUsed());
    880     }
    881     entry->Close();
    882     count++;
    883   };
    884   EXPECT_EQ(kNumEntries, count);
    885 }
    886 
    887 TEST_F(DiskCacheBackendTest, Enumerations) {
    888   BackendEnumerations();
    889 }
    890 
    891 TEST_F(DiskCacheBackendTest, NewEvictionEnumerations) {
    892   SetNewEviction();
    893   BackendEnumerations();
    894 }
    895 
    896 TEST_F(DiskCacheBackendTest, MemoryOnlyEnumerations) {
    897   SetMemoryOnlyMode();
    898   BackendEnumerations();
    899 }
    900 
    901 // Flaky, http://crbug.com/74387.
    902 TEST_F(DiskCacheBackendTest, FLAKY_AppCacheEnumerations) {
    903   SetCacheType(net::APP_CACHE);
    904   BackendEnumerations();
    905 }
    906 
    907 // Verifies enumerations while entries are open.
    908 void DiskCacheBackendTest::BackendEnumerations2() {
    909   InitCache();
    910   const std::string first("first");
    911   const std::string second("second");
    912   disk_cache::Entry *entry1, *entry2;
    913   ASSERT_EQ(net::OK, CreateEntry(first, &entry1));
    914   entry1->Close();
    915   ASSERT_EQ(net::OK, CreateEntry(second, &entry2));
    916   entry2->Close();
    917 
    918   // Make sure that the timestamp is not the same.
    919   base::PlatformThread::Sleep(20);
    920   ASSERT_EQ(net::OK, OpenEntry(second, &entry1));
    921   void* iter = NULL;
    922   ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry2));
    923   EXPECT_EQ(entry2->GetKey(), second);
    924 
    925   // Two entries and the iterator pointing at "first".
    926   entry1->Close();
    927   entry2->Close();
    928 
    929   // The iterator should still be valid, so we should not crash.
    930   ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry2));
    931   EXPECT_EQ(entry2->GetKey(), first);
    932   entry2->Close();
    933   cache_->EndEnumeration(&iter);
    934 
    935   // Modify the oldest entry and get the newest element.
    936   ASSERT_EQ(net::OK, OpenEntry(first, &entry1));
    937   EXPECT_EQ(0, WriteData(entry1, 0, 200, NULL, 0, false));
    938   ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry2));
    939   if (type_ == net::APP_CACHE) {
    940     // The list is not updated.
    941     EXPECT_EQ(entry2->GetKey(), second);
    942   } else {
    943     EXPECT_EQ(entry2->GetKey(), first);
    944   }
    945 
    946   entry1->Close();
    947   entry2->Close();
    948   cache_->EndEnumeration(&iter);
    949 }
    950 
    951 TEST_F(DiskCacheBackendTest, Enumerations2) {
    952   BackendEnumerations2();
    953 }
    954 
    955 TEST_F(DiskCacheBackendTest, NewEvictionEnumerations2) {
    956   SetNewEviction();
    957   BackendEnumerations2();
    958 }
    959 
    960 TEST_F(DiskCacheBackendTest, MemoryOnlyEnumerations2) {
    961   SetMemoryOnlyMode();
    962   BackendEnumerations2();
    963 }
    964 
    965 TEST_F(DiskCacheBackendTest, AppCacheEnumerations2) {
    966   SetCacheType(net::APP_CACHE);
    967   BackendEnumerations2();
    968 }
    969 
    970 // Verify handling of invalid entries while doing enumerations.
    971 // We'll be leaking memory from this test.
    972 void DiskCacheBackendTest::BackendInvalidEntryEnumeration() {
    973   // Use the implementation directly... we need to simulate a crash.
    974   SetDirectMode();
    975   InitCache();
    976 
    977   std::string key("Some key");
    978   disk_cache::Entry *entry, *entry1, *entry2;
    979   ASSERT_EQ(net::OK, CreateEntry(key, &entry1));
    980 
    981   const int kSize = 50;
    982   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
    983   memset(buffer1->data(), 0, kSize);
    984   base::strlcpy(buffer1->data(), "And the data to save", kSize);
    985   EXPECT_EQ(kSize, WriteData(entry1, 0, 0, buffer1, kSize, false));
    986   entry1->Close();
    987   ASSERT_EQ(net::OK, OpenEntry(key, &entry1));
    988   EXPECT_EQ(kSize, ReadData(entry1, 0, 0, buffer1, kSize));
    989 
    990   std::string key2("Another key");
    991   ASSERT_EQ(net::OK, CreateEntry(key2, &entry2));
    992   entry2->Close();
    993   ASSERT_EQ(2, cache_->GetEntryCount());
    994 
    995   SimulateCrash();
    996 
    997   void* iter = NULL;
    998   int count = 0;
    999   while (OpenNextEntry(&iter, &entry) == net::OK) {
   1000     ASSERT_TRUE(NULL != entry);
   1001     EXPECT_EQ(key2, entry->GetKey());
   1002     entry->Close();
   1003     count++;
   1004   };
   1005   EXPECT_EQ(1, count);
   1006   EXPECT_EQ(1, cache_->GetEntryCount());
   1007 }
   1008 
   1009 // We'll be leaking memory from this test.
   1010 TEST_F(DiskCacheBackendTest, InvalidEntryEnumeration) {
   1011   BackendInvalidEntryEnumeration();
   1012 }
   1013 
   1014 // We'll be leaking memory from this test.
   1015 TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntryEnumeration) {
   1016   SetNewEviction();
   1017   BackendInvalidEntryEnumeration();
   1018 }
   1019 
   1020 // Tests that if for some reason entries are modified close to existing cache
   1021 // iterators, we don't generate fatal errors or reset the cache.
   1022 void DiskCacheBackendTest::BackendFixEnumerators() {
   1023   InitCache();
   1024 
   1025   int seed = static_cast<int>(Time::Now().ToInternalValue());
   1026   srand(seed);
   1027 
   1028   const int kNumEntries = 10;
   1029   for (int i = 0; i < kNumEntries; i++) {
   1030     std::string key = GenerateKey(true);
   1031     disk_cache::Entry* entry;
   1032     ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   1033     entry->Close();
   1034   }
   1035   EXPECT_EQ(kNumEntries, cache_->GetEntryCount());
   1036 
   1037   disk_cache::Entry *entry1, *entry2;
   1038   void* iter1 = NULL;
   1039   void* iter2 = NULL;
   1040   ASSERT_EQ(net::OK, OpenNextEntry(&iter1, &entry1));
   1041   ASSERT_TRUE(NULL != entry1);
   1042   entry1->Close();
   1043   entry1 = NULL;
   1044 
   1045   // Let's go to the middle of the list.
   1046   for (int i = 0; i < kNumEntries / 2; i++) {
   1047     if (entry1)
   1048       entry1->Close();
   1049     ASSERT_EQ(net::OK, OpenNextEntry(&iter1, &entry1));
   1050     ASSERT_TRUE(NULL != entry1);
   1051 
   1052     ASSERT_EQ(net::OK, OpenNextEntry(&iter2, &entry2));
   1053     ASSERT_TRUE(NULL != entry2);
   1054     entry2->Close();
   1055   }
   1056 
   1057   // Messing up with entry1 will modify entry2->next.
   1058   entry1->Doom();
   1059   ASSERT_EQ(net::OK, OpenNextEntry(&iter2, &entry2));
   1060   ASSERT_TRUE(NULL != entry2);
   1061 
   1062   // The link entry2->entry1 should be broken.
   1063   EXPECT_NE(entry2->GetKey(), entry1->GetKey());
   1064   entry1->Close();
   1065   entry2->Close();
   1066 
   1067   // And the second iterator should keep working.
   1068   ASSERT_EQ(net::OK, OpenNextEntry(&iter2, &entry2));
   1069   ASSERT_TRUE(NULL != entry2);
   1070   entry2->Close();
   1071 
   1072   cache_->EndEnumeration(&iter1);
   1073   cache_->EndEnumeration(&iter2);
   1074 }
   1075 
   1076 TEST_F(DiskCacheBackendTest, FixEnumerators) {
   1077   BackendFixEnumerators();
   1078 }
   1079 
   1080 TEST_F(DiskCacheBackendTest, NewEvictionFixEnumerators) {
   1081   SetNewEviction();
   1082   BackendFixEnumerators();
   1083 }
   1084 
   1085 void DiskCacheBackendTest::BackendDoomRecent() {
   1086   InitCache();
   1087   Time initial = Time::Now();
   1088 
   1089   disk_cache::Entry *entry;
   1090   ASSERT_EQ(net::OK, CreateEntry("first", &entry));
   1091   entry->Close();
   1092   ASSERT_EQ(net::OK, CreateEntry("second", &entry));
   1093   entry->Close();
   1094 
   1095   base::PlatformThread::Sleep(20);
   1096   Time middle = Time::Now();
   1097 
   1098   ASSERT_EQ(net::OK, CreateEntry("third", &entry));
   1099   entry->Close();
   1100   ASSERT_EQ(net::OK, CreateEntry("fourth", &entry));
   1101   entry->Close();
   1102 
   1103   base::PlatformThread::Sleep(20);
   1104   Time final = Time::Now();
   1105 
   1106   ASSERT_EQ(4, cache_->GetEntryCount());
   1107   EXPECT_EQ(net::OK, DoomEntriesSince(final));
   1108   ASSERT_EQ(4, cache_->GetEntryCount());
   1109 
   1110   EXPECT_EQ(net::OK, DoomEntriesSince(middle));
   1111   ASSERT_EQ(2, cache_->GetEntryCount());
   1112 
   1113   ASSERT_EQ(net::OK, OpenEntry("second", &entry));
   1114   entry->Close();
   1115 }
   1116 
   1117 TEST_F(DiskCacheBackendTest, DoomRecent) {
   1118   BackendDoomRecent();
   1119 }
   1120 
   1121 TEST_F(DiskCacheBackendTest, NewEvictionDoomRecent) {
   1122   SetNewEviction();
   1123   BackendDoomRecent();
   1124 }
   1125 
   1126 TEST_F(DiskCacheBackendTest, MemoryOnlyDoomRecent) {
   1127   SetMemoryOnlyMode();
   1128   BackendDoomRecent();
   1129 }
   1130 
   1131 void DiskCacheBackendTest::BackendDoomBetween() {
   1132   InitCache();
   1133   Time initial = Time::Now();
   1134 
   1135   disk_cache::Entry *entry;
   1136   ASSERT_EQ(net::OK, CreateEntry("first", &entry));
   1137   entry->Close();
   1138 
   1139   base::PlatformThread::Sleep(20);
   1140   Time middle_start = Time::Now();
   1141 
   1142   ASSERT_EQ(net::OK, CreateEntry("second", &entry));
   1143   entry->Close();
   1144   ASSERT_EQ(net::OK, CreateEntry("third", &entry));
   1145   entry->Close();
   1146 
   1147   base::PlatformThread::Sleep(20);
   1148   Time middle_end = Time::Now();
   1149 
   1150   ASSERT_EQ(net::OK, CreateEntry("fourth", &entry));
   1151   entry->Close();
   1152   ASSERT_EQ(net::OK, OpenEntry("fourth", &entry));
   1153   entry->Close();
   1154 
   1155   base::PlatformThread::Sleep(20);
   1156   Time final = Time::Now();
   1157 
   1158   ASSERT_EQ(4, cache_->GetEntryCount());
   1159   EXPECT_EQ(net::OK, DoomEntriesBetween(middle_start, middle_end));
   1160   ASSERT_EQ(2, cache_->GetEntryCount());
   1161 
   1162   ASSERT_EQ(net::OK, OpenEntry("fourth", &entry));
   1163   entry->Close();
   1164 
   1165   EXPECT_EQ(net::OK, DoomEntriesBetween(middle_start, final));
   1166   ASSERT_EQ(1, cache_->GetEntryCount());
   1167 
   1168   ASSERT_EQ(net::OK, OpenEntry("first", &entry));
   1169   entry->Close();
   1170 }
   1171 
   1172 TEST_F(DiskCacheBackendTest, DoomBetween) {
   1173   BackendDoomBetween();
   1174 }
   1175 
   1176 TEST_F(DiskCacheBackendTest, NewEvictionDoomBetween) {
   1177   SetNewEviction();
   1178   BackendDoomBetween();
   1179 }
   1180 
   1181 TEST_F(DiskCacheBackendTest, MemoryOnlyDoomBetween) {
   1182   SetMemoryOnlyMode();
   1183   BackendDoomBetween();
   1184 }
   1185 
   1186 void DiskCacheBackendTest::BackendTransaction(const std::string& name,
   1187                                               int num_entries, bool load) {
   1188   success_ = false;
   1189   ASSERT_TRUE(CopyTestCache(name));
   1190   DisableFirstCleanup();
   1191 
   1192   if (load) {
   1193     SetMask(0xf);
   1194     SetMaxSize(0x100000);
   1195   } else {
   1196     // Clear the settings from the previous run.
   1197     SetMask(0);
   1198     SetMaxSize(0);
   1199   }
   1200 
   1201   InitCache();
   1202   ASSERT_EQ(num_entries + 1, cache_->GetEntryCount());
   1203 
   1204   std::string key("the first key");
   1205   disk_cache::Entry* entry1;
   1206   ASSERT_NE(net::OK, OpenEntry(key, &entry1));
   1207 
   1208   int actual = cache_->GetEntryCount();
   1209   if (num_entries != actual) {
   1210     ASSERT_TRUE(load);
   1211     // If there is a heavy load, inserting an entry will make another entry
   1212     // dirty (on the hash bucket) so two entries are removed.
   1213     ASSERT_EQ(num_entries - 1, actual);
   1214   }
   1215 
   1216   delete cache_;
   1217   cache_ = NULL;
   1218   cache_impl_ = NULL;
   1219 
   1220   ASSERT_TRUE(CheckCacheIntegrity(GetCacheFilePath(), new_eviction_));
   1221   success_ = true;
   1222 }
   1223 
   1224 void DiskCacheBackendTest::BackendRecoverInsert() {
   1225   // Tests with an empty cache.
   1226   BackendTransaction("insert_empty1", 0, false);
   1227   ASSERT_TRUE(success_) << "insert_empty1";
   1228   BackendTransaction("insert_empty2", 0, false);
   1229   ASSERT_TRUE(success_) << "insert_empty2";
   1230   BackendTransaction("insert_empty3", 0, false);
   1231   ASSERT_TRUE(success_) << "insert_empty3";
   1232 
   1233   // Tests with one entry on the cache.
   1234   BackendTransaction("insert_one1", 1, false);
   1235   ASSERT_TRUE(success_) << "insert_one1";
   1236   BackendTransaction("insert_one2", 1, false);
   1237   ASSERT_TRUE(success_) << "insert_one2";
   1238   BackendTransaction("insert_one3", 1, false);
   1239   ASSERT_TRUE(success_) << "insert_one3";
   1240 
   1241   // Tests with one hundred entries on the cache, tiny index.
   1242   BackendTransaction("insert_load1", 100, true);
   1243   ASSERT_TRUE(success_) << "insert_load1";
   1244   BackendTransaction("insert_load2", 100, true);
   1245   ASSERT_TRUE(success_) << "insert_load2";
   1246 }
   1247 
   1248 TEST_F(DiskCacheBackendTest, RecoverInsert) {
   1249   BackendRecoverInsert();
   1250 }
   1251 
   1252 TEST_F(DiskCacheBackendTest, NewEvictionRecoverInsert) {
   1253   SetNewEviction();
   1254   BackendRecoverInsert();
   1255 }
   1256 
   1257 void DiskCacheBackendTest::BackendRecoverRemove() {
   1258   // Removing the only element.
   1259   BackendTransaction("remove_one1", 0, false);
   1260   ASSERT_TRUE(success_) << "remove_one1";
   1261   BackendTransaction("remove_one2", 0, false);
   1262   ASSERT_TRUE(success_) << "remove_one2";
   1263   BackendTransaction("remove_one3", 0, false);
   1264   ASSERT_TRUE(success_) << "remove_one3";
   1265 
   1266   // Removing the head.
   1267   BackendTransaction("remove_head1", 1, false);
   1268   ASSERT_TRUE(success_) << "remove_head1";
   1269   BackendTransaction("remove_head2", 1, false);
   1270   ASSERT_TRUE(success_) << "remove_head2";
   1271   BackendTransaction("remove_head3", 1, false);
   1272   ASSERT_TRUE(success_) << "remove_head3";
   1273 
   1274   // Removing the tail.
   1275   BackendTransaction("remove_tail1", 1, false);
   1276   ASSERT_TRUE(success_) << "remove_tail1";
   1277   BackendTransaction("remove_tail2", 1, false);
   1278   ASSERT_TRUE(success_) << "remove_tail2";
   1279   BackendTransaction("remove_tail3", 1, false);
   1280   ASSERT_TRUE(success_) << "remove_tail3";
   1281 
   1282   // Removing with one hundred entries on the cache, tiny index.
   1283   BackendTransaction("remove_load1", 100, true);
   1284   ASSERT_TRUE(success_) << "remove_load1";
   1285   BackendTransaction("remove_load2", 100, true);
   1286   ASSERT_TRUE(success_) << "remove_load2";
   1287   BackendTransaction("remove_load3", 100, true);
   1288   ASSERT_TRUE(success_) << "remove_load3";
   1289 
   1290   // This case cannot be reverted.
   1291   BackendTransaction("remove_one4", 0, false);
   1292   ASSERT_TRUE(success_) << "remove_one4";
   1293   BackendTransaction("remove_head4", 1, false);
   1294   ASSERT_TRUE(success_) << "remove_head4";
   1295 }
   1296 
   1297 TEST_F(DiskCacheBackendTest, RecoverRemove) {
   1298   BackendRecoverRemove();
   1299 }
   1300 
   1301 TEST_F(DiskCacheBackendTest, NewEvictionRecoverRemove) {
   1302   SetNewEviction();
   1303   BackendRecoverRemove();
   1304 }
   1305 
   1306 void DiskCacheBackendTest::BackendRecoverWithEviction() {
   1307   success_ = false;
   1308   ASSERT_TRUE(CopyTestCache("insert_load1"));
   1309   DisableFirstCleanup();
   1310 
   1311   SetMask(0xf);
   1312   SetMaxSize(0x1000);
   1313 
   1314   // We should not crash here.
   1315   InitCache();
   1316   DisableIntegrityCheck();
   1317 }
   1318 
   1319 TEST_F(DiskCacheBackendTest, RecoverWithEviction) {
   1320   BackendRecoverWithEviction();
   1321 }
   1322 
   1323 TEST_F(DiskCacheBackendTest, NewEvictionRecoverWithEviction) {
   1324   SetNewEviction();
   1325   BackendRecoverWithEviction();
   1326 }
   1327 
   1328 // Tests dealing with cache files that cannot be recovered.
   1329 TEST_F(DiskCacheTest, DeleteOld) {
   1330   ASSERT_TRUE(CopyTestCache("wrong_version"));
   1331   FilePath path = GetCacheFilePath();
   1332   base::Thread cache_thread("CacheThread");
   1333   ASSERT_TRUE(cache_thread.StartWithOptions(
   1334                   base::Thread::Options(MessageLoop::TYPE_IO, 0)));
   1335   TestCompletionCallback cb;
   1336 
   1337   disk_cache::Backend* cache;
   1338   int rv = disk_cache::BackendImpl::CreateBackend(
   1339                path, true, 0, net::DISK_CACHE, disk_cache::kNoRandom,
   1340                cache_thread.message_loop_proxy(), NULL, &cache, &cb);
   1341   ASSERT_EQ(net::OK, cb.GetResult(rv));
   1342 
   1343   MessageLoopHelper helper;
   1344 
   1345   ASSERT_TRUE(NULL != cache);
   1346   ASSERT_EQ(0, cache->GetEntryCount());
   1347 
   1348   delete cache;
   1349 }
   1350 
   1351 // We want to be able to deal with messed up entries on disk.
   1352 void DiskCacheBackendTest::BackendInvalidEntry2() {
   1353   ASSERT_TRUE(CopyTestCache("bad_entry"));
   1354   DisableFirstCleanup();
   1355   InitCache();
   1356 
   1357   disk_cache::Entry *entry1, *entry2;
   1358   ASSERT_EQ(net::OK, OpenEntry("the first key", &entry1));
   1359   EXPECT_NE(net::OK, OpenEntry("some other key", &entry2));
   1360   entry1->Close();
   1361 
   1362   // CheckCacheIntegrity will fail at this point.
   1363   DisableIntegrityCheck();
   1364 }
   1365 
   1366 TEST_F(DiskCacheBackendTest, InvalidEntry2) {
   1367   BackendInvalidEntry2();
   1368 }
   1369 
   1370 TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry2) {
   1371   SetNewEviction();
   1372   BackendInvalidEntry2();
   1373 }
   1374 
   1375 // Tests that we don't crash or hang when enumerating this cache.
   1376 void DiskCacheBackendTest::BackendInvalidEntry3() {
   1377   SetMask(0x1);  // 2-entry table.
   1378   SetMaxSize(0x3000);  // 12 kB.
   1379   DisableFirstCleanup();
   1380   InitCache();
   1381 
   1382   disk_cache::Entry* entry;
   1383   void* iter = NULL;
   1384   while (OpenNextEntry(&iter, &entry) == net::OK) {
   1385     entry->Close();
   1386   }
   1387 }
   1388 
   1389 TEST_F(DiskCacheBackendTest, InvalidEntry3) {
   1390   ASSERT_TRUE(CopyTestCache("dirty_entry3"));
   1391   BackendInvalidEntry3();
   1392 }
   1393 
   1394 TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry3) {
   1395   ASSERT_TRUE(CopyTestCache("dirty_entry4"));
   1396   SetNewEviction();
   1397   BackendInvalidEntry3();
   1398   DisableIntegrityCheck();
   1399 }
   1400 
   1401 // Test that we handle a dirty entry on the LRU list, already replaced with
   1402 // the same key, and with hash collisions.
   1403 TEST_F(DiskCacheBackendTest, InvalidEntry4) {
   1404   ASSERT_TRUE(CopyTestCache("dirty_entry3"));
   1405   SetMask(0x1);  // 2-entry table.
   1406   SetMaxSize(0x3000);  // 12 kB.
   1407   DisableFirstCleanup();
   1408   InitCache();
   1409 
   1410   TrimForTest(false);
   1411 }
   1412 
   1413 // Test that we handle a dirty entry on the deleted list, already replaced with
   1414 // the same key, and with hash collisions.
   1415 TEST_F(DiskCacheBackendTest, InvalidEntry5) {
   1416   ASSERT_TRUE(CopyTestCache("dirty_entry4"));
   1417   SetNewEviction();
   1418   SetMask(0x1);  // 2-entry table.
   1419   SetMaxSize(0x3000);  // 12 kB.
   1420   DisableFirstCleanup();
   1421   InitCache();
   1422 
   1423   TrimDeletedListForTest(false);
   1424 }
   1425 
   1426 TEST_F(DiskCacheBackendTest, InvalidEntry6) {
   1427   ASSERT_TRUE(CopyTestCache("dirty_entry5"));
   1428   SetMask(0x1);  // 2-entry table.
   1429   SetMaxSize(0x3000);  // 12 kB.
   1430   DisableFirstCleanup();
   1431   InitCache();
   1432 
   1433   // There is a dirty entry (but marked as clean) at the end, pointing to a
   1434   // deleted entry through the hash collision list. We should not re-insert the
   1435   // deleted entry into the index table.
   1436 
   1437   TrimForTest(false);
   1438   // The cache should be clean (as detected by CheckCacheIntegrity).
   1439 }
   1440 
   1441 // Tests that we don't hang when there is a loop on the hash collision list.
   1442 // The test cache could be a result of bug 69135.
   1443 TEST_F(DiskCacheBackendTest, BadNextEntry1) {
   1444   ASSERT_TRUE(CopyTestCache("list_loop2"));
   1445   SetMask(0x1);  // 2-entry table.
   1446   SetMaxSize(0x3000);  // 12 kB.
   1447   DisableFirstCleanup();
   1448   InitCache();
   1449 
   1450   // The second entry points at itselft, and the first entry is not accessible
   1451   // though the index, but it is at the head of the LRU.
   1452 
   1453   disk_cache::Entry* entry;
   1454   ASSERT_EQ(net::OK, CreateEntry("The first key", &entry));
   1455   entry->Close();
   1456 
   1457   TrimForTest(false);
   1458   TrimForTest(false);
   1459   ASSERT_EQ(net::OK, OpenEntry("The first key", &entry));
   1460   entry->Close();
   1461   EXPECT_EQ(1, cache_->GetEntryCount());
   1462 }
   1463 
   1464 // Tests that we don't hang when there is a loop on the hash collision list.
   1465 // The test cache could be a result of bug 69135.
   1466 TEST_F(DiskCacheBackendTest, BadNextEntry2) {
   1467   ASSERT_TRUE(CopyTestCache("list_loop3"));
   1468   SetMask(0x1);  // 2-entry table.
   1469   SetMaxSize(0x3000);  // 12 kB.
   1470   DisableFirstCleanup();
   1471   InitCache();
   1472 
   1473   // There is a wide loop of 5 entries.
   1474 
   1475   disk_cache::Entry* entry;
   1476   ASSERT_NE(net::OK, OpenEntry("Not present key", &entry));
   1477 }
   1478 
   1479 TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry6) {
   1480   ASSERT_TRUE(CopyTestCache("bad_rankings3"));
   1481   DisableFirstCleanup();
   1482   SetNewEviction();
   1483   InitCache();
   1484 
   1485   // The second entry is dirty, but removing it should not corrupt the list.
   1486   disk_cache::Entry* entry;
   1487   ASSERT_NE(net::OK, OpenEntry("the second key", &entry));
   1488   ASSERT_EQ(net::OK, OpenEntry("the first key", &entry));
   1489 
   1490   // This should not delete the cache.
   1491   entry->Doom();
   1492   FlushQueueForTest();
   1493   entry->Close();
   1494 
   1495   ASSERT_EQ(net::OK, OpenEntry("some other key", &entry));
   1496   entry->Close();
   1497 }
   1498 
   1499 // We want to be able to deal with abnormal dirty entries.
   1500 void DiskCacheBackendTest::BackendNotMarkedButDirty(const std::string& name) {
   1501   ASSERT_TRUE(CopyTestCache(name));
   1502   DisableFirstCleanup();
   1503   InitCache();
   1504 
   1505   disk_cache::Entry *entry1, *entry2;
   1506   ASSERT_EQ(net::OK, OpenEntry("the first key", &entry1));
   1507   EXPECT_NE(net::OK, OpenEntry("some other key", &entry2));
   1508   entry1->Close();
   1509 }
   1510 
   1511 TEST_F(DiskCacheBackendTest, NotMarkedButDirty) {
   1512   BackendNotMarkedButDirty("dirty_entry");
   1513 }
   1514 
   1515 TEST_F(DiskCacheBackendTest, NewEvictionNotMarkedButDirty) {
   1516   SetNewEviction();
   1517   BackendNotMarkedButDirty("dirty_entry");
   1518 }
   1519 
   1520 TEST_F(DiskCacheBackendTest, NotMarkedButDirty2) {
   1521   BackendNotMarkedButDirty("dirty_entry2");
   1522 }
   1523 
   1524 TEST_F(DiskCacheBackendTest, NewEvictionNotMarkedButDirty2) {
   1525   SetNewEviction();
   1526   BackendNotMarkedButDirty("dirty_entry2");
   1527 }
   1528 
   1529 // We want to be able to deal with messed up entries on disk.
   1530 void DiskCacheBackendTest::BackendInvalidRankings2() {
   1531   ASSERT_TRUE(CopyTestCache("bad_rankings"));
   1532   FilePath path = GetCacheFilePath();
   1533   DisableFirstCleanup();
   1534   InitCache();
   1535 
   1536   disk_cache::Entry *entry1, *entry2;
   1537   EXPECT_NE(net::OK, OpenEntry("the first key", &entry1));
   1538   ASSERT_EQ(net::OK, OpenEntry("some other key", &entry2));
   1539   entry2->Close();
   1540 
   1541   // CheckCacheIntegrity will fail at this point.
   1542   DisableIntegrityCheck();
   1543 }
   1544 
   1545 TEST_F(DiskCacheBackendTest, InvalidRankings2) {
   1546   BackendInvalidRankings2();
   1547 }
   1548 
   1549 TEST_F(DiskCacheBackendTest, NewEvictionInvalidRankings2) {
   1550   SetNewEviction();
   1551   BackendInvalidRankings2();
   1552 }
   1553 
   1554 // If the LRU is corrupt, we delete the cache.
   1555 void DiskCacheBackendTest::BackendInvalidRankings() {
   1556   disk_cache::Entry* entry;
   1557   void* iter = NULL;
   1558   ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry));
   1559   entry->Close();
   1560   EXPECT_EQ(2, cache_->GetEntryCount());
   1561 
   1562   EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry));
   1563   FlushQueueForTest();  // Allow the restart to finish.
   1564   EXPECT_EQ(0, cache_->GetEntryCount());
   1565 }
   1566 
   1567 TEST_F(DiskCacheBackendTest, InvalidRankingsSuccess) {
   1568   ASSERT_TRUE(CopyTestCache("bad_rankings"));
   1569   DisableFirstCleanup();
   1570   SetDirectMode();
   1571   InitCache();
   1572   BackendInvalidRankings();
   1573 }
   1574 
   1575 TEST_F(DiskCacheBackendTest, NewEvictionInvalidRankingsSuccess) {
   1576   ASSERT_TRUE(CopyTestCache("bad_rankings"));
   1577   DisableFirstCleanup();
   1578   SetDirectMode();
   1579   SetNewEviction();
   1580   InitCache();
   1581   BackendInvalidRankings();
   1582 }
   1583 
   1584 TEST_F(DiskCacheBackendTest, InvalidRankingsFailure) {
   1585   ASSERT_TRUE(CopyTestCache("bad_rankings"));
   1586   DisableFirstCleanup();
   1587   SetDirectMode();
   1588   InitCache();
   1589   SetTestMode();  // Fail cache reinitialization.
   1590   BackendInvalidRankings();
   1591 }
   1592 
   1593 TEST_F(DiskCacheBackendTest, NewEvictionInvalidRankingsFailure) {
   1594   ASSERT_TRUE(CopyTestCache("bad_rankings"));
   1595   DisableFirstCleanup();
   1596   SetDirectMode();
   1597   SetNewEviction();
   1598   InitCache();
   1599   SetTestMode();  // Fail cache reinitialization.
   1600   BackendInvalidRankings();
   1601 }
   1602 
   1603 // If the LRU is corrupt and we have open entries, we disable the cache.
   1604 void DiskCacheBackendTest::BackendDisable() {
   1605   disk_cache::Entry *entry1, *entry2;
   1606   void* iter = NULL;
   1607   ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry1));
   1608 
   1609   EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry2));
   1610   EXPECT_EQ(0, cache_->GetEntryCount());
   1611   EXPECT_NE(net::OK, CreateEntry("Something new", &entry2));
   1612 
   1613   entry1->Close();
   1614   FlushQueueForTest();  // Flushing the Close posts a task to restart the cache.
   1615   FlushQueueForTest();  // This one actually allows that task to complete.
   1616 
   1617   EXPECT_EQ(0, cache_->GetEntryCount());
   1618 }
   1619 
   1620 TEST_F(DiskCacheBackendTest, DisableSuccess) {
   1621   ASSERT_TRUE(CopyTestCache("bad_rankings"));
   1622   DisableFirstCleanup();
   1623   SetDirectMode();
   1624   InitCache();
   1625   BackendDisable();
   1626 }
   1627 
   1628 TEST_F(DiskCacheBackendTest, NewEvictionDisableSuccess) {
   1629   ASSERT_TRUE(CopyTestCache("bad_rankings"));
   1630   DisableFirstCleanup();
   1631   SetDirectMode();
   1632   SetNewEviction();
   1633   InitCache();
   1634   BackendDisable();
   1635 }
   1636 
   1637 TEST_F(DiskCacheBackendTest, DisableFailure) {
   1638   ASSERT_TRUE(CopyTestCache("bad_rankings"));
   1639   DisableFirstCleanup();
   1640   SetDirectMode();
   1641   InitCache();
   1642   SetTestMode();  // Fail cache reinitialization.
   1643   BackendDisable();
   1644 }
   1645 
   1646 TEST_F(DiskCacheBackendTest, NewEvictionDisableFailure) {
   1647   ASSERT_TRUE(CopyTestCache("bad_rankings"));
   1648   DisableFirstCleanup();
   1649   SetDirectMode();
   1650   SetNewEviction();
   1651   InitCache();
   1652   SetTestMode();  // Fail cache reinitialization.
   1653   BackendDisable();
   1654 }
   1655 
   1656 // This is another type of corruption on the LRU; disable the cache.
   1657 void DiskCacheBackendTest::BackendDisable2() {
   1658   EXPECT_EQ(8, cache_->GetEntryCount());
   1659 
   1660   disk_cache::Entry* entry;
   1661   void* iter = NULL;
   1662   int count = 0;
   1663   while (OpenNextEntry(&iter, &entry) == net::OK) {
   1664     ASSERT_TRUE(NULL != entry);
   1665     entry->Close();
   1666     count++;
   1667     ASSERT_LT(count, 9);
   1668   };
   1669 
   1670   FlushQueueForTest();
   1671   EXPECT_EQ(0, cache_->GetEntryCount());
   1672 }
   1673 
   1674 TEST_F(DiskCacheBackendTest, DisableSuccess2) {
   1675   ASSERT_TRUE(CopyTestCache("list_loop"));
   1676   DisableFirstCleanup();
   1677   SetDirectMode();
   1678   InitCache();
   1679   BackendDisable2();
   1680 }
   1681 
   1682 TEST_F(DiskCacheBackendTest, NewEvictionDisableSuccess2) {
   1683   ASSERT_TRUE(CopyTestCache("list_loop"));
   1684   DisableFirstCleanup();
   1685   SetNewEviction();
   1686   SetDirectMode();
   1687   InitCache();
   1688   BackendDisable2();
   1689 }
   1690 
   1691 TEST_F(DiskCacheBackendTest, DisableFailure2) {
   1692   ASSERT_TRUE(CopyTestCache("list_loop"));
   1693   DisableFirstCleanup();
   1694   SetDirectMode();
   1695   InitCache();
   1696   SetTestMode();  // Fail cache reinitialization.
   1697   BackendDisable2();
   1698 }
   1699 
   1700 TEST_F(DiskCacheBackendTest, NewEvictionDisableFailure2) {
   1701   ASSERT_TRUE(CopyTestCache("list_loop"));
   1702   DisableFirstCleanup();
   1703   SetDirectMode();
   1704   SetNewEviction();
   1705   InitCache();
   1706   SetTestMode();  // Fail cache reinitialization.
   1707   BackendDisable2();
   1708 }
   1709 
   1710 // If the index size changes when we disable the cache, we should not crash.
   1711 void DiskCacheBackendTest::BackendDisable3() {
   1712   disk_cache::Entry *entry1, *entry2;
   1713   void* iter = NULL;
   1714   EXPECT_EQ(2, cache_->GetEntryCount());
   1715   ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry1));
   1716   entry1->Close();
   1717 
   1718   EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry2));
   1719   FlushQueueForTest();
   1720 
   1721   ASSERT_EQ(net::OK, CreateEntry("Something new", &entry2));
   1722   entry2->Close();
   1723 
   1724   EXPECT_EQ(1, cache_->GetEntryCount());
   1725 }
   1726 
   1727 TEST_F(DiskCacheBackendTest, DisableSuccess3) {
   1728   ASSERT_TRUE(CopyTestCache("bad_rankings2"));
   1729   DisableFirstCleanup();
   1730   SetMaxSize(20 * 1024 * 1024);
   1731   InitCache();
   1732   BackendDisable3();
   1733 }
   1734 
   1735 TEST_F(DiskCacheBackendTest, NewEvictionDisableSuccess3) {
   1736   ASSERT_TRUE(CopyTestCache("bad_rankings2"));
   1737   DisableFirstCleanup();
   1738   SetMaxSize(20 * 1024 * 1024);
   1739   SetNewEviction();
   1740   InitCache();
   1741   BackendDisable3();
   1742 }
   1743 
   1744 // If we disable the cache, already open entries should work as far as possible.
   1745 void DiskCacheBackendTest::BackendDisable4() {
   1746   disk_cache::Entry *entry1, *entry2, *entry3, *entry4;
   1747   void* iter = NULL;
   1748   ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry1));
   1749 
   1750   char key2[2000];
   1751   char key3[20000];
   1752   CacheTestFillBuffer(key2, sizeof(key2), true);
   1753   CacheTestFillBuffer(key3, sizeof(key3), true);
   1754   key2[sizeof(key2) - 1] = '\0';
   1755   key3[sizeof(key3) - 1] = '\0';
   1756   ASSERT_EQ(net::OK, CreateEntry(key2, &entry2));
   1757   ASSERT_EQ(net::OK, CreateEntry(key3, &entry3));
   1758 
   1759   const int kBufSize = 20000;
   1760   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kBufSize));
   1761   memset(buf->data(), 0, kBufSize);
   1762   EXPECT_EQ(100, WriteData(entry2, 0, 0, buf, 100, false));
   1763   EXPECT_EQ(kBufSize, WriteData(entry3, 0, 0, buf, kBufSize, false));
   1764 
   1765   // This line should disable the cache but not delete it.
   1766   EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry4));
   1767   EXPECT_EQ(0, cache_->GetEntryCount());
   1768 
   1769   EXPECT_NE(net::OK, CreateEntry("cache is disabled", &entry4));
   1770 
   1771   EXPECT_EQ(100, ReadData(entry2, 0, 0, buf, 100));
   1772   EXPECT_EQ(100, WriteData(entry2, 0, 0, buf, 100, false));
   1773   EXPECT_EQ(100, WriteData(entry2, 1, 0, buf, 100, false));
   1774 
   1775   EXPECT_EQ(kBufSize, ReadData(entry3, 0, 0, buf, kBufSize));
   1776   EXPECT_EQ(kBufSize, WriteData(entry3, 0, 0, buf, kBufSize, false));
   1777   EXPECT_EQ(kBufSize, WriteData(entry3, 1, 0, buf, kBufSize, false));
   1778 
   1779   std::string key = entry2->GetKey();
   1780   EXPECT_EQ(sizeof(key2) - 1, key.size());
   1781   key = entry3->GetKey();
   1782   EXPECT_EQ(sizeof(key3) - 1, key.size());
   1783 
   1784   entry1->Close();
   1785   entry2->Close();
   1786   entry3->Close();
   1787   FlushQueueForTest();  // Flushing the Close posts a task to restart the cache.
   1788   FlushQueueForTest();  // This one actually allows that task to complete.
   1789 
   1790   EXPECT_EQ(0, cache_->GetEntryCount());
   1791 }
   1792 
   1793 TEST_F(DiskCacheBackendTest, DisableSuccess4) {
   1794   ASSERT_TRUE(CopyTestCache("bad_rankings"));
   1795   DisableFirstCleanup();
   1796   SetDirectMode();
   1797   InitCache();
   1798   BackendDisable4();
   1799 }
   1800 
   1801 TEST_F(DiskCacheBackendTest, NewEvictionDisableSuccess4) {
   1802   ASSERT_TRUE(CopyTestCache("bad_rankings"));
   1803   DisableFirstCleanup();
   1804   SetDirectMode();
   1805   SetNewEviction();
   1806   InitCache();
   1807   BackendDisable4();
   1808 }
   1809 
   1810 TEST_F(DiskCacheTest, Backend_UsageStats) {
   1811   MessageLoopHelper helper;
   1812 
   1813   FilePath path = GetCacheFilePath();
   1814   ASSERT_TRUE(DeleteCache(path));
   1815   scoped_ptr<disk_cache::BackendImpl> cache;
   1816   cache.reset(new disk_cache::BackendImpl(
   1817                   path, base::MessageLoopProxy::CreateForCurrentThread(),
   1818                   NULL));
   1819   ASSERT_TRUE(NULL != cache.get());
   1820   cache->SetUnitTestMode();
   1821   ASSERT_EQ(net::OK, cache->SyncInit());
   1822 
   1823   // Wait for a callback that never comes... about 2 secs :). The message loop
   1824   // has to run to allow invocation of the usage timer.
   1825   helper.WaitUntilCacheIoFinished(1);
   1826 }
   1827 
   1828 void DiskCacheBackendTest::BackendDoomAll() {
   1829   InitCache();
   1830   Time initial = Time::Now();
   1831 
   1832   disk_cache::Entry *entry1, *entry2;
   1833   ASSERT_EQ(net::OK, CreateEntry("first", &entry1));
   1834   ASSERT_EQ(net::OK, CreateEntry("second", &entry2));
   1835   entry1->Close();
   1836   entry2->Close();
   1837 
   1838   ASSERT_EQ(net::OK, CreateEntry("third", &entry1));
   1839   ASSERT_EQ(net::OK, CreateEntry("fourth", &entry2));
   1840 
   1841   ASSERT_EQ(4, cache_->GetEntryCount());
   1842   EXPECT_EQ(net::OK, DoomAllEntries());
   1843   ASSERT_EQ(0, cache_->GetEntryCount());
   1844 
   1845   // We should stop posting tasks at some point (if we post any).
   1846   MessageLoop::current()->RunAllPending();
   1847 
   1848   disk_cache::Entry *entry3, *entry4;
   1849   ASSERT_EQ(net::OK, CreateEntry("third", &entry3));
   1850   ASSERT_EQ(net::OK, CreateEntry("fourth", &entry4));
   1851 
   1852   EXPECT_EQ(net::OK, DoomAllEntries());
   1853   ASSERT_EQ(0, cache_->GetEntryCount());
   1854 
   1855   entry1->Close();
   1856   entry2->Close();
   1857   entry3->Doom();  // The entry should be already doomed, but this must work.
   1858   entry3->Close();
   1859   entry4->Close();
   1860 
   1861   // Now try with all references released.
   1862   ASSERT_EQ(net::OK, CreateEntry("third", &entry1));
   1863   ASSERT_EQ(net::OK, CreateEntry("fourth", &entry2));
   1864   entry1->Close();
   1865   entry2->Close();
   1866 
   1867   ASSERT_EQ(2, cache_->GetEntryCount());
   1868   EXPECT_EQ(net::OK, DoomAllEntries());
   1869   ASSERT_EQ(0, cache_->GetEntryCount());
   1870 }
   1871 
   1872 TEST_F(DiskCacheBackendTest, DoomAll) {
   1873   BackendDoomAll();
   1874 }
   1875 
   1876 TEST_F(DiskCacheBackendTest, NewEvictionDoomAll) {
   1877   SetNewEviction();
   1878   BackendDoomAll();
   1879 }
   1880 
   1881 TEST_F(DiskCacheBackendTest, MemoryOnlyDoomAll) {
   1882   SetMemoryOnlyMode();
   1883   BackendDoomAll();
   1884 }
   1885 
   1886 TEST_F(DiskCacheBackendTest, AppCacheOnlyDoomAll) {
   1887   SetCacheType(net::APP_CACHE);
   1888   BackendDoomAll();
   1889 }
   1890 
   1891 // If the index size changes when we doom the cache, we should not crash.
   1892 void DiskCacheBackendTest::BackendDoomAll2() {
   1893   EXPECT_EQ(2, cache_->GetEntryCount());
   1894   EXPECT_EQ(net::OK, DoomAllEntries());
   1895 
   1896   disk_cache::Entry* entry;
   1897   ASSERT_EQ(net::OK, CreateEntry("Something new", &entry));
   1898   entry->Close();
   1899 
   1900   EXPECT_EQ(1, cache_->GetEntryCount());
   1901 }
   1902 
   1903 TEST_F(DiskCacheBackendTest, DoomAll2) {
   1904   ASSERT_TRUE(CopyTestCache("bad_rankings2"));
   1905   DisableFirstCleanup();
   1906   SetMaxSize(20 * 1024 * 1024);
   1907   InitCache();
   1908   BackendDoomAll2();
   1909 }
   1910 
   1911 TEST_F(DiskCacheBackendTest, NewEvictionDoomAll2) {
   1912   ASSERT_TRUE(CopyTestCache("bad_rankings2"));
   1913   DisableFirstCleanup();
   1914   SetMaxSize(20 * 1024 * 1024);
   1915   SetNewEviction();
   1916   InitCache();
   1917   BackendDoomAll2();
   1918 }
   1919 
   1920 // We should be able to create the same entry on multiple simultaneous instances
   1921 // of the cache.
   1922 TEST_F(DiskCacheTest, MultipleInstances) {
   1923   ScopedTestCache store1;
   1924   ScopedTestCache store2("cache_test2");
   1925   ScopedTestCache store3("cache_test3");
   1926   base::Thread cache_thread("CacheThread");
   1927   ASSERT_TRUE(cache_thread.StartWithOptions(
   1928                   base::Thread::Options(MessageLoop::TYPE_IO, 0)));
   1929   TestCompletionCallback cb;
   1930 
   1931   const int kNumberOfCaches = 2;
   1932   disk_cache::Backend* cache[kNumberOfCaches];
   1933 
   1934   int rv = disk_cache::BackendImpl::CreateBackend(
   1935                store1.path(), false, 0, net::DISK_CACHE, disk_cache::kNone,
   1936                cache_thread.message_loop_proxy(), NULL, &cache[0], &cb);
   1937   ASSERT_EQ(net::OK, cb.GetResult(rv));
   1938   rv = disk_cache::BackendImpl::CreateBackend(
   1939            store2.path(), false, 0, net::MEDIA_CACHE, disk_cache::kNone,
   1940            cache_thread.message_loop_proxy(), NULL, &cache[1], &cb);
   1941   ASSERT_EQ(net::OK, cb.GetResult(rv));
   1942 
   1943   ASSERT_TRUE(cache[0] != NULL && cache[1] != NULL);
   1944 
   1945   std::string key("the first key");
   1946   disk_cache::Entry* entry;
   1947   for (int i = 0; i < kNumberOfCaches; i++) {
   1948     rv = cache[i]->CreateEntry(key, &entry, &cb);
   1949     ASSERT_EQ(net::OK, cb.GetResult(rv));
   1950     entry->Close();
   1951   }
   1952   delete cache[0];
   1953   delete cache[1];
   1954 }
   1955 
   1956 // Test the six regions of the curve that determines the max cache size.
   1957 TEST_F(DiskCacheTest, AutomaticMaxSize) {
   1958   const int kDefaultSize = 80 * 1024 * 1024;
   1959   int64 large_size = kDefaultSize;
   1960   int64 largest_size = kint32max;
   1961 
   1962   // Region 1: expected = available * 0.8
   1963   EXPECT_EQ((kDefaultSize - 1) * 8 / 10,
   1964             disk_cache::PreferedCacheSize(large_size - 1));
   1965   EXPECT_EQ(kDefaultSize * 8 / 10,
   1966             disk_cache::PreferedCacheSize(large_size));
   1967   EXPECT_EQ(kDefaultSize - 1,
   1968             disk_cache::PreferedCacheSize(large_size * 10 / 8 - 1));
   1969 
   1970   // Region 2: expected = default_size
   1971   EXPECT_EQ(kDefaultSize,
   1972             disk_cache::PreferedCacheSize(large_size * 10 / 8));
   1973   EXPECT_EQ(kDefaultSize,
   1974             disk_cache::PreferedCacheSize(large_size * 10 - 1));
   1975 
   1976   // Region 3: expected = available * 0.1
   1977   EXPECT_EQ(kDefaultSize,
   1978             disk_cache::PreferedCacheSize(large_size * 10));
   1979   EXPECT_EQ((kDefaultSize * 25 - 1) / 10,
   1980             disk_cache::PreferedCacheSize(large_size * 25 - 1));
   1981 
   1982   // Region 4: expected = default_size * 2.5
   1983   EXPECT_EQ(kDefaultSize * 25 / 10,
   1984             disk_cache::PreferedCacheSize(large_size * 25));
   1985   EXPECT_EQ(kDefaultSize * 25 / 10,
   1986             disk_cache::PreferedCacheSize(large_size * 100 - 1));
   1987   EXPECT_EQ(kDefaultSize * 25 / 10,
   1988             disk_cache::PreferedCacheSize(large_size * 100));
   1989   EXPECT_EQ(kDefaultSize * 25 / 10,
   1990             disk_cache::PreferedCacheSize(large_size * 250 - 1));
   1991 
   1992   // Region 5: expected = available * 0.1
   1993   EXPECT_EQ(kDefaultSize * 25 / 10,
   1994             disk_cache::PreferedCacheSize(large_size * 250));
   1995   EXPECT_EQ(kint32max - 1,
   1996             disk_cache::PreferedCacheSize(largest_size * 100 - 1));
   1997 
   1998   // Region 6: expected = kint32max
   1999   EXPECT_EQ(kint32max,
   2000             disk_cache::PreferedCacheSize(largest_size * 100));
   2001   EXPECT_EQ(kint32max,
   2002             disk_cache::PreferedCacheSize(largest_size * 10000));
   2003 }
   2004 
   2005 // Tests that we can "migrate" a running instance from one experiment group to
   2006 // another.
   2007 TEST_F(DiskCacheBackendTest, Histograms) {
   2008   SetDirectMode();
   2009   InitCache();
   2010   disk_cache::BackendImpl* backend_ = cache_impl_;  // Needed be the macro.
   2011 
   2012   for (int i = 1; i < 3; i++) {
   2013     CACHE_UMA(HOURS, "FillupTime", i, 28);
   2014   }
   2015 }
   2016 
   2017 // Make sure that we keep the total memory used by the internal buffers under
   2018 // control.
   2019 TEST_F(DiskCacheBackendTest, TotalBuffersSize1) {
   2020   SetDirectMode();
   2021   InitCache();
   2022   std::string key("the first key");
   2023   disk_cache::Entry* entry;
   2024   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   2025 
   2026   const int kSize = 200;
   2027   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
   2028   CacheTestFillBuffer(buffer->data(), kSize, true);
   2029 
   2030   for (int i = 0; i < 10; i++) {
   2031     SCOPED_TRACE(i);
   2032     // Allocate 2MB for this entry.
   2033     EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer, kSize, true));
   2034     EXPECT_EQ(kSize, WriteData(entry, 1, 0, buffer, kSize, true));
   2035     EXPECT_EQ(kSize, WriteData(entry, 0, 1024 * 1024, buffer, kSize, false));
   2036     EXPECT_EQ(kSize, WriteData(entry, 1, 1024 * 1024, buffer, kSize, false));
   2037 
   2038     // Delete one of the buffers and truncate the other.
   2039     EXPECT_EQ(0, WriteData(entry, 0, 0, buffer, 0, true));
   2040     EXPECT_EQ(0, WriteData(entry, 1, 10, buffer, 0, true));
   2041 
   2042     // Delete the second buffer, writing 10 bytes to disk.
   2043     entry->Close();
   2044     ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   2045   }
   2046 
   2047   entry->Close();
   2048   EXPECT_EQ(0, cache_impl_->GetTotalBuffersSize());
   2049 }
   2050 
   2051 // This test assumes at least 150MB of system memory.
   2052 TEST_F(DiskCacheBackendTest, TotalBuffersSize2) {
   2053   SetDirectMode();
   2054   InitCache();
   2055 
   2056   const int kOneMB = 1024 * 1024;
   2057   EXPECT_TRUE(cache_impl_->IsAllocAllowed(0, kOneMB));
   2058   EXPECT_EQ(kOneMB, cache_impl_->GetTotalBuffersSize());
   2059 
   2060   EXPECT_TRUE(cache_impl_->IsAllocAllowed(0, kOneMB));
   2061   EXPECT_EQ(kOneMB * 2, cache_impl_->GetTotalBuffersSize());
   2062 
   2063   EXPECT_TRUE(cache_impl_->IsAllocAllowed(0, kOneMB));
   2064   EXPECT_EQ(kOneMB * 3, cache_impl_->GetTotalBuffersSize());
   2065 
   2066   cache_impl_->BufferDeleted(kOneMB);
   2067   EXPECT_EQ(kOneMB * 2, cache_impl_->GetTotalBuffersSize());
   2068 
   2069   // Check the upper limit.
   2070   EXPECT_FALSE(cache_impl_->IsAllocAllowed(0, 30 * kOneMB));
   2071 
   2072   for (int i = 0; i < 30; i++)
   2073     cache_impl_->IsAllocAllowed(0, kOneMB);  // Ignore the result.
   2074 
   2075   EXPECT_FALSE(cache_impl_->IsAllocAllowed(0, kOneMB));
   2076 }
   2077 
   2078 // Tests that sharing of external files works and we are able to delete the
   2079 // files when we need to.
   2080 TEST_F(DiskCacheBackendTest, FileSharing) {
   2081   SetDirectMode();
   2082   InitCache();
   2083 
   2084   disk_cache::Addr address(0x80000001);
   2085   ASSERT_TRUE(cache_impl_->CreateExternalFile(&address));
   2086   FilePath name = cache_impl_->GetFileName(address);
   2087 
   2088   scoped_refptr<disk_cache::File> file(new disk_cache::File(false));
   2089   file->Init(name);
   2090 
   2091 #if defined(OS_WIN)
   2092   DWORD sharing = FILE_SHARE_READ | FILE_SHARE_WRITE;
   2093   DWORD access = GENERIC_READ | GENERIC_WRITE;
   2094   base::win::ScopedHandle file2(CreateFile(
   2095       name.value().c_str(), access, sharing, NULL, OPEN_EXISTING, 0, NULL));
   2096   EXPECT_FALSE(file2.IsValid());
   2097 
   2098   sharing |= FILE_SHARE_DELETE;
   2099   file2.Set(CreateFile(name.value().c_str(), access, sharing, NULL,
   2100                        OPEN_EXISTING, 0, NULL));
   2101   EXPECT_TRUE(file2.IsValid());
   2102 #endif
   2103 
   2104   EXPECT_TRUE(file_util::Delete(name, false));
   2105 
   2106   // We should be able to use the file.
   2107   const int kSize = 200;
   2108   char buffer1[kSize];
   2109   char buffer2[kSize];
   2110   memset(buffer1, 't', kSize);
   2111   memset(buffer2, 0, kSize);
   2112   EXPECT_TRUE(file->Write(buffer1, kSize, 0));
   2113   EXPECT_TRUE(file->Read(buffer2, kSize, 0));
   2114   EXPECT_EQ(0, memcmp(buffer1, buffer2, kSize));
   2115 
   2116   EXPECT_TRUE(disk_cache::DeleteCacheFile(name));
   2117 }
   2118