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 "net/disk_cache/disk_cache_test_base.h"
      6 
      7 #include "base/file_util.h"
      8 #include "base/path_service.h"
      9 #include "base/run_loop.h"
     10 #include "base/threading/platform_thread.h"
     11 #include "net/base/io_buffer.h"
     12 #include "net/base/net_errors.h"
     13 #include "net/base/test_completion_callback.h"
     14 #include "net/disk_cache/backend_impl.h"
     15 #include "net/disk_cache/cache_util.h"
     16 #include "net/disk_cache/disk_cache.h"
     17 #include "net/disk_cache/disk_cache_test_util.h"
     18 #include "net/disk_cache/mem_backend_impl.h"
     19 #include "net/disk_cache/simple/simple_backend_impl.h"
     20 #include "net/disk_cache/simple/simple_index.h"
     21 
     22 DiskCacheTest::DiskCacheTest() {
     23   CHECK(temp_dir_.CreateUniqueTempDir());
     24   cache_path_ = temp_dir_.path();
     25   if (!base::MessageLoop::current())
     26     message_loop_.reset(new base::MessageLoopForIO());
     27 }
     28 
     29 DiskCacheTest::~DiskCacheTest() {
     30 }
     31 
     32 bool DiskCacheTest::CopyTestCache(const std::string& name) {
     33   base::FilePath path;
     34   PathService::Get(base::DIR_SOURCE_ROOT, &path);
     35   path = path.AppendASCII("net");
     36   path = path.AppendASCII("data");
     37   path = path.AppendASCII("cache_tests");
     38   path = path.AppendASCII(name);
     39 
     40   if (!CleanupCacheDir())
     41     return false;
     42   return base::CopyDirectory(path, cache_path_, false);
     43 }
     44 
     45 bool DiskCacheTest::CleanupCacheDir() {
     46   return DeleteCache(cache_path_);
     47 }
     48 
     49 void DiskCacheTest::TearDown() {
     50   base::RunLoop().RunUntilIdle();
     51 }
     52 
     53 DiskCacheTestWithCache::DiskCacheTestWithCache()
     54     : cache_impl_(NULL),
     55       simple_cache_impl_(NULL),
     56       mem_cache_(NULL),
     57       mask_(0),
     58       size_(0),
     59       type_(net::DISK_CACHE),
     60       memory_only_(false),
     61       simple_cache_mode_(false),
     62       simple_cache_wait_for_index_(true),
     63       force_creation_(false),
     64       new_eviction_(false),
     65       first_cleanup_(true),
     66       integrity_(true),
     67       use_current_thread_(false),
     68       cache_thread_("CacheThread") {
     69 }
     70 
     71 DiskCacheTestWithCache::~DiskCacheTestWithCache() {}
     72 
     73 void DiskCacheTestWithCache::InitCache() {
     74   if (memory_only_)
     75     InitMemoryCache();
     76   else
     77     InitDiskCache();
     78 
     79   ASSERT_TRUE(NULL != cache_);
     80   if (first_cleanup_)
     81     ASSERT_EQ(0, cache_->GetEntryCount());
     82 }
     83 
     84 // We are expected to leak memory when simulating crashes.
     85 void DiskCacheTestWithCache::SimulateCrash() {
     86   ASSERT_TRUE(!memory_only_);
     87   net::TestCompletionCallback cb;
     88   int rv = cache_impl_->FlushQueueForTest(cb.callback());
     89   ASSERT_EQ(net::OK, cb.GetResult(rv));
     90   cache_impl_->ClearRefCountForTest();
     91 
     92   cache_.reset();
     93   EXPECT_TRUE(CheckCacheIntegrity(cache_path_, new_eviction_, mask_));
     94 
     95   CreateBackend(disk_cache::kNoRandom, &cache_thread_);
     96 }
     97 
     98 void DiskCacheTestWithCache::SetTestMode() {
     99   ASSERT_TRUE(!memory_only_);
    100   cache_impl_->SetUnitTestMode();
    101 }
    102 
    103 void DiskCacheTestWithCache::SetMaxSize(int size) {
    104   size_ = size;
    105   if (simple_cache_impl_)
    106     EXPECT_TRUE(simple_cache_impl_->SetMaxSize(size));
    107 
    108   if (cache_impl_)
    109     EXPECT_TRUE(cache_impl_->SetMaxSize(size));
    110 
    111   if (mem_cache_)
    112     EXPECT_TRUE(mem_cache_->SetMaxSize(size));
    113 }
    114 
    115 int DiskCacheTestWithCache::OpenEntry(const std::string& key,
    116                                       disk_cache::Entry** entry) {
    117   net::TestCompletionCallback cb;
    118   int rv = cache_->OpenEntry(key, entry, cb.callback());
    119   return cb.GetResult(rv);
    120 }
    121 
    122 int DiskCacheTestWithCache::CreateEntry(const std::string& key,
    123                                         disk_cache::Entry** entry) {
    124   net::TestCompletionCallback cb;
    125   int rv = cache_->CreateEntry(key, entry, cb.callback());
    126   return cb.GetResult(rv);
    127 }
    128 
    129 int DiskCacheTestWithCache::DoomEntry(const std::string& key) {
    130   net::TestCompletionCallback cb;
    131   int rv = cache_->DoomEntry(key, cb.callback());
    132   return cb.GetResult(rv);
    133 }
    134 
    135 int DiskCacheTestWithCache::DoomAllEntries() {
    136   net::TestCompletionCallback cb;
    137   int rv = cache_->DoomAllEntries(cb.callback());
    138   return cb.GetResult(rv);
    139 }
    140 
    141 int DiskCacheTestWithCache::DoomEntriesBetween(const base::Time initial_time,
    142                                                const base::Time end_time) {
    143   net::TestCompletionCallback cb;
    144   int rv = cache_->DoomEntriesBetween(initial_time, end_time, cb.callback());
    145   return cb.GetResult(rv);
    146 }
    147 
    148 int DiskCacheTestWithCache::DoomEntriesSince(const base::Time initial_time) {
    149   net::TestCompletionCallback cb;
    150   int rv = cache_->DoomEntriesSince(initial_time, cb.callback());
    151   return cb.GetResult(rv);
    152 }
    153 
    154 int DiskCacheTestWithCache::OpenNextEntry(void** iter,
    155                                           disk_cache::Entry** next_entry) {
    156   net::TestCompletionCallback cb;
    157   int rv = cache_->OpenNextEntry(iter, next_entry, cb.callback());
    158   return cb.GetResult(rv);
    159 }
    160 
    161 void DiskCacheTestWithCache::FlushQueueForTest() {
    162   if (memory_only_ || !cache_impl_)
    163     return;
    164 
    165   net::TestCompletionCallback cb;
    166   int rv = cache_impl_->FlushQueueForTest(cb.callback());
    167   EXPECT_EQ(net::OK, cb.GetResult(rv));
    168 }
    169 
    170 void DiskCacheTestWithCache::RunTaskForTest(const base::Closure& closure) {
    171   if (memory_only_ || !cache_impl_) {
    172     closure.Run();
    173     return;
    174   }
    175 
    176   net::TestCompletionCallback cb;
    177   int rv = cache_impl_->RunTaskForTest(closure, cb.callback());
    178   EXPECT_EQ(net::OK, cb.GetResult(rv));
    179 }
    180 
    181 int DiskCacheTestWithCache::ReadData(disk_cache::Entry* entry, int index,
    182                                      int offset, net::IOBuffer* buf, int len) {
    183   net::TestCompletionCallback cb;
    184   int rv = entry->ReadData(index, offset, buf, len, cb.callback());
    185   return cb.GetResult(rv);
    186 }
    187 
    188 int DiskCacheTestWithCache::WriteData(disk_cache::Entry* entry, int index,
    189                                       int offset, net::IOBuffer* buf, int len,
    190                                       bool truncate) {
    191   net::TestCompletionCallback cb;
    192   int rv = entry->WriteData(index, offset, buf, len, cb.callback(), truncate);
    193   return cb.GetResult(rv);
    194 }
    195 
    196 int DiskCacheTestWithCache::ReadSparseData(disk_cache::Entry* entry,
    197                                            int64 offset, net::IOBuffer* buf,
    198                                            int len) {
    199   net::TestCompletionCallback cb;
    200   int rv = entry->ReadSparseData(offset, buf, len, cb.callback());
    201   return cb.GetResult(rv);
    202 }
    203 
    204 int DiskCacheTestWithCache::WriteSparseData(disk_cache::Entry* entry,
    205                                             int64 offset,
    206                                             net::IOBuffer* buf, int len) {
    207   net::TestCompletionCallback cb;
    208   int rv = entry->WriteSparseData(offset, buf, len, cb.callback());
    209   return cb.GetResult(rv);
    210 }
    211 
    212 void DiskCacheTestWithCache::TrimForTest(bool empty) {
    213   RunTaskForTest(base::Bind(&disk_cache::BackendImpl::TrimForTest,
    214                             base::Unretained(cache_impl_),
    215                             empty));
    216 }
    217 
    218 void DiskCacheTestWithCache::TrimDeletedListForTest(bool empty) {
    219   RunTaskForTest(base::Bind(&disk_cache::BackendImpl::TrimDeletedListForTest,
    220                             base::Unretained(cache_impl_),
    221                             empty));
    222 }
    223 
    224 void DiskCacheTestWithCache::AddDelay() {
    225   if (simple_cache_mode_) {
    226     // The simple cache uses second resolution for many timeouts, so it's safest
    227     // to advance by at least whole seconds before falling back into the normal
    228     // disk cache epsilon advance.
    229     const base::Time initial_time = base::Time::Now();
    230     do {
    231       base::PlatformThread::YieldCurrentThread();
    232     } while (base::Time::Now() -
    233              initial_time < base::TimeDelta::FromSeconds(1));
    234   }
    235 
    236   base::Time initial = base::Time::Now();
    237   while (base::Time::Now() <= initial) {
    238     base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
    239   };
    240 }
    241 
    242 void DiskCacheTestWithCache::TearDown() {
    243   base::RunLoop().RunUntilIdle();
    244   disk_cache::SimpleBackendImpl::FlushWorkerPoolForTesting();
    245   base::RunLoop().RunUntilIdle();
    246   cache_.reset();
    247   if (cache_thread_.IsRunning())
    248     cache_thread_.Stop();
    249 
    250   if (!memory_only_ && !simple_cache_mode_ && integrity_) {
    251     EXPECT_TRUE(CheckCacheIntegrity(cache_path_, new_eviction_, mask_));
    252   }
    253   base::RunLoop().RunUntilIdle();
    254   disk_cache::SimpleBackendImpl::FlushWorkerPoolForTesting();
    255   DiskCacheTest::TearDown();
    256 }
    257 
    258 void DiskCacheTestWithCache::InitMemoryCache() {
    259   mem_cache_ = new disk_cache::MemBackendImpl(NULL);
    260   cache_.reset(mem_cache_);
    261   ASSERT_TRUE(cache_);
    262 
    263   if (size_)
    264     EXPECT_TRUE(mem_cache_->SetMaxSize(size_));
    265 
    266   ASSERT_TRUE(mem_cache_->Init());
    267 }
    268 
    269 void DiskCacheTestWithCache::InitDiskCache() {
    270   if (first_cleanup_)
    271     ASSERT_TRUE(CleanupCacheDir());
    272 
    273   if (!cache_thread_.IsRunning()) {
    274     ASSERT_TRUE(cache_thread_.StartWithOptions(
    275         base::Thread::Options(base::MessageLoop::TYPE_IO, 0)));
    276   }
    277   ASSERT_TRUE(cache_thread_.message_loop() != NULL);
    278 
    279   CreateBackend(disk_cache::kNoRandom, &cache_thread_);
    280 }
    281 
    282 void DiskCacheTestWithCache::CreateBackend(uint32 flags, base::Thread* thread) {
    283   base::MessageLoopProxy* runner;
    284   if (use_current_thread_)
    285     runner = base::MessageLoopProxy::current().get();
    286   else
    287     runner = thread->message_loop_proxy().get();
    288 
    289   if (simple_cache_mode_) {
    290     net::TestCompletionCallback cb;
    291     scoped_ptr<disk_cache::SimpleBackendImpl> simple_backend(
    292         new disk_cache::SimpleBackendImpl(
    293             cache_path_, size_, type_, make_scoped_refptr(runner).get(), NULL));
    294     int rv = simple_backend->Init(cb.callback());
    295     ASSERT_EQ(net::OK, cb.GetResult(rv));
    296     simple_cache_impl_ = simple_backend.get();
    297     cache_ = simple_backend.PassAs<disk_cache::Backend>();
    298     if (simple_cache_wait_for_index_) {
    299       net::TestCompletionCallback wait_for_index_cb;
    300       rv = simple_cache_impl_->index()->ExecuteWhenReady(
    301           wait_for_index_cb.callback());
    302       ASSERT_EQ(net::OK, wait_for_index_cb.GetResult(rv));
    303     }
    304     return;
    305   }
    306 
    307   if (mask_)
    308     cache_impl_ = new disk_cache::BackendImpl(cache_path_, mask_, runner, NULL);
    309   else
    310     cache_impl_ = new disk_cache::BackendImpl(cache_path_, runner, NULL);
    311   cache_.reset(cache_impl_);
    312   ASSERT_TRUE(cache_);
    313   if (size_)
    314     EXPECT_TRUE(cache_impl_->SetMaxSize(size_));
    315   if (new_eviction_)
    316     cache_impl_->SetNewEviction();
    317   cache_impl_->SetType(type_);
    318   cache_impl_->SetFlags(flags);
    319   net::TestCompletionCallback cb;
    320   int rv = cache_impl_->Init(cb.callback());
    321   ASSERT_EQ(net::OK, cb.GetResult(rv));
    322 }
    323