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/bind.h"
      7 #include "base/bind_helpers.h"
      8 #include "base/file_util.h"
      9 #include "base/files/file.h"
     10 #include "base/strings/string_util.h"
     11 #include "base/strings/stringprintf.h"
     12 #include "base/threading/platform_thread.h"
     13 #include "base/timer/timer.h"
     14 #include "net/base/completion_callback.h"
     15 #include "net/base/io_buffer.h"
     16 #include "net/base/net_errors.h"
     17 #include "net/base/test_completion_callback.h"
     18 #include "net/disk_cache/blockfile/backend_impl.h"
     19 #include "net/disk_cache/blockfile/entry_impl.h"
     20 #include "net/disk_cache/disk_cache_test_base.h"
     21 #include "net/disk_cache/disk_cache_test_util.h"
     22 #include "net/disk_cache/memory/mem_entry_impl.h"
     23 #include "net/disk_cache/simple/simple_entry_format.h"
     24 #include "net/disk_cache/simple/simple_entry_impl.h"
     25 #include "net/disk_cache/simple/simple_synchronous_entry.h"
     26 #include "net/disk_cache/simple/simple_test_util.h"
     27 #include "net/disk_cache/simple/simple_util.h"
     28 #include "testing/gtest/include/gtest/gtest.h"
     29 
     30 using base::Time;
     31 using disk_cache::ScopedEntryPtr;
     32 
     33 // Tests that can run with different types of caches.
     34 class DiskCacheEntryTest : public DiskCacheTestWithCache {
     35  public:
     36   void InternalSyncIOBackground(disk_cache::Entry* entry);
     37   void ExternalSyncIOBackground(disk_cache::Entry* entry);
     38 
     39  protected:
     40   void InternalSyncIO();
     41   void InternalAsyncIO();
     42   void ExternalSyncIO();
     43   void ExternalAsyncIO();
     44   void ReleaseBuffer(int stream_index);
     45   void StreamAccess();
     46   void GetKey();
     47   void GetTimes(int stream_index);
     48   void GrowData(int stream_index);
     49   void TruncateData(int stream_index);
     50   void ZeroLengthIO(int stream_index);
     51   void Buffering();
     52   void SizeAtCreate();
     53   void SizeChanges(int stream_index);
     54   void ReuseEntry(int size, int stream_index);
     55   void InvalidData(int stream_index);
     56   void ReadWriteDestroyBuffer(int stream_index);
     57   void DoomNormalEntry();
     58   void DoomEntryNextToOpenEntry();
     59   void DoomedEntry(int stream_index);
     60   void BasicSparseIO();
     61   void HugeSparseIO();
     62   void GetAvailableRange();
     63   void CouldBeSparse();
     64   void UpdateSparseEntry();
     65   void DoomSparseEntry();
     66   void PartialSparseEntry();
     67   bool SimpleCacheMakeBadChecksumEntry(const std::string& key, int* data_size);
     68   bool SimpleCacheThirdStreamFileExists(const char* key);
     69   void SyncDoomEntry(const char* key);
     70 };
     71 
     72 // This part of the test runs on the background thread.
     73 void DiskCacheEntryTest::InternalSyncIOBackground(disk_cache::Entry* entry) {
     74   const int kSize1 = 10;
     75   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
     76   CacheTestFillBuffer(buffer1->data(), kSize1, false);
     77   EXPECT_EQ(
     78       0,
     79       entry->ReadData(0, 0, buffer1.get(), kSize1, net::CompletionCallback()));
     80   base::strlcpy(buffer1->data(), "the data", kSize1);
     81   EXPECT_EQ(10,
     82             entry->WriteData(
     83                 0, 0, buffer1.get(), kSize1, net::CompletionCallback(), false));
     84   memset(buffer1->data(), 0, kSize1);
     85   EXPECT_EQ(
     86       10,
     87       entry->ReadData(0, 0, buffer1.get(), kSize1, net::CompletionCallback()));
     88   EXPECT_STREQ("the data", buffer1->data());
     89 
     90   const int kSize2 = 5000;
     91   const int kSize3 = 10000;
     92   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2));
     93   scoped_refptr<net::IOBuffer> buffer3(new net::IOBuffer(kSize3));
     94   memset(buffer3->data(), 0, kSize3);
     95   CacheTestFillBuffer(buffer2->data(), kSize2, false);
     96   base::strlcpy(buffer2->data(), "The really big data goes here", kSize2);
     97   EXPECT_EQ(
     98       5000,
     99       entry->WriteData(
    100           1, 1500, buffer2.get(), kSize2, net::CompletionCallback(), false));
    101   memset(buffer2->data(), 0, kSize2);
    102   EXPECT_EQ(4989,
    103             entry->ReadData(
    104                 1, 1511, buffer2.get(), kSize2, net::CompletionCallback()));
    105   EXPECT_STREQ("big data goes here", buffer2->data());
    106   EXPECT_EQ(
    107       5000,
    108       entry->ReadData(1, 0, buffer2.get(), kSize2, net::CompletionCallback()));
    109   EXPECT_EQ(0, memcmp(buffer2->data(), buffer3->data(), 1500));
    110   EXPECT_EQ(1500,
    111             entry->ReadData(
    112                 1, 5000, buffer2.get(), kSize2, net::CompletionCallback()));
    113 
    114   EXPECT_EQ(0,
    115             entry->ReadData(
    116                 1, 6500, buffer2.get(), kSize2, net::CompletionCallback()));
    117   EXPECT_EQ(
    118       6500,
    119       entry->ReadData(1, 0, buffer3.get(), kSize3, net::CompletionCallback()));
    120   EXPECT_EQ(8192,
    121             entry->WriteData(
    122                 1, 0, buffer3.get(), 8192, net::CompletionCallback(), false));
    123   EXPECT_EQ(
    124       8192,
    125       entry->ReadData(1, 0, buffer3.get(), kSize3, net::CompletionCallback()));
    126   EXPECT_EQ(8192, entry->GetDataSize(1));
    127 
    128   // We need to delete the memory buffer on this thread.
    129   EXPECT_EQ(0, entry->WriteData(
    130       0, 0, NULL, 0, net::CompletionCallback(), true));
    131   EXPECT_EQ(0, entry->WriteData(
    132       1, 0, NULL, 0, net::CompletionCallback(), true));
    133 }
    134 
    135 // We need to support synchronous IO even though it is not a supported operation
    136 // from the point of view of the disk cache's public interface, because we use
    137 // it internally, not just by a few tests, but as part of the implementation
    138 // (see sparse_control.cc, for example).
    139 void DiskCacheEntryTest::InternalSyncIO() {
    140   disk_cache::Entry* entry = NULL;
    141   ASSERT_EQ(net::OK, CreateEntry("the first key", &entry));
    142   ASSERT_TRUE(NULL != entry);
    143 
    144   // The bulk of the test runs from within the callback, on the cache thread.
    145   RunTaskForTest(base::Bind(&DiskCacheEntryTest::InternalSyncIOBackground,
    146                             base::Unretained(this),
    147                             entry));
    148 
    149 
    150   entry->Doom();
    151   entry->Close();
    152   FlushQueueForTest();
    153   EXPECT_EQ(0, cache_->GetEntryCount());
    154 }
    155 
    156 TEST_F(DiskCacheEntryTest, InternalSyncIO) {
    157   InitCache();
    158   InternalSyncIO();
    159 }
    160 
    161 TEST_F(DiskCacheEntryTest, MemoryOnlyInternalSyncIO) {
    162   SetMemoryOnlyMode();
    163   InitCache();
    164   InternalSyncIO();
    165 }
    166 
    167 void DiskCacheEntryTest::InternalAsyncIO() {
    168   disk_cache::Entry* entry = NULL;
    169   ASSERT_EQ(net::OK, CreateEntry("the first key", &entry));
    170   ASSERT_TRUE(NULL != entry);
    171 
    172   // Avoid using internal buffers for the test. We have to write something to
    173   // the entry and close it so that we flush the internal buffer to disk. After
    174   // that, IO operations will be really hitting the disk. We don't care about
    175   // the content, so just extending the entry is enough (all extensions zero-
    176   // fill any holes).
    177   EXPECT_EQ(0, WriteData(entry, 0, 15 * 1024, NULL, 0, false));
    178   EXPECT_EQ(0, WriteData(entry, 1, 15 * 1024, NULL, 0, false));
    179   entry->Close();
    180   ASSERT_EQ(net::OK, OpenEntry("the first key", &entry));
    181 
    182   MessageLoopHelper helper;
    183   // Let's verify that each IO goes to the right callback object.
    184   CallbackTest callback1(&helper, false);
    185   CallbackTest callback2(&helper, false);
    186   CallbackTest callback3(&helper, false);
    187   CallbackTest callback4(&helper, false);
    188   CallbackTest callback5(&helper, false);
    189   CallbackTest callback6(&helper, false);
    190   CallbackTest callback7(&helper, false);
    191   CallbackTest callback8(&helper, false);
    192   CallbackTest callback9(&helper, false);
    193   CallbackTest callback10(&helper, false);
    194   CallbackTest callback11(&helper, false);
    195   CallbackTest callback12(&helper, false);
    196   CallbackTest callback13(&helper, false);
    197 
    198   const int kSize1 = 10;
    199   const int kSize2 = 5000;
    200   const int kSize3 = 10000;
    201   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
    202   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2));
    203   scoped_refptr<net::IOBuffer> buffer3(new net::IOBuffer(kSize3));
    204   CacheTestFillBuffer(buffer1->data(), kSize1, false);
    205   CacheTestFillBuffer(buffer2->data(), kSize2, false);
    206   CacheTestFillBuffer(buffer3->data(), kSize3, false);
    207 
    208   EXPECT_EQ(0,
    209             entry->ReadData(
    210                 0,
    211                 15 * 1024,
    212                 buffer1.get(),
    213                 kSize1,
    214                 base::Bind(&CallbackTest::Run, base::Unretained(&callback1))));
    215   base::strlcpy(buffer1->data(), "the data", kSize1);
    216   int expected = 0;
    217   int ret = entry->WriteData(
    218       0,
    219       0,
    220       buffer1.get(),
    221       kSize1,
    222       base::Bind(&CallbackTest::Run, base::Unretained(&callback2)),
    223       false);
    224   EXPECT_TRUE(10 == ret || net::ERR_IO_PENDING == ret);
    225   if (net::ERR_IO_PENDING == ret)
    226     expected++;
    227 
    228   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    229   memset(buffer2->data(), 0, kSize2);
    230   ret = entry->ReadData(
    231       0,
    232       0,
    233       buffer2.get(),
    234       kSize1,
    235       base::Bind(&CallbackTest::Run, base::Unretained(&callback3)));
    236   EXPECT_TRUE(10 == ret || net::ERR_IO_PENDING == ret);
    237   if (net::ERR_IO_PENDING == ret)
    238     expected++;
    239 
    240   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    241   EXPECT_STREQ("the data", buffer2->data());
    242 
    243   base::strlcpy(buffer2->data(), "The really big data goes here", kSize2);
    244   ret = entry->WriteData(
    245       1,
    246       1500,
    247       buffer2.get(),
    248       kSize2,
    249       base::Bind(&CallbackTest::Run, base::Unretained(&callback4)),
    250       true);
    251   EXPECT_TRUE(5000 == ret || net::ERR_IO_PENDING == ret);
    252   if (net::ERR_IO_PENDING == ret)
    253     expected++;
    254 
    255   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    256   memset(buffer3->data(), 0, kSize3);
    257   ret = entry->ReadData(
    258       1,
    259       1511,
    260       buffer3.get(),
    261       kSize2,
    262       base::Bind(&CallbackTest::Run, base::Unretained(&callback5)));
    263   EXPECT_TRUE(4989 == ret || net::ERR_IO_PENDING == ret);
    264   if (net::ERR_IO_PENDING == ret)
    265     expected++;
    266 
    267   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    268   EXPECT_STREQ("big data goes here", buffer3->data());
    269   ret = entry->ReadData(
    270       1,
    271       0,
    272       buffer2.get(),
    273       kSize2,
    274       base::Bind(&CallbackTest::Run, base::Unretained(&callback6)));
    275   EXPECT_TRUE(5000 == ret || net::ERR_IO_PENDING == ret);
    276   if (net::ERR_IO_PENDING == ret)
    277     expected++;
    278 
    279   memset(buffer3->data(), 0, kSize3);
    280 
    281   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    282   EXPECT_EQ(0, memcmp(buffer2->data(), buffer3->data(), 1500));
    283   ret = entry->ReadData(
    284       1,
    285       5000,
    286       buffer2.get(),
    287       kSize2,
    288       base::Bind(&CallbackTest::Run, base::Unretained(&callback7)));
    289   EXPECT_TRUE(1500 == ret || net::ERR_IO_PENDING == ret);
    290   if (net::ERR_IO_PENDING == ret)
    291     expected++;
    292 
    293   ret = entry->ReadData(
    294       1,
    295       0,
    296       buffer3.get(),
    297       kSize3,
    298       base::Bind(&CallbackTest::Run, base::Unretained(&callback9)));
    299   EXPECT_TRUE(6500 == ret || net::ERR_IO_PENDING == ret);
    300   if (net::ERR_IO_PENDING == ret)
    301     expected++;
    302 
    303   ret = entry->WriteData(
    304       1,
    305       0,
    306       buffer3.get(),
    307       8192,
    308       base::Bind(&CallbackTest::Run, base::Unretained(&callback10)),
    309       true);
    310   EXPECT_TRUE(8192 == ret || net::ERR_IO_PENDING == ret);
    311   if (net::ERR_IO_PENDING == ret)
    312     expected++;
    313 
    314   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    315   ret = entry->ReadData(
    316       1,
    317       0,
    318       buffer3.get(),
    319       kSize3,
    320       base::Bind(&CallbackTest::Run, base::Unretained(&callback11)));
    321   EXPECT_TRUE(8192 == ret || net::ERR_IO_PENDING == ret);
    322   if (net::ERR_IO_PENDING == ret)
    323     expected++;
    324 
    325   EXPECT_EQ(8192, entry->GetDataSize(1));
    326 
    327   ret = entry->ReadData(
    328       0,
    329       0,
    330       buffer1.get(),
    331       kSize1,
    332       base::Bind(&CallbackTest::Run, base::Unretained(&callback12)));
    333   EXPECT_TRUE(10 == ret || net::ERR_IO_PENDING == ret);
    334   if (net::ERR_IO_PENDING == ret)
    335     expected++;
    336 
    337   ret = entry->ReadData(
    338       1,
    339       0,
    340       buffer2.get(),
    341       kSize2,
    342       base::Bind(&CallbackTest::Run, base::Unretained(&callback13)));
    343   EXPECT_TRUE(5000 == ret || net::ERR_IO_PENDING == ret);
    344   if (net::ERR_IO_PENDING == ret)
    345     expected++;
    346 
    347   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    348 
    349   EXPECT_FALSE(helper.callback_reused_error());
    350 
    351   entry->Doom();
    352   entry->Close();
    353   FlushQueueForTest();
    354   EXPECT_EQ(0, cache_->GetEntryCount());
    355 }
    356 
    357 TEST_F(DiskCacheEntryTest, InternalAsyncIO) {
    358   InitCache();
    359   InternalAsyncIO();
    360 }
    361 
    362 TEST_F(DiskCacheEntryTest, MemoryOnlyInternalAsyncIO) {
    363   SetMemoryOnlyMode();
    364   InitCache();
    365   InternalAsyncIO();
    366 }
    367 
    368 // This part of the test runs on the background thread.
    369 void DiskCacheEntryTest::ExternalSyncIOBackground(disk_cache::Entry* entry) {
    370   const int kSize1 = 17000;
    371   const int kSize2 = 25000;
    372   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
    373   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2));
    374   CacheTestFillBuffer(buffer1->data(), kSize1, false);
    375   CacheTestFillBuffer(buffer2->data(), kSize2, false);
    376   base::strlcpy(buffer1->data(), "the data", kSize1);
    377   EXPECT_EQ(17000,
    378             entry->WriteData(
    379                 0, 0, buffer1.get(), kSize1, net::CompletionCallback(), false));
    380   memset(buffer1->data(), 0, kSize1);
    381   EXPECT_EQ(
    382       17000,
    383       entry->ReadData(0, 0, buffer1.get(), kSize1, net::CompletionCallback()));
    384   EXPECT_STREQ("the data", buffer1->data());
    385 
    386   base::strlcpy(buffer2->data(), "The really big data goes here", kSize2);
    387   EXPECT_EQ(
    388       25000,
    389       entry->WriteData(
    390           1, 10000, buffer2.get(), kSize2, net::CompletionCallback(), false));
    391   memset(buffer2->data(), 0, kSize2);
    392   EXPECT_EQ(24989,
    393             entry->ReadData(
    394                 1, 10011, buffer2.get(), kSize2, net::CompletionCallback()));
    395   EXPECT_STREQ("big data goes here", buffer2->data());
    396   EXPECT_EQ(
    397       25000,
    398       entry->ReadData(1, 0, buffer2.get(), kSize2, net::CompletionCallback()));
    399   EXPECT_EQ(5000,
    400             entry->ReadData(
    401                 1, 30000, buffer2.get(), kSize2, net::CompletionCallback()));
    402 
    403   EXPECT_EQ(0,
    404             entry->ReadData(
    405                 1, 35000, buffer2.get(), kSize2, net::CompletionCallback()));
    406   EXPECT_EQ(
    407       17000,
    408       entry->ReadData(1, 0, buffer1.get(), kSize1, net::CompletionCallback()));
    409   EXPECT_EQ(
    410       17000,
    411       entry->WriteData(
    412           1, 20000, buffer1.get(), kSize1, net::CompletionCallback(), false));
    413   EXPECT_EQ(37000, entry->GetDataSize(1));
    414 
    415   // We need to delete the memory buffer on this thread.
    416   EXPECT_EQ(0, entry->WriteData(
    417       0, 0, NULL, 0, net::CompletionCallback(), true));
    418   EXPECT_EQ(0, entry->WriteData(
    419       1, 0, NULL, 0, net::CompletionCallback(), true));
    420 }
    421 
    422 void DiskCacheEntryTest::ExternalSyncIO() {
    423   disk_cache::Entry* entry;
    424   ASSERT_EQ(net::OK, CreateEntry("the first key", &entry));
    425 
    426   // The bulk of the test runs from within the callback, on the cache thread.
    427   RunTaskForTest(base::Bind(&DiskCacheEntryTest::ExternalSyncIOBackground,
    428                             base::Unretained(this),
    429                             entry));
    430 
    431   entry->Doom();
    432   entry->Close();
    433   FlushQueueForTest();
    434   EXPECT_EQ(0, cache_->GetEntryCount());
    435 }
    436 
    437 TEST_F(DiskCacheEntryTest, ExternalSyncIO) {
    438   InitCache();
    439   ExternalSyncIO();
    440 }
    441 
    442 TEST_F(DiskCacheEntryTest, ExternalSyncIONoBuffer) {
    443   InitCache();
    444   cache_impl_->SetFlags(disk_cache::kNoBuffering);
    445   ExternalSyncIO();
    446 }
    447 
    448 TEST_F(DiskCacheEntryTest, MemoryOnlyExternalSyncIO) {
    449   SetMemoryOnlyMode();
    450   InitCache();
    451   ExternalSyncIO();
    452 }
    453 
    454 void DiskCacheEntryTest::ExternalAsyncIO() {
    455   disk_cache::Entry* entry;
    456   ASSERT_EQ(net::OK, CreateEntry("the first key", &entry));
    457 
    458   int expected = 0;
    459 
    460   MessageLoopHelper helper;
    461   // Let's verify that each IO goes to the right callback object.
    462   CallbackTest callback1(&helper, false);
    463   CallbackTest callback2(&helper, false);
    464   CallbackTest callback3(&helper, false);
    465   CallbackTest callback4(&helper, false);
    466   CallbackTest callback5(&helper, false);
    467   CallbackTest callback6(&helper, false);
    468   CallbackTest callback7(&helper, false);
    469   CallbackTest callback8(&helper, false);
    470   CallbackTest callback9(&helper, false);
    471 
    472   const int kSize1 = 17000;
    473   const int kSize2 = 25000;
    474   const int kSize3 = 25000;
    475   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
    476   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2));
    477   scoped_refptr<net::IOBuffer> buffer3(new net::IOBuffer(kSize3));
    478   CacheTestFillBuffer(buffer1->data(), kSize1, false);
    479   CacheTestFillBuffer(buffer2->data(), kSize2, false);
    480   CacheTestFillBuffer(buffer3->data(), kSize3, false);
    481   base::strlcpy(buffer1->data(), "the data", kSize1);
    482   int ret = entry->WriteData(
    483       0,
    484       0,
    485       buffer1.get(),
    486       kSize1,
    487       base::Bind(&CallbackTest::Run, base::Unretained(&callback1)),
    488       false);
    489   EXPECT_TRUE(17000 == ret || net::ERR_IO_PENDING == ret);
    490   if (net::ERR_IO_PENDING == ret)
    491     expected++;
    492 
    493   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    494 
    495   memset(buffer2->data(), 0, kSize1);
    496   ret = entry->ReadData(
    497       0,
    498       0,
    499       buffer2.get(),
    500       kSize1,
    501       base::Bind(&CallbackTest::Run, base::Unretained(&callback2)));
    502   EXPECT_TRUE(17000 == ret || net::ERR_IO_PENDING == ret);
    503   if (net::ERR_IO_PENDING == ret)
    504     expected++;
    505 
    506   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    507   EXPECT_STREQ("the data", buffer2->data());
    508 
    509   base::strlcpy(buffer2->data(), "The really big data goes here", kSize2);
    510   ret = entry->WriteData(
    511       1,
    512       10000,
    513       buffer2.get(),
    514       kSize2,
    515       base::Bind(&CallbackTest::Run, base::Unretained(&callback3)),
    516       false);
    517   EXPECT_TRUE(25000 == ret || net::ERR_IO_PENDING == ret);
    518   if (net::ERR_IO_PENDING == ret)
    519     expected++;
    520 
    521   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    522 
    523   memset(buffer3->data(), 0, kSize3);
    524   ret = entry->ReadData(
    525       1,
    526       10011,
    527       buffer3.get(),
    528       kSize3,
    529       base::Bind(&CallbackTest::Run, base::Unretained(&callback4)));
    530   EXPECT_TRUE(24989 == ret || net::ERR_IO_PENDING == ret);
    531   if (net::ERR_IO_PENDING == ret)
    532     expected++;
    533 
    534   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    535   EXPECT_STREQ("big data goes here", buffer3->data());
    536   ret = entry->ReadData(
    537       1,
    538       0,
    539       buffer2.get(),
    540       kSize2,
    541       base::Bind(&CallbackTest::Run, base::Unretained(&callback5)));
    542   EXPECT_TRUE(25000 == ret || net::ERR_IO_PENDING == ret);
    543   if (net::ERR_IO_PENDING == ret)
    544     expected++;
    545 
    546   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    547   memset(buffer3->data(), 0, kSize3);
    548   EXPECT_EQ(0, memcmp(buffer2->data(), buffer3->data(), 10000));
    549   ret = entry->ReadData(
    550       1,
    551       30000,
    552       buffer2.get(),
    553       kSize2,
    554       base::Bind(&CallbackTest::Run, base::Unretained(&callback6)));
    555   EXPECT_TRUE(5000 == ret || net::ERR_IO_PENDING == ret);
    556   if (net::ERR_IO_PENDING == ret)
    557     expected++;
    558 
    559   EXPECT_EQ(0,
    560             entry->ReadData(
    561                 1,
    562                 35000,
    563                 buffer2.get(),
    564                 kSize2,
    565                 base::Bind(&CallbackTest::Run, base::Unretained(&callback7))));
    566   ret = entry->ReadData(
    567       1,
    568       0,
    569       buffer1.get(),
    570       kSize1,
    571       base::Bind(&CallbackTest::Run, base::Unretained(&callback8)));
    572   EXPECT_TRUE(17000 == ret || net::ERR_IO_PENDING == ret);
    573   if (net::ERR_IO_PENDING == ret)
    574     expected++;
    575   ret = entry->WriteData(
    576       1,
    577       20000,
    578       buffer3.get(),
    579       kSize1,
    580       base::Bind(&CallbackTest::Run, base::Unretained(&callback9)),
    581       false);
    582   EXPECT_TRUE(17000 == ret || net::ERR_IO_PENDING == ret);
    583   if (net::ERR_IO_PENDING == ret)
    584     expected++;
    585 
    586   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    587   EXPECT_EQ(37000, entry->GetDataSize(1));
    588 
    589   EXPECT_FALSE(helper.callback_reused_error());
    590 
    591   entry->Doom();
    592   entry->Close();
    593   FlushQueueForTest();
    594   EXPECT_EQ(0, cache_->GetEntryCount());
    595 }
    596 
    597 TEST_F(DiskCacheEntryTest, ExternalAsyncIO) {
    598   InitCache();
    599   ExternalAsyncIO();
    600 }
    601 
    602 TEST_F(DiskCacheEntryTest, ExternalAsyncIONoBuffer) {
    603   InitCache();
    604   cache_impl_->SetFlags(disk_cache::kNoBuffering);
    605   ExternalAsyncIO();
    606 }
    607 
    608 TEST_F(DiskCacheEntryTest, MemoryOnlyExternalAsyncIO) {
    609   SetMemoryOnlyMode();
    610   InitCache();
    611   ExternalAsyncIO();
    612 }
    613 
    614 // Tests that IOBuffers are not referenced after IO completes.
    615 void DiskCacheEntryTest::ReleaseBuffer(int stream_index) {
    616   disk_cache::Entry* entry = NULL;
    617   ASSERT_EQ(net::OK, CreateEntry("the first key", &entry));
    618   ASSERT_TRUE(NULL != entry);
    619 
    620   const int kBufferSize = 1024;
    621   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
    622   CacheTestFillBuffer(buffer->data(), kBufferSize, false);
    623 
    624   net::ReleaseBufferCompletionCallback cb(buffer.get());
    625   int rv = entry->WriteData(
    626       stream_index, 0, buffer.get(), kBufferSize, cb.callback(), false);
    627   EXPECT_EQ(kBufferSize, cb.GetResult(rv));
    628   entry->Close();
    629 }
    630 
    631 TEST_F(DiskCacheEntryTest, ReleaseBuffer) {
    632   InitCache();
    633   cache_impl_->SetFlags(disk_cache::kNoBuffering);
    634   ReleaseBuffer(0);
    635 }
    636 
    637 TEST_F(DiskCacheEntryTest, MemoryOnlyReleaseBuffer) {
    638   SetMemoryOnlyMode();
    639   InitCache();
    640   ReleaseBuffer(0);
    641 }
    642 
    643 void DiskCacheEntryTest::StreamAccess() {
    644   disk_cache::Entry* entry = NULL;
    645   ASSERT_EQ(net::OK, CreateEntry("the first key", &entry));
    646   ASSERT_TRUE(NULL != entry);
    647 
    648   const int kBufferSize = 1024;
    649   const int kNumStreams = 3;
    650   scoped_refptr<net::IOBuffer> reference_buffers[kNumStreams];
    651   for (int i = 0; i < kNumStreams; i++) {
    652     reference_buffers[i] = new net::IOBuffer(kBufferSize);
    653     CacheTestFillBuffer(reference_buffers[i]->data(), kBufferSize, false);
    654   }
    655   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kBufferSize));
    656   for (int i = 0; i < kNumStreams; i++) {
    657     EXPECT_EQ(
    658         kBufferSize,
    659         WriteData(entry, i, 0, reference_buffers[i].get(), kBufferSize, false));
    660     memset(buffer1->data(), 0, kBufferSize);
    661     EXPECT_EQ(kBufferSize, ReadData(entry, i, 0, buffer1.get(), kBufferSize));
    662     EXPECT_EQ(
    663         0, memcmp(reference_buffers[i]->data(), buffer1->data(), kBufferSize));
    664   }
    665   EXPECT_EQ(net::ERR_INVALID_ARGUMENT,
    666             ReadData(entry, kNumStreams, 0, buffer1.get(), kBufferSize));
    667   entry->Close();
    668 
    669   // Open the entry and read it in chunks, including a read past the end.
    670   ASSERT_EQ(net::OK, OpenEntry("the first key", &entry));
    671   ASSERT_TRUE(NULL != entry);
    672   const int kReadBufferSize = 600;
    673   const int kFinalReadSize = kBufferSize - kReadBufferSize;
    674   COMPILE_ASSERT(kFinalReadSize < kReadBufferSize, should_be_exactly_two_reads);
    675   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kReadBufferSize));
    676   for (int i = 0; i < kNumStreams; i++) {
    677     memset(buffer2->data(), 0, kReadBufferSize);
    678     EXPECT_EQ(kReadBufferSize,
    679               ReadData(entry, i, 0, buffer2.get(), kReadBufferSize));
    680     EXPECT_EQ(
    681         0,
    682         memcmp(reference_buffers[i]->data(), buffer2->data(), kReadBufferSize));
    683 
    684     memset(buffer2->data(), 0, kReadBufferSize);
    685     EXPECT_EQ(
    686         kFinalReadSize,
    687         ReadData(entry, i, kReadBufferSize, buffer2.get(), kReadBufferSize));
    688     EXPECT_EQ(0,
    689               memcmp(reference_buffers[i]->data() + kReadBufferSize,
    690                      buffer2->data(),
    691                      kFinalReadSize));
    692   }
    693 
    694   entry->Close();
    695 }
    696 
    697 TEST_F(DiskCacheEntryTest, StreamAccess) {
    698   InitCache();
    699   StreamAccess();
    700 }
    701 
    702 TEST_F(DiskCacheEntryTest, MemoryOnlyStreamAccess) {
    703   SetMemoryOnlyMode();
    704   InitCache();
    705   StreamAccess();
    706 }
    707 
    708 void DiskCacheEntryTest::GetKey() {
    709   std::string key("the first key");
    710   disk_cache::Entry* entry;
    711   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
    712   EXPECT_EQ(key, entry->GetKey()) << "short key";
    713   entry->Close();
    714 
    715   int seed = static_cast<int>(Time::Now().ToInternalValue());
    716   srand(seed);
    717   char key_buffer[20000];
    718 
    719   CacheTestFillBuffer(key_buffer, 3000, true);
    720   key_buffer[1000] = '\0';
    721 
    722   key = key_buffer;
    723   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
    724   EXPECT_TRUE(key == entry->GetKey()) << "1000 bytes key";
    725   entry->Close();
    726 
    727   key_buffer[1000] = 'p';
    728   key_buffer[3000] = '\0';
    729   key = key_buffer;
    730   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
    731   EXPECT_TRUE(key == entry->GetKey()) << "medium size key";
    732   entry->Close();
    733 
    734   CacheTestFillBuffer(key_buffer, sizeof(key_buffer), true);
    735   key_buffer[19999] = '\0';
    736 
    737   key = key_buffer;
    738   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
    739   EXPECT_TRUE(key == entry->GetKey()) << "long key";
    740   entry->Close();
    741 
    742   CacheTestFillBuffer(key_buffer, 0x4000, true);
    743   key_buffer[0x4000] = '\0';
    744 
    745   key = key_buffer;
    746   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
    747   EXPECT_TRUE(key == entry->GetKey()) << "16KB key";
    748   entry->Close();
    749 }
    750 
    751 TEST_F(DiskCacheEntryTest, GetKey) {
    752   InitCache();
    753   GetKey();
    754 }
    755 
    756 TEST_F(DiskCacheEntryTest, MemoryOnlyGetKey) {
    757   SetMemoryOnlyMode();
    758   InitCache();
    759   GetKey();
    760 }
    761 
    762 void DiskCacheEntryTest::GetTimes(int stream_index) {
    763   std::string key("the first key");
    764   disk_cache::Entry* entry;
    765 
    766   Time t1 = Time::Now();
    767   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
    768   EXPECT_TRUE(entry->GetLastModified() >= t1);
    769   EXPECT_TRUE(entry->GetLastModified() == entry->GetLastUsed());
    770 
    771   AddDelay();
    772   Time t2 = Time::Now();
    773   EXPECT_TRUE(t2 > t1);
    774   EXPECT_EQ(0, WriteData(entry, stream_index, 200, NULL, 0, false));
    775   if (type_ == net::APP_CACHE) {
    776     EXPECT_TRUE(entry->GetLastModified() < t2);
    777   } else {
    778     EXPECT_TRUE(entry->GetLastModified() >= t2);
    779   }
    780   EXPECT_TRUE(entry->GetLastModified() == entry->GetLastUsed());
    781 
    782   AddDelay();
    783   Time t3 = Time::Now();
    784   EXPECT_TRUE(t3 > t2);
    785   const int kSize = 200;
    786   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
    787   EXPECT_EQ(kSize, ReadData(entry, stream_index, 0, buffer.get(), kSize));
    788   if (type_ == net::APP_CACHE) {
    789     EXPECT_TRUE(entry->GetLastUsed() < t2);
    790     EXPECT_TRUE(entry->GetLastModified() < t2);
    791   } else if (type_ == net::SHADER_CACHE) {
    792     EXPECT_TRUE(entry->GetLastUsed() < t3);
    793     EXPECT_TRUE(entry->GetLastModified() < t3);
    794   } else {
    795     EXPECT_TRUE(entry->GetLastUsed() >= t3);
    796     EXPECT_TRUE(entry->GetLastModified() < t3);
    797   }
    798   entry->Close();
    799 }
    800 
    801 TEST_F(DiskCacheEntryTest, GetTimes) {
    802   InitCache();
    803   GetTimes(0);
    804 }
    805 
    806 TEST_F(DiskCacheEntryTest, MemoryOnlyGetTimes) {
    807   SetMemoryOnlyMode();
    808   InitCache();
    809   GetTimes(0);
    810 }
    811 
    812 TEST_F(DiskCacheEntryTest, AppCacheGetTimes) {
    813   SetCacheType(net::APP_CACHE);
    814   InitCache();
    815   GetTimes(0);
    816 }
    817 
    818 TEST_F(DiskCacheEntryTest, ShaderCacheGetTimes) {
    819   SetCacheType(net::SHADER_CACHE);
    820   InitCache();
    821   GetTimes(0);
    822 }
    823 
    824 void DiskCacheEntryTest::GrowData(int stream_index) {
    825   std::string key1("the first key");
    826   disk_cache::Entry* entry;
    827   ASSERT_EQ(net::OK, CreateEntry(key1, &entry));
    828 
    829   const int kSize = 20000;
    830   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
    831   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize));
    832   CacheTestFillBuffer(buffer1->data(), kSize, false);
    833   memset(buffer2->data(), 0, kSize);
    834 
    835   base::strlcpy(buffer1->data(), "the data", kSize);
    836   EXPECT_EQ(10, WriteData(entry, stream_index, 0, buffer1.get(), 10, false));
    837   EXPECT_EQ(10, ReadData(entry, stream_index, 0, buffer2.get(), 10));
    838   EXPECT_STREQ("the data", buffer2->data());
    839   EXPECT_EQ(10, entry->GetDataSize(stream_index));
    840 
    841   EXPECT_EQ(2000,
    842             WriteData(entry, stream_index, 0, buffer1.get(), 2000, false));
    843   EXPECT_EQ(2000, entry->GetDataSize(stream_index));
    844   EXPECT_EQ(2000, ReadData(entry, stream_index, 0, buffer2.get(), 2000));
    845   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 2000));
    846 
    847   EXPECT_EQ(20000,
    848             WriteData(entry, stream_index, 0, buffer1.get(), kSize, false));
    849   EXPECT_EQ(20000, entry->GetDataSize(stream_index));
    850   EXPECT_EQ(20000, ReadData(entry, stream_index, 0, buffer2.get(), kSize));
    851   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), kSize));
    852   entry->Close();
    853 
    854   memset(buffer2->data(), 0, kSize);
    855   std::string key2("Second key");
    856   ASSERT_EQ(net::OK, CreateEntry(key2, &entry));
    857   EXPECT_EQ(10, WriteData(entry, stream_index, 0, buffer1.get(), 10, false));
    858   EXPECT_EQ(10, entry->GetDataSize(stream_index));
    859   entry->Close();
    860 
    861   // Go from an internal address to a bigger block size.
    862   ASSERT_EQ(net::OK, OpenEntry(key2, &entry));
    863   EXPECT_EQ(2000,
    864             WriteData(entry, stream_index, 0, buffer1.get(), 2000, false));
    865   EXPECT_EQ(2000, entry->GetDataSize(stream_index));
    866   EXPECT_EQ(2000, ReadData(entry, stream_index, 0, buffer2.get(), 2000));
    867   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 2000));
    868   entry->Close();
    869   memset(buffer2->data(), 0, kSize);
    870 
    871   // Go from an internal address to an external one.
    872   ASSERT_EQ(net::OK, OpenEntry(key2, &entry));
    873   EXPECT_EQ(20000,
    874             WriteData(entry, stream_index, 0, buffer1.get(), kSize, false));
    875   EXPECT_EQ(20000, entry->GetDataSize(stream_index));
    876   EXPECT_EQ(20000, ReadData(entry, stream_index, 0, buffer2.get(), kSize));
    877   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), kSize));
    878   entry->Close();
    879 
    880   // Double check the size from disk.
    881   ASSERT_EQ(net::OK, OpenEntry(key2, &entry));
    882   EXPECT_EQ(20000, entry->GetDataSize(stream_index));
    883 
    884   // Now extend the entry without actual data.
    885   EXPECT_EQ(0, WriteData(entry, stream_index, 45500, buffer1.get(), 0, false));
    886   entry->Close();
    887 
    888   // And check again from disk.
    889   ASSERT_EQ(net::OK, OpenEntry(key2, &entry));
    890   EXPECT_EQ(45500, entry->GetDataSize(stream_index));
    891   entry->Close();
    892 }
    893 
    894 TEST_F(DiskCacheEntryTest, GrowData) {
    895   InitCache();
    896   GrowData(0);
    897 }
    898 
    899 TEST_F(DiskCacheEntryTest, GrowDataNoBuffer) {
    900   InitCache();
    901   cache_impl_->SetFlags(disk_cache::kNoBuffering);
    902   GrowData(0);
    903 }
    904 
    905 TEST_F(DiskCacheEntryTest, MemoryOnlyGrowData) {
    906   SetMemoryOnlyMode();
    907   InitCache();
    908   GrowData(0);
    909 }
    910 
    911 void DiskCacheEntryTest::TruncateData(int stream_index) {
    912   std::string key("the first key");
    913   disk_cache::Entry* entry;
    914   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
    915 
    916   const int kSize1 = 20000;
    917   const int kSize2 = 20000;
    918   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
    919   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2));
    920 
    921   CacheTestFillBuffer(buffer1->data(), kSize1, false);
    922   memset(buffer2->data(), 0, kSize2);
    923 
    924   // Simple truncation:
    925   EXPECT_EQ(200, WriteData(entry, stream_index, 0, buffer1.get(), 200, false));
    926   EXPECT_EQ(200, entry->GetDataSize(stream_index));
    927   EXPECT_EQ(100, WriteData(entry, stream_index, 0, buffer1.get(), 100, false));
    928   EXPECT_EQ(200, entry->GetDataSize(stream_index));
    929   EXPECT_EQ(100, WriteData(entry, stream_index, 0, buffer1.get(), 100, true));
    930   EXPECT_EQ(100, entry->GetDataSize(stream_index));
    931   EXPECT_EQ(0, WriteData(entry, stream_index, 50, buffer1.get(), 0, true));
    932   EXPECT_EQ(50, entry->GetDataSize(stream_index));
    933   EXPECT_EQ(0, WriteData(entry, stream_index, 0, buffer1.get(), 0, true));
    934   EXPECT_EQ(0, entry->GetDataSize(stream_index));
    935   entry->Close();
    936   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
    937 
    938   // Go to an external file.
    939   EXPECT_EQ(20000,
    940             WriteData(entry, stream_index, 0, buffer1.get(), 20000, true));
    941   EXPECT_EQ(20000, entry->GetDataSize(stream_index));
    942   EXPECT_EQ(20000, ReadData(entry, stream_index, 0, buffer2.get(), 20000));
    943   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 20000));
    944   memset(buffer2->data(), 0, kSize2);
    945 
    946   // External file truncation
    947   EXPECT_EQ(18000,
    948             WriteData(entry, stream_index, 0, buffer1.get(), 18000, false));
    949   EXPECT_EQ(20000, entry->GetDataSize(stream_index));
    950   EXPECT_EQ(18000,
    951             WriteData(entry, stream_index, 0, buffer1.get(), 18000, true));
    952   EXPECT_EQ(18000, entry->GetDataSize(stream_index));
    953   EXPECT_EQ(0, WriteData(entry, stream_index, 17500, buffer1.get(), 0, true));
    954   EXPECT_EQ(17500, entry->GetDataSize(stream_index));
    955 
    956   // And back to an internal block.
    957   EXPECT_EQ(600,
    958             WriteData(entry, stream_index, 1000, buffer1.get(), 600, true));
    959   EXPECT_EQ(1600, entry->GetDataSize(stream_index));
    960   EXPECT_EQ(600, ReadData(entry, stream_index, 1000, buffer2.get(), 600));
    961   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 600));
    962   EXPECT_EQ(1000, ReadData(entry, stream_index, 0, buffer2.get(), 1000));
    963   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 1000))
    964       << "Preserves previous data";
    965 
    966   // Go from external file to zero length.
    967   EXPECT_EQ(20000,
    968             WriteData(entry, stream_index, 0, buffer1.get(), 20000, true));
    969   EXPECT_EQ(20000, entry->GetDataSize(stream_index));
    970   EXPECT_EQ(0, WriteData(entry, stream_index, 0, buffer1.get(), 0, true));
    971   EXPECT_EQ(0, entry->GetDataSize(stream_index));
    972 
    973   entry->Close();
    974 }
    975 
    976 TEST_F(DiskCacheEntryTest, TruncateData) {
    977   InitCache();
    978   TruncateData(0);
    979 }
    980 
    981 TEST_F(DiskCacheEntryTest, TruncateDataNoBuffer) {
    982   InitCache();
    983   cache_impl_->SetFlags(disk_cache::kNoBuffering);
    984   TruncateData(0);
    985 }
    986 
    987 TEST_F(DiskCacheEntryTest, MemoryOnlyTruncateData) {
    988   SetMemoryOnlyMode();
    989   InitCache();
    990   TruncateData(0);
    991 }
    992 
    993 void DiskCacheEntryTest::ZeroLengthIO(int stream_index) {
    994   std::string key("the first key");
    995   disk_cache::Entry* entry;
    996   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
    997 
    998   EXPECT_EQ(0, ReadData(entry, stream_index, 0, NULL, 0));
    999   EXPECT_EQ(0, WriteData(entry, stream_index, 0, NULL, 0, false));
   1000 
   1001   // This write should extend the entry.
   1002   EXPECT_EQ(0, WriteData(entry, stream_index, 1000, NULL, 0, false));
   1003   EXPECT_EQ(0, ReadData(entry, stream_index, 500, NULL, 0));
   1004   EXPECT_EQ(0, ReadData(entry, stream_index, 2000, NULL, 0));
   1005   EXPECT_EQ(1000, entry->GetDataSize(stream_index));
   1006 
   1007   EXPECT_EQ(0, WriteData(entry, stream_index, 100000, NULL, 0, true));
   1008   EXPECT_EQ(0, ReadData(entry, stream_index, 50000, NULL, 0));
   1009   EXPECT_EQ(100000, entry->GetDataSize(stream_index));
   1010 
   1011   // Let's verify the actual content.
   1012   const int kSize = 20;
   1013   const char zeros[kSize] = {};
   1014   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
   1015 
   1016   CacheTestFillBuffer(buffer->data(), kSize, false);
   1017   EXPECT_EQ(kSize, ReadData(entry, stream_index, 500, buffer.get(), kSize));
   1018   EXPECT_TRUE(!memcmp(buffer->data(), zeros, kSize));
   1019 
   1020   CacheTestFillBuffer(buffer->data(), kSize, false);
   1021   EXPECT_EQ(kSize, ReadData(entry, stream_index, 5000, buffer.get(), kSize));
   1022   EXPECT_TRUE(!memcmp(buffer->data(), zeros, kSize));
   1023 
   1024   CacheTestFillBuffer(buffer->data(), kSize, false);
   1025   EXPECT_EQ(kSize, ReadData(entry, stream_index, 50000, buffer.get(), kSize));
   1026   EXPECT_TRUE(!memcmp(buffer->data(), zeros, kSize));
   1027 
   1028   entry->Close();
   1029 }
   1030 
   1031 TEST_F(DiskCacheEntryTest, ZeroLengthIO) {
   1032   InitCache();
   1033   ZeroLengthIO(0);
   1034 }
   1035 
   1036 TEST_F(DiskCacheEntryTest, ZeroLengthIONoBuffer) {
   1037   InitCache();
   1038   cache_impl_->SetFlags(disk_cache::kNoBuffering);
   1039   ZeroLengthIO(0);
   1040 }
   1041 
   1042 TEST_F(DiskCacheEntryTest, MemoryOnlyZeroLengthIO) {
   1043   SetMemoryOnlyMode();
   1044   InitCache();
   1045   ZeroLengthIO(0);
   1046 }
   1047 
   1048 // Tests that we handle the content correctly when buffering, a feature of the
   1049 // standard cache that permits fast responses to certain reads.
   1050 void DiskCacheEntryTest::Buffering() {
   1051   std::string key("the first key");
   1052   disk_cache::Entry* entry;
   1053   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   1054 
   1055   const int kSize = 200;
   1056   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
   1057   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize));
   1058   CacheTestFillBuffer(buffer1->data(), kSize, true);
   1059   CacheTestFillBuffer(buffer2->data(), kSize, true);
   1060 
   1061   EXPECT_EQ(kSize, WriteData(entry, 1, 0, buffer1.get(), kSize, false));
   1062   entry->Close();
   1063 
   1064   // Write a little more and read what we wrote before.
   1065   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   1066   EXPECT_EQ(kSize, WriteData(entry, 1, 5000, buffer1.get(), kSize, false));
   1067   EXPECT_EQ(kSize, ReadData(entry, 1, 0, buffer2.get(), kSize));
   1068   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
   1069 
   1070   // Now go to an external file.
   1071   EXPECT_EQ(kSize, WriteData(entry, 1, 18000, buffer1.get(), kSize, false));
   1072   entry->Close();
   1073 
   1074   // Write something else and verify old data.
   1075   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   1076   EXPECT_EQ(kSize, WriteData(entry, 1, 10000, buffer1.get(), kSize, false));
   1077   CacheTestFillBuffer(buffer2->data(), kSize, true);
   1078   EXPECT_EQ(kSize, ReadData(entry, 1, 5000, buffer2.get(), kSize));
   1079   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
   1080   CacheTestFillBuffer(buffer2->data(), kSize, true);
   1081   EXPECT_EQ(kSize, ReadData(entry, 1, 0, buffer2.get(), kSize));
   1082   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
   1083   CacheTestFillBuffer(buffer2->data(), kSize, true);
   1084   EXPECT_EQ(kSize, ReadData(entry, 1, 18000, buffer2.get(), kSize));
   1085   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
   1086 
   1087   // Extend the file some more.
   1088   EXPECT_EQ(kSize, WriteData(entry, 1, 23000, buffer1.get(), kSize, false));
   1089   entry->Close();
   1090 
   1091   // And now make sure that we can deal with data in both places (ram/disk).
   1092   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   1093   EXPECT_EQ(kSize, WriteData(entry, 1, 17000, buffer1.get(), kSize, false));
   1094 
   1095   // We should not overwrite the data at 18000 with this.
   1096   EXPECT_EQ(kSize, WriteData(entry, 1, 19000, buffer1.get(), kSize, false));
   1097   CacheTestFillBuffer(buffer2->data(), kSize, true);
   1098   EXPECT_EQ(kSize, ReadData(entry, 1, 18000, buffer2.get(), kSize));
   1099   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
   1100   CacheTestFillBuffer(buffer2->data(), kSize, true);
   1101   EXPECT_EQ(kSize, ReadData(entry, 1, 17000, buffer2.get(), kSize));
   1102   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
   1103 
   1104   EXPECT_EQ(kSize, WriteData(entry, 1, 22900, buffer1.get(), kSize, false));
   1105   CacheTestFillBuffer(buffer2->data(), kSize, true);
   1106   EXPECT_EQ(100, ReadData(entry, 1, 23000, buffer2.get(), kSize));
   1107   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data() + 100, 100));
   1108 
   1109   CacheTestFillBuffer(buffer2->data(), kSize, true);
   1110   EXPECT_EQ(100, ReadData(entry, 1, 23100, buffer2.get(), kSize));
   1111   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data() + 100, 100));
   1112 
   1113   // Extend the file again and read before without closing the entry.
   1114   EXPECT_EQ(kSize, WriteData(entry, 1, 25000, buffer1.get(), kSize, false));
   1115   EXPECT_EQ(kSize, WriteData(entry, 1, 45000, buffer1.get(), kSize, false));
   1116   CacheTestFillBuffer(buffer2->data(), kSize, true);
   1117   EXPECT_EQ(kSize, ReadData(entry, 1, 25000, buffer2.get(), kSize));
   1118   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
   1119   CacheTestFillBuffer(buffer2->data(), kSize, true);
   1120   EXPECT_EQ(kSize, ReadData(entry, 1, 45000, buffer2.get(), kSize));
   1121   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize));
   1122 
   1123   entry->Close();
   1124 }
   1125 
   1126 TEST_F(DiskCacheEntryTest, Buffering) {
   1127   InitCache();
   1128   Buffering();
   1129 }
   1130 
   1131 TEST_F(DiskCacheEntryTest, BufferingNoBuffer) {
   1132   InitCache();
   1133   cache_impl_->SetFlags(disk_cache::kNoBuffering);
   1134   Buffering();
   1135 }
   1136 
   1137 // Checks that entries are zero length when created.
   1138 void DiskCacheEntryTest::SizeAtCreate() {
   1139   const char key[]  = "the first key";
   1140   disk_cache::Entry* entry;
   1141   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   1142 
   1143   const int kNumStreams = 3;
   1144   for (int i = 0; i < kNumStreams; ++i)
   1145     EXPECT_EQ(0, entry->GetDataSize(i));
   1146   entry->Close();
   1147 }
   1148 
   1149 TEST_F(DiskCacheEntryTest, SizeAtCreate) {
   1150   InitCache();
   1151   SizeAtCreate();
   1152 }
   1153 
   1154 TEST_F(DiskCacheEntryTest, MemoryOnlySizeAtCreate) {
   1155   SetMemoryOnlyMode();
   1156   InitCache();
   1157   SizeAtCreate();
   1158 }
   1159 
   1160 // Some extra tests to make sure that buffering works properly when changing
   1161 // the entry size.
   1162 void DiskCacheEntryTest::SizeChanges(int stream_index) {
   1163   std::string key("the first key");
   1164   disk_cache::Entry* entry;
   1165   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   1166 
   1167   const int kSize = 200;
   1168   const char zeros[kSize] = {};
   1169   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
   1170   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize));
   1171   CacheTestFillBuffer(buffer1->data(), kSize, true);
   1172   CacheTestFillBuffer(buffer2->data(), kSize, true);
   1173 
   1174   EXPECT_EQ(kSize,
   1175             WriteData(entry, stream_index, 0, buffer1.get(), kSize, true));
   1176   EXPECT_EQ(kSize,
   1177             WriteData(entry, stream_index, 17000, buffer1.get(), kSize, true));
   1178   EXPECT_EQ(kSize,
   1179             WriteData(entry, stream_index, 23000, buffer1.get(), kSize, true));
   1180   entry->Close();
   1181 
   1182   // Extend the file and read between the old size and the new write.
   1183   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   1184   EXPECT_EQ(23000 + kSize, entry->GetDataSize(stream_index));
   1185   EXPECT_EQ(kSize,
   1186             WriteData(entry, stream_index, 25000, buffer1.get(), kSize, true));
   1187   EXPECT_EQ(25000 + kSize, entry->GetDataSize(stream_index));
   1188   EXPECT_EQ(kSize, ReadData(entry, stream_index, 24000, buffer2.get(), kSize));
   1189   EXPECT_TRUE(!memcmp(buffer2->data(), zeros, kSize));
   1190 
   1191   // Read at the end of the old file size.
   1192   EXPECT_EQ(
   1193       kSize,
   1194       ReadData(entry, stream_index, 23000 + kSize - 35, buffer2.get(), kSize));
   1195   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data() + kSize - 35, 35));
   1196 
   1197   // Read slightly before the last write.
   1198   CacheTestFillBuffer(buffer2->data(), kSize, true);
   1199   EXPECT_EQ(kSize, ReadData(entry, stream_index, 24900, buffer2.get(), kSize));
   1200   EXPECT_TRUE(!memcmp(buffer2->data(), zeros, 100));
   1201   EXPECT_TRUE(!memcmp(buffer2->data() + 100, buffer1->data(), kSize - 100));
   1202 
   1203   // Extend the entry a little more.
   1204   EXPECT_EQ(kSize,
   1205             WriteData(entry, stream_index, 26000, buffer1.get(), kSize, true));
   1206   EXPECT_EQ(26000 + kSize, entry->GetDataSize(stream_index));
   1207   CacheTestFillBuffer(buffer2->data(), kSize, true);
   1208   EXPECT_EQ(kSize, ReadData(entry, stream_index, 25900, buffer2.get(), kSize));
   1209   EXPECT_TRUE(!memcmp(buffer2->data(), zeros, 100));
   1210   EXPECT_TRUE(!memcmp(buffer2->data() + 100, buffer1->data(), kSize - 100));
   1211 
   1212   // And now reduce the size.
   1213   EXPECT_EQ(kSize,
   1214             WriteData(entry, stream_index, 25000, buffer1.get(), kSize, true));
   1215   EXPECT_EQ(25000 + kSize, entry->GetDataSize(stream_index));
   1216   EXPECT_EQ(
   1217       28,
   1218       ReadData(entry, stream_index, 25000 + kSize - 28, buffer2.get(), kSize));
   1219   EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data() + kSize - 28, 28));
   1220 
   1221   // Reduce the size with a buffer that is not extending the size.
   1222   EXPECT_EQ(kSize,
   1223             WriteData(entry, stream_index, 24000, buffer1.get(), kSize, false));
   1224   EXPECT_EQ(25000 + kSize, entry->GetDataSize(stream_index));
   1225   EXPECT_EQ(kSize,
   1226             WriteData(entry, stream_index, 24500, buffer1.get(), kSize, true));
   1227   EXPECT_EQ(24500 + kSize, entry->GetDataSize(stream_index));
   1228   EXPECT_EQ(kSize, ReadData(entry, stream_index, 23900, buffer2.get(), kSize));
   1229   EXPECT_TRUE(!memcmp(buffer2->data(), zeros, 100));
   1230   EXPECT_TRUE(!memcmp(buffer2->data() + 100, buffer1->data(), kSize - 100));
   1231 
   1232   // And now reduce the size below the old size.
   1233   EXPECT_EQ(kSize,
   1234             WriteData(entry, stream_index, 19000, buffer1.get(), kSize, true));
   1235   EXPECT_EQ(19000 + kSize, entry->GetDataSize(stream_index));
   1236   EXPECT_EQ(kSize, ReadData(entry, stream_index, 18900, buffer2.get(), kSize));
   1237   EXPECT_TRUE(!memcmp(buffer2->data(), zeros, 100));
   1238   EXPECT_TRUE(!memcmp(buffer2->data() + 100, buffer1->data(), kSize - 100));
   1239 
   1240   // Verify that the actual file is truncated.
   1241   entry->Close();
   1242   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   1243   EXPECT_EQ(19000 + kSize, entry->GetDataSize(stream_index));
   1244 
   1245   // Extend the newly opened file with a zero length write, expect zero fill.
   1246   EXPECT_EQ(
   1247       0,
   1248       WriteData(entry, stream_index, 20000 + kSize, buffer1.get(), 0, false));
   1249   EXPECT_EQ(kSize,
   1250             ReadData(entry, stream_index, 19000 + kSize, buffer1.get(), kSize));
   1251   EXPECT_EQ(0, memcmp(buffer1->data(), zeros, kSize));
   1252 
   1253   entry->Close();
   1254 }
   1255 
   1256 TEST_F(DiskCacheEntryTest, SizeChanges) {
   1257   InitCache();
   1258   SizeChanges(1);
   1259 }
   1260 
   1261 TEST_F(DiskCacheEntryTest, SizeChangesNoBuffer) {
   1262   InitCache();
   1263   cache_impl_->SetFlags(disk_cache::kNoBuffering);
   1264   SizeChanges(1);
   1265 }
   1266 
   1267 // Write more than the total cache capacity but to a single entry. |size| is the
   1268 // amount of bytes to write each time.
   1269 void DiskCacheEntryTest::ReuseEntry(int size, int stream_index) {
   1270   std::string key1("the first key");
   1271   disk_cache::Entry* entry;
   1272   ASSERT_EQ(net::OK, CreateEntry(key1, &entry));
   1273 
   1274   entry->Close();
   1275   std::string key2("the second key");
   1276   ASSERT_EQ(net::OK, CreateEntry(key2, &entry));
   1277 
   1278   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(size));
   1279   CacheTestFillBuffer(buffer->data(), size, false);
   1280 
   1281   for (int i = 0; i < 15; i++) {
   1282     EXPECT_EQ(0, WriteData(entry, stream_index, 0, buffer.get(), 0, true));
   1283     EXPECT_EQ(size,
   1284               WriteData(entry, stream_index, 0, buffer.get(), size, false));
   1285     entry->Close();
   1286     ASSERT_EQ(net::OK, OpenEntry(key2, &entry));
   1287   }
   1288 
   1289   entry->Close();
   1290   ASSERT_EQ(net::OK, OpenEntry(key1, &entry)) << "have not evicted this entry";
   1291   entry->Close();
   1292 }
   1293 
   1294 TEST_F(DiskCacheEntryTest, ReuseExternalEntry) {
   1295   SetMaxSize(200 * 1024);
   1296   InitCache();
   1297   ReuseEntry(20 * 1024, 0);
   1298 }
   1299 
   1300 TEST_F(DiskCacheEntryTest, MemoryOnlyReuseExternalEntry) {
   1301   SetMemoryOnlyMode();
   1302   SetMaxSize(200 * 1024);
   1303   InitCache();
   1304   ReuseEntry(20 * 1024, 0);
   1305 }
   1306 
   1307 TEST_F(DiskCacheEntryTest, ReuseInternalEntry) {
   1308   SetMaxSize(100 * 1024);
   1309   InitCache();
   1310   ReuseEntry(10 * 1024, 0);
   1311 }
   1312 
   1313 TEST_F(DiskCacheEntryTest, MemoryOnlyReuseInternalEntry) {
   1314   SetMemoryOnlyMode();
   1315   SetMaxSize(100 * 1024);
   1316   InitCache();
   1317   ReuseEntry(10 * 1024, 0);
   1318 }
   1319 
   1320 // Reading somewhere that was not written should return zeros.
   1321 void DiskCacheEntryTest::InvalidData(int stream_index) {
   1322   std::string key("the first key");
   1323   disk_cache::Entry* entry;
   1324   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   1325 
   1326   const int kSize1 = 20000;
   1327   const int kSize2 = 20000;
   1328   const int kSize3 = 20000;
   1329   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
   1330   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2));
   1331   scoped_refptr<net::IOBuffer> buffer3(new net::IOBuffer(kSize3));
   1332 
   1333   CacheTestFillBuffer(buffer1->data(), kSize1, false);
   1334   memset(buffer2->data(), 0, kSize2);
   1335 
   1336   // Simple data grow:
   1337   EXPECT_EQ(200,
   1338             WriteData(entry, stream_index, 400, buffer1.get(), 200, false));
   1339   EXPECT_EQ(600, entry->GetDataSize(stream_index));
   1340   EXPECT_EQ(100, ReadData(entry, stream_index, 300, buffer3.get(), 100));
   1341   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 100));
   1342   entry->Close();
   1343   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   1344 
   1345   // The entry is now on disk. Load it and extend it.
   1346   EXPECT_EQ(200,
   1347             WriteData(entry, stream_index, 800, buffer1.get(), 200, false));
   1348   EXPECT_EQ(1000, entry->GetDataSize(stream_index));
   1349   EXPECT_EQ(100, ReadData(entry, stream_index, 700, buffer3.get(), 100));
   1350   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 100));
   1351   entry->Close();
   1352   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   1353 
   1354   // This time using truncate.
   1355   EXPECT_EQ(200,
   1356             WriteData(entry, stream_index, 1800, buffer1.get(), 200, true));
   1357   EXPECT_EQ(2000, entry->GetDataSize(stream_index));
   1358   EXPECT_EQ(100, ReadData(entry, stream_index, 1500, buffer3.get(), 100));
   1359   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 100));
   1360 
   1361   // Go to an external file.
   1362   EXPECT_EQ(200,
   1363             WriteData(entry, stream_index, 19800, buffer1.get(), 200, false));
   1364   EXPECT_EQ(20000, entry->GetDataSize(stream_index));
   1365   EXPECT_EQ(4000, ReadData(entry, stream_index, 14000, buffer3.get(), 4000));
   1366   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 4000));
   1367 
   1368   // And back to an internal block.
   1369   EXPECT_EQ(600,
   1370             WriteData(entry, stream_index, 1000, buffer1.get(), 600, true));
   1371   EXPECT_EQ(1600, entry->GetDataSize(stream_index));
   1372   EXPECT_EQ(600, ReadData(entry, stream_index, 1000, buffer3.get(), 600));
   1373   EXPECT_TRUE(!memcmp(buffer3->data(), buffer1->data(), 600));
   1374 
   1375   // Extend it again.
   1376   EXPECT_EQ(600,
   1377             WriteData(entry, stream_index, 2000, buffer1.get(), 600, false));
   1378   EXPECT_EQ(2600, entry->GetDataSize(stream_index));
   1379   EXPECT_EQ(200, ReadData(entry, stream_index, 1800, buffer3.get(), 200));
   1380   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 200));
   1381 
   1382   // And again (with truncation flag).
   1383   EXPECT_EQ(600,
   1384             WriteData(entry, stream_index, 3000, buffer1.get(), 600, true));
   1385   EXPECT_EQ(3600, entry->GetDataSize(stream_index));
   1386   EXPECT_EQ(200, ReadData(entry, stream_index, 2800, buffer3.get(), 200));
   1387   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 200));
   1388 
   1389   entry->Close();
   1390 }
   1391 
   1392 TEST_F(DiskCacheEntryTest, InvalidData) {
   1393   InitCache();
   1394   InvalidData(0);
   1395 }
   1396 
   1397 TEST_F(DiskCacheEntryTest, InvalidDataNoBuffer) {
   1398   InitCache();
   1399   cache_impl_->SetFlags(disk_cache::kNoBuffering);
   1400   InvalidData(0);
   1401 }
   1402 
   1403 TEST_F(DiskCacheEntryTest, MemoryOnlyInvalidData) {
   1404   SetMemoryOnlyMode();
   1405   InitCache();
   1406   InvalidData(0);
   1407 }
   1408 
   1409 // Tests that the cache preserves the buffer of an IO operation.
   1410 void DiskCacheEntryTest::ReadWriteDestroyBuffer(int stream_index) {
   1411   std::string key("the first key");
   1412   disk_cache::Entry* entry;
   1413   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   1414 
   1415   const int kSize = 200;
   1416   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
   1417   CacheTestFillBuffer(buffer->data(), kSize, false);
   1418 
   1419   net::TestCompletionCallback cb;
   1420   EXPECT_EQ(net::ERR_IO_PENDING,
   1421             entry->WriteData(
   1422                 stream_index, 0, buffer.get(), kSize, cb.callback(), false));
   1423 
   1424   // Release our reference to the buffer.
   1425   buffer = NULL;
   1426   EXPECT_EQ(kSize, cb.WaitForResult());
   1427 
   1428   // And now test with a Read().
   1429   buffer = new net::IOBuffer(kSize);
   1430   CacheTestFillBuffer(buffer->data(), kSize, false);
   1431 
   1432   EXPECT_EQ(
   1433       net::ERR_IO_PENDING,
   1434       entry->ReadData(stream_index, 0, buffer.get(), kSize, cb.callback()));
   1435   buffer = NULL;
   1436   EXPECT_EQ(kSize, cb.WaitForResult());
   1437 
   1438   entry->Close();
   1439 }
   1440 
   1441 TEST_F(DiskCacheEntryTest, ReadWriteDestroyBuffer) {
   1442   InitCache();
   1443   ReadWriteDestroyBuffer(0);
   1444 }
   1445 
   1446 void DiskCacheEntryTest::DoomNormalEntry() {
   1447   std::string key("the first key");
   1448   disk_cache::Entry* entry;
   1449   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   1450   entry->Doom();
   1451   entry->Close();
   1452 
   1453   const int kSize = 20000;
   1454   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
   1455   CacheTestFillBuffer(buffer->data(), kSize, true);
   1456   buffer->data()[19999] = '\0';
   1457 
   1458   key = buffer->data();
   1459   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   1460   EXPECT_EQ(20000, WriteData(entry, 0, 0, buffer.get(), kSize, false));
   1461   EXPECT_EQ(20000, WriteData(entry, 1, 0, buffer.get(), kSize, false));
   1462   entry->Doom();
   1463   entry->Close();
   1464 
   1465   FlushQueueForTest();
   1466   EXPECT_EQ(0, cache_->GetEntryCount());
   1467 }
   1468 
   1469 TEST_F(DiskCacheEntryTest, DoomEntry) {
   1470   InitCache();
   1471   DoomNormalEntry();
   1472 }
   1473 
   1474 TEST_F(DiskCacheEntryTest, MemoryOnlyDoomEntry) {
   1475   SetMemoryOnlyMode();
   1476   InitCache();
   1477   DoomNormalEntry();
   1478 }
   1479 
   1480 // Tests dooming an entry that's linked to an open entry.
   1481 void DiskCacheEntryTest::DoomEntryNextToOpenEntry() {
   1482   disk_cache::Entry* entry1;
   1483   disk_cache::Entry* entry2;
   1484   ASSERT_EQ(net::OK, CreateEntry("fixed", &entry1));
   1485   entry1->Close();
   1486   ASSERT_EQ(net::OK, CreateEntry("foo", &entry1));
   1487   entry1->Close();
   1488   ASSERT_EQ(net::OK, CreateEntry("bar", &entry1));
   1489   entry1->Close();
   1490 
   1491   ASSERT_EQ(net::OK, OpenEntry("foo", &entry1));
   1492   ASSERT_EQ(net::OK, OpenEntry("bar", &entry2));
   1493   entry2->Doom();
   1494   entry2->Close();
   1495 
   1496   ASSERT_EQ(net::OK, OpenEntry("foo", &entry2));
   1497   entry2->Doom();
   1498   entry2->Close();
   1499   entry1->Close();
   1500 
   1501   ASSERT_EQ(net::OK, OpenEntry("fixed", &entry1));
   1502   entry1->Close();
   1503 }
   1504 
   1505 TEST_F(DiskCacheEntryTest, DoomEntryNextToOpenEntry) {
   1506   InitCache();
   1507   DoomEntryNextToOpenEntry();
   1508 }
   1509 
   1510 TEST_F(DiskCacheEntryTest, NewEvictionDoomEntryNextToOpenEntry) {
   1511   SetNewEviction();
   1512   InitCache();
   1513   DoomEntryNextToOpenEntry();
   1514 }
   1515 
   1516 TEST_F(DiskCacheEntryTest, AppCacheDoomEntryNextToOpenEntry) {
   1517   SetCacheType(net::APP_CACHE);
   1518   InitCache();
   1519   DoomEntryNextToOpenEntry();
   1520 }
   1521 
   1522 // Verify that basic operations work as expected with doomed entries.
   1523 void DiskCacheEntryTest::DoomedEntry(int stream_index) {
   1524   std::string key("the first key");
   1525   disk_cache::Entry* entry;
   1526   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   1527   entry->Doom();
   1528 
   1529   FlushQueueForTest();
   1530   EXPECT_EQ(0, cache_->GetEntryCount());
   1531   Time initial = Time::Now();
   1532   AddDelay();
   1533 
   1534   const int kSize1 = 2000;
   1535   const int kSize2 = 2000;
   1536   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
   1537   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2));
   1538   CacheTestFillBuffer(buffer1->data(), kSize1, false);
   1539   memset(buffer2->data(), 0, kSize2);
   1540 
   1541   EXPECT_EQ(2000,
   1542             WriteData(entry, stream_index, 0, buffer1.get(), 2000, false));
   1543   EXPECT_EQ(2000, ReadData(entry, stream_index, 0, buffer2.get(), 2000));
   1544   EXPECT_EQ(0, memcmp(buffer1->data(), buffer2->data(), kSize1));
   1545   EXPECT_EQ(key, entry->GetKey());
   1546   EXPECT_TRUE(initial < entry->GetLastModified());
   1547   EXPECT_TRUE(initial < entry->GetLastUsed());
   1548 
   1549   entry->Close();
   1550 }
   1551 
   1552 TEST_F(DiskCacheEntryTest, DoomedEntry) {
   1553   InitCache();
   1554   DoomedEntry(0);
   1555 }
   1556 
   1557 TEST_F(DiskCacheEntryTest, MemoryOnlyDoomedEntry) {
   1558   SetMemoryOnlyMode();
   1559   InitCache();
   1560   DoomedEntry(0);
   1561 }
   1562 
   1563 // Tests that we discard entries if the data is missing.
   1564 TEST_F(DiskCacheEntryTest, MissingData) {
   1565   InitCache();
   1566 
   1567   std::string key("the first key");
   1568   disk_cache::Entry* entry;
   1569   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   1570 
   1571   // Write to an external file.
   1572   const int kSize = 20000;
   1573   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
   1574   CacheTestFillBuffer(buffer->data(), kSize, false);
   1575   EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, false));
   1576   entry->Close();
   1577   FlushQueueForTest();
   1578 
   1579   disk_cache::Addr address(0x80000001);
   1580   base::FilePath name = cache_impl_->GetFileName(address);
   1581   EXPECT_TRUE(base::DeleteFile(name, false));
   1582 
   1583   // Attempt to read the data.
   1584   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   1585   EXPECT_EQ(net::ERR_FILE_NOT_FOUND,
   1586             ReadData(entry, 0, 0, buffer.get(), kSize));
   1587   entry->Close();
   1588 
   1589   // The entry should be gone.
   1590   ASSERT_NE(net::OK, OpenEntry(key, &entry));
   1591 }
   1592 
   1593 // Test that child entries in a memory cache backend are not visible from
   1594 // enumerations.
   1595 TEST_F(DiskCacheEntryTest, MemoryOnlyEnumerationWithSparseEntries) {
   1596   SetMemoryOnlyMode();
   1597   InitCache();
   1598 
   1599   const int kSize = 4096;
   1600   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
   1601   CacheTestFillBuffer(buf->data(), kSize, false);
   1602 
   1603   std::string key("the first key");
   1604   disk_cache::Entry* parent_entry;
   1605   ASSERT_EQ(net::OK, CreateEntry(key, &parent_entry));
   1606 
   1607   // Writes to the parent entry.
   1608   EXPECT_EQ(kSize,
   1609             parent_entry->WriteSparseData(
   1610                 0, buf.get(), kSize, net::CompletionCallback()));
   1611 
   1612   // This write creates a child entry and writes to it.
   1613   EXPECT_EQ(kSize,
   1614             parent_entry->WriteSparseData(
   1615                 8192, buf.get(), kSize, net::CompletionCallback()));
   1616 
   1617   parent_entry->Close();
   1618 
   1619   // Perform the enumerations.
   1620   void* iter = NULL;
   1621   disk_cache::Entry* entry = NULL;
   1622   int count = 0;
   1623   while (OpenNextEntry(&iter, &entry) == net::OK) {
   1624     ASSERT_TRUE(entry != NULL);
   1625     ++count;
   1626     disk_cache::MemEntryImpl* mem_entry =
   1627         reinterpret_cast<disk_cache::MemEntryImpl*>(entry);
   1628     EXPECT_EQ(disk_cache::MemEntryImpl::kParentEntry, mem_entry->type());
   1629     mem_entry->Close();
   1630   }
   1631   EXPECT_EQ(1, count);
   1632 }
   1633 
   1634 // Writes |buf_1| to offset and reads it back as |buf_2|.
   1635 void VerifySparseIO(disk_cache::Entry* entry, int64 offset,
   1636                     net::IOBuffer* buf_1, int size, net::IOBuffer* buf_2) {
   1637   net::TestCompletionCallback cb;
   1638 
   1639   memset(buf_2->data(), 0, size);
   1640   int ret = entry->ReadSparseData(offset, buf_2, size, cb.callback());
   1641   EXPECT_EQ(0, cb.GetResult(ret));
   1642 
   1643   ret = entry->WriteSparseData(offset, buf_1, size, cb.callback());
   1644   EXPECT_EQ(size, cb.GetResult(ret));
   1645 
   1646   ret = entry->ReadSparseData(offset, buf_2, size, cb.callback());
   1647   EXPECT_EQ(size, cb.GetResult(ret));
   1648 
   1649   EXPECT_EQ(0, memcmp(buf_1->data(), buf_2->data(), size));
   1650 }
   1651 
   1652 // Reads |size| bytes from |entry| at |offset| and verifies that they are the
   1653 // same as the content of the provided |buffer|.
   1654 void VerifyContentSparseIO(disk_cache::Entry* entry, int64 offset, char* buffer,
   1655                            int size) {
   1656   net::TestCompletionCallback cb;
   1657 
   1658   scoped_refptr<net::IOBuffer> buf_1(new net::IOBuffer(size));
   1659   memset(buf_1->data(), 0, size);
   1660   int ret = entry->ReadSparseData(offset, buf_1.get(), size, cb.callback());
   1661   EXPECT_EQ(size, cb.GetResult(ret));
   1662   EXPECT_EQ(0, memcmp(buf_1->data(), buffer, size));
   1663 }
   1664 
   1665 void DiskCacheEntryTest::BasicSparseIO() {
   1666   std::string key("the first key");
   1667   disk_cache::Entry* entry;
   1668   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   1669 
   1670   const int kSize = 2048;
   1671   scoped_refptr<net::IOBuffer> buf_1(new net::IOBuffer(kSize));
   1672   scoped_refptr<net::IOBuffer> buf_2(new net::IOBuffer(kSize));
   1673   CacheTestFillBuffer(buf_1->data(), kSize, false);
   1674 
   1675   // Write at offset 0.
   1676   VerifySparseIO(entry, 0, buf_1.get(), kSize, buf_2.get());
   1677 
   1678   // Write at offset 0x400000 (4 MB).
   1679   VerifySparseIO(entry, 0x400000, buf_1.get(), kSize, buf_2.get());
   1680 
   1681   // Write at offset 0x800000000 (32 GB).
   1682   VerifySparseIO(entry, 0x800000000LL, buf_1.get(), kSize, buf_2.get());
   1683 
   1684   entry->Close();
   1685 
   1686   // Check everything again.
   1687   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   1688   VerifyContentSparseIO(entry, 0, buf_1->data(), kSize);
   1689   VerifyContentSparseIO(entry, 0x400000, buf_1->data(), kSize);
   1690   VerifyContentSparseIO(entry, 0x800000000LL, buf_1->data(), kSize);
   1691   entry->Close();
   1692 }
   1693 
   1694 TEST_F(DiskCacheEntryTest, BasicSparseIO) {
   1695   InitCache();
   1696   BasicSparseIO();
   1697 }
   1698 
   1699 TEST_F(DiskCacheEntryTest, MemoryOnlyBasicSparseIO) {
   1700   SetMemoryOnlyMode();
   1701   InitCache();
   1702   BasicSparseIO();
   1703 }
   1704 
   1705 void DiskCacheEntryTest::HugeSparseIO() {
   1706   std::string key("the first key");
   1707   disk_cache::Entry* entry;
   1708   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   1709 
   1710   // Write 1.2 MB so that we cover multiple entries.
   1711   const int kSize = 1200 * 1024;
   1712   scoped_refptr<net::IOBuffer> buf_1(new net::IOBuffer(kSize));
   1713   scoped_refptr<net::IOBuffer> buf_2(new net::IOBuffer(kSize));
   1714   CacheTestFillBuffer(buf_1->data(), kSize, false);
   1715 
   1716   // Write at offset 0x20F0000 (33 MB - 64 KB).
   1717   VerifySparseIO(entry, 0x20F0000, buf_1.get(), kSize, buf_2.get());
   1718   entry->Close();
   1719 
   1720   // Check it again.
   1721   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   1722   VerifyContentSparseIO(entry, 0x20F0000, buf_1->data(), kSize);
   1723   entry->Close();
   1724 }
   1725 
   1726 TEST_F(DiskCacheEntryTest, HugeSparseIO) {
   1727   InitCache();
   1728   HugeSparseIO();
   1729 }
   1730 
   1731 TEST_F(DiskCacheEntryTest, MemoryOnlyHugeSparseIO) {
   1732   SetMemoryOnlyMode();
   1733   InitCache();
   1734   HugeSparseIO();
   1735 }
   1736 
   1737 void DiskCacheEntryTest::GetAvailableRange() {
   1738   std::string key("the first key");
   1739   disk_cache::Entry* entry;
   1740   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   1741 
   1742   const int kSize = 16 * 1024;
   1743   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
   1744   CacheTestFillBuffer(buf->data(), kSize, false);
   1745 
   1746   // Write at offset 0x20F0000 (33 MB - 64 KB), and 0x20F4400 (33 MB - 47 KB).
   1747   EXPECT_EQ(kSize, WriteSparseData(entry, 0x20F0000, buf.get(), kSize));
   1748   EXPECT_EQ(kSize, WriteSparseData(entry, 0x20F4400, buf.get(), kSize));
   1749 
   1750   // We stop at the first empty block.
   1751   int64 start;
   1752   net::TestCompletionCallback cb;
   1753   int rv = entry->GetAvailableRange(
   1754       0x20F0000, kSize * 2, &start, cb.callback());
   1755   EXPECT_EQ(kSize, cb.GetResult(rv));
   1756   EXPECT_EQ(0x20F0000, start);
   1757 
   1758   start = 0;
   1759   rv = entry->GetAvailableRange(0, kSize, &start, cb.callback());
   1760   EXPECT_EQ(0, cb.GetResult(rv));
   1761   rv = entry->GetAvailableRange(
   1762       0x20F0000 - kSize, kSize, &start, cb.callback());
   1763   EXPECT_EQ(0, cb.GetResult(rv));
   1764   rv = entry->GetAvailableRange(0, 0x2100000, &start, cb.callback());
   1765   EXPECT_EQ(kSize, cb.GetResult(rv));
   1766   EXPECT_EQ(0x20F0000, start);
   1767 
   1768   // We should be able to Read based on the results of GetAvailableRange.
   1769   start = -1;
   1770   rv = entry->GetAvailableRange(0x2100000, kSize, &start, cb.callback());
   1771   EXPECT_EQ(0, cb.GetResult(rv));
   1772   rv = entry->ReadSparseData(start, buf.get(), kSize, cb.callback());
   1773   EXPECT_EQ(0, cb.GetResult(rv));
   1774 
   1775   start = 0;
   1776   rv = entry->GetAvailableRange(0x20F2000, kSize, &start, cb.callback());
   1777   EXPECT_EQ(0x2000, cb.GetResult(rv));
   1778   EXPECT_EQ(0x20F2000, start);
   1779   EXPECT_EQ(0x2000, ReadSparseData(entry, start, buf.get(), kSize));
   1780 
   1781   // Make sure that we respect the |len| argument.
   1782   start = 0;
   1783   rv = entry->GetAvailableRange(
   1784       0x20F0001 - kSize, kSize, &start, cb.callback());
   1785   EXPECT_EQ(1, cb.GetResult(rv));
   1786   EXPECT_EQ(0x20F0000, start);
   1787 
   1788   entry->Close();
   1789 }
   1790 
   1791 TEST_F(DiskCacheEntryTest, GetAvailableRange) {
   1792   InitCache();
   1793   GetAvailableRange();
   1794 }
   1795 
   1796 TEST_F(DiskCacheEntryTest, MemoryOnlyGetAvailableRange) {
   1797   SetMemoryOnlyMode();
   1798   InitCache();
   1799   GetAvailableRange();
   1800 }
   1801 
   1802 void DiskCacheEntryTest::CouldBeSparse() {
   1803   std::string key("the first key");
   1804   disk_cache::Entry* entry;
   1805   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   1806 
   1807   const int kSize = 16 * 1024;
   1808   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
   1809   CacheTestFillBuffer(buf->data(), kSize, false);
   1810 
   1811   // Write at offset 0x20F0000 (33 MB - 64 KB).
   1812   EXPECT_EQ(kSize, WriteSparseData(entry, 0x20F0000, buf.get(), kSize));
   1813 
   1814   EXPECT_TRUE(entry->CouldBeSparse());
   1815   entry->Close();
   1816 
   1817   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   1818   EXPECT_TRUE(entry->CouldBeSparse());
   1819   entry->Close();
   1820 
   1821   // Now verify a regular entry.
   1822   key.assign("another key");
   1823   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   1824   EXPECT_FALSE(entry->CouldBeSparse());
   1825 
   1826   EXPECT_EQ(kSize, WriteData(entry, 0, 0, buf.get(), kSize, false));
   1827   EXPECT_EQ(kSize, WriteData(entry, 1, 0, buf.get(), kSize, false));
   1828   EXPECT_EQ(kSize, WriteData(entry, 2, 0, buf.get(), kSize, false));
   1829 
   1830   EXPECT_FALSE(entry->CouldBeSparse());
   1831   entry->Close();
   1832 
   1833   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   1834   EXPECT_FALSE(entry->CouldBeSparse());
   1835   entry->Close();
   1836 }
   1837 
   1838 TEST_F(DiskCacheEntryTest, CouldBeSparse) {
   1839   InitCache();
   1840   CouldBeSparse();
   1841 }
   1842 
   1843 TEST_F(DiskCacheEntryTest, MemoryCouldBeSparse) {
   1844   SetMemoryOnlyMode();
   1845   InitCache();
   1846   CouldBeSparse();
   1847 }
   1848 
   1849 TEST_F(DiskCacheEntryTest, MemoryOnlyMisalignedSparseIO) {
   1850   SetMemoryOnlyMode();
   1851   InitCache();
   1852 
   1853   const int kSize = 8192;
   1854   scoped_refptr<net::IOBuffer> buf_1(new net::IOBuffer(kSize));
   1855   scoped_refptr<net::IOBuffer> buf_2(new net::IOBuffer(kSize));
   1856   CacheTestFillBuffer(buf_1->data(), kSize, false);
   1857 
   1858   std::string key("the first key");
   1859   disk_cache::Entry* entry;
   1860   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   1861 
   1862   // This loop writes back to back starting from offset 0 and 9000.
   1863   for (int i = 0; i < kSize; i += 1024) {
   1864     scoped_refptr<net::WrappedIOBuffer> buf_3(
   1865       new net::WrappedIOBuffer(buf_1->data() + i));
   1866     VerifySparseIO(entry, i, buf_3.get(), 1024, buf_2.get());
   1867     VerifySparseIO(entry, 9000 + i, buf_3.get(), 1024, buf_2.get());
   1868   }
   1869 
   1870   // Make sure we have data written.
   1871   VerifyContentSparseIO(entry, 0, buf_1->data(), kSize);
   1872   VerifyContentSparseIO(entry, 9000, buf_1->data(), kSize);
   1873 
   1874   // This tests a large write that spans 3 entries from a misaligned offset.
   1875   VerifySparseIO(entry, 20481, buf_1.get(), 8192, buf_2.get());
   1876 
   1877   entry->Close();
   1878 }
   1879 
   1880 TEST_F(DiskCacheEntryTest, MemoryOnlyMisalignedGetAvailableRange) {
   1881   SetMemoryOnlyMode();
   1882   InitCache();
   1883 
   1884   const int kSize = 8192;
   1885   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
   1886   CacheTestFillBuffer(buf->data(), kSize, false);
   1887 
   1888   disk_cache::Entry* entry;
   1889   std::string key("the first key");
   1890   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   1891 
   1892   // Writes in the middle of an entry.
   1893   EXPECT_EQ(
   1894       1024,
   1895       entry->WriteSparseData(0, buf.get(), 1024, net::CompletionCallback()));
   1896   EXPECT_EQ(
   1897       1024,
   1898       entry->WriteSparseData(5120, buf.get(), 1024, net::CompletionCallback()));
   1899   EXPECT_EQ(1024,
   1900             entry->WriteSparseData(
   1901                 10000, buf.get(), 1024, net::CompletionCallback()));
   1902 
   1903   // Writes in the middle of an entry and spans 2 child entries.
   1904   EXPECT_EQ(8192,
   1905             entry->WriteSparseData(
   1906                 50000, buf.get(), 8192, net::CompletionCallback()));
   1907 
   1908   int64 start;
   1909   net::TestCompletionCallback cb;
   1910   // Test that we stop at a discontinuous child at the second block.
   1911   int rv = entry->GetAvailableRange(0, 10000, &start, cb.callback());
   1912   EXPECT_EQ(1024, cb.GetResult(rv));
   1913   EXPECT_EQ(0, start);
   1914 
   1915   // Test that number of bytes is reported correctly when we start from the
   1916   // middle of a filled region.
   1917   rv = entry->GetAvailableRange(512, 10000, &start, cb.callback());
   1918   EXPECT_EQ(512, cb.GetResult(rv));
   1919   EXPECT_EQ(512, start);
   1920 
   1921   // Test that we found bytes in the child of next block.
   1922   rv = entry->GetAvailableRange(1024, 10000, &start, cb.callback());
   1923   EXPECT_EQ(1024, cb.GetResult(rv));
   1924   EXPECT_EQ(5120, start);
   1925 
   1926   // Test that the desired length is respected. It starts within a filled
   1927   // region.
   1928   rv = entry->GetAvailableRange(5500, 512, &start, cb.callback());
   1929   EXPECT_EQ(512, cb.GetResult(rv));
   1930   EXPECT_EQ(5500, start);
   1931 
   1932   // Test that the desired length is respected. It starts before a filled
   1933   // region.
   1934   rv = entry->GetAvailableRange(5000, 620, &start, cb.callback());
   1935   EXPECT_EQ(500, cb.GetResult(rv));
   1936   EXPECT_EQ(5120, start);
   1937 
   1938   // Test that multiple blocks are scanned.
   1939   rv = entry->GetAvailableRange(40000, 20000, &start, cb.callback());
   1940   EXPECT_EQ(8192, cb.GetResult(rv));
   1941   EXPECT_EQ(50000, start);
   1942 
   1943   entry->Close();
   1944 }
   1945 
   1946 void DiskCacheEntryTest::UpdateSparseEntry() {
   1947   std::string key("the first key");
   1948   disk_cache::Entry* entry1;
   1949   ASSERT_EQ(net::OK, CreateEntry(key, &entry1));
   1950 
   1951   const int kSize = 2048;
   1952   scoped_refptr<net::IOBuffer> buf_1(new net::IOBuffer(kSize));
   1953   scoped_refptr<net::IOBuffer> buf_2(new net::IOBuffer(kSize));
   1954   CacheTestFillBuffer(buf_1->data(), kSize, false);
   1955 
   1956   // Write at offset 0.
   1957   VerifySparseIO(entry1, 0, buf_1.get(), kSize, buf_2.get());
   1958   entry1->Close();
   1959 
   1960   // Write at offset 2048.
   1961   ASSERT_EQ(net::OK, OpenEntry(key, &entry1));
   1962   VerifySparseIO(entry1, 2048, buf_1.get(), kSize, buf_2.get());
   1963 
   1964   disk_cache::Entry* entry2;
   1965   ASSERT_EQ(net::OK, CreateEntry("the second key", &entry2));
   1966 
   1967   entry1->Close();
   1968   entry2->Close();
   1969   FlushQueueForTest();
   1970   if (memory_only_ || simple_cache_mode_)
   1971     EXPECT_EQ(2, cache_->GetEntryCount());
   1972   else
   1973     EXPECT_EQ(3, cache_->GetEntryCount());
   1974 }
   1975 
   1976 TEST_F(DiskCacheEntryTest, UpdateSparseEntry) {
   1977   SetCacheType(net::MEDIA_CACHE);
   1978   InitCache();
   1979   UpdateSparseEntry();
   1980 }
   1981 
   1982 TEST_F(DiskCacheEntryTest, MemoryOnlyUpdateSparseEntry) {
   1983   SetMemoryOnlyMode();
   1984   SetCacheType(net::MEDIA_CACHE);
   1985   InitCache();
   1986   UpdateSparseEntry();
   1987 }
   1988 
   1989 void DiskCacheEntryTest::DoomSparseEntry() {
   1990   std::string key1("the first key");
   1991   std::string key2("the second key");
   1992   disk_cache::Entry *entry1, *entry2;
   1993   ASSERT_EQ(net::OK, CreateEntry(key1, &entry1));
   1994   ASSERT_EQ(net::OK, CreateEntry(key2, &entry2));
   1995 
   1996   const int kSize = 4 * 1024;
   1997   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
   1998   CacheTestFillBuffer(buf->data(), kSize, false);
   1999 
   2000   int64 offset = 1024;
   2001   // Write to a bunch of ranges.
   2002   for (int i = 0; i < 12; i++) {
   2003     EXPECT_EQ(kSize, WriteSparseData(entry1, offset, buf.get(), kSize));
   2004     // Keep the second map under the default size.
   2005     if (i < 9)
   2006       EXPECT_EQ(kSize, WriteSparseData(entry2, offset, buf.get(), kSize));
   2007 
   2008     offset *= 4;
   2009   }
   2010 
   2011   if (memory_only_ || simple_cache_mode_)
   2012     EXPECT_EQ(2, cache_->GetEntryCount());
   2013   else
   2014     EXPECT_EQ(15, cache_->GetEntryCount());
   2015 
   2016   // Doom the first entry while it's still open.
   2017   entry1->Doom();
   2018   entry1->Close();
   2019   entry2->Close();
   2020 
   2021   // Doom the second entry after it's fully saved.
   2022   EXPECT_EQ(net::OK, DoomEntry(key2));
   2023 
   2024   // Make sure we do all needed work. This may fail for entry2 if between Close
   2025   // and DoomEntry the system decides to remove all traces of the file from the
   2026   // system cache so we don't see that there is pending IO.
   2027   base::MessageLoop::current()->RunUntilIdle();
   2028 
   2029   if (memory_only_) {
   2030     EXPECT_EQ(0, cache_->GetEntryCount());
   2031   } else {
   2032     if (5 == cache_->GetEntryCount()) {
   2033       // Most likely we are waiting for the result of reading the sparse info
   2034       // (it's always async on Posix so it is easy to miss). Unfortunately we
   2035       // don't have any signal to watch for so we can only wait.
   2036       base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(500));
   2037       base::MessageLoop::current()->RunUntilIdle();
   2038     }
   2039     EXPECT_EQ(0, cache_->GetEntryCount());
   2040   }
   2041 }
   2042 
   2043 TEST_F(DiskCacheEntryTest, DoomSparseEntry) {
   2044   UseCurrentThread();
   2045   InitCache();
   2046   DoomSparseEntry();
   2047 }
   2048 
   2049 TEST_F(DiskCacheEntryTest, MemoryOnlyDoomSparseEntry) {
   2050   SetMemoryOnlyMode();
   2051   InitCache();
   2052   DoomSparseEntry();
   2053 }
   2054 
   2055 // A CompletionCallback wrapper that deletes the cache from within the callback.
   2056 // The way a CompletionCallback works means that all tasks (even new ones)
   2057 // are executed by the message loop before returning to the caller so the only
   2058 // way to simulate a race is to execute what we want on the callback.
   2059 class SparseTestCompletionCallback: public net::TestCompletionCallback {
   2060  public:
   2061   explicit SparseTestCompletionCallback(scoped_ptr<disk_cache::Backend> cache)
   2062       : cache_(cache.Pass()) {
   2063   }
   2064 
   2065  private:
   2066   virtual void SetResult(int result) OVERRIDE {
   2067     cache_.reset();
   2068     TestCompletionCallback::SetResult(result);
   2069   }
   2070 
   2071   scoped_ptr<disk_cache::Backend> cache_;
   2072   DISALLOW_COPY_AND_ASSIGN(SparseTestCompletionCallback);
   2073 };
   2074 
   2075 // Tests that we don't crash when the backend is deleted while we are working
   2076 // deleting the sub-entries of a sparse entry.
   2077 TEST_F(DiskCacheEntryTest, DoomSparseEntry2) {
   2078   UseCurrentThread();
   2079   InitCache();
   2080   std::string key("the key");
   2081   disk_cache::Entry* entry;
   2082   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   2083 
   2084   const int kSize = 4 * 1024;
   2085   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
   2086   CacheTestFillBuffer(buf->data(), kSize, false);
   2087 
   2088   int64 offset = 1024;
   2089   // Write to a bunch of ranges.
   2090   for (int i = 0; i < 12; i++) {
   2091     EXPECT_EQ(kSize,
   2092               entry->WriteSparseData(
   2093                   offset, buf.get(), kSize, net::CompletionCallback()));
   2094     offset *= 4;
   2095   }
   2096   EXPECT_EQ(9, cache_->GetEntryCount());
   2097 
   2098   entry->Close();
   2099   disk_cache::Backend* cache = cache_.get();
   2100   SparseTestCompletionCallback cb(cache_.Pass());
   2101   int rv = cache->DoomEntry(key, cb.callback());
   2102   EXPECT_EQ(net::ERR_IO_PENDING, rv);
   2103   EXPECT_EQ(net::OK, cb.WaitForResult());
   2104 }
   2105 
   2106 void DiskCacheEntryTest::PartialSparseEntry() {
   2107   std::string key("the first key");
   2108   disk_cache::Entry* entry;
   2109   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   2110 
   2111   // We should be able to deal with IO that is not aligned to the block size
   2112   // of a sparse entry, at least to write a big range without leaving holes.
   2113   const int kSize = 4 * 1024;
   2114   const int kSmallSize = 128;
   2115   scoped_refptr<net::IOBuffer> buf1(new net::IOBuffer(kSize));
   2116   CacheTestFillBuffer(buf1->data(), kSize, false);
   2117 
   2118   // The first write is just to extend the entry. The third write occupies
   2119   // a 1KB block partially, it may not be written internally depending on the
   2120   // implementation.
   2121   EXPECT_EQ(kSize, WriteSparseData(entry, 20000, buf1.get(), kSize));
   2122   EXPECT_EQ(kSize, WriteSparseData(entry, 500, buf1.get(), kSize));
   2123   EXPECT_EQ(kSmallSize,
   2124             WriteSparseData(entry, 1080321, buf1.get(), kSmallSize));
   2125   entry->Close();
   2126   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   2127 
   2128   scoped_refptr<net::IOBuffer> buf2(new net::IOBuffer(kSize));
   2129   memset(buf2->data(), 0, kSize);
   2130   EXPECT_EQ(0, ReadSparseData(entry, 8000, buf2.get(), kSize));
   2131 
   2132   EXPECT_EQ(500, ReadSparseData(entry, kSize, buf2.get(), kSize));
   2133   EXPECT_EQ(0, memcmp(buf2->data(), buf1->data() + kSize - 500, 500));
   2134   EXPECT_EQ(0, ReadSparseData(entry, 0, buf2.get(), kSize));
   2135 
   2136   // This read should not change anything.
   2137   EXPECT_EQ(96, ReadSparseData(entry, 24000, buf2.get(), kSize));
   2138   EXPECT_EQ(500, ReadSparseData(entry, kSize, buf2.get(), kSize));
   2139   EXPECT_EQ(0, ReadSparseData(entry, 99, buf2.get(), kSize));
   2140 
   2141   int rv;
   2142   int64 start;
   2143   net::TestCompletionCallback cb;
   2144   if (memory_only_ || simple_cache_mode_) {
   2145     rv = entry->GetAvailableRange(0, 600, &start, cb.callback());
   2146     EXPECT_EQ(100, cb.GetResult(rv));
   2147     EXPECT_EQ(500, start);
   2148   } else {
   2149     rv = entry->GetAvailableRange(0, 2048, &start, cb.callback());
   2150     EXPECT_EQ(1024, cb.GetResult(rv));
   2151     EXPECT_EQ(1024, start);
   2152   }
   2153   rv = entry->GetAvailableRange(kSize, kSize, &start, cb.callback());
   2154   EXPECT_EQ(500, cb.GetResult(rv));
   2155   EXPECT_EQ(kSize, start);
   2156   rv = entry->GetAvailableRange(20 * 1024, 10000, &start, cb.callback());
   2157   EXPECT_EQ(3616, cb.GetResult(rv));
   2158   EXPECT_EQ(20 * 1024, start);
   2159 
   2160   // 1. Query before a filled 1KB block.
   2161   // 2. Query within a filled 1KB block.
   2162   // 3. Query beyond a filled 1KB block.
   2163   if (memory_only_ || simple_cache_mode_) {
   2164     rv = entry->GetAvailableRange(19400, kSize, &start, cb.callback());
   2165     EXPECT_EQ(3496, cb.GetResult(rv));
   2166     EXPECT_EQ(20000, start);
   2167   } else {
   2168     rv = entry->GetAvailableRange(19400, kSize, &start, cb.callback());
   2169     EXPECT_EQ(3016, cb.GetResult(rv));
   2170     EXPECT_EQ(20480, start);
   2171   }
   2172   rv = entry->GetAvailableRange(3073, kSize, &start, cb.callback());
   2173   EXPECT_EQ(1523, cb.GetResult(rv));
   2174   EXPECT_EQ(3073, start);
   2175   rv = entry->GetAvailableRange(4600, kSize, &start, cb.callback());
   2176   EXPECT_EQ(0, cb.GetResult(rv));
   2177   EXPECT_EQ(4600, start);
   2178 
   2179   // Now make another write and verify that there is no hole in between.
   2180   EXPECT_EQ(kSize, WriteSparseData(entry, 500 + kSize, buf1.get(), kSize));
   2181   rv = entry->GetAvailableRange(1024, 10000, &start, cb.callback());
   2182   EXPECT_EQ(7 * 1024 + 500, cb.GetResult(rv));
   2183   EXPECT_EQ(1024, start);
   2184   EXPECT_EQ(kSize, ReadSparseData(entry, kSize, buf2.get(), kSize));
   2185   EXPECT_EQ(0, memcmp(buf2->data(), buf1->data() + kSize - 500, 500));
   2186   EXPECT_EQ(0, memcmp(buf2->data() + 500, buf1->data(), kSize - 500));
   2187 
   2188   entry->Close();
   2189 }
   2190 
   2191 TEST_F(DiskCacheEntryTest, PartialSparseEntry) {
   2192   InitCache();
   2193   PartialSparseEntry();
   2194 }
   2195 
   2196 TEST_F(DiskCacheEntryTest, MemoryPartialSparseEntry) {
   2197   SetMemoryOnlyMode();
   2198   InitCache();
   2199   PartialSparseEntry();
   2200 }
   2201 
   2202 // Tests that corrupt sparse children are removed automatically.
   2203 TEST_F(DiskCacheEntryTest, CleanupSparseEntry) {
   2204   InitCache();
   2205   std::string key("the first key");
   2206   disk_cache::Entry* entry;
   2207   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   2208 
   2209   const int kSize = 4 * 1024;
   2210   scoped_refptr<net::IOBuffer> buf1(new net::IOBuffer(kSize));
   2211   CacheTestFillBuffer(buf1->data(), kSize, false);
   2212 
   2213   const int k1Meg = 1024 * 1024;
   2214   EXPECT_EQ(kSize, WriteSparseData(entry, 8192, buf1.get(), kSize));
   2215   EXPECT_EQ(kSize, WriteSparseData(entry, k1Meg + 8192, buf1.get(), kSize));
   2216   EXPECT_EQ(kSize, WriteSparseData(entry, 2 * k1Meg + 8192, buf1.get(), kSize));
   2217   entry->Close();
   2218   EXPECT_EQ(4, cache_->GetEntryCount());
   2219 
   2220   void* iter = NULL;
   2221   int count = 0;
   2222   std::string child_key[2];
   2223   while (OpenNextEntry(&iter, &entry) == net::OK) {
   2224     ASSERT_TRUE(entry != NULL);
   2225     // Writing to an entry will alter the LRU list and invalidate the iterator.
   2226     if (entry->GetKey() != key && count < 2)
   2227       child_key[count++] = entry->GetKey();
   2228     entry->Close();
   2229   }
   2230   for (int i = 0; i < 2; i++) {
   2231     ASSERT_EQ(net::OK, OpenEntry(child_key[i], &entry));
   2232     // Overwrite the header's magic and signature.
   2233     EXPECT_EQ(12, WriteData(entry, 2, 0, buf1.get(), 12, false));
   2234     entry->Close();
   2235   }
   2236 
   2237   EXPECT_EQ(4, cache_->GetEntryCount());
   2238   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   2239 
   2240   // Two children should be gone. One while reading and one while writing.
   2241   EXPECT_EQ(0, ReadSparseData(entry, 2 * k1Meg + 8192, buf1.get(), kSize));
   2242   EXPECT_EQ(kSize, WriteSparseData(entry, k1Meg + 16384, buf1.get(), kSize));
   2243   EXPECT_EQ(0, ReadSparseData(entry, k1Meg + 8192, buf1.get(), kSize));
   2244 
   2245   // We never touched this one.
   2246   EXPECT_EQ(kSize, ReadSparseData(entry, 8192, buf1.get(), kSize));
   2247   entry->Close();
   2248 
   2249   // We re-created one of the corrupt children.
   2250   EXPECT_EQ(3, cache_->GetEntryCount());
   2251 }
   2252 
   2253 TEST_F(DiskCacheEntryTest, CancelSparseIO) {
   2254   UseCurrentThread();
   2255   InitCache();
   2256   std::string key("the first key");
   2257   disk_cache::Entry* entry;
   2258   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   2259 
   2260   const int kSize = 40 * 1024;
   2261   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
   2262   CacheTestFillBuffer(buf->data(), kSize, false);
   2263 
   2264   // This will open and write two "real" entries.
   2265   net::TestCompletionCallback cb1, cb2, cb3, cb4, cb5;
   2266   int rv = entry->WriteSparseData(
   2267       1024 * 1024 - 4096, buf.get(), kSize, cb1.callback());
   2268   EXPECT_EQ(net::ERR_IO_PENDING, rv);
   2269 
   2270   int64 offset = 0;
   2271   rv = entry->GetAvailableRange(offset, kSize, &offset, cb5.callback());
   2272   rv = cb5.GetResult(rv);
   2273   if (!cb1.have_result()) {
   2274     // We may or may not have finished writing to the entry. If we have not,
   2275     // we cannot start another operation at this time.
   2276     EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED, rv);
   2277   }
   2278 
   2279   // We cancel the pending operation, and register multiple notifications.
   2280   entry->CancelSparseIO();
   2281   EXPECT_EQ(net::ERR_IO_PENDING, entry->ReadyForSparseIO(cb2.callback()));
   2282   EXPECT_EQ(net::ERR_IO_PENDING, entry->ReadyForSparseIO(cb3.callback()));
   2283   entry->CancelSparseIO();  // Should be a no op at this point.
   2284   EXPECT_EQ(net::ERR_IO_PENDING, entry->ReadyForSparseIO(cb4.callback()));
   2285 
   2286   if (!cb1.have_result()) {
   2287     EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED,
   2288               entry->ReadSparseData(
   2289                   offset, buf.get(), kSize, net::CompletionCallback()));
   2290     EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED,
   2291               entry->WriteSparseData(
   2292                   offset, buf.get(), kSize, net::CompletionCallback()));
   2293   }
   2294 
   2295   // Now see if we receive all notifications. Note that we should not be able
   2296   // to write everything (unless the timing of the system is really weird).
   2297   rv = cb1.WaitForResult();
   2298   EXPECT_TRUE(rv == 4096 || rv == kSize);
   2299   EXPECT_EQ(net::OK, cb2.WaitForResult());
   2300   EXPECT_EQ(net::OK, cb3.WaitForResult());
   2301   EXPECT_EQ(net::OK, cb4.WaitForResult());
   2302 
   2303   rv = entry->GetAvailableRange(offset, kSize, &offset, cb5.callback());
   2304   EXPECT_EQ(0, cb5.GetResult(rv));
   2305   entry->Close();
   2306 }
   2307 
   2308 // Tests that we perform sanity checks on an entry's key. Note that there are
   2309 // other tests that exercise sanity checks by using saved corrupt files.
   2310 TEST_F(DiskCacheEntryTest, KeySanityCheck) {
   2311   UseCurrentThread();
   2312   InitCache();
   2313   std::string key("the first key");
   2314   disk_cache::Entry* entry;
   2315   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   2316 
   2317   disk_cache::EntryImpl* entry_impl =
   2318       static_cast<disk_cache::EntryImpl*>(entry);
   2319   disk_cache::EntryStore* store = entry_impl->entry()->Data();
   2320 
   2321   // We have reserved space for a short key (one block), let's say that the key
   2322   // takes more than one block, and remove the NULLs after the actual key.
   2323   store->key_len = 800;
   2324   memset(store->key + key.size(), 'k', sizeof(store->key) - key.size());
   2325   entry_impl->entry()->set_modified();
   2326   entry->Close();
   2327 
   2328   // We have a corrupt entry. Now reload it. We should NOT read beyond the
   2329   // allocated buffer here.
   2330   ASSERT_NE(net::OK, OpenEntry(key, &entry));
   2331   DisableIntegrityCheck();
   2332 }
   2333 
   2334 // The Simple Cache backend requires a few guarantees from the filesystem like
   2335 // atomic renaming of recently open files. Those guarantees are not provided in
   2336 // general on Windows.
   2337 #if defined(OS_POSIX)
   2338 
   2339 TEST_F(DiskCacheEntryTest, SimpleCacheInternalAsyncIO) {
   2340   SetSimpleCacheMode();
   2341   InitCache();
   2342   InternalAsyncIO();
   2343 }
   2344 
   2345 TEST_F(DiskCacheEntryTest, SimpleCacheExternalAsyncIO) {
   2346   SetSimpleCacheMode();
   2347   InitCache();
   2348   ExternalAsyncIO();
   2349 }
   2350 
   2351 TEST_F(DiskCacheEntryTest, SimpleCacheReleaseBuffer) {
   2352   SetSimpleCacheMode();
   2353   InitCache();
   2354   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
   2355     EXPECT_EQ(net::OK, DoomAllEntries());
   2356     ReleaseBuffer(i);
   2357   }
   2358 }
   2359 
   2360 TEST_F(DiskCacheEntryTest, SimpleCacheStreamAccess) {
   2361   SetSimpleCacheMode();
   2362   InitCache();
   2363   StreamAccess();
   2364 }
   2365 
   2366 TEST_F(DiskCacheEntryTest, SimpleCacheGetKey) {
   2367   SetSimpleCacheMode();
   2368   InitCache();
   2369   GetKey();
   2370 }
   2371 
   2372 TEST_F(DiskCacheEntryTest, SimpleCacheGetTimes) {
   2373   SetSimpleCacheMode();
   2374   InitCache();
   2375   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
   2376     EXPECT_EQ(net::OK, DoomAllEntries());
   2377     GetTimes(i);
   2378   }
   2379 }
   2380 
   2381 TEST_F(DiskCacheEntryTest, SimpleCacheGrowData) {
   2382   SetSimpleCacheMode();
   2383   InitCache();
   2384   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
   2385     EXPECT_EQ(net::OK, DoomAllEntries());
   2386     GrowData(i);
   2387   }
   2388 }
   2389 
   2390 TEST_F(DiskCacheEntryTest, SimpleCacheTruncateData) {
   2391   SetSimpleCacheMode();
   2392   InitCache();
   2393   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
   2394     EXPECT_EQ(net::OK, DoomAllEntries());
   2395     TruncateData(i);
   2396   }
   2397 }
   2398 
   2399 TEST_F(DiskCacheEntryTest, SimpleCacheZeroLengthIO) {
   2400   SetSimpleCacheMode();
   2401   InitCache();
   2402   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
   2403     EXPECT_EQ(net::OK, DoomAllEntries());
   2404     ZeroLengthIO(i);
   2405   }
   2406 }
   2407 
   2408 TEST_F(DiskCacheEntryTest, SimpleCacheSizeAtCreate) {
   2409   SetSimpleCacheMode();
   2410   InitCache();
   2411   SizeAtCreate();
   2412 }
   2413 
   2414 TEST_F(DiskCacheEntryTest, SimpleCacheReuseExternalEntry) {
   2415   SetSimpleCacheMode();
   2416   SetMaxSize(200 * 1024);
   2417   InitCache();
   2418   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
   2419     EXPECT_EQ(net::OK, DoomAllEntries());
   2420     ReuseEntry(20 * 1024, i);
   2421   }
   2422 }
   2423 
   2424 TEST_F(DiskCacheEntryTest, SimpleCacheReuseInternalEntry) {
   2425   SetSimpleCacheMode();
   2426   SetMaxSize(100 * 1024);
   2427   InitCache();
   2428   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
   2429     EXPECT_EQ(net::OK, DoomAllEntries());
   2430     ReuseEntry(10 * 1024, i);
   2431   }
   2432 }
   2433 
   2434 TEST_F(DiskCacheEntryTest, SimpleCacheSizeChanges) {
   2435   SetSimpleCacheMode();
   2436   InitCache();
   2437   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
   2438     EXPECT_EQ(net::OK, DoomAllEntries());
   2439     SizeChanges(i);
   2440   }
   2441 }
   2442 
   2443 TEST_F(DiskCacheEntryTest, SimpleCacheInvalidData) {
   2444   SetSimpleCacheMode();
   2445   InitCache();
   2446   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
   2447     EXPECT_EQ(net::OK, DoomAllEntries());
   2448     InvalidData(i);
   2449   }
   2450 }
   2451 
   2452 TEST_F(DiskCacheEntryTest, SimpleCacheReadWriteDestroyBuffer) {
   2453   // Proving that the test works well with optimistic operations enabled is
   2454   // subtle, instead run only in APP_CACHE mode to disable optimistic
   2455   // operations. Stream 0 always uses optimistic operations, so the test is not
   2456   // run on stream 0.
   2457   SetCacheType(net::APP_CACHE);
   2458   SetSimpleCacheMode();
   2459   InitCache();
   2460   for (int i = 1; i < disk_cache::kSimpleEntryStreamCount; ++i) {
   2461     EXPECT_EQ(net::OK, DoomAllEntries());
   2462     ReadWriteDestroyBuffer(i);
   2463   }
   2464 }
   2465 
   2466 TEST_F(DiskCacheEntryTest, SimpleCacheDoomEntry) {
   2467   SetSimpleCacheMode();
   2468   InitCache();
   2469   DoomNormalEntry();
   2470 }
   2471 
   2472 TEST_F(DiskCacheEntryTest, SimpleCacheDoomEntryNextToOpenEntry) {
   2473   SetSimpleCacheMode();
   2474   InitCache();
   2475   DoomEntryNextToOpenEntry();
   2476 }
   2477 
   2478 TEST_F(DiskCacheEntryTest, SimpleCacheDoomedEntry) {
   2479   SetSimpleCacheMode();
   2480   InitCache();
   2481   // Stream 2 is excluded because the implementation does not support writing to
   2482   // it on a doomed entry, if it was previously lazily omitted.
   2483   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount - 1; ++i) {
   2484     EXPECT_EQ(net::OK, DoomAllEntries());
   2485     DoomedEntry(i);
   2486   }
   2487 }
   2488 
   2489 // Creates an entry with corrupted last byte in stream 0.
   2490 // Requires SimpleCacheMode.
   2491 bool DiskCacheEntryTest::SimpleCacheMakeBadChecksumEntry(const std::string& key,
   2492                                                          int* data_size) {
   2493   disk_cache::Entry* entry = NULL;
   2494 
   2495   if (CreateEntry(key, &entry) != net::OK || !entry) {
   2496     LOG(ERROR) << "Could not create entry";
   2497     return false;
   2498   }
   2499 
   2500   const char data[] = "this is very good data";
   2501   const int kDataSize = arraysize(data);
   2502   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kDataSize));
   2503   base::strlcpy(buffer->data(), data, kDataSize);
   2504 
   2505   EXPECT_EQ(kDataSize, WriteData(entry, 1, 0, buffer.get(), kDataSize, false));
   2506   entry->Close();
   2507   entry = NULL;
   2508 
   2509   // Corrupt the last byte of the data.
   2510   base::FilePath entry_file0_path = cache_path_.AppendASCII(
   2511       disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0));
   2512   base::File entry_file0(entry_file0_path,
   2513                          base::File::FLAG_WRITE | base::File::FLAG_OPEN);
   2514   if (!entry_file0.IsValid())
   2515     return false;
   2516 
   2517   int64 file_offset =
   2518       sizeof(disk_cache::SimpleFileHeader) + key.size() + kDataSize - 2;
   2519   EXPECT_EQ(1, entry_file0.Write(file_offset, "X", 1));
   2520   *data_size = kDataSize;
   2521   return true;
   2522 }
   2523 
   2524 // Tests that the simple cache can detect entries that have bad data.
   2525 TEST_F(DiskCacheEntryTest, SimpleCacheBadChecksum) {
   2526   SetSimpleCacheMode();
   2527   InitCache();
   2528 
   2529   const char key[] = "the first key";
   2530   int size_unused;
   2531   ASSERT_TRUE(SimpleCacheMakeBadChecksumEntry(key, &size_unused));
   2532 
   2533   disk_cache::Entry* entry = NULL;
   2534 
   2535   // Open the entry.
   2536   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   2537   ScopedEntryPtr entry_closer(entry);
   2538 
   2539   const int kReadBufferSize = 200;
   2540   EXPECT_GE(kReadBufferSize, entry->GetDataSize(1));
   2541   scoped_refptr<net::IOBuffer> read_buffer(new net::IOBuffer(kReadBufferSize));
   2542   EXPECT_EQ(net::ERR_CACHE_CHECKSUM_MISMATCH,
   2543             ReadData(entry, 1, 0, read_buffer.get(), kReadBufferSize));
   2544 }
   2545 
   2546 // Tests that an entry that has had an IO error occur can still be Doomed().
   2547 TEST_F(DiskCacheEntryTest, SimpleCacheErrorThenDoom) {
   2548   SetSimpleCacheMode();
   2549   InitCache();
   2550 
   2551   const char key[] = "the first key";
   2552   int size_unused;
   2553   ASSERT_TRUE(SimpleCacheMakeBadChecksumEntry(key, &size_unused));
   2554 
   2555   disk_cache::Entry* entry = NULL;
   2556 
   2557   // Open the entry, forcing an IO error.
   2558   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   2559   ScopedEntryPtr entry_closer(entry);
   2560 
   2561   const int kReadBufferSize = 200;
   2562   EXPECT_GE(kReadBufferSize, entry->GetDataSize(1));
   2563   scoped_refptr<net::IOBuffer> read_buffer(new net::IOBuffer(kReadBufferSize));
   2564   EXPECT_EQ(net::ERR_CACHE_CHECKSUM_MISMATCH,
   2565             ReadData(entry, 1, 0, read_buffer.get(), kReadBufferSize));
   2566 
   2567   entry->Doom();  // Should not crash.
   2568 }
   2569 
   2570 bool TruncatePath(const base::FilePath& file_path, int64 length)  {
   2571   base::File file(file_path, base::File::FLAG_WRITE | base::File::FLAG_OPEN);
   2572   if (!file.IsValid())
   2573     return false;
   2574   return file.SetLength(length);
   2575 }
   2576 
   2577 TEST_F(DiskCacheEntryTest, SimpleCacheNoEOF) {
   2578   SetSimpleCacheMode();
   2579   InitCache();
   2580 
   2581   const char key[] = "the first key";
   2582 
   2583   disk_cache::Entry* entry = NULL;
   2584   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   2585   disk_cache::Entry* null = NULL;
   2586   EXPECT_NE(null, entry);
   2587   entry->Close();
   2588   entry = NULL;
   2589 
   2590   // Force the entry to flush to disk, so subsequent platform file operations
   2591   // succed.
   2592   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   2593   entry->Close();
   2594   entry = NULL;
   2595 
   2596   // Truncate the file such that the length isn't sufficient to have an EOF
   2597   // record.
   2598   int kTruncationBytes = -implicit_cast<int>(sizeof(disk_cache::SimpleFileEOF));
   2599   const base::FilePath entry_path = cache_path_.AppendASCII(
   2600       disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0));
   2601   const int64 invalid_size =
   2602       disk_cache::simple_util::GetFileSizeFromKeyAndDataSize(key,
   2603                                                              kTruncationBytes);
   2604   EXPECT_TRUE(TruncatePath(entry_path, invalid_size));
   2605   EXPECT_EQ(net::ERR_FAILED, OpenEntry(key, &entry));
   2606   DisableIntegrityCheck();
   2607 }
   2608 
   2609 TEST_F(DiskCacheEntryTest, SimpleCacheNonOptimisticOperationsBasic) {
   2610   // Test sequence:
   2611   // Create, Write, Read, Close.
   2612   SetCacheType(net::APP_CACHE);  // APP_CACHE doesn't use optimistic operations.
   2613   SetSimpleCacheMode();
   2614   InitCache();
   2615   disk_cache::Entry* const null_entry = NULL;
   2616 
   2617   disk_cache::Entry* entry = NULL;
   2618   EXPECT_EQ(net::OK, CreateEntry("my key", &entry));
   2619   ASSERT_NE(null_entry, entry);
   2620   ScopedEntryPtr entry_closer(entry);
   2621 
   2622   const int kBufferSize = 10;
   2623   scoped_refptr<net::IOBufferWithSize> write_buffer(
   2624       new net::IOBufferWithSize(kBufferSize));
   2625   CacheTestFillBuffer(write_buffer->data(), write_buffer->size(), false);
   2626   EXPECT_EQ(
   2627       write_buffer->size(),
   2628       WriteData(entry, 1, 0, write_buffer.get(), write_buffer->size(), false));
   2629 
   2630   scoped_refptr<net::IOBufferWithSize> read_buffer(
   2631       new net::IOBufferWithSize(kBufferSize));
   2632   EXPECT_EQ(read_buffer->size(),
   2633             ReadData(entry, 1, 0, read_buffer.get(), read_buffer->size()));
   2634 }
   2635 
   2636 TEST_F(DiskCacheEntryTest, SimpleCacheNonOptimisticOperationsDontBlock) {
   2637   // Test sequence:
   2638   // Create, Write, Close.
   2639   SetCacheType(net::APP_CACHE);  // APP_CACHE doesn't use optimistic operations.
   2640   SetSimpleCacheMode();
   2641   InitCache();
   2642   disk_cache::Entry* const null_entry = NULL;
   2643 
   2644   MessageLoopHelper helper;
   2645   CallbackTest create_callback(&helper, false);
   2646 
   2647   int expected_callback_runs = 0;
   2648   const int kBufferSize = 10;
   2649   scoped_refptr<net::IOBufferWithSize> write_buffer(
   2650       new net::IOBufferWithSize(kBufferSize));
   2651 
   2652   disk_cache::Entry* entry = NULL;
   2653   EXPECT_EQ(net::OK, CreateEntry("my key", &entry));
   2654   ASSERT_NE(null_entry, entry);
   2655   ScopedEntryPtr entry_closer(entry);
   2656 
   2657   CacheTestFillBuffer(write_buffer->data(), write_buffer->size(), false);
   2658   CallbackTest write_callback(&helper, false);
   2659   int ret = entry->WriteData(
   2660       1,
   2661       0,
   2662       write_buffer.get(),
   2663       write_buffer->size(),
   2664       base::Bind(&CallbackTest::Run, base::Unretained(&write_callback)),
   2665       false);
   2666   ASSERT_EQ(net::ERR_IO_PENDING, ret);
   2667   helper.WaitUntilCacheIoFinished(++expected_callback_runs);
   2668 }
   2669 
   2670 TEST_F(DiskCacheEntryTest,
   2671        SimpleCacheNonOptimisticOperationsBasicsWithoutWaiting) {
   2672   // Test sequence:
   2673   // Create, Write, Read, Close.
   2674   SetCacheType(net::APP_CACHE);  // APP_CACHE doesn't use optimistic operations.
   2675   SetSimpleCacheMode();
   2676   InitCache();
   2677   disk_cache::Entry* const null_entry = NULL;
   2678   MessageLoopHelper helper;
   2679 
   2680   disk_cache::Entry* entry = NULL;
   2681   // Note that |entry| is only set once CreateEntry() completed which is why we
   2682   // have to wait (i.e. use the helper CreateEntry() function).
   2683   EXPECT_EQ(net::OK, CreateEntry("my key", &entry));
   2684   ASSERT_NE(null_entry, entry);
   2685   ScopedEntryPtr entry_closer(entry);
   2686 
   2687   const int kBufferSize = 10;
   2688   scoped_refptr<net::IOBufferWithSize> write_buffer(
   2689       new net::IOBufferWithSize(kBufferSize));
   2690   CacheTestFillBuffer(write_buffer->data(), write_buffer->size(), false);
   2691   CallbackTest write_callback(&helper, false);
   2692   int ret = entry->WriteData(
   2693       1,
   2694       0,
   2695       write_buffer.get(),
   2696       write_buffer->size(),
   2697       base::Bind(&CallbackTest::Run, base::Unretained(&write_callback)),
   2698       false);
   2699   EXPECT_EQ(net::ERR_IO_PENDING, ret);
   2700   int expected_callback_runs = 1;
   2701 
   2702   scoped_refptr<net::IOBufferWithSize> read_buffer(
   2703       new net::IOBufferWithSize(kBufferSize));
   2704   CallbackTest read_callback(&helper, false);
   2705   ret = entry->ReadData(
   2706       1,
   2707       0,
   2708       read_buffer.get(),
   2709       read_buffer->size(),
   2710       base::Bind(&CallbackTest::Run, base::Unretained(&read_callback)));
   2711   EXPECT_EQ(net::ERR_IO_PENDING, ret);
   2712   ++expected_callback_runs;
   2713 
   2714   helper.WaitUntilCacheIoFinished(expected_callback_runs);
   2715   ASSERT_EQ(read_buffer->size(), write_buffer->size());
   2716   EXPECT_EQ(
   2717       0,
   2718       memcmp(read_buffer->data(), write_buffer->data(), read_buffer->size()));
   2719 }
   2720 
   2721 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic) {
   2722   // Test sequence:
   2723   // Create, Write, Read, Write, Read, Close.
   2724   SetSimpleCacheMode();
   2725   InitCache();
   2726   disk_cache::Entry* null = NULL;
   2727   const char key[] = "the first key";
   2728 
   2729   MessageLoopHelper helper;
   2730   CallbackTest callback1(&helper, false);
   2731   CallbackTest callback2(&helper, false);
   2732   CallbackTest callback3(&helper, false);
   2733   CallbackTest callback4(&helper, false);
   2734   CallbackTest callback5(&helper, false);
   2735 
   2736   int expected = 0;
   2737   const int kSize1 = 10;
   2738   const int kSize2 = 20;
   2739   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
   2740   scoped_refptr<net::IOBuffer> buffer1_read(new net::IOBuffer(kSize1));
   2741   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2));
   2742   scoped_refptr<net::IOBuffer> buffer2_read(new net::IOBuffer(kSize2));
   2743   CacheTestFillBuffer(buffer1->data(), kSize1, false);
   2744   CacheTestFillBuffer(buffer2->data(), kSize2, false);
   2745 
   2746   disk_cache::Entry* entry = NULL;
   2747   // Create is optimistic, must return OK.
   2748   ASSERT_EQ(net::OK,
   2749             cache_->CreateEntry(key, &entry,
   2750                                 base::Bind(&CallbackTest::Run,
   2751                                            base::Unretained(&callback1))));
   2752   EXPECT_NE(null, entry);
   2753   ScopedEntryPtr entry_closer(entry);
   2754 
   2755   // This write may or may not be optimistic (it depends if the previous
   2756   // optimistic create already finished by the time we call the write here).
   2757   int ret = entry->WriteData(
   2758       1,
   2759       0,
   2760       buffer1.get(),
   2761       kSize1,
   2762       base::Bind(&CallbackTest::Run, base::Unretained(&callback2)),
   2763       false);
   2764   EXPECT_TRUE(kSize1 == ret || net::ERR_IO_PENDING == ret);
   2765   if (net::ERR_IO_PENDING == ret)
   2766     expected++;
   2767 
   2768   // This Read must not be optimistic, since we don't support that yet.
   2769   EXPECT_EQ(net::ERR_IO_PENDING,
   2770             entry->ReadData(
   2771                 1,
   2772                 0,
   2773                 buffer1_read.get(),
   2774                 kSize1,
   2775                 base::Bind(&CallbackTest::Run, base::Unretained(&callback3))));
   2776   expected++;
   2777   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
   2778   EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read->data(), kSize1));
   2779 
   2780   // At this point after waiting, the pending operations queue on the entry
   2781   // should be empty, so the next Write operation must run as optimistic.
   2782   EXPECT_EQ(kSize2,
   2783             entry->WriteData(
   2784                 1,
   2785                 0,
   2786                 buffer2.get(),
   2787                 kSize2,
   2788                 base::Bind(&CallbackTest::Run, base::Unretained(&callback4)),
   2789                 false));
   2790 
   2791   // Lets do another read so we block until both the write and the read
   2792   // operation finishes and we can then test for HasOneRef() below.
   2793   EXPECT_EQ(net::ERR_IO_PENDING,
   2794             entry->ReadData(
   2795                 1,
   2796                 0,
   2797                 buffer2_read.get(),
   2798                 kSize2,
   2799                 base::Bind(&CallbackTest::Run, base::Unretained(&callback5))));
   2800   expected++;
   2801 
   2802   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
   2803   EXPECT_EQ(0, memcmp(buffer2->data(), buffer2_read->data(), kSize2));
   2804 
   2805   // Check that we are not leaking.
   2806   EXPECT_NE(entry, null);
   2807   EXPECT_TRUE(
   2808       static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
   2809 }
   2810 
   2811 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic2) {
   2812   // Test sequence:
   2813   // Create, Open, Close, Close.
   2814   SetSimpleCacheMode();
   2815   InitCache();
   2816   disk_cache::Entry* null = NULL;
   2817   const char key[] = "the first key";
   2818 
   2819   MessageLoopHelper helper;
   2820   CallbackTest callback1(&helper, false);
   2821   CallbackTest callback2(&helper, false);
   2822 
   2823   disk_cache::Entry* entry = NULL;
   2824   ASSERT_EQ(net::OK,
   2825             cache_->CreateEntry(key, &entry,
   2826                                 base::Bind(&CallbackTest::Run,
   2827                                            base::Unretained(&callback1))));
   2828   EXPECT_NE(null, entry);
   2829   ScopedEntryPtr entry_closer(entry);
   2830 
   2831   disk_cache::Entry* entry2 = NULL;
   2832   ASSERT_EQ(net::ERR_IO_PENDING,
   2833             cache_->OpenEntry(key, &entry2,
   2834                               base::Bind(&CallbackTest::Run,
   2835                                          base::Unretained(&callback2))));
   2836   ASSERT_TRUE(helper.WaitUntilCacheIoFinished(1));
   2837 
   2838   EXPECT_NE(null, entry2);
   2839   EXPECT_EQ(entry, entry2);
   2840 
   2841   // We have to call close twice, since we called create and open above.
   2842   entry->Close();
   2843 
   2844   // Check that we are not leaking.
   2845   EXPECT_TRUE(
   2846       static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
   2847 }
   2848 
   2849 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic3) {
   2850   // Test sequence:
   2851   // Create, Close, Open, Close.
   2852   SetSimpleCacheMode();
   2853   InitCache();
   2854   disk_cache::Entry* null = NULL;
   2855   const char key[] = "the first key";
   2856 
   2857   disk_cache::Entry* entry = NULL;
   2858   ASSERT_EQ(net::OK,
   2859             cache_->CreateEntry(key, &entry, net::CompletionCallback()));
   2860   EXPECT_NE(null, entry);
   2861   entry->Close();
   2862 
   2863   net::TestCompletionCallback cb;
   2864   disk_cache::Entry* entry2 = NULL;
   2865   ASSERT_EQ(net::ERR_IO_PENDING,
   2866             cache_->OpenEntry(key, &entry2, cb.callback()));
   2867   ASSERT_EQ(net::OK, cb.GetResult(net::ERR_IO_PENDING));
   2868   ScopedEntryPtr entry_closer(entry2);
   2869 
   2870   EXPECT_NE(null, entry2);
   2871   EXPECT_EQ(entry, entry2);
   2872 
   2873   // Check that we are not leaking.
   2874   EXPECT_TRUE(
   2875       static_cast<disk_cache::SimpleEntryImpl*>(entry2)->HasOneRef());
   2876 }
   2877 
   2878 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic4) {
   2879   // Test sequence:
   2880   // Create, Close, Write, Open, Open, Close, Write, Read, Close.
   2881   SetSimpleCacheMode();
   2882   InitCache();
   2883   disk_cache::Entry* null = NULL;
   2884   const char key[] = "the first key";
   2885 
   2886   net::TestCompletionCallback cb;
   2887   const int kSize1 = 10;
   2888   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
   2889   CacheTestFillBuffer(buffer1->data(), kSize1, false);
   2890   disk_cache::Entry* entry = NULL;
   2891 
   2892   ASSERT_EQ(net::OK,
   2893             cache_->CreateEntry(key, &entry, net::CompletionCallback()));
   2894   EXPECT_NE(null, entry);
   2895   entry->Close();
   2896 
   2897   // Lets do a Write so we block until both the Close and the Write
   2898   // operation finishes. Write must fail since we are writing in a closed entry.
   2899   EXPECT_EQ(
   2900       net::ERR_IO_PENDING,
   2901       entry->WriteData(1, 0, buffer1.get(), kSize1, cb.callback(), false));
   2902   EXPECT_EQ(net::ERR_FAILED, cb.GetResult(net::ERR_IO_PENDING));
   2903 
   2904   // Finish running the pending tasks so that we fully complete the close
   2905   // operation and destroy the entry object.
   2906   base::MessageLoop::current()->RunUntilIdle();
   2907 
   2908   // At this point the |entry| must have been destroyed, and called
   2909   // RemoveSelfFromBackend().
   2910   disk_cache::Entry* entry2 = NULL;
   2911   ASSERT_EQ(net::ERR_IO_PENDING,
   2912             cache_->OpenEntry(key, &entry2, cb.callback()));
   2913   ASSERT_EQ(net::OK, cb.GetResult(net::ERR_IO_PENDING));
   2914   EXPECT_NE(null, entry2);
   2915 
   2916   disk_cache::Entry* entry3 = NULL;
   2917   ASSERT_EQ(net::ERR_IO_PENDING,
   2918             cache_->OpenEntry(key, &entry3, cb.callback()));
   2919   ASSERT_EQ(net::OK, cb.GetResult(net::ERR_IO_PENDING));
   2920   EXPECT_NE(null, entry3);
   2921   EXPECT_EQ(entry2, entry3);
   2922   entry3->Close();
   2923 
   2924   // The previous Close doesn't actually closes the entry since we opened it
   2925   // twice, so the next Write operation must succeed and it must be able to
   2926   // perform it optimistically, since there is no operation running on this
   2927   // entry.
   2928   EXPECT_EQ(kSize1,
   2929             entry2->WriteData(
   2930                 1, 0, buffer1.get(), kSize1, net::CompletionCallback(), false));
   2931 
   2932   // Lets do another read so we block until both the write and the read
   2933   // operation finishes and we can then test for HasOneRef() below.
   2934   EXPECT_EQ(net::ERR_IO_PENDING,
   2935             entry2->ReadData(1, 0, buffer1.get(), kSize1, cb.callback()));
   2936   EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING));
   2937 
   2938   // Check that we are not leaking.
   2939   EXPECT_TRUE(
   2940       static_cast<disk_cache::SimpleEntryImpl*>(entry2)->HasOneRef());
   2941   entry2->Close();
   2942 }
   2943 
   2944 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic5) {
   2945   // Test sequence:
   2946   // Create, Doom, Write, Read, Close.
   2947   SetSimpleCacheMode();
   2948   InitCache();
   2949   disk_cache::Entry* null = NULL;
   2950   const char key[] = "the first key";
   2951 
   2952   net::TestCompletionCallback cb;
   2953   const int kSize1 = 10;
   2954   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
   2955   CacheTestFillBuffer(buffer1->data(), kSize1, false);
   2956   disk_cache::Entry* entry = NULL;
   2957 
   2958   ASSERT_EQ(net::OK,
   2959             cache_->CreateEntry(key, &entry, net::CompletionCallback()));
   2960   EXPECT_NE(null, entry);
   2961   ScopedEntryPtr entry_closer(entry);
   2962   entry->Doom();
   2963 
   2964   EXPECT_EQ(
   2965       net::ERR_IO_PENDING,
   2966       entry->WriteData(1, 0, buffer1.get(), kSize1, cb.callback(), false));
   2967   EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING));
   2968 
   2969   EXPECT_EQ(net::ERR_IO_PENDING,
   2970             entry->ReadData(1, 0, buffer1.get(), kSize1, cb.callback()));
   2971   EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING));
   2972 
   2973   // Check that we are not leaking.
   2974   EXPECT_TRUE(
   2975       static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
   2976 }
   2977 
   2978 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic6) {
   2979   // Test sequence:
   2980   // Create, Write, Doom, Doom, Read, Doom, Close.
   2981   SetSimpleCacheMode();
   2982   InitCache();
   2983   disk_cache::Entry* null = NULL;
   2984   const char key[] = "the first key";
   2985 
   2986   net::TestCompletionCallback cb;
   2987   const int kSize1 = 10;
   2988   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
   2989   scoped_refptr<net::IOBuffer> buffer1_read(new net::IOBuffer(kSize1));
   2990   CacheTestFillBuffer(buffer1->data(), kSize1, false);
   2991   disk_cache::Entry* entry = NULL;
   2992 
   2993   ASSERT_EQ(net::OK,
   2994             cache_->CreateEntry(key, &entry, net::CompletionCallback()));
   2995   EXPECT_NE(null, entry);
   2996   ScopedEntryPtr entry_closer(entry);
   2997 
   2998   EXPECT_EQ(
   2999       net::ERR_IO_PENDING,
   3000       entry->WriteData(1, 0, buffer1.get(), kSize1, cb.callback(), false));
   3001   EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING));
   3002 
   3003   entry->Doom();
   3004   entry->Doom();
   3005 
   3006   // This Read must not be optimistic, since we don't support that yet.
   3007   EXPECT_EQ(net::ERR_IO_PENDING,
   3008             entry->ReadData(1, 0, buffer1_read.get(), kSize1, cb.callback()));
   3009   EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING));
   3010   EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read->data(), kSize1));
   3011 
   3012   entry->Doom();
   3013 }
   3014 
   3015 // Confirm that IO buffers are not referenced by the Simple Cache after a write
   3016 // completes.
   3017 TEST_F(DiskCacheEntryTest, SimpleCacheOptimisticWriteReleases) {
   3018   SetSimpleCacheMode();
   3019   InitCache();
   3020 
   3021   const char key[] = "the first key";
   3022   disk_cache::Entry* entry = NULL;
   3023 
   3024   // First, an optimistic create.
   3025   ASSERT_EQ(net::OK,
   3026             cache_->CreateEntry(key, &entry, net::CompletionCallback()));
   3027   ASSERT_TRUE(entry);
   3028   ScopedEntryPtr entry_closer(entry);
   3029 
   3030   const int kWriteSize = 512;
   3031   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kWriteSize));
   3032   EXPECT_TRUE(buffer1->HasOneRef());
   3033   CacheTestFillBuffer(buffer1->data(), kWriteSize, false);
   3034 
   3035   // An optimistic write happens only when there is an empty queue of pending
   3036   // operations. To ensure the queue is empty, we issue a write and wait until
   3037   // it completes.
   3038   EXPECT_EQ(kWriteSize,
   3039             WriteData(entry, 1, 0, buffer1.get(), kWriteSize, false));
   3040   EXPECT_TRUE(buffer1->HasOneRef());
   3041 
   3042   // Finally, we should perform an optimistic write and confirm that all
   3043   // references to the IO buffer have been released.
   3044   EXPECT_EQ(
   3045       kWriteSize,
   3046       entry->WriteData(
   3047           1, 0, buffer1.get(), kWriteSize, net::CompletionCallback(), false));
   3048   EXPECT_TRUE(buffer1->HasOneRef());
   3049 }
   3050 
   3051 TEST_F(DiskCacheEntryTest, SimpleCacheCreateDoomRace) {
   3052   // Test sequence:
   3053   // Create, Doom, Write, Close, Check files are not on disk anymore.
   3054   SetSimpleCacheMode();
   3055   InitCache();
   3056   disk_cache::Entry* null = NULL;
   3057   const char key[] = "the first key";
   3058 
   3059   net::TestCompletionCallback cb;
   3060   const int kSize1 = 10;
   3061   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
   3062   CacheTestFillBuffer(buffer1->data(), kSize1, false);
   3063   disk_cache::Entry* entry = NULL;
   3064 
   3065   ASSERT_EQ(net::OK,
   3066             cache_->CreateEntry(key, &entry, net::CompletionCallback()));
   3067   EXPECT_NE(null, entry);
   3068 
   3069   EXPECT_EQ(net::ERR_IO_PENDING, cache_->DoomEntry(key, cb.callback()));
   3070   EXPECT_EQ(net::OK, cb.GetResult(net::ERR_IO_PENDING));
   3071 
   3072   EXPECT_EQ(
   3073       kSize1,
   3074       entry->WriteData(0, 0, buffer1.get(), kSize1, cb.callback(), false));
   3075 
   3076   entry->Close();
   3077 
   3078   // Finish running the pending tasks so that we fully complete the close
   3079   // operation and destroy the entry object.
   3080   base::MessageLoop::current()->RunUntilIdle();
   3081 
   3082   for (int i = 0; i < disk_cache::kSimpleEntryFileCount; ++i) {
   3083     base::FilePath entry_file_path = cache_path_.AppendASCII(
   3084         disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, i));
   3085     base::File::Info info;
   3086     EXPECT_FALSE(base::GetFileInfo(entry_file_path, &info));
   3087   }
   3088 }
   3089 
   3090 TEST_F(DiskCacheEntryTest, SimpleCacheDoomCreateRace) {
   3091   // This test runs as APP_CACHE to make operations more synchronous. Test
   3092   // sequence:
   3093   // Create, Doom, Create.
   3094   SetCacheType(net::APP_CACHE);
   3095   SetSimpleCacheMode();
   3096   InitCache();
   3097   disk_cache::Entry* null = NULL;
   3098   const char key[] = "the first key";
   3099 
   3100   net::TestCompletionCallback create_callback;
   3101 
   3102   disk_cache::Entry* entry1 = NULL;
   3103   ASSERT_EQ(net::OK,
   3104             create_callback.GetResult(
   3105                 cache_->CreateEntry(key, &entry1, create_callback.callback())));
   3106   ScopedEntryPtr entry1_closer(entry1);
   3107   EXPECT_NE(null, entry1);
   3108 
   3109   net::TestCompletionCallback doom_callback;
   3110   EXPECT_EQ(net::ERR_IO_PENDING,
   3111             cache_->DoomEntry(key, doom_callback.callback()));
   3112 
   3113   disk_cache::Entry* entry2 = NULL;
   3114   ASSERT_EQ(net::OK,
   3115             create_callback.GetResult(
   3116                 cache_->CreateEntry(key, &entry2, create_callback.callback())));
   3117   ScopedEntryPtr entry2_closer(entry2);
   3118   EXPECT_EQ(net::OK, doom_callback.GetResult(net::ERR_IO_PENDING));
   3119 }
   3120 
   3121 TEST_F(DiskCacheEntryTest, SimpleCacheDoomDoom) {
   3122   // Test sequence:
   3123   // Create, Doom, Create, Doom (1st entry), Open.
   3124   SetSimpleCacheMode();
   3125   InitCache();
   3126   disk_cache::Entry* null = NULL;
   3127 
   3128   const char key[] = "the first key";
   3129 
   3130   disk_cache::Entry* entry1 = NULL;
   3131   ASSERT_EQ(net::OK, CreateEntry(key, &entry1));
   3132   ScopedEntryPtr entry1_closer(entry1);
   3133   EXPECT_NE(null, entry1);
   3134 
   3135   EXPECT_EQ(net::OK, DoomEntry(key));
   3136 
   3137   disk_cache::Entry* entry2 = NULL;
   3138   ASSERT_EQ(net::OK, CreateEntry(key, &entry2));
   3139   ScopedEntryPtr entry2_closer(entry2);
   3140   EXPECT_NE(null, entry2);
   3141 
   3142   // Redundantly dooming entry1 should not delete entry2.
   3143   disk_cache::SimpleEntryImpl* simple_entry1 =
   3144       static_cast<disk_cache::SimpleEntryImpl*>(entry1);
   3145   net::TestCompletionCallback cb;
   3146   EXPECT_EQ(net::OK,
   3147             cb.GetResult(simple_entry1->DoomEntry(cb.callback())));
   3148 
   3149   disk_cache::Entry* entry3 = NULL;
   3150   ASSERT_EQ(net::OK, OpenEntry(key, &entry3));
   3151   ScopedEntryPtr entry3_closer(entry3);
   3152   EXPECT_NE(null, entry3);
   3153 }
   3154 
   3155 TEST_F(DiskCacheEntryTest, SimpleCacheDoomCreateDoom) {
   3156   // Test sequence:
   3157   // Create, Doom, Create, Doom.
   3158   SetSimpleCacheMode();
   3159   InitCache();
   3160 
   3161   disk_cache::Entry* null = NULL;
   3162 
   3163   const char key[] = "the first key";
   3164 
   3165   disk_cache::Entry* entry1 = NULL;
   3166   ASSERT_EQ(net::OK, CreateEntry(key, &entry1));
   3167   ScopedEntryPtr entry1_closer(entry1);
   3168   EXPECT_NE(null, entry1);
   3169 
   3170   entry1->Doom();
   3171 
   3172   disk_cache::Entry* entry2 = NULL;
   3173   ASSERT_EQ(net::OK, CreateEntry(key, &entry2));
   3174   ScopedEntryPtr entry2_closer(entry2);
   3175   EXPECT_NE(null, entry2);
   3176 
   3177   entry2->Doom();
   3178 
   3179   // This test passes if it doesn't crash.
   3180 }
   3181 
   3182 // Checks that an optimistic Create would fail later on a racing Open.
   3183 TEST_F(DiskCacheEntryTest, SimpleCacheOptimisticCreateFailsOnOpen) {
   3184   SetSimpleCacheMode();
   3185   InitCache();
   3186 
   3187   // Create a corrupt file in place of a future entry. Optimistic create should
   3188   // initially succeed, but realize later that creation failed.
   3189   const std::string key = "the key";
   3190   net::TestCompletionCallback cb;
   3191   disk_cache::Entry* entry = NULL;
   3192   disk_cache::Entry* entry2 = NULL;
   3193 
   3194   EXPECT_TRUE(disk_cache::simple_util::CreateCorruptFileForTests(
   3195       key, cache_path_));
   3196   EXPECT_EQ(net::OK, cache_->CreateEntry(key, &entry, cb.callback()));
   3197   ASSERT_TRUE(entry);
   3198   ScopedEntryPtr entry_closer(entry);
   3199   ASSERT_NE(net::OK, OpenEntry(key, &entry2));
   3200 
   3201   // Check that we are not leaking.
   3202   EXPECT_TRUE(
   3203       static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
   3204 
   3205   DisableIntegrityCheck();
   3206 }
   3207 
   3208 // Tests that old entries are evicted while new entries remain in the index.
   3209 // This test relies on non-mandatory properties of the simple Cache Backend:
   3210 // LRU eviction, specific values of high-watermark and low-watermark etc.
   3211 // When changing the eviction algorithm, the test will have to be re-engineered.
   3212 TEST_F(DiskCacheEntryTest, SimpleCacheEvictOldEntries) {
   3213   const int kMaxSize = 200 * 1024;
   3214   const int kWriteSize = kMaxSize / 10;
   3215   const int kNumExtraEntries = 12;
   3216   SetSimpleCacheMode();
   3217   SetMaxSize(kMaxSize);
   3218   InitCache();
   3219 
   3220   std::string key1("the first key");
   3221   disk_cache::Entry* entry;
   3222   ASSERT_EQ(net::OK, CreateEntry(key1, &entry));
   3223   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kWriteSize));
   3224   CacheTestFillBuffer(buffer->data(), kWriteSize, false);
   3225   EXPECT_EQ(kWriteSize,
   3226             WriteData(entry, 1, 0, buffer.get(), kWriteSize, false));
   3227   entry->Close();
   3228   AddDelay();
   3229 
   3230   std::string key2("the key prefix");
   3231   for (int i = 0; i < kNumExtraEntries; i++) {
   3232     if (i == kNumExtraEntries - 2) {
   3233       // Create a distinct timestamp for the last two entries. These entries
   3234       // will be checked for outliving the eviction.
   3235       AddDelay();
   3236     }
   3237     ASSERT_EQ(net::OK, CreateEntry(key2 + base::StringPrintf("%d", i), &entry));
   3238     ScopedEntryPtr entry_closer(entry);
   3239     EXPECT_EQ(kWriteSize,
   3240               WriteData(entry, 1, 0, buffer.get(), kWriteSize, false));
   3241   }
   3242 
   3243   // TODO(pasko): Find a way to wait for the eviction task(s) to finish by using
   3244   // the internal knowledge about |SimpleBackendImpl|.
   3245   ASSERT_NE(net::OK, OpenEntry(key1, &entry))
   3246       << "Should have evicted the old entry";
   3247   for (int i = 0; i < 2; i++) {
   3248     int entry_no = kNumExtraEntries - i - 1;
   3249     // Generally there is no guarantee that at this point the backround eviction
   3250     // is finished. We are testing the positive case, i.e. when the eviction
   3251     // never reaches this entry, should be non-flaky.
   3252     ASSERT_EQ(net::OK, OpenEntry(key2 + base::StringPrintf("%d", entry_no),
   3253                                  &entry))
   3254         << "Should not have evicted fresh entry " << entry_no;
   3255     entry->Close();
   3256   }
   3257 }
   3258 
   3259 // Tests that if a read and a following in-flight truncate are both in progress
   3260 // simultaniously that they both can occur successfully. See
   3261 // http://crbug.com/239223
   3262 TEST_F(DiskCacheEntryTest, SimpleCacheInFlightTruncate)  {
   3263   SetSimpleCacheMode();
   3264   InitCache();
   3265 
   3266   const char key[] = "the first key";
   3267 
   3268   const int kBufferSize = 1024;
   3269   scoped_refptr<net::IOBuffer> write_buffer(new net::IOBuffer(kBufferSize));
   3270   CacheTestFillBuffer(write_buffer->data(), kBufferSize, false);
   3271 
   3272   disk_cache::Entry* entry = NULL;
   3273   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   3274 
   3275   EXPECT_EQ(kBufferSize,
   3276             WriteData(entry, 1, 0, write_buffer.get(), kBufferSize, false));
   3277   entry->Close();
   3278   entry = NULL;
   3279 
   3280   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   3281   ScopedEntryPtr entry_closer(entry);
   3282 
   3283   MessageLoopHelper helper;
   3284   int expected = 0;
   3285 
   3286   // Make a short read.
   3287   const int kReadBufferSize = 512;
   3288   scoped_refptr<net::IOBuffer> read_buffer(new net::IOBuffer(kReadBufferSize));
   3289   CallbackTest read_callback(&helper, false);
   3290   EXPECT_EQ(net::ERR_IO_PENDING,
   3291             entry->ReadData(1,
   3292                             0,
   3293                             read_buffer.get(),
   3294                             kReadBufferSize,
   3295                             base::Bind(&CallbackTest::Run,
   3296                                        base::Unretained(&read_callback))));
   3297   ++expected;
   3298 
   3299   // Truncate the entry to the length of that read.
   3300   scoped_refptr<net::IOBuffer>
   3301       truncate_buffer(new net::IOBuffer(kReadBufferSize));
   3302   CacheTestFillBuffer(truncate_buffer->data(), kReadBufferSize, false);
   3303   CallbackTest truncate_callback(&helper, false);
   3304   EXPECT_EQ(net::ERR_IO_PENDING,
   3305             entry->WriteData(1,
   3306                              0,
   3307                              truncate_buffer.get(),
   3308                              kReadBufferSize,
   3309                              base::Bind(&CallbackTest::Run,
   3310                                         base::Unretained(&truncate_callback)),
   3311                              true));
   3312   ++expected;
   3313 
   3314   // Wait for both the read and truncation to finish, and confirm that both
   3315   // succeeded.
   3316   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
   3317   EXPECT_EQ(kReadBufferSize, read_callback.last_result());
   3318   EXPECT_EQ(kReadBufferSize, truncate_callback.last_result());
   3319   EXPECT_EQ(0,
   3320             memcmp(write_buffer->data(), read_buffer->data(), kReadBufferSize));
   3321 }
   3322 
   3323 // Tests that if a write and a read dependant on it are both in flight
   3324 // simultaneiously that they both can complete successfully without erroneous
   3325 // early returns. See http://crbug.com/239223
   3326 TEST_F(DiskCacheEntryTest, SimpleCacheInFlightRead) {
   3327   SetSimpleCacheMode();
   3328   InitCache();
   3329 
   3330   const char key[] = "the first key";
   3331   disk_cache::Entry* entry = NULL;
   3332   ASSERT_EQ(net::OK,
   3333             cache_->CreateEntry(key, &entry, net::CompletionCallback()));
   3334   ScopedEntryPtr entry_closer(entry);
   3335 
   3336   const int kBufferSize = 1024;
   3337   scoped_refptr<net::IOBuffer> write_buffer(new net::IOBuffer(kBufferSize));
   3338   CacheTestFillBuffer(write_buffer->data(), kBufferSize, false);
   3339 
   3340   MessageLoopHelper helper;
   3341   int expected = 0;
   3342 
   3343   CallbackTest write_callback(&helper, false);
   3344   EXPECT_EQ(net::ERR_IO_PENDING,
   3345             entry->WriteData(1,
   3346                              0,
   3347                              write_buffer.get(),
   3348                              kBufferSize,
   3349                              base::Bind(&CallbackTest::Run,
   3350                                         base::Unretained(&write_callback)),
   3351                              true));
   3352   ++expected;
   3353 
   3354   scoped_refptr<net::IOBuffer> read_buffer(new net::IOBuffer(kBufferSize));
   3355   CallbackTest read_callback(&helper, false);
   3356   EXPECT_EQ(net::ERR_IO_PENDING,
   3357             entry->ReadData(1,
   3358                             0,
   3359                             read_buffer.get(),
   3360                             kBufferSize,
   3361                             base::Bind(&CallbackTest::Run,
   3362                                        base::Unretained(&read_callback))));
   3363   ++expected;
   3364 
   3365   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
   3366   EXPECT_EQ(kBufferSize, write_callback.last_result());
   3367   EXPECT_EQ(kBufferSize, read_callback.last_result());
   3368   EXPECT_EQ(0, memcmp(write_buffer->data(), read_buffer->data(), kBufferSize));
   3369 }
   3370 
   3371 TEST_F(DiskCacheEntryTest, SimpleCacheOpenCreateRaceWithNoIndex) {
   3372   SetSimpleCacheMode();
   3373   DisableSimpleCacheWaitForIndex();
   3374   DisableIntegrityCheck();
   3375   InitCache();
   3376 
   3377   // Assume the index is not initialized, which is likely, since we are blocking
   3378   // the IO thread from executing the index finalization step.
   3379   disk_cache::Entry* entry1;
   3380   net::TestCompletionCallback cb1;
   3381   disk_cache::Entry* entry2;
   3382   net::TestCompletionCallback cb2;
   3383   int rv1 = cache_->OpenEntry("key", &entry1, cb1.callback());
   3384   int rv2 = cache_->CreateEntry("key", &entry2, cb2.callback());
   3385 
   3386   EXPECT_EQ(net::ERR_FAILED, cb1.GetResult(rv1));
   3387   ASSERT_EQ(net::OK, cb2.GetResult(rv2));
   3388   entry2->Close();
   3389 }
   3390 
   3391 // Checks that reading two entries simultaneously does not discard a CRC check.
   3392 // TODO(pasko): make it work with Simple Cache.
   3393 TEST_F(DiskCacheEntryTest, DISABLED_SimpleCacheMultipleReadersCheckCRC) {
   3394   SetSimpleCacheMode();
   3395   InitCache();
   3396 
   3397   const char key[] = "key";
   3398 
   3399   int size;
   3400   ASSERT_TRUE(SimpleCacheMakeBadChecksumEntry(key, &size));
   3401 
   3402   scoped_refptr<net::IOBuffer> read_buffer1(new net::IOBuffer(size));
   3403   scoped_refptr<net::IOBuffer> read_buffer2(new net::IOBuffer(size));
   3404 
   3405   // Advance the first reader a little.
   3406   disk_cache::Entry* entry = NULL;
   3407   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   3408   EXPECT_EQ(1, ReadData(entry, 0, 0, read_buffer1.get(), 1));
   3409 
   3410   // Make the second reader pass the point where the first one is, and close.
   3411   disk_cache::Entry* entry2 = NULL;
   3412   EXPECT_EQ(net::OK, OpenEntry(key, &entry2));
   3413   EXPECT_EQ(1, ReadData(entry2, 0, 0, read_buffer2.get(), 1));
   3414   EXPECT_EQ(1, ReadData(entry2, 0, 1, read_buffer2.get(), 1));
   3415   entry2->Close();
   3416 
   3417   // Read the data till the end should produce an error.
   3418   EXPECT_GT(0, ReadData(entry, 0, 1, read_buffer1.get(), size));
   3419   entry->Close();
   3420   DisableIntegrityCheck();
   3421 }
   3422 
   3423 // Checking one more scenario of overlapped reading of a bad entry.
   3424 // Differs from the |SimpleCacheMultipleReadersCheckCRC| only by the order of
   3425 // last two reads.
   3426 TEST_F(DiskCacheEntryTest, SimpleCacheMultipleReadersCheckCRC2) {
   3427   SetSimpleCacheMode();
   3428   InitCache();
   3429 
   3430   const char key[] = "key";
   3431   int size;
   3432   ASSERT_TRUE(SimpleCacheMakeBadChecksumEntry(key, &size));
   3433 
   3434   scoped_refptr<net::IOBuffer> read_buffer1(new net::IOBuffer(size));
   3435   scoped_refptr<net::IOBuffer> read_buffer2(new net::IOBuffer(size));
   3436 
   3437   // Advance the first reader a little.
   3438   disk_cache::Entry* entry = NULL;
   3439   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   3440   ScopedEntryPtr entry_closer(entry);
   3441   EXPECT_EQ(1, ReadData(entry, 1, 0, read_buffer1.get(), 1));
   3442 
   3443   // Advance the 2nd reader by the same amount.
   3444   disk_cache::Entry* entry2 = NULL;
   3445   EXPECT_EQ(net::OK, OpenEntry(key, &entry2));
   3446   ScopedEntryPtr entry2_closer(entry2);
   3447   EXPECT_EQ(1, ReadData(entry2, 1, 0, read_buffer2.get(), 1));
   3448 
   3449   // Continue reading 1st.
   3450   EXPECT_GT(0, ReadData(entry, 1, 1, read_buffer1.get(), size));
   3451 
   3452   // This read should fail as well because we have previous read failures.
   3453   EXPECT_GT(0, ReadData(entry2, 1, 1, read_buffer2.get(), 1));
   3454   DisableIntegrityCheck();
   3455 }
   3456 
   3457 // Test if we can sequentially read each subset of the data until all the data
   3458 // is read, then the CRC is calculated correctly and the reads are successful.
   3459 TEST_F(DiskCacheEntryTest, SimpleCacheReadCombineCRC) {
   3460   // Test sequence:
   3461   // Create, Write, Read (first half of data), Read (second half of data),
   3462   // Close.
   3463   SetSimpleCacheMode();
   3464   InitCache();
   3465   disk_cache::Entry* null = NULL;
   3466   const char key[] = "the first key";
   3467 
   3468   const int kHalfSize = 200;
   3469   const int kSize = 2 * kHalfSize;
   3470   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
   3471   CacheTestFillBuffer(buffer1->data(), kSize, false);
   3472   disk_cache::Entry* entry = NULL;
   3473 
   3474   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   3475   EXPECT_NE(null, entry);
   3476 
   3477   EXPECT_EQ(kSize, WriteData(entry, 1, 0, buffer1.get(), kSize, false));
   3478   entry->Close();
   3479 
   3480   disk_cache::Entry* entry2 = NULL;
   3481   ASSERT_EQ(net::OK, OpenEntry(key, &entry2));
   3482   EXPECT_EQ(entry, entry2);
   3483 
   3484   // Read the first half of the data.
   3485   int offset = 0;
   3486   int buf_len = kHalfSize;
   3487   scoped_refptr<net::IOBuffer> buffer1_read1(new net::IOBuffer(buf_len));
   3488   EXPECT_EQ(buf_len, ReadData(entry2, 1, offset, buffer1_read1.get(), buf_len));
   3489   EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read1->data(), buf_len));
   3490 
   3491   // Read the second half of the data.
   3492   offset = buf_len;
   3493   buf_len = kHalfSize;
   3494   scoped_refptr<net::IOBuffer> buffer1_read2(new net::IOBuffer(buf_len));
   3495   EXPECT_EQ(buf_len, ReadData(entry2, 1, offset, buffer1_read2.get(), buf_len));
   3496   char* buffer1_data = buffer1->data() + offset;
   3497   EXPECT_EQ(0, memcmp(buffer1_data, buffer1_read2->data(), buf_len));
   3498 
   3499   // Check that we are not leaking.
   3500   EXPECT_NE(entry, null);
   3501   EXPECT_TRUE(
   3502       static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
   3503   entry->Close();
   3504   entry = NULL;
   3505 }
   3506 
   3507 // Test if we can write the data not in sequence and read correctly. In
   3508 // this case the CRC will not be present.
   3509 TEST_F(DiskCacheEntryTest, SimpleCacheNonSequentialWrite) {
   3510   // Test sequence:
   3511   // Create, Write (second half of data), Write (first half of data), Read,
   3512   // Close.
   3513   SetSimpleCacheMode();
   3514   InitCache();
   3515   disk_cache::Entry* null = NULL;
   3516   const char key[] = "the first key";
   3517 
   3518   const int kHalfSize = 200;
   3519   const int kSize = 2 * kHalfSize;
   3520   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
   3521   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize));
   3522   CacheTestFillBuffer(buffer1->data(), kSize, false);
   3523   char* buffer1_data = buffer1->data() + kHalfSize;
   3524   memcpy(buffer2->data(), buffer1_data, kHalfSize);
   3525 
   3526   disk_cache::Entry* entry = NULL;
   3527   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   3528   entry->Close();
   3529   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
   3530     ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   3531     EXPECT_NE(null, entry);
   3532 
   3533     int offset = kHalfSize;
   3534     int buf_len = kHalfSize;
   3535 
   3536     EXPECT_EQ(buf_len,
   3537               WriteData(entry, i, offset, buffer2.get(), buf_len, false));
   3538     offset = 0;
   3539     buf_len = kHalfSize;
   3540     EXPECT_EQ(buf_len,
   3541               WriteData(entry, i, offset, buffer1.get(), buf_len, false));
   3542     entry->Close();
   3543 
   3544     ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   3545 
   3546     scoped_refptr<net::IOBuffer> buffer1_read1(new net::IOBuffer(kSize));
   3547     EXPECT_EQ(kSize, ReadData(entry, i, 0, buffer1_read1.get(), kSize));
   3548     EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read1->data(), kSize));
   3549     // Check that we are not leaking.
   3550     ASSERT_NE(entry, null);
   3551     EXPECT_TRUE(static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
   3552     entry->Close();
   3553   }
   3554 }
   3555 
   3556 // Test that changing stream1 size does not affect stream0 (stream0 and stream1
   3557 // are stored in the same file in Simple Cache).
   3558 TEST_F(DiskCacheEntryTest, SimpleCacheStream1SizeChanges) {
   3559   SetSimpleCacheMode();
   3560   InitCache();
   3561   disk_cache::Entry* entry = NULL;
   3562   const char key[] = "the key";
   3563   const int kSize = 100;
   3564   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
   3565   scoped_refptr<net::IOBuffer> buffer_read(new net::IOBuffer(kSize));
   3566   CacheTestFillBuffer(buffer->data(), kSize, false);
   3567 
   3568   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   3569   EXPECT_TRUE(entry);
   3570 
   3571   // Write something into stream0.
   3572   EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, false));
   3573   EXPECT_EQ(kSize, ReadData(entry, 0, 0, buffer_read.get(), kSize));
   3574   EXPECT_EQ(0, memcmp(buffer->data(), buffer_read->data(), kSize));
   3575   entry->Close();
   3576 
   3577   // Extend stream1.
   3578   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   3579   int stream1_size = 100;
   3580   EXPECT_EQ(0, WriteData(entry, 1, stream1_size, buffer.get(), 0, false));
   3581   EXPECT_EQ(stream1_size, entry->GetDataSize(1));
   3582   entry->Close();
   3583 
   3584   // Check that stream0 data has not been modified and that the EOF record for
   3585   // stream 0 contains a crc.
   3586   // The entry needs to be reopened before checking the crc: Open will perform
   3587   // the synchronization with the previous Close. This ensures the EOF records
   3588   // have been written to disk before we attempt to read them independently.
   3589   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   3590   base::FilePath entry_file0_path = cache_path_.AppendASCII(
   3591       disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0));
   3592   base::File entry_file0(entry_file0_path,
   3593                          base::File::FLAG_READ | base::File::FLAG_OPEN);
   3594   ASSERT_TRUE(entry_file0.IsValid());
   3595 
   3596   int data_size[disk_cache::kSimpleEntryStreamCount] = {kSize, stream1_size, 0};
   3597   int sparse_data_size = 0;
   3598   disk_cache::SimpleEntryStat entry_stat(
   3599       base::Time::Now(), base::Time::Now(), data_size, sparse_data_size);
   3600   int eof_offset = entry_stat.GetEOFOffsetInFile(key, 0);
   3601   disk_cache::SimpleFileEOF eof_record;
   3602   ASSERT_EQ(static_cast<int>(sizeof(eof_record)),
   3603             entry_file0.Read(eof_offset, reinterpret_cast<char*>(&eof_record),
   3604                              sizeof(eof_record)));
   3605   EXPECT_EQ(disk_cache::kSimpleFinalMagicNumber, eof_record.final_magic_number);
   3606   EXPECT_TRUE((eof_record.flags & disk_cache::SimpleFileEOF::FLAG_HAS_CRC32) ==
   3607               disk_cache::SimpleFileEOF::FLAG_HAS_CRC32);
   3608 
   3609   buffer_read = new net::IOBuffer(kSize);
   3610   EXPECT_EQ(kSize, ReadData(entry, 0, 0, buffer_read.get(), kSize));
   3611   EXPECT_EQ(0, memcmp(buffer->data(), buffer_read->data(), kSize));
   3612 
   3613   // Shrink stream1.
   3614   stream1_size = 50;
   3615   EXPECT_EQ(0, WriteData(entry, 1, stream1_size, buffer.get(), 0, true));
   3616   EXPECT_EQ(stream1_size, entry->GetDataSize(1));
   3617   entry->Close();
   3618 
   3619   // Check that stream0 data has not been modified.
   3620   buffer_read = new net::IOBuffer(kSize);
   3621   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   3622   EXPECT_EQ(kSize, ReadData(entry, 0, 0, buffer_read.get(), kSize));
   3623   EXPECT_EQ(0, memcmp(buffer->data(), buffer_read->data(), kSize));
   3624   entry->Close();
   3625   entry = NULL;
   3626 }
   3627 
   3628 // Test that writing within the range for which the crc has already been
   3629 // computed will properly invalidate the computed crc.
   3630 TEST_F(DiskCacheEntryTest, SimpleCacheCRCRewrite) {
   3631   // Test sequence:
   3632   // Create, Write (big data), Write (small data in the middle), Close.
   3633   // Open, Read (all), Close.
   3634   SetSimpleCacheMode();
   3635   InitCache();
   3636   disk_cache::Entry* null = NULL;
   3637   const char key[] = "the first key";
   3638 
   3639   const int kHalfSize = 200;
   3640   const int kSize = 2 * kHalfSize;
   3641   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
   3642   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kHalfSize));
   3643   CacheTestFillBuffer(buffer1->data(), kSize, false);
   3644   CacheTestFillBuffer(buffer2->data(), kHalfSize, false);
   3645 
   3646   disk_cache::Entry* entry = NULL;
   3647   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   3648   EXPECT_NE(null, entry);
   3649   entry->Close();
   3650 
   3651   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
   3652     ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   3653     int offset = 0;
   3654     int buf_len = kSize;
   3655 
   3656     EXPECT_EQ(buf_len,
   3657               WriteData(entry, i, offset, buffer1.get(), buf_len, false));
   3658     offset = kHalfSize;
   3659     buf_len = kHalfSize;
   3660     EXPECT_EQ(buf_len,
   3661               WriteData(entry, i, offset, buffer2.get(), buf_len, false));
   3662     entry->Close();
   3663 
   3664     ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   3665 
   3666     scoped_refptr<net::IOBuffer> buffer1_read1(new net::IOBuffer(kSize));
   3667     EXPECT_EQ(kSize, ReadData(entry, i, 0, buffer1_read1.get(), kSize));
   3668     EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read1->data(), kHalfSize));
   3669     EXPECT_EQ(
   3670         0,
   3671         memcmp(buffer2->data(), buffer1_read1->data() + kHalfSize, kHalfSize));
   3672 
   3673     entry->Close();
   3674   }
   3675 }
   3676 
   3677 bool DiskCacheEntryTest::SimpleCacheThirdStreamFileExists(const char* key) {
   3678   int third_stream_file_index =
   3679       disk_cache::simple_util::GetFileIndexFromStreamIndex(2);
   3680   base::FilePath third_stream_file_path = cache_path_.AppendASCII(
   3681       disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(
   3682           key, third_stream_file_index));
   3683   return PathExists(third_stream_file_path);
   3684 }
   3685 
   3686 void DiskCacheEntryTest::SyncDoomEntry(const char* key) {
   3687   net::TestCompletionCallback callback;
   3688   cache_->DoomEntry(key, callback.callback());
   3689   callback.WaitForResult();
   3690 }
   3691 
   3692 // Check that a newly-created entry with no third-stream writes omits the
   3693 // third stream file.
   3694 TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream1) {
   3695   SetSimpleCacheMode();
   3696   InitCache();
   3697 
   3698   const char key[] = "key";
   3699 
   3700   disk_cache::Entry* entry;
   3701 
   3702   // Create entry and close without writing: third stream file should be
   3703   // omitted, since the stream is empty.
   3704   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   3705   entry->Close();
   3706   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
   3707 
   3708   SyncDoomEntry(key);
   3709   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
   3710 }
   3711 
   3712 // Check that a newly-created entry with only a single zero-offset, zero-length
   3713 // write omits the third stream file.
   3714 TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream2) {
   3715   SetSimpleCacheMode();
   3716   InitCache();
   3717 
   3718   const int kHalfSize = 8;
   3719   const int kSize = kHalfSize * 2;
   3720   const char key[] = "key";
   3721   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
   3722   CacheTestFillBuffer(buffer->data(), kHalfSize, false);
   3723 
   3724   disk_cache::Entry* entry;
   3725 
   3726   // Create entry, write empty buffer to third stream, and close: third stream
   3727   // should still be omitted, since the entry ignores writes that don't modify
   3728   // data or change the length.
   3729   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   3730   EXPECT_EQ(0, WriteData(entry, 2, 0, buffer, 0, true));
   3731   entry->Close();
   3732   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
   3733 
   3734   SyncDoomEntry(key);
   3735   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
   3736 }
   3737 
   3738 // Check that we can read back data written to the third stream.
   3739 TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream3) {
   3740   SetSimpleCacheMode();
   3741   InitCache();
   3742 
   3743   const int kHalfSize = 8;
   3744   const int kSize = kHalfSize * 2;
   3745   const char key[] = "key";
   3746   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
   3747   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize));
   3748   CacheTestFillBuffer(buffer1->data(), kHalfSize, false);
   3749 
   3750   disk_cache::Entry* entry;
   3751 
   3752   // Create entry, write data to third stream, and close: third stream should
   3753   // not be omitted, since it contains data.  Re-open entry and ensure there
   3754   // are that many bytes in the third stream.
   3755   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   3756   EXPECT_EQ(kHalfSize, WriteData(entry, 2, 0, buffer1, kHalfSize, true));
   3757   entry->Close();
   3758   EXPECT_TRUE(SimpleCacheThirdStreamFileExists(key));
   3759 
   3760   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   3761   EXPECT_EQ(kHalfSize, ReadData(entry, 2, 0, buffer2, kSize));
   3762   EXPECT_EQ(0, memcmp(buffer1->data(), buffer2->data(), kHalfSize));
   3763   entry->Close();
   3764   EXPECT_TRUE(SimpleCacheThirdStreamFileExists(key));
   3765 
   3766   SyncDoomEntry(key);
   3767   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
   3768 }
   3769 
   3770 // Check that we remove the third stream file upon opening an entry and finding
   3771 // the third stream empty.  (This is the upgrade path for entries written
   3772 // before the third stream was optional.)
   3773 TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream4) {
   3774   SetSimpleCacheMode();
   3775   InitCache();
   3776 
   3777   const int kHalfSize = 8;
   3778   const int kSize = kHalfSize * 2;
   3779   const char key[] = "key";
   3780   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
   3781   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize));
   3782   CacheTestFillBuffer(buffer1->data(), kHalfSize, false);
   3783 
   3784   disk_cache::Entry* entry;
   3785 
   3786   // Create entry, write data to third stream, truncate third stream back to
   3787   // empty, and close: third stream will not initially be omitted, since entry
   3788   // creates the file when the first significant write comes in, and only
   3789   // removes it on open if it is empty.  Reopen, ensure that the file is
   3790   // deleted, and that there's no data in the third stream.
   3791   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   3792   EXPECT_EQ(kHalfSize, WriteData(entry, 2, 0, buffer1, kHalfSize, true));
   3793   EXPECT_EQ(0, WriteData(entry, 2, 0, buffer1, 0, true));
   3794   entry->Close();
   3795   EXPECT_TRUE(SimpleCacheThirdStreamFileExists(key));
   3796 
   3797   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   3798   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
   3799   EXPECT_EQ(0, ReadData(entry, 2, 0, buffer2, kSize));
   3800   entry->Close();
   3801   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
   3802 
   3803   SyncDoomEntry(key);
   3804   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
   3805 }
   3806 
   3807 // Check that we don't accidentally create the third stream file once the entry
   3808 // has been doomed.
   3809 TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream5) {
   3810   SetSimpleCacheMode();
   3811   InitCache();
   3812 
   3813   const int kHalfSize = 8;
   3814   const int kSize = kHalfSize * 2;
   3815   const char key[] = "key";
   3816   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
   3817   CacheTestFillBuffer(buffer->data(), kHalfSize, false);
   3818 
   3819   disk_cache::Entry* entry;
   3820 
   3821   // Create entry, doom entry, write data to third stream, and close: third
   3822   // stream should not exist.  (Note: We don't care if the write fails, just
   3823   // that it doesn't cause the file to be created on disk.)
   3824   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   3825   entry->Doom();
   3826   WriteData(entry, 2, 0, buffer, kHalfSize, true);
   3827   entry->Close();
   3828   EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key));
   3829 }
   3830 
   3831 // There could be a race between Doom and an optimistic write.
   3832 TEST_F(DiskCacheEntryTest, SimpleCacheDoomOptimisticWritesRace) {
   3833   // Test sequence:
   3834   // Create, first Write, second Write, Close.
   3835   // Open, Close.
   3836   SetSimpleCacheMode();
   3837   InitCache();
   3838   disk_cache::Entry* null = NULL;
   3839   const char key[] = "the first key";
   3840 
   3841   const int kSize = 200;
   3842   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
   3843   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize));
   3844   CacheTestFillBuffer(buffer1->data(), kSize, false);
   3845   CacheTestFillBuffer(buffer2->data(), kSize, false);
   3846 
   3847   // The race only happens on stream 1 and stream 2.
   3848   for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) {
   3849     ASSERT_EQ(net::OK, DoomAllEntries());
   3850     disk_cache::Entry* entry = NULL;
   3851 
   3852     ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   3853     EXPECT_NE(null, entry);
   3854     entry->Close();
   3855     entry = NULL;
   3856 
   3857     ASSERT_EQ(net::OK, DoomAllEntries());
   3858     ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   3859     EXPECT_NE(null, entry);
   3860 
   3861     int offset = 0;
   3862     int buf_len = kSize;
   3863     // This write should not be optimistic (since create is).
   3864     EXPECT_EQ(buf_len,
   3865               WriteData(entry, i, offset, buffer1.get(), buf_len, false));
   3866 
   3867     offset = kSize;
   3868     // This write should be optimistic.
   3869     EXPECT_EQ(buf_len,
   3870               WriteData(entry, i, offset, buffer2.get(), buf_len, false));
   3871     entry->Close();
   3872 
   3873     ASSERT_EQ(net::OK, OpenEntry(key, &entry));
   3874     EXPECT_NE(null, entry);
   3875 
   3876     entry->Close();
   3877     entry = NULL;
   3878   }
   3879 }
   3880 
   3881 TEST_F(DiskCacheEntryTest, SimpleCacheBasicSparseIO) {
   3882   SetSimpleCacheMode();
   3883   InitCache();
   3884   BasicSparseIO();
   3885 }
   3886 
   3887 TEST_F(DiskCacheEntryTest, SimpleCacheHugeSparseIO) {
   3888   SetSimpleCacheMode();
   3889   InitCache();
   3890   HugeSparseIO();
   3891 }
   3892 
   3893 TEST_F(DiskCacheEntryTest, SimpleCacheGetAvailableRange) {
   3894   SetSimpleCacheMode();
   3895   InitCache();
   3896   GetAvailableRange();
   3897 }
   3898 
   3899 TEST_F(DiskCacheEntryTest, DISABLED_SimpleCacheCouldBeSparse) {
   3900   SetSimpleCacheMode();
   3901   InitCache();
   3902   CouldBeSparse();
   3903 }
   3904 
   3905 TEST_F(DiskCacheEntryTest, SimpleCacheUpdateSparseEntry) {
   3906   SetSimpleCacheMode();
   3907   InitCache();
   3908   UpdateSparseEntry();
   3909 }
   3910 
   3911 TEST_F(DiskCacheEntryTest, SimpleCacheDoomSparseEntry) {
   3912   SetSimpleCacheMode();
   3913   InitCache();
   3914   DoomSparseEntry();
   3915 }
   3916 
   3917 TEST_F(DiskCacheEntryTest, SimpleCachePartialSparseEntry) {
   3918   SetSimpleCacheMode();
   3919   InitCache();
   3920   PartialSparseEntry();
   3921 }
   3922 
   3923 TEST_F(DiskCacheEntryTest, SimpleCacheTruncateLargeSparseFile) {
   3924   const int kSize = 1024;
   3925 
   3926   SetSimpleCacheMode();
   3927   // An entry is allowed sparse data 1/10 the size of the cache, so this size
   3928   // allows for one |kSize|-sized range plus overhead, but not two ranges.
   3929   SetMaxSize(kSize * 15);
   3930   InitCache();
   3931 
   3932   const char key[] = "key";
   3933   disk_cache::Entry* null = NULL;
   3934   disk_cache::Entry* entry;
   3935   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
   3936   EXPECT_NE(null, entry);
   3937 
   3938   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
   3939   CacheTestFillBuffer(buffer->data(), kSize, false);
   3940   net::TestCompletionCallback callback;
   3941   int ret;
   3942 
   3943   // Verify initial conditions.
   3944   ret = entry->ReadSparseData(0, buffer, kSize, callback.callback());
   3945   EXPECT_EQ(0, callback.GetResult(ret));
   3946 
   3947   ret = entry->ReadSparseData(kSize, buffer, kSize, callback.callback());
   3948   EXPECT_EQ(0, callback.GetResult(ret));
   3949 
   3950   // Write a range and make sure it reads back.
   3951   ret = entry->WriteSparseData(0, buffer, kSize, callback.callback());
   3952   EXPECT_EQ(kSize, callback.GetResult(ret));
   3953 
   3954   ret = entry->ReadSparseData(0, buffer, kSize, callback.callback());
   3955   EXPECT_EQ(kSize, callback.GetResult(ret));
   3956 
   3957   // Write another range and make sure it reads back.
   3958   ret = entry->WriteSparseData(kSize, buffer, kSize, callback.callback());
   3959   EXPECT_EQ(kSize, callback.GetResult(ret));
   3960 
   3961   ret = entry->ReadSparseData(kSize, buffer, kSize, callback.callback());
   3962   EXPECT_EQ(kSize, callback.GetResult(ret));
   3963 
   3964   // Make sure the first range was removed when the second was written.
   3965   ret = entry->ReadSparseData(0, buffer, kSize, callback.callback());
   3966   EXPECT_EQ(0, callback.GetResult(ret));
   3967 
   3968   entry->Close();
   3969 }
   3970 
   3971 #endif  // defined(OS_POSIX)
   3972