Home | History | Annotate | Download | only in disk_cache
      1 // Copyright (c) 2006-2009 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/platform_thread.h"
      7 #include "base/timer.h"
      8 #include "base/string_util.h"
      9 #include "net/base/io_buffer.h"
     10 #include "net/base/net_errors.h"
     11 #include "net/base/test_completion_callback.h"
     12 #include "net/disk_cache/disk_cache_test_base.h"
     13 #include "net/disk_cache/disk_cache_test_util.h"
     14 #include "net/disk_cache/entry_impl.h"
     15 #include "net/disk_cache/mem_entry_impl.h"
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 
     18 using base::Time;
     19 
     20 extern volatile int g_cache_tests_received;
     21 extern volatile bool g_cache_tests_error;
     22 
     23 // Tests that can run with different types of caches.
     24 class DiskCacheEntryTest : public DiskCacheTestWithCache {
     25  protected:
     26   void InternalSyncIO();
     27   void InternalAsyncIO();
     28   void ExternalSyncIO();
     29   void ExternalAsyncIO();
     30   void StreamAccess();
     31   void GetKey();
     32   void GrowData();
     33   void TruncateData();
     34   void ZeroLengthIO();
     35   void ReuseEntry(int size);
     36   void InvalidData();
     37   void DoomEntry();
     38   void DoomedEntry();
     39   void BasicSparseIO(bool async);
     40   void HugeSparseIO(bool async);
     41   void GetAvailableRange();
     42   void DoomSparseEntry();
     43   void PartialSparseEntry();
     44 };
     45 
     46 void DiskCacheEntryTest::InternalSyncIO() {
     47   disk_cache::Entry *entry1 = NULL;
     48   ASSERT_TRUE(cache_->CreateEntry("the first key", &entry1));
     49   ASSERT_TRUE(NULL != entry1);
     50 
     51   const int kSize1 = 10;
     52   scoped_refptr<net::IOBuffer> buffer1 = new net::IOBuffer(kSize1);
     53   CacheTestFillBuffer(buffer1->data(), kSize1, false);
     54   EXPECT_EQ(0, entry1->ReadData(0, 0, buffer1, kSize1, NULL));
     55   base::strlcpy(buffer1->data(), "the data", kSize1);
     56   EXPECT_EQ(10, entry1->WriteData(0, 0, buffer1, kSize1, NULL, false));
     57   memset(buffer1->data(), 0, kSize1);
     58   EXPECT_EQ(10, entry1->ReadData(0, 0, buffer1, kSize1, NULL));
     59   EXPECT_STREQ("the data", buffer1->data());
     60 
     61   const int kSize2 = 5000;
     62   const int kSize3 = 10000;
     63   scoped_refptr<net::IOBuffer> buffer2 = new net::IOBuffer(kSize2);
     64   scoped_refptr<net::IOBuffer> buffer3 = new net::IOBuffer(kSize3);
     65   memset(buffer3->data(), 0, kSize3);
     66   CacheTestFillBuffer(buffer2->data(), kSize2, false);
     67   base::strlcpy(buffer2->data(), "The really big data goes here", kSize2);
     68   EXPECT_EQ(5000, entry1->WriteData(1, 1500, buffer2, kSize2, NULL, false));
     69   memset(buffer2->data(), 0, kSize2);
     70   EXPECT_EQ(4989, entry1->ReadData(1, 1511, buffer2, kSize2, NULL));
     71   EXPECT_STREQ("big data goes here", buffer2->data());
     72   EXPECT_EQ(5000, entry1->ReadData(1, 0, buffer2, kSize2, NULL));
     73   EXPECT_EQ(0, memcmp(buffer2->data(), buffer3->data(), 1500));
     74   EXPECT_EQ(1500, entry1->ReadData(1, 5000, buffer2, kSize2, NULL));
     75 
     76   EXPECT_EQ(0, entry1->ReadData(1, 6500, buffer2, kSize2, NULL));
     77   EXPECT_EQ(6500, entry1->ReadData(1, 0, buffer3, kSize3, NULL));
     78   EXPECT_EQ(8192, entry1->WriteData(1, 0, buffer3, 8192, NULL, false));
     79   EXPECT_EQ(8192, entry1->ReadData(1, 0, buffer3, kSize3, NULL));
     80   EXPECT_EQ(8192, entry1->GetDataSize(1));
     81 
     82   entry1->Doom();
     83   entry1->Close();
     84   EXPECT_EQ(0, cache_->GetEntryCount());
     85 }
     86 
     87 TEST_F(DiskCacheEntryTest, InternalSyncIO) {
     88   InitCache();
     89   InternalSyncIO();
     90 }
     91 
     92 TEST_F(DiskCacheEntryTest, MemoryOnlyInternalSyncIO) {
     93   SetMemoryOnlyMode();
     94   InitCache();
     95   InternalSyncIO();
     96 }
     97 
     98 void DiskCacheEntryTest::InternalAsyncIO() {
     99   disk_cache::Entry *entry1 = NULL;
    100   ASSERT_TRUE(cache_->CreateEntry("the first key", &entry1));
    101   ASSERT_TRUE(NULL != entry1);
    102 
    103   // Avoid using internal buffers for the test. We have to write something to
    104   // the entry and close it so that we flush the internal buffer to disk. After
    105   // that, IO operations will be really hitting the disk. We don't care about
    106   // the content, so just extending the entry is enough (all extensions zero-
    107   // fill any holes).
    108   EXPECT_EQ(0, entry1->WriteData(0, 15 * 1024, NULL, 0, NULL, false));
    109   EXPECT_EQ(0, entry1->WriteData(1, 15 * 1024, NULL, 0, NULL, false));
    110   entry1->Close();
    111   ASSERT_TRUE(cache_->OpenEntry("the first key", &entry1));
    112 
    113   // Let's verify that each IO goes to the right callback object.
    114   CallbackTest callback1(false);
    115   CallbackTest callback2(false);
    116   CallbackTest callback3(false);
    117   CallbackTest callback4(false);
    118   CallbackTest callback5(false);
    119   CallbackTest callback6(false);
    120   CallbackTest callback7(false);
    121   CallbackTest callback8(false);
    122   CallbackTest callback9(false);
    123   CallbackTest callback10(false);
    124   CallbackTest callback11(false);
    125   CallbackTest callback12(false);
    126   CallbackTest callback13(false);
    127 
    128   g_cache_tests_error = false;
    129   g_cache_tests_received = 0;
    130 
    131   MessageLoopHelper helper;
    132 
    133   const int kSize1 = 10;
    134   const int kSize2 = 5000;
    135   const int kSize3 = 10000;
    136   scoped_refptr<net::IOBuffer> buffer1 = new net::IOBuffer(kSize1);
    137   scoped_refptr<net::IOBuffer> buffer2 = new net::IOBuffer(kSize2);
    138   scoped_refptr<net::IOBuffer> buffer3 = new net::IOBuffer(kSize3);
    139   CacheTestFillBuffer(buffer1->data(), kSize1, false);
    140   CacheTestFillBuffer(buffer2->data(), kSize2, false);
    141   CacheTestFillBuffer(buffer3->data(), kSize3, false);
    142 
    143   EXPECT_EQ(0, entry1->ReadData(0, 15 * 1024, buffer1, kSize1, &callback1));
    144   base::strlcpy(buffer1->data(), "the data", kSize1);
    145   int expected = 0;
    146   int ret = entry1->WriteData(0, 0, buffer1, kSize1, &callback2, false);
    147   EXPECT_TRUE(10 == ret || net::ERR_IO_PENDING == ret);
    148   if (net::ERR_IO_PENDING == ret)
    149     expected++;
    150 
    151   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    152   memset(buffer2->data(), 0, kSize2);
    153   ret = entry1->ReadData(0, 0, buffer2, kSize1, &callback3);
    154   EXPECT_TRUE(10 == ret || net::ERR_IO_PENDING == ret);
    155   if (net::ERR_IO_PENDING == ret)
    156     expected++;
    157 
    158   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    159   EXPECT_STREQ("the data", buffer2->data());
    160 
    161   base::strlcpy(buffer2->data(), "The really big data goes here", kSize2);
    162   ret = entry1->WriteData(1, 1500, buffer2, kSize2, &callback4, true);
    163   EXPECT_TRUE(5000 == ret || net::ERR_IO_PENDING == ret);
    164   if (net::ERR_IO_PENDING == ret)
    165     expected++;
    166 
    167   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    168   memset(buffer3->data(), 0, kSize3);
    169   ret = entry1->ReadData(1, 1511, buffer3, kSize2, &callback5);
    170   EXPECT_TRUE(4989 == ret || net::ERR_IO_PENDING == ret);
    171   if (net::ERR_IO_PENDING == ret)
    172     expected++;
    173 
    174   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    175   EXPECT_STREQ("big data goes here", buffer3->data());
    176   ret = entry1->ReadData(1, 0, buffer2, kSize2, &callback6);
    177   EXPECT_TRUE(5000 == ret || net::ERR_IO_PENDING == ret);
    178   if (net::ERR_IO_PENDING == ret)
    179     expected++;
    180 
    181   memset(buffer3->data(), 0, kSize3);
    182 
    183   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    184   EXPECT_EQ(0, memcmp(buffer2->data(), buffer3->data(), 1500));
    185   ret = entry1->ReadData(1, 5000, buffer2, kSize2, &callback7);
    186   EXPECT_TRUE(1500 == ret || net::ERR_IO_PENDING == ret);
    187   if (net::ERR_IO_PENDING == ret)
    188     expected++;
    189 
    190   ret = entry1->ReadData(1, 0, buffer3, kSize3, &callback9);
    191   EXPECT_TRUE(6500 == ret || net::ERR_IO_PENDING == ret);
    192   if (net::ERR_IO_PENDING == ret)
    193     expected++;
    194 
    195   ret = entry1->WriteData(1, 0, buffer3, 8192, &callback10, true);
    196   EXPECT_TRUE(8192 == ret || net::ERR_IO_PENDING == ret);
    197   if (net::ERR_IO_PENDING == ret)
    198     expected++;
    199 
    200   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    201   ret = entry1->ReadData(1, 0, buffer3, kSize3, &callback11);
    202   EXPECT_TRUE(8192 == ret || net::ERR_IO_PENDING == ret);
    203   if (net::ERR_IO_PENDING == ret)
    204     expected++;
    205 
    206   EXPECT_EQ(8192, entry1->GetDataSize(1));
    207 
    208   ret = entry1->ReadData(0, 0, buffer1, kSize1, &callback12);
    209   EXPECT_TRUE(10 == ret || net::ERR_IO_PENDING == ret);
    210   if (net::ERR_IO_PENDING == ret)
    211     expected++;
    212 
    213   ret = entry1->ReadData(1, 0, buffer2, kSize2, &callback13);
    214   EXPECT_TRUE(5000 == ret || net::ERR_IO_PENDING == ret);
    215   if (net::ERR_IO_PENDING == ret)
    216     expected++;
    217 
    218   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    219 
    220   EXPECT_FALSE(g_cache_tests_error);
    221   EXPECT_EQ(expected, g_cache_tests_received);
    222 
    223   entry1->Doom();
    224   entry1->Close();
    225   EXPECT_EQ(0, cache_->GetEntryCount());
    226 }
    227 
    228 TEST_F(DiskCacheEntryTest, InternalAsyncIO) {
    229   InitCache();
    230   InternalAsyncIO();
    231 }
    232 
    233 TEST_F(DiskCacheEntryTest, MemoryOnlyInternalAsyncIO) {
    234   SetMemoryOnlyMode();
    235   InitCache();
    236   InternalAsyncIO();
    237 }
    238 
    239 void DiskCacheEntryTest::ExternalSyncIO() {
    240   disk_cache::Entry *entry1;
    241   ASSERT_TRUE(cache_->CreateEntry("the first key", &entry1));
    242 
    243   const int kSize1 = 17000;
    244   const int kSize2 = 25000;
    245   scoped_refptr<net::IOBuffer> buffer1 = new net::IOBuffer(kSize1);
    246   scoped_refptr<net::IOBuffer> buffer2 = new net::IOBuffer(kSize2);
    247   CacheTestFillBuffer(buffer1->data(), kSize1, false);
    248   CacheTestFillBuffer(buffer2->data(), kSize2, false);
    249   base::strlcpy(buffer1->data(), "the data", kSize1);
    250   EXPECT_EQ(17000, entry1->WriteData(0, 0, buffer1, kSize1, NULL, false));
    251   memset(buffer1->data(), 0, kSize1);
    252   EXPECT_EQ(17000, entry1->ReadData(0, 0, buffer1, kSize1, NULL));
    253   EXPECT_STREQ("the data", buffer1->data());
    254 
    255   base::strlcpy(buffer2->data(), "The really big data goes here", kSize2);
    256   EXPECT_EQ(25000, entry1->WriteData(1, 10000, buffer2, kSize2, NULL, false));
    257   memset(buffer2->data(), 0, kSize2);
    258   EXPECT_EQ(24989, entry1->ReadData(1, 10011, buffer2, kSize2, NULL));
    259   EXPECT_STREQ("big data goes here", buffer2->data());
    260   EXPECT_EQ(25000, entry1->ReadData(1, 0, buffer2, kSize2, NULL));
    261   EXPECT_EQ(0, memcmp(buffer2->data(), buffer2->data(), 10000));
    262   EXPECT_EQ(5000, entry1->ReadData(1, 30000, buffer2, kSize2, NULL));
    263 
    264   EXPECT_EQ(0, entry1->ReadData(1, 35000, buffer2, kSize2, NULL));
    265   EXPECT_EQ(17000, entry1->ReadData(1, 0, buffer1, kSize1, NULL));
    266   EXPECT_EQ(17000, entry1->WriteData(1, 20000, buffer1, kSize1, NULL, false));
    267   EXPECT_EQ(37000, entry1->GetDataSize(1));
    268 
    269   entry1->Doom();
    270   entry1->Close();
    271   EXPECT_EQ(0, cache_->GetEntryCount());
    272 }
    273 
    274 TEST_F(DiskCacheEntryTest, ExternalSyncIO) {
    275   InitCache();
    276   ExternalSyncIO();
    277 }
    278 
    279 TEST_F(DiskCacheEntryTest, MemoryOnlyExternalSyncIO) {
    280   SetMemoryOnlyMode();
    281   InitCache();
    282   ExternalSyncIO();
    283 }
    284 
    285 void DiskCacheEntryTest::ExternalAsyncIO() {
    286   disk_cache::Entry *entry1;
    287   ASSERT_TRUE(cache_->CreateEntry("the first key", &entry1));
    288 
    289   // Let's verify that each IO goes to the right callback object.
    290   CallbackTest callback1(false);
    291   CallbackTest callback2(false);
    292   CallbackTest callback3(false);
    293   CallbackTest callback4(false);
    294   CallbackTest callback5(false);
    295   CallbackTest callback6(false);
    296   CallbackTest callback7(false);
    297   CallbackTest callback8(false);
    298   CallbackTest callback9(false);
    299 
    300   g_cache_tests_error = false;
    301   g_cache_tests_received = 0;
    302   int expected = 0;
    303 
    304   MessageLoopHelper helper;
    305 
    306   const int kSize1 = 17000;
    307   const int kSize2 = 25000;
    308   const int kSize3 = 25000;
    309   scoped_refptr<net::IOBuffer> buffer1 = new net::IOBuffer(kSize1);
    310   scoped_refptr<net::IOBuffer> buffer2 = new net::IOBuffer(kSize2);
    311   scoped_refptr<net::IOBuffer> buffer3 = new net::IOBuffer(kSize3);
    312   CacheTestFillBuffer(buffer1->data(), kSize1, false);
    313   CacheTestFillBuffer(buffer2->data(), kSize2, false);
    314   CacheTestFillBuffer(buffer3->data(), kSize3, false);
    315   base::strlcpy(buffer1->data(), "the data", kSize1);
    316   int ret = entry1->WriteData(0, 0, buffer1, kSize1, &callback1, false);
    317   EXPECT_TRUE(17000 == ret || net::ERR_IO_PENDING == ret);
    318   if (net::ERR_IO_PENDING == ret)
    319     expected++;
    320 
    321   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    322 
    323   memset(buffer2->data(), 0, kSize1);
    324   ret = entry1->ReadData(0, 0, buffer2, kSize1, &callback2);
    325   EXPECT_TRUE(17000 == ret || net::ERR_IO_PENDING == ret);
    326   if (net::ERR_IO_PENDING == ret)
    327     expected++;
    328 
    329   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    330   EXPECT_STREQ("the data", buffer1->data());
    331 
    332   base::strlcpy(buffer2->data(), "The really big data goes here", kSize2);
    333   ret = entry1->WriteData(1, 10000, buffer2, kSize2, &callback3, false);
    334   EXPECT_TRUE(25000 == ret || net::ERR_IO_PENDING == ret);
    335   if (net::ERR_IO_PENDING == ret)
    336     expected++;
    337 
    338   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    339 
    340   memset(buffer3->data(), 0, kSize3);
    341   ret = entry1->ReadData(1, 10011, buffer3, kSize3, &callback4);
    342   EXPECT_TRUE(24989 == ret || net::ERR_IO_PENDING == ret);
    343   if (net::ERR_IO_PENDING == ret)
    344     expected++;
    345 
    346   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    347   EXPECT_STREQ("big data goes here", buffer3->data());
    348   ret = entry1->ReadData(1, 0, buffer2, kSize2, &callback5);
    349   EXPECT_TRUE(25000 == ret || net::ERR_IO_PENDING == ret);
    350   if (net::ERR_IO_PENDING == ret)
    351     expected++;
    352 
    353   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    354   EXPECT_EQ(0, memcmp(buffer2->data(), buffer2->data(), 10000));
    355   ret = entry1->ReadData(1, 30000, buffer2, kSize2, &callback6);
    356   EXPECT_TRUE(5000 == ret || net::ERR_IO_PENDING == ret);
    357   if (net::ERR_IO_PENDING == ret)
    358     expected++;
    359 
    360   EXPECT_EQ(0, entry1->ReadData(1, 35000, buffer2, kSize2, &callback7));
    361   ret = entry1->ReadData(1, 0, buffer1, kSize1, &callback8);
    362   EXPECT_TRUE(17000 == ret || net::ERR_IO_PENDING == ret);
    363   if (net::ERR_IO_PENDING == ret)
    364     expected++;
    365   ret = entry1->WriteData(1, 20000, buffer1, kSize1, &callback9, false);
    366   EXPECT_TRUE(17000 == ret || net::ERR_IO_PENDING == ret);
    367   if (net::ERR_IO_PENDING == ret)
    368     expected++;
    369   EXPECT_EQ(37000, entry1->GetDataSize(1));
    370 
    371   EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
    372 
    373   EXPECT_FALSE(g_cache_tests_error);
    374   EXPECT_EQ(expected, g_cache_tests_received);
    375 
    376   entry1->Doom();
    377   entry1->Close();
    378   EXPECT_EQ(0, cache_->GetEntryCount());
    379 }
    380 
    381 TEST_F(DiskCacheEntryTest, ExternalAsyncIO) {
    382   InitCache();
    383   ExternalAsyncIO();
    384 }
    385 
    386 TEST_F(DiskCacheEntryTest, MemoryOnlyExternalAsyncIO) {
    387   SetMemoryOnlyMode();
    388   InitCache();
    389   ExternalAsyncIO();
    390 }
    391 
    392 void DiskCacheEntryTest::StreamAccess() {
    393   disk_cache::Entry *entry = NULL;
    394   ASSERT_TRUE(cache_->CreateEntry("the first key", &entry));
    395   ASSERT_TRUE(NULL != entry);
    396 
    397   const int kBufferSize = 1024;
    398   scoped_refptr<net::IOBuffer> buffer1 = new net::IOBuffer(kBufferSize);
    399   scoped_refptr<net::IOBuffer> buffer2 = new net::IOBuffer(kBufferSize);
    400 
    401   const int kNumStreams = 3;
    402   for (int i = 0; i < kNumStreams; i++) {
    403     CacheTestFillBuffer(buffer1->data(), kBufferSize, false);
    404     EXPECT_EQ(kBufferSize, entry->WriteData(i, 0, buffer1, kBufferSize, NULL,
    405                                             false));
    406     memset(buffer2->data(), 0, kBufferSize);
    407     EXPECT_EQ(kBufferSize, entry->ReadData(i, 0, buffer2, kBufferSize, NULL));
    408     EXPECT_EQ(0, memcmp(buffer1->data(), buffer2->data(), kBufferSize));
    409   }
    410 
    411   EXPECT_EQ(net::ERR_INVALID_ARGUMENT,
    412             entry->ReadData(kNumStreams, 0, buffer1, kBufferSize, NULL));
    413   entry->Close();
    414 }
    415 
    416 TEST_F(DiskCacheEntryTest, StreamAccess) {
    417   InitCache();
    418   StreamAccess();
    419 }
    420 
    421 TEST_F(DiskCacheEntryTest, MemoryOnlyStreamAccess) {
    422   SetMemoryOnlyMode();
    423   InitCache();
    424   StreamAccess();
    425 }
    426 
    427 void DiskCacheEntryTest::GetKey() {
    428   std::string key1("the first key");
    429   disk_cache::Entry *entry1;
    430   ASSERT_TRUE(cache_->CreateEntry(key1, &entry1));
    431   EXPECT_EQ(key1, entry1->GetKey()) << "short key";
    432   entry1->Close();
    433 
    434   int seed = static_cast<int>(Time::Now().ToInternalValue());
    435   srand(seed);
    436   char key_buffer[20000];
    437 
    438   CacheTestFillBuffer(key_buffer, 3000, true);
    439   key_buffer[1000] = '\0';
    440 
    441   key1 = key_buffer;
    442   ASSERT_TRUE(cache_->CreateEntry(key1, &entry1));
    443   EXPECT_TRUE(key1 == entry1->GetKey()) << "1000 bytes key";
    444   entry1->Close();
    445 
    446   key_buffer[1000] = 'p';
    447   key_buffer[3000] = '\0';
    448   key1 = key_buffer;
    449   ASSERT_TRUE(cache_->CreateEntry(key1, &entry1));
    450   EXPECT_TRUE(key1 == entry1->GetKey()) << "medium size key";
    451   entry1->Close();
    452 
    453   CacheTestFillBuffer(key_buffer, sizeof(key_buffer), true);
    454   key_buffer[19999] = '\0';
    455 
    456   key1 = key_buffer;
    457   ASSERT_TRUE(cache_->CreateEntry(key1, &entry1));
    458   EXPECT_TRUE(key1 == entry1->GetKey()) << "long key";
    459   entry1->Close();
    460 }
    461 
    462 TEST_F(DiskCacheEntryTest, GetKey) {
    463   InitCache();
    464   GetKey();
    465 }
    466 
    467 TEST_F(DiskCacheEntryTest, MemoryOnlyGetKey) {
    468   SetMemoryOnlyMode();
    469   InitCache();
    470   GetKey();
    471 }
    472 
    473 void DiskCacheEntryTest::GrowData() {
    474   std::string key1("the first key");
    475   disk_cache::Entry *entry1, *entry2;
    476   ASSERT_TRUE(cache_->CreateEntry(key1, &entry1));
    477 
    478   const int kSize = 20000;
    479   scoped_refptr<net::IOBuffer> buffer1 = new net::IOBuffer(kSize);
    480   scoped_refptr<net::IOBuffer> buffer2 = new net::IOBuffer(kSize);
    481   CacheTestFillBuffer(buffer1->data(), kSize, false);
    482   memset(buffer2->data(), 0, kSize);
    483 
    484   base::strlcpy(buffer1->data(), "the data", kSize);
    485   EXPECT_EQ(10, entry1->WriteData(0, 0, buffer1, 10, NULL, false));
    486   EXPECT_EQ(10, entry1->ReadData(0, 0, buffer2, 10, NULL));
    487   EXPECT_STREQ("the data", buffer2->data());
    488   EXPECT_EQ(10, entry1->GetDataSize(0));
    489 
    490   EXPECT_EQ(2000, entry1->WriteData(0, 0, buffer1, 2000, NULL, false));
    491   EXPECT_EQ(2000, entry1->GetDataSize(0));
    492   EXPECT_EQ(2000, entry1->ReadData(0, 0, buffer2, 2000, NULL));
    493   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 2000));
    494 
    495   EXPECT_EQ(20000, entry1->WriteData(0, 0, buffer1, kSize, NULL, false));
    496   EXPECT_EQ(20000, entry1->GetDataSize(0));
    497   EXPECT_EQ(20000, entry1->ReadData(0, 0, buffer2, kSize, NULL));
    498   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), kSize));
    499   entry1->Close();
    500 
    501   memset(buffer2->data(), 0, kSize);
    502   ASSERT_TRUE(cache_->CreateEntry("Second key", &entry2));
    503   EXPECT_EQ(10, entry2->WriteData(0, 0, buffer1, 10, NULL, false));
    504   EXPECT_EQ(10, entry2->GetDataSize(0));
    505   entry2->Close();
    506 
    507   // Go from an internal address to a bigger block size.
    508   ASSERT_TRUE(cache_->OpenEntry("Second key", &entry2));
    509   EXPECT_EQ(2000, entry2->WriteData(0, 0, buffer1, 2000, NULL, false));
    510   EXPECT_EQ(2000, entry2->GetDataSize(0));
    511   EXPECT_EQ(2000, entry2->ReadData(0, 0, buffer2, 2000, NULL));
    512   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 2000));
    513   entry2->Close();
    514   memset(buffer2->data(), 0, kSize);
    515 
    516   // Go from an internal address to an external one.
    517   ASSERT_TRUE(cache_->OpenEntry("Second key", &entry2));
    518   EXPECT_EQ(20000, entry2->WriteData(0, 0, buffer1, kSize, NULL, false));
    519   EXPECT_EQ(20000, entry2->GetDataSize(0));
    520   EXPECT_EQ(20000, entry2->ReadData(0, 0, buffer2, kSize, NULL));
    521   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), kSize));
    522   entry2->Close();
    523 }
    524 
    525 TEST_F(DiskCacheEntryTest, GrowData) {
    526   InitCache();
    527   GrowData();
    528 }
    529 
    530 TEST_F(DiskCacheEntryTest, MemoryOnlyGrowData) {
    531   SetMemoryOnlyMode();
    532   InitCache();
    533   GrowData();
    534 }
    535 
    536 void DiskCacheEntryTest::TruncateData() {
    537   std::string key1("the first key");
    538   disk_cache::Entry *entry1;
    539   ASSERT_TRUE(cache_->CreateEntry(key1, &entry1));
    540 
    541   const int kSize1 = 20000;
    542   const int kSize2 = 20000;
    543   scoped_refptr<net::IOBuffer> buffer1 = new net::IOBuffer(kSize1);
    544   scoped_refptr<net::IOBuffer> buffer2 = new net::IOBuffer(kSize2);
    545 
    546   CacheTestFillBuffer(buffer1->data(), kSize1, false);
    547   memset(buffer2->data(), 0, kSize2);
    548 
    549   // Simple truncation:
    550   EXPECT_EQ(200, entry1->WriteData(0, 0, buffer1, 200, NULL, false));
    551   EXPECT_EQ(200, entry1->GetDataSize(0));
    552   EXPECT_EQ(100, entry1->WriteData(0, 0, buffer1, 100, NULL, false));
    553   EXPECT_EQ(200, entry1->GetDataSize(0));
    554   EXPECT_EQ(100, entry1->WriteData(0, 0, buffer1, 100, NULL, true));
    555   EXPECT_EQ(100, entry1->GetDataSize(0));
    556   EXPECT_EQ(0, entry1->WriteData(0, 50, buffer1, 0, NULL, true));
    557   EXPECT_EQ(50, entry1->GetDataSize(0));
    558   EXPECT_EQ(0, entry1->WriteData(0, 0, buffer1, 0, NULL, true));
    559   EXPECT_EQ(0, entry1->GetDataSize(0));
    560   entry1->Close();
    561   ASSERT_TRUE(cache_->OpenEntry(key1, &entry1));
    562 
    563   // Go to an external file.
    564   EXPECT_EQ(20000, entry1->WriteData(0, 0, buffer1, 20000, NULL, true));
    565   EXPECT_EQ(20000, entry1->GetDataSize(0));
    566   EXPECT_EQ(20000, entry1->ReadData(0, 0, buffer2, 20000, NULL));
    567   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 20000));
    568   memset(buffer2->data(), 0, kSize2);
    569 
    570   // External file truncation
    571   EXPECT_EQ(18000, entry1->WriteData(0, 0, buffer1, 18000, NULL, false));
    572   EXPECT_EQ(20000, entry1->GetDataSize(0));
    573   EXPECT_EQ(18000, entry1->WriteData(0, 0, buffer1, 18000, NULL, true));
    574   EXPECT_EQ(18000, entry1->GetDataSize(0));
    575   EXPECT_EQ(0, entry1->WriteData(0, 17500, buffer1, 0, NULL, true));
    576   EXPECT_EQ(17500, entry1->GetDataSize(0));
    577 
    578   // And back to an internal block.
    579   EXPECT_EQ(600, entry1->WriteData(0, 1000, buffer1, 600, NULL, true));
    580   EXPECT_EQ(1600, entry1->GetDataSize(0));
    581   EXPECT_EQ(600, entry1->ReadData(0, 1000, buffer2, 600, NULL));
    582   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 600));
    583   EXPECT_EQ(1000, entry1->ReadData(0, 0, buffer2, 1000, NULL));
    584   EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 1000)) <<
    585       "Preserves previous data";
    586 
    587   // Go from external file to zero length.
    588   EXPECT_EQ(20000, entry1->WriteData(0, 0, buffer1, 20000, NULL, true));
    589   EXPECT_EQ(20000, entry1->GetDataSize(0));
    590   EXPECT_EQ(0, entry1->WriteData(0, 0, buffer1, 0, NULL, true));
    591   EXPECT_EQ(0, entry1->GetDataSize(0));
    592 
    593   entry1->Close();
    594 }
    595 
    596 TEST_F(DiskCacheEntryTest, TruncateData) {
    597   InitCache();
    598   TruncateData();
    599 
    600   // We generate asynchronous IO that is not really tracked until completion
    601   // so we just wait here before running the next test.
    602   MessageLoopHelper helper;
    603   helper.WaitUntilCacheIoFinished(1);
    604 }
    605 
    606 TEST_F(DiskCacheEntryTest, MemoryOnlyTruncateData) {
    607   SetMemoryOnlyMode();
    608   InitCache();
    609   TruncateData();
    610 }
    611 
    612 void DiskCacheEntryTest::ZeroLengthIO() {
    613   std::string key1("the first key");
    614   disk_cache::Entry *entry1;
    615   ASSERT_TRUE(cache_->CreateEntry(key1, &entry1));
    616 
    617   EXPECT_EQ(0, entry1->ReadData(0, 0, NULL, 0, NULL));
    618   EXPECT_EQ(0, entry1->WriteData(0, 0, NULL, 0, NULL, false));
    619 
    620   // This write should extend the entry.
    621   EXPECT_EQ(0, entry1->WriteData(0, 1000, NULL, 0, NULL, false));
    622   EXPECT_EQ(0, entry1->ReadData(0, 500, NULL, 0, NULL));
    623   EXPECT_EQ(0, entry1->ReadData(0, 2000, NULL, 0, NULL));
    624   EXPECT_EQ(1000, entry1->GetDataSize(0));
    625   entry1->Close();
    626 }
    627 
    628 TEST_F(DiskCacheEntryTest, ZeroLengthIO) {
    629   InitCache();
    630   ZeroLengthIO();
    631 }
    632 
    633 TEST_F(DiskCacheEntryTest, MemoryOnlyZeroLengthIO) {
    634   SetMemoryOnlyMode();
    635   InitCache();
    636   ZeroLengthIO();
    637 }
    638 
    639 // Write more than the total cache capacity but to a single entry. |size| is the
    640 // amount of bytes to write each time.
    641 void DiskCacheEntryTest::ReuseEntry(int size) {
    642   std::string key1("the first key");
    643   disk_cache::Entry *entry;
    644   ASSERT_TRUE(cache_->CreateEntry(key1, &entry));
    645 
    646   entry->Close();
    647   std::string key2("the second key");
    648   ASSERT_TRUE(cache_->CreateEntry(key2, &entry));
    649 
    650   scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(size);
    651   CacheTestFillBuffer(buffer->data(), size, false);
    652 
    653   for (int i = 0; i < 15; i++) {
    654     EXPECT_EQ(0, entry->WriteData(0, 0, buffer, 0, NULL, true));
    655     EXPECT_EQ(size, entry->WriteData(0, 0, buffer, size, NULL, false));
    656     entry->Close();
    657     ASSERT_TRUE(cache_->OpenEntry(key2, &entry));
    658   }
    659 
    660   entry->Close();
    661   ASSERT_TRUE(cache_->OpenEntry(key1, &entry)) << "have not evicted this entry";
    662   entry->Close();
    663 }
    664 
    665 TEST_F(DiskCacheEntryTest, ReuseExternalEntry) {
    666   SetDirectMode();
    667   SetMaxSize(200 * 1024);
    668   InitCache();
    669   ReuseEntry(20 * 1024);
    670 }
    671 
    672 TEST_F(DiskCacheEntryTest, MemoryOnlyReuseExternalEntry) {
    673   SetDirectMode();
    674   SetMemoryOnlyMode();
    675   SetMaxSize(200 * 1024);
    676   InitCache();
    677   ReuseEntry(20 * 1024);
    678 }
    679 
    680 TEST_F(DiskCacheEntryTest, ReuseInternalEntry) {
    681   SetDirectMode();
    682   SetMaxSize(100 * 1024);
    683   InitCache();
    684   ReuseEntry(10 * 1024);
    685 }
    686 
    687 TEST_F(DiskCacheEntryTest, MemoryOnlyReuseInternalEntry) {
    688   SetDirectMode();
    689   SetMemoryOnlyMode();
    690   SetMaxSize(100 * 1024);
    691   InitCache();
    692   ReuseEntry(10 * 1024);
    693 }
    694 
    695 // Reading somewhere that was not written should return zeros.
    696 void DiskCacheEntryTest::InvalidData() {
    697   std::string key1("the first key");
    698   disk_cache::Entry *entry1;
    699   ASSERT_TRUE(cache_->CreateEntry(key1, &entry1));
    700 
    701   const int kSize1 = 20000;
    702   const int kSize2 = 20000;
    703   const int kSize3 = 20000;
    704   scoped_refptr<net::IOBuffer> buffer1 = new net::IOBuffer(kSize1);
    705   scoped_refptr<net::IOBuffer> buffer2 = new net::IOBuffer(kSize2);
    706   scoped_refptr<net::IOBuffer> buffer3 = new net::IOBuffer(kSize3);
    707 
    708   CacheTestFillBuffer(buffer1->data(), kSize1, false);
    709   memset(buffer2->data(), 0, kSize2);
    710 
    711   // Simple data grow:
    712   EXPECT_EQ(200, entry1->WriteData(0, 400, buffer1, 200, NULL, false));
    713   EXPECT_EQ(600, entry1->GetDataSize(0));
    714   EXPECT_EQ(100, entry1->ReadData(0, 300, buffer3, 100, NULL));
    715   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 100));
    716   entry1->Close();
    717   ASSERT_TRUE(cache_->OpenEntry(key1, &entry1));
    718 
    719   // The entry is now on disk. Load it and extend it.
    720   EXPECT_EQ(200, entry1->WriteData(0, 800, buffer1, 200, NULL, false));
    721   EXPECT_EQ(1000, entry1->GetDataSize(0));
    722   EXPECT_EQ(100, entry1->ReadData(0, 700, buffer3, 100, NULL));
    723   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 100));
    724   entry1->Close();
    725   ASSERT_TRUE(cache_->OpenEntry(key1, &entry1));
    726 
    727   // This time using truncate.
    728   EXPECT_EQ(200, entry1->WriteData(0, 1800, buffer1, 200, NULL, true));
    729   EXPECT_EQ(2000, entry1->GetDataSize(0));
    730   EXPECT_EQ(100, entry1->ReadData(0, 1500, buffer3, 100, NULL));
    731   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 100));
    732 
    733   // Go to an external file.
    734   EXPECT_EQ(200, entry1->WriteData(0, 19800, buffer1, 200, NULL, false));
    735   EXPECT_EQ(20000, entry1->GetDataSize(0));
    736   EXPECT_EQ(4000, entry1->ReadData(0, 14000, buffer3, 4000, NULL));
    737   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 4000));
    738 
    739   // And back to an internal block.
    740   EXPECT_EQ(600, entry1->WriteData(0, 1000, buffer1, 600, NULL, true));
    741   EXPECT_EQ(1600, entry1->GetDataSize(0));
    742   EXPECT_EQ(600, entry1->ReadData(0, 1000, buffer3, 600, NULL));
    743   EXPECT_TRUE(!memcmp(buffer3->data(), buffer1->data(), 600));
    744 
    745   // Extend it again.
    746   EXPECT_EQ(600, entry1->WriteData(0, 2000, buffer1, 600, NULL, false));
    747   EXPECT_EQ(2600, entry1->GetDataSize(0));
    748   EXPECT_EQ(200, entry1->ReadData(0, 1800, buffer3, 200, NULL));
    749   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 200));
    750 
    751   // And again (with truncation flag).
    752   EXPECT_EQ(600, entry1->WriteData(0, 3000, buffer1, 600, NULL, true));
    753   EXPECT_EQ(3600, entry1->GetDataSize(0));
    754   EXPECT_EQ(200, entry1->ReadData(0, 2800, buffer3, 200, NULL));
    755   EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 200));
    756 
    757   entry1->Close();
    758 }
    759 
    760 TEST_F(DiskCacheEntryTest, InvalidData) {
    761   InitCache();
    762   InvalidData();
    763 }
    764 
    765 TEST_F(DiskCacheEntryTest, MemoryOnlyInvalidData) {
    766   SetMemoryOnlyMode();
    767   InitCache();
    768   InvalidData();
    769 }
    770 
    771 void DiskCacheEntryTest::DoomEntry() {
    772   std::string key1("the first key");
    773   disk_cache::Entry *entry1;
    774   ASSERT_TRUE(cache_->CreateEntry(key1, &entry1));
    775   entry1->Doom();
    776   entry1->Close();
    777 
    778   const int kSize = 20000;
    779   scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kSize);
    780   CacheTestFillBuffer(buffer->data(), kSize, true);
    781   buffer->data()[19999] = '\0';
    782 
    783   key1 = buffer->data();
    784   ASSERT_TRUE(cache_->CreateEntry(key1, &entry1));
    785   EXPECT_EQ(20000, entry1->WriteData(0, 0, buffer, kSize, NULL, false));
    786   EXPECT_EQ(20000, entry1->WriteData(1, 0, buffer, kSize, NULL, false));
    787   entry1->Doom();
    788   entry1->Close();
    789 
    790   EXPECT_EQ(0, cache_->GetEntryCount());
    791 }
    792 
    793 TEST_F(DiskCacheEntryTest, DoomEntry) {
    794   InitCache();
    795   DoomEntry();
    796 }
    797 
    798 TEST_F(DiskCacheEntryTest, MemoryOnlyDoomEntry) {
    799   SetMemoryOnlyMode();
    800   InitCache();
    801   DoomEntry();
    802 }
    803 
    804 // Verify that basic operations work as expected with doomed entries.
    805 void DiskCacheEntryTest::DoomedEntry() {
    806   std::string key("the first key");
    807   disk_cache::Entry *entry;
    808   ASSERT_TRUE(cache_->CreateEntry(key, &entry));
    809   entry->Doom();
    810 
    811   EXPECT_EQ(0, cache_->GetEntryCount());
    812   Time initial = Time::Now();
    813   PlatformThread::Sleep(20);
    814 
    815   const int kSize1 = 2000;
    816   const int kSize2 = 2000;
    817   scoped_refptr<net::IOBuffer> buffer1 = new net::IOBuffer(kSize1);
    818   scoped_refptr<net::IOBuffer> buffer2 = new net::IOBuffer(kSize2);
    819   CacheTestFillBuffer(buffer1->data(), kSize1, false);
    820   memset(buffer2->data(), 0, kSize2);
    821 
    822   EXPECT_EQ(2000, entry->WriteData(0, 0, buffer1, 2000, NULL, false));
    823   EXPECT_EQ(2000, entry->ReadData(0, 0, buffer2, 2000, NULL));
    824   EXPECT_EQ(0, memcmp(buffer1->data(), buffer2->data(), kSize1));
    825   EXPECT_EQ(key, entry->GetKey());
    826   EXPECT_TRUE(initial < entry->GetLastModified());
    827   EXPECT_TRUE(initial < entry->GetLastUsed());
    828 
    829   entry->Close();
    830 }
    831 
    832 TEST_F(DiskCacheEntryTest, DoomedEntry) {
    833   InitCache();
    834   DoomEntry();
    835 }
    836 
    837 TEST_F(DiskCacheEntryTest, MemoryOnlyDoomedEntry) {
    838   SetMemoryOnlyMode();
    839   InitCache();
    840   DoomEntry();
    841 }
    842 
    843 // Test that child entries in a memory cache backend are not visible from
    844 // enumerations.
    845 TEST_F(DiskCacheEntryTest, MemoryOnlyEnumerationWithSparseEntries) {
    846   SetMemoryOnlyMode();
    847   InitCache();
    848 
    849   const int kSize = 4096;
    850   scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(kSize);
    851   CacheTestFillBuffer(buf->data(), kSize, false);
    852 
    853   std::string key("the first key");
    854   disk_cache::Entry* parent_entry;
    855   ASSERT_TRUE(cache_->CreateEntry(key, &parent_entry));
    856 
    857   // Writes to the parent entry.
    858   EXPECT_EQ(kSize, parent_entry->WriteSparseData(0, buf, kSize, NULL));
    859 
    860   // This write creates a child entry and writes to it.
    861   EXPECT_EQ(kSize, parent_entry->WriteSparseData(8192, buf, kSize, NULL));
    862 
    863   parent_entry->Close();
    864 
    865   // Perform the enumerations.
    866   void* iter = NULL;
    867   disk_cache::Entry* entry = NULL;
    868   int count = 0;
    869   while (cache_->OpenNextEntry(&iter, &entry)) {
    870     ASSERT_TRUE(entry != NULL);
    871     ++count;
    872     disk_cache::MemEntryImpl* mem_entry =
    873         reinterpret_cast<disk_cache::MemEntryImpl*>(entry);
    874     EXPECT_EQ(disk_cache::MemEntryImpl::kParentEntry, mem_entry->type());
    875     mem_entry->Close();
    876   }
    877   EXPECT_EQ(1, count);
    878 }
    879 
    880 // Writes |buf_1| to offset and reads it back as |buf_2|.
    881 void VerifySparseIO(disk_cache::Entry* entry, int64 offset,
    882                     net::IOBuffer* buf_1, int size, bool async,
    883                     net::IOBuffer* buf_2) {
    884   TestCompletionCallback callback;
    885   TestCompletionCallback* cb = async ? &callback : NULL;
    886 
    887   memset(buf_2->data(), 0, size);
    888   int ret = entry->ReadSparseData(offset, buf_2, size, cb);
    889   ret = callback.GetResult(ret);
    890   EXPECT_EQ(0, ret);
    891 
    892   ret = entry->WriteSparseData(offset, buf_1, size, cb);
    893   ret = callback.GetResult(ret);
    894   EXPECT_EQ(size, ret);
    895 
    896   ret = entry->ReadSparseData(offset, buf_2, size, cb);
    897   ret = callback.GetResult(ret);
    898   EXPECT_EQ(size, ret);
    899 
    900   EXPECT_EQ(0, memcmp(buf_1->data(), buf_2->data(), size));
    901 }
    902 
    903 // Reads |size| bytes from |entry| at |offset| and verifies that they are the
    904 // same as the content of the provided |buffer|.
    905 void VerifyContentSparseIO(disk_cache::Entry* entry, int64 offset, char* buffer,
    906                            int size, bool async) {
    907   TestCompletionCallback callback;
    908   TestCompletionCallback* cb = async ? &callback : NULL;
    909 
    910   scoped_refptr<net::IOBuffer> buf_1 = new net::IOBuffer(size);
    911   memset(buf_1->data(), 0, size);
    912   int ret = entry->ReadSparseData(offset, buf_1, size, cb);
    913   ret = callback.GetResult(ret);
    914   EXPECT_EQ(size, ret);
    915 
    916   EXPECT_EQ(0, memcmp(buf_1->data(), buffer, size));
    917 }
    918 
    919 void DiskCacheEntryTest::BasicSparseIO(bool async) {
    920   std::string key("the first key");
    921   disk_cache::Entry* entry;
    922   ASSERT_TRUE(cache_->CreateEntry(key, &entry));
    923 
    924   const int kSize = 2048;
    925   scoped_refptr<net::IOBuffer> buf_1 = new net::IOBuffer(kSize);
    926   scoped_refptr<net::IOBuffer> buf_2 = new net::IOBuffer(kSize);
    927   CacheTestFillBuffer(buf_1->data(), kSize, false);
    928 
    929   // Write at offset 0.
    930   VerifySparseIO(entry, 0, buf_1, kSize, async, buf_2);
    931 
    932   // Write at offset 0x400000 (4 MB).
    933   VerifySparseIO(entry, 0x400000, buf_1, kSize, async, buf_2);
    934 
    935   // Write at offset 0x800000000 (32 GB).
    936   VerifySparseIO(entry, 0x800000000LL, buf_1, kSize, async, buf_2);
    937 
    938   entry->Close();
    939 
    940   // Check everything again.
    941   ASSERT_TRUE(cache_->OpenEntry(key, &entry));
    942   VerifyContentSparseIO(entry, 0, buf_1->data(), kSize, async);
    943   VerifyContentSparseIO(entry, 0x400000, buf_1->data(), kSize, async);
    944   VerifyContentSparseIO(entry, 0x800000000LL, buf_1->data(), kSize, async);
    945   entry->Close();
    946 }
    947 
    948 TEST_F(DiskCacheEntryTest, BasicSparseSyncIO) {
    949   InitCache();
    950   BasicSparseIO(false);
    951 }
    952 
    953 TEST_F(DiskCacheEntryTest, MemoryOnlyBasicSparseSyncIO) {
    954   SetMemoryOnlyMode();
    955   InitCache();
    956   BasicSparseIO(false);
    957 }
    958 
    959 TEST_F(DiskCacheEntryTest, BasicSparseAsyncIO) {
    960   InitCache();
    961   BasicSparseIO(true);
    962 }
    963 
    964 TEST_F(DiskCacheEntryTest, MemoryOnlyBasicSparseAsyncIO) {
    965   SetMemoryOnlyMode();
    966   InitCache();
    967   BasicSparseIO(true);
    968 }
    969 
    970 void DiskCacheEntryTest::HugeSparseIO(bool async) {
    971   std::string key("the first key");
    972   disk_cache::Entry* entry;
    973   ASSERT_TRUE(cache_->CreateEntry(key, &entry));
    974 
    975   // Write 1.2 MB so that we cover multiple entries.
    976   const int kSize = 1200 * 1024;
    977   scoped_refptr<net::IOBuffer> buf_1 = new net::IOBuffer(kSize);
    978   scoped_refptr<net::IOBuffer> buf_2 = new net::IOBuffer(kSize);
    979   CacheTestFillBuffer(buf_1->data(), kSize, false);
    980 
    981   // Write at offset 0x20F0000 (33 MB - 64 KB).
    982   VerifySparseIO(entry, 0x20F0000, buf_1, kSize, async, buf_2);
    983   entry->Close();
    984 
    985   // Check it again.
    986   ASSERT_TRUE(cache_->OpenEntry(key, &entry));
    987   VerifyContentSparseIO(entry, 0x20F0000, buf_1->data(), kSize, async);
    988   entry->Close();
    989 }
    990 
    991 TEST_F(DiskCacheEntryTest, HugeSparseSyncIO) {
    992   InitCache();
    993   HugeSparseIO(false);
    994 }
    995 
    996 TEST_F(DiskCacheEntryTest, MemoryOnlyHugeSparseSyncIO) {
    997   SetMemoryOnlyMode();
    998   InitCache();
    999   HugeSparseIO(false);
   1000 }
   1001 
   1002 TEST_F(DiskCacheEntryTest, HugeSparseAsyncIO) {
   1003   InitCache();
   1004   HugeSparseIO(true);
   1005 }
   1006 
   1007 TEST_F(DiskCacheEntryTest, MemoryOnlyHugeSparseAsyncIO) {
   1008   SetMemoryOnlyMode();
   1009   InitCache();
   1010   HugeSparseIO(true);
   1011 }
   1012 
   1013 void DiskCacheEntryTest::GetAvailableRange() {
   1014   std::string key("the first key");
   1015   disk_cache::Entry* entry;
   1016   ASSERT_TRUE(cache_->CreateEntry(key, &entry));
   1017 
   1018   const int kSize = 16 * 1024;
   1019   scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(kSize);
   1020   CacheTestFillBuffer(buf->data(), kSize, false);
   1021 
   1022   // Write at offset 0x20F0000 (33 MB - 64 KB), and 0x20F4400 (33 MB - 47 KB).
   1023   EXPECT_EQ(kSize, entry->WriteSparseData(0x20F0000, buf, kSize, NULL));
   1024   EXPECT_EQ(kSize, entry->WriteSparseData(0x20F4400, buf, kSize, NULL));
   1025 
   1026   // We stop at the first empty block.
   1027   int64 start;
   1028   EXPECT_EQ(kSize, entry->GetAvailableRange(0x20F0000, kSize * 2, &start));
   1029   EXPECT_EQ(0x20F0000, start);
   1030 
   1031   start = 0;
   1032   EXPECT_EQ(0, entry->GetAvailableRange(0, kSize, &start));
   1033   EXPECT_EQ(0, entry->GetAvailableRange(0x20F0000 - kSize, kSize, &start));
   1034   EXPECT_EQ(kSize, entry->GetAvailableRange(0, 0x2100000, &start));
   1035   EXPECT_EQ(0x20F0000, start);
   1036 
   1037   // We should be able to Read based on the results of GetAvailableRange.
   1038   start = -1;
   1039   EXPECT_EQ(0, entry->GetAvailableRange(0x2100000, kSize, &start));
   1040   EXPECT_EQ(0, entry->ReadSparseData(start, buf, kSize, NULL));
   1041 
   1042   start = 0;
   1043   EXPECT_EQ(0x2000, entry->GetAvailableRange(0x20F2000, kSize, &start));
   1044   EXPECT_EQ(0x20F2000, start);
   1045   EXPECT_EQ(0x2000, entry->ReadSparseData(start, buf, kSize, NULL));
   1046 
   1047   // Make sure that we respect the |len| argument.
   1048   start = 0;
   1049   EXPECT_EQ(1, entry->GetAvailableRange(0x20F0001 - kSize, kSize, &start));
   1050   EXPECT_EQ(0x20F0000, start);
   1051 
   1052   entry->Close();
   1053 }
   1054 
   1055 TEST_F(DiskCacheEntryTest, GetAvailableRange) {
   1056   InitCache();
   1057   GetAvailableRange();
   1058 }
   1059 
   1060 TEST_F(DiskCacheEntryTest, MemoryOnlyGetAvailableRange) {
   1061   SetMemoryOnlyMode();
   1062   InitCache();
   1063   GetAvailableRange();
   1064 }
   1065 
   1066 TEST_F(DiskCacheEntryTest, MemoryOnlyMisalignedSparseIO) {
   1067   SetMemoryOnlyMode();
   1068   InitCache();
   1069 
   1070   const int kSize = 8192;
   1071   scoped_refptr<net::IOBuffer> buf_1 = new net::IOBuffer(kSize);
   1072   scoped_refptr<net::IOBuffer> buf_2 = new net::IOBuffer(kSize);
   1073   CacheTestFillBuffer(buf_1->data(), kSize, false);
   1074 
   1075   std::string key("the first key");
   1076   disk_cache::Entry* entry;
   1077   ASSERT_TRUE(cache_->CreateEntry(key, &entry));
   1078 
   1079   // This loop writes back to back starting from offset 0 and 9000.
   1080   for (int i = 0; i < kSize; i += 1024) {
   1081     scoped_refptr<net::WrappedIOBuffer> buf_3 =
   1082       new net::WrappedIOBuffer(buf_1->data() + i);
   1083     VerifySparseIO(entry, i, buf_3, 1024, false, buf_2);
   1084     VerifySparseIO(entry, 9000 + i, buf_3, 1024, false, buf_2);
   1085   }
   1086 
   1087   // Make sure we have data written.
   1088   VerifyContentSparseIO(entry, 0, buf_1->data(), kSize, false);
   1089   VerifyContentSparseIO(entry, 9000, buf_1->data(), kSize, false);
   1090 
   1091   // This tests a large write that spans 3 entries from a misaligned offset.
   1092   VerifySparseIO(entry, 20481, buf_1, 8192, false, buf_2);
   1093 
   1094   entry->Close();
   1095 }
   1096 
   1097 TEST_F(DiskCacheEntryTest, MemoryOnlyMisalignedGetAvailableRange) {
   1098   SetMemoryOnlyMode();
   1099   InitCache();
   1100 
   1101   const int kSize = 8192;
   1102   scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(kSize);
   1103   CacheTestFillBuffer(buf->data(), kSize, false);
   1104 
   1105   disk_cache::Entry* entry;
   1106   std::string key("the first key");
   1107   ASSERT_TRUE(cache_->CreateEntry(key, &entry));
   1108 
   1109   // Writes in the middle of an entry.
   1110   EXPECT_EQ(1024, entry->WriteSparseData(0, buf, 1024, NULL));
   1111   EXPECT_EQ(1024, entry->WriteSparseData(5120, buf, 1024, NULL));
   1112   EXPECT_EQ(1024, entry->WriteSparseData(10000, buf, 1024, NULL));
   1113 
   1114   // Writes in the middle of an entry and spans 2 child entries.
   1115   EXPECT_EQ(8192, entry->WriteSparseData(50000, buf, 8192, NULL));
   1116 
   1117   int64 start;
   1118   // Test that we stop at a discontinuous child at the second block.
   1119   EXPECT_EQ(1024, entry->GetAvailableRange(0, 10000, &start));
   1120   EXPECT_EQ(0, start);
   1121 
   1122   // Test that number of bytes is reported correctly when we start from the
   1123   // middle of a filled region.
   1124   EXPECT_EQ(512, entry->GetAvailableRange(512, 10000, &start));
   1125   EXPECT_EQ(512, start);
   1126 
   1127   // Test that we found bytes in the child of next block.
   1128   EXPECT_EQ(1024, entry->GetAvailableRange(1024, 10000, &start));
   1129   EXPECT_EQ(5120, start);
   1130 
   1131   // Test that the desired length is respected. It starts within a filled
   1132   // region.
   1133   EXPECT_EQ(512, entry->GetAvailableRange(5500, 512, &start));
   1134   EXPECT_EQ(5500, start);
   1135 
   1136   // Test that the desired length is respected. It starts before a filled
   1137   // region.
   1138   EXPECT_EQ(500, entry->GetAvailableRange(5000, 620, &start));
   1139   EXPECT_EQ(5120, start);
   1140 
   1141   // Test that multiple blocks are scanned.
   1142   EXPECT_EQ(8192, entry->GetAvailableRange(40000, 20000, &start));
   1143   EXPECT_EQ(50000, start);
   1144 
   1145   entry->Close();
   1146 }
   1147 
   1148 void DiskCacheEntryTest::DoomSparseEntry() {
   1149   std::string key1("the first key");
   1150   std::string key2("the second key");
   1151   disk_cache::Entry *entry1, *entry2;
   1152   ASSERT_TRUE(cache_->CreateEntry(key1, &entry1));
   1153   ASSERT_TRUE(cache_->CreateEntry(key2, &entry2));
   1154 
   1155   const int kSize = 4 * 1024;
   1156   scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(kSize);
   1157   CacheTestFillBuffer(buf->data(), kSize, false);
   1158 
   1159   int64 offset = 1024;
   1160   // Write to a bunch of ranges.
   1161   for (int i = 0; i < 12; i++) {
   1162     EXPECT_EQ(kSize, entry1->WriteSparseData(offset, buf, kSize, NULL));
   1163     // Keep the second map under the default size.
   1164     if (i < 9)
   1165       EXPECT_EQ(kSize, entry2->WriteSparseData(offset, buf, kSize, NULL));
   1166     offset *= 4;
   1167   }
   1168 
   1169   if (memory_only_)
   1170     EXPECT_EQ(2, cache_->GetEntryCount());
   1171   else
   1172     EXPECT_EQ(15, cache_->GetEntryCount());
   1173 
   1174   // Doom the first entry while it's still open.
   1175   entry1->Doom();
   1176   entry1->Close();
   1177   entry2->Close();
   1178 
   1179   // Doom the second entry after it's fully saved.
   1180   EXPECT_TRUE(cache_->DoomEntry(key2));
   1181 
   1182   // Make sure we do all needed work. This may fail for entry2 if between Close
   1183   // and DoomEntry the system decides to remove all traces of the file from the
   1184   // system cache so we don't see that there is pending IO.
   1185   MessageLoop::current()->RunAllPending();
   1186 
   1187   if (memory_only_) {
   1188     EXPECT_EQ(0, cache_->GetEntryCount());
   1189   } else {
   1190     if (5 == cache_->GetEntryCount()) {
   1191       // Most likely we are waiting for the result of reading the sparse info
   1192       // (it's always async on Posix so it is easy to miss). Unfortunately we
   1193       // don't have any signal to watch for so we can only wait.
   1194       PlatformThread::Sleep(500);
   1195       MessageLoop::current()->RunAllPending();
   1196     }
   1197     EXPECT_EQ(0, cache_->GetEntryCount());
   1198   }
   1199 }
   1200 
   1201 TEST_F(DiskCacheEntryTest, DoomSparseEntry) {
   1202   InitCache();
   1203   DoomSparseEntry();
   1204 }
   1205 
   1206 TEST_F(DiskCacheEntryTest, MemoryOnlyDoomSparseEntry) {
   1207   SetMemoryOnlyMode();
   1208   InitCache();
   1209   DoomSparseEntry();
   1210 }
   1211 
   1212 void DiskCacheEntryTest::PartialSparseEntry() {
   1213   std::string key("the first key");
   1214   disk_cache::Entry* entry;
   1215   ASSERT_TRUE(cache_->CreateEntry(key, &entry));
   1216 
   1217   // We should be able to deal with IO that is not aligned to the block size
   1218   // of a sparse entry, at least to write a big range without leaving holes.
   1219   const int kSize = 4 * 1024;
   1220   const int kSmallSize = 128;
   1221   scoped_refptr<net::IOBuffer> buf1 = new net::IOBuffer(kSize);
   1222   CacheTestFillBuffer(buf1->data(), kSize, false);
   1223 
   1224   // The first write is just to extend the entry. The third write occupies
   1225   // a 1KB block partially, it may not be written internally depending on the
   1226   // implementation.
   1227   EXPECT_EQ(kSize, entry->WriteSparseData(20000, buf1, kSize, NULL));
   1228   EXPECT_EQ(kSize, entry->WriteSparseData(500, buf1, kSize, NULL));
   1229   EXPECT_EQ(kSmallSize,
   1230             entry->WriteSparseData(1080321, buf1, kSmallSize, NULL));
   1231   entry->Close();
   1232   ASSERT_TRUE(cache_->OpenEntry(key, &entry));
   1233 
   1234   scoped_refptr<net::IOBuffer> buf2 = new net::IOBuffer(kSize);
   1235   memset(buf2->data(), 0, kSize);
   1236   EXPECT_EQ(0, entry->ReadSparseData(8000, buf2, kSize, NULL));
   1237 
   1238   EXPECT_EQ(500, entry->ReadSparseData(kSize, buf2, kSize, NULL));
   1239   EXPECT_EQ(0, memcmp(buf2->data(), buf1->data() + kSize - 500, 500));
   1240   EXPECT_EQ(0, entry->ReadSparseData(0, buf2, kSize, NULL));
   1241 
   1242   // This read should not change anything.
   1243   EXPECT_EQ(96, entry->ReadSparseData(24000, buf2, kSize, NULL));
   1244   EXPECT_EQ(500, entry->ReadSparseData(kSize, buf2, kSize, NULL));
   1245   EXPECT_EQ(0, entry->ReadSparseData(499, buf2, kSize, NULL));
   1246 
   1247   int64 start;
   1248   if (memory_only_) {
   1249     EXPECT_EQ(100, entry->GetAvailableRange(0, 600, &start));
   1250     EXPECT_EQ(500, start);
   1251   } else {
   1252     EXPECT_EQ(1024, entry->GetAvailableRange(0, 2048, &start));
   1253     EXPECT_EQ(1024, start);
   1254   }
   1255   EXPECT_EQ(500, entry->GetAvailableRange(kSize, kSize, &start));
   1256   EXPECT_EQ(kSize, start);
   1257   EXPECT_EQ(3616, entry->GetAvailableRange(20 * 1024, 10000, &start));
   1258   EXPECT_EQ(20 * 1024, start);
   1259 
   1260   // 1. Query before a filled 1KB block.
   1261   // 2. Query within a filled 1KB block.
   1262   // 3. Query beyond a filled 1KB block.
   1263   if (memory_only_) {
   1264     EXPECT_EQ(3496, entry->GetAvailableRange(19400, kSize, &start));
   1265     EXPECT_EQ(20000, start);
   1266   } else {
   1267     EXPECT_EQ(3016, entry->GetAvailableRange(19400, kSize, &start));
   1268     EXPECT_EQ(20480, start);
   1269   }
   1270   EXPECT_EQ(1523, entry->GetAvailableRange(3073, kSize, &start));
   1271   EXPECT_EQ(3073, start);
   1272   EXPECT_EQ(0, entry->GetAvailableRange(4600, kSize, &start));
   1273   EXPECT_EQ(4600, start);
   1274 
   1275   // Now make another write and verify that there is no hole in between.
   1276   EXPECT_EQ(kSize, entry->WriteSparseData(500 + kSize, buf1, kSize, NULL));
   1277   EXPECT_EQ(7 * 1024 + 500, entry->GetAvailableRange(1024, 10000, &start));
   1278   EXPECT_EQ(1024, start);
   1279   EXPECT_EQ(kSize, entry->ReadSparseData(kSize, buf2, kSize, NULL));
   1280   EXPECT_EQ(0, memcmp(buf2->data(), buf1->data() + kSize - 500, 500));
   1281   EXPECT_EQ(0, memcmp(buf2->data() + 500, buf1->data(), kSize - 500));
   1282 
   1283   entry->Close();
   1284 }
   1285 
   1286 TEST_F(DiskCacheEntryTest, PartialSparseEntry) {
   1287   InitCache();
   1288   PartialSparseEntry();
   1289 }
   1290 
   1291 TEST_F(DiskCacheEntryTest, MemoryPartialSparseEntry) {
   1292   SetMemoryOnlyMode();
   1293   InitCache();
   1294   PartialSparseEntry();
   1295 }
   1296 
   1297 TEST_F(DiskCacheEntryTest, CleanupSparseEntry) {
   1298   InitCache();
   1299   std::string key("the first key");
   1300   disk_cache::Entry* entry;
   1301   ASSERT_TRUE(cache_->CreateEntry(key, &entry));
   1302 
   1303   // Corrupt sparse children should be removed automatically.
   1304   const int kSize = 4 * 1024;
   1305   scoped_refptr<net::IOBuffer> buf1 = new net::IOBuffer(kSize);
   1306   CacheTestFillBuffer(buf1->data(), kSize, false);
   1307 
   1308   const int k1Meg = 1024 * 1024;
   1309   EXPECT_EQ(kSize, entry->WriteSparseData(8192, buf1, kSize, NULL));
   1310   EXPECT_EQ(kSize, entry->WriteSparseData(k1Meg + 8192, buf1, kSize, NULL));
   1311   EXPECT_EQ(kSize, entry->WriteSparseData(2 * k1Meg + 8192, buf1, kSize, NULL));
   1312   entry->Close();
   1313   EXPECT_EQ(4, cache_->GetEntryCount());
   1314 
   1315   void* iter = NULL;
   1316   int count = 0;
   1317   std::string child_key[2];
   1318   while (cache_->OpenNextEntry(&iter, &entry)) {
   1319     ASSERT_TRUE(entry != NULL);
   1320     // Writing to an entry will alter the LRU list and invalidate the iterator.
   1321     if (entry->GetKey() != key && count < 2)
   1322       child_key[count++] = entry->GetKey();
   1323     entry->Close();
   1324   }
   1325   for (int i = 0; i < 2; i++) {
   1326     ASSERT_TRUE(cache_->OpenEntry(child_key[i], &entry));
   1327     // Overwrite the header's magic and signature.
   1328     EXPECT_EQ(12, entry->WriteData(2, 0, buf1, 12, NULL, false));
   1329     entry->Close();
   1330   }
   1331 
   1332   EXPECT_EQ(4, cache_->GetEntryCount());
   1333   ASSERT_TRUE(cache_->OpenEntry(key, &entry));
   1334 
   1335   // Two children should be gone. One while reading and one while writing.
   1336   EXPECT_EQ(0, entry->ReadSparseData(2 * k1Meg + 8192, buf1, kSize, NULL));
   1337   EXPECT_EQ(kSize, entry->WriteSparseData(k1Meg + 16384, buf1, kSize, NULL));
   1338   EXPECT_EQ(0, entry->ReadSparseData(k1Meg + 8192, buf1, kSize, NULL));
   1339 
   1340   // We never touched this one.
   1341   EXPECT_EQ(kSize, entry->ReadSparseData(8192, buf1, kSize, NULL));
   1342   entry->Close();
   1343 
   1344   // We re-created one of the corrupt children.
   1345   EXPECT_EQ(3, cache_->GetEntryCount());
   1346 }
   1347 
   1348 TEST_F(DiskCacheEntryTest, CancelSparseIO) {
   1349   InitCache();
   1350   std::string key("the first key");
   1351   disk_cache::Entry* entry;
   1352   ASSERT_TRUE(cache_->CreateEntry(key, &entry));
   1353 
   1354   const int kSize = 40 * 1024;
   1355   scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(kSize);
   1356   CacheTestFillBuffer(buf->data(), kSize, false);
   1357 
   1358   TestCompletionCallback cb1, cb2, cb3, cb4;
   1359   int64 offset = 0;
   1360   int tries = 0;
   1361   const int maxtries = 100;   // Avoid hang on infinitely fast disks
   1362   for (int ret = 0; ret != net::ERR_IO_PENDING; offset += kSize * 4) {
   1363     ret = entry->WriteSparseData(offset, buf, kSize, &cb1);
   1364     if (++tries > maxtries) {
   1365        LOG(ERROR) << "Data writes never come back PENDING; skipping test";
   1366        entry->Close();
   1367        return;
   1368     }
   1369   }
   1370 
   1371   // Cannot use the entry at this point.
   1372   offset = 0;
   1373   EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED,
   1374             entry->GetAvailableRange(offset, kSize, &offset));
   1375   EXPECT_EQ(net::OK, entry->ReadyForSparseIO(&cb2));
   1376 
   1377   // We cancel the pending operation, and register multiple notifications.
   1378   entry->CancelSparseIO();
   1379   EXPECT_EQ(net::ERR_IO_PENDING, entry->ReadyForSparseIO(&cb2));
   1380   EXPECT_EQ(net::ERR_IO_PENDING, entry->ReadyForSparseIO(&cb3));
   1381   entry->CancelSparseIO();  // Should be a no op at this point.
   1382   EXPECT_EQ(net::ERR_IO_PENDING, entry->ReadyForSparseIO(&cb4));
   1383 
   1384   offset = 0;
   1385   EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED,
   1386             entry->GetAvailableRange(offset, kSize, &offset));
   1387   EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED,
   1388             entry->ReadSparseData(offset, buf, kSize, NULL));
   1389   EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED,
   1390             entry->WriteSparseData(offset, buf, kSize, NULL));
   1391 
   1392   // Now see if we receive all notifications.
   1393   EXPECT_EQ(kSize, cb1.GetResult(net::ERR_IO_PENDING));
   1394   EXPECT_EQ(net::OK, cb2.GetResult(net::ERR_IO_PENDING));
   1395   EXPECT_EQ(net::OK, cb3.GetResult(net::ERR_IO_PENDING));
   1396   EXPECT_EQ(net::OK, cb4.GetResult(net::ERR_IO_PENDING));
   1397 
   1398   EXPECT_EQ(kSize, entry->GetAvailableRange(offset, kSize, &offset));
   1399   EXPECT_EQ(net::OK, entry->ReadyForSparseIO(&cb2));
   1400   entry->Close();
   1401 }
   1402