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