• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/blockfile/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/memory/mem_backend_impl.h"
19 #include "net/disk_cache/simple/simple_backend_impl.h"
20 #include "net/disk_cache/simple/simple_index.h"
21 
DiskCacheTest()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 
~DiskCacheTest()29 DiskCacheTest::~DiskCacheTest() {
30 }
31 
CopyTestCache(const std::string & name)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 
CleanupCacheDir()45 bool DiskCacheTest::CleanupCacheDir() {
46   return DeleteCache(cache_path_);
47 }
48 
TearDown()49 void DiskCacheTest::TearDown() {
50   base::RunLoop().RunUntilIdle();
51 }
52 
DiskCacheTestWithCache()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 
~DiskCacheTestWithCache()71 DiskCacheTestWithCache::~DiskCacheTestWithCache() {}
72 
InitCache()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.
SimulateCrash()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 
SetTestMode()98 void DiskCacheTestWithCache::SetTestMode() {
99   ASSERT_TRUE(!memory_only_);
100   cache_impl_->SetUnitTestMode();
101 }
102 
SetMaxSize(int size)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 
OpenEntry(const std::string & key,disk_cache::Entry ** entry)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 
CreateEntry(const std::string & key,disk_cache::Entry ** entry)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 
DoomEntry(const std::string & key)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 
DoomAllEntries()135 int DiskCacheTestWithCache::DoomAllEntries() {
136   net::TestCompletionCallback cb;
137   int rv = cache_->DoomAllEntries(cb.callback());
138   return cb.GetResult(rv);
139 }
140 
DoomEntriesBetween(const base::Time initial_time,const base::Time end_time)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 
DoomEntriesSince(const base::Time initial_time)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 
OpenNextEntry(void ** iter,disk_cache::Entry ** next_entry)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 
FlushQueueForTest()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 
RunTaskForTest(const base::Closure & closure)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 
ReadData(disk_cache::Entry * entry,int index,int offset,net::IOBuffer * buf,int len)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 
WriteData(disk_cache::Entry * entry,int index,int offset,net::IOBuffer * buf,int len,bool truncate)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 
ReadSparseData(disk_cache::Entry * entry,int64 offset,net::IOBuffer * buf,int len)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 
WriteSparseData(disk_cache::Entry * entry,int64 offset,net::IOBuffer * buf,int len)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 
TrimForTest(bool empty)212 void DiskCacheTestWithCache::TrimForTest(bool empty) {
213   RunTaskForTest(base::Bind(&disk_cache::BackendImpl::TrimForTest,
214                             base::Unretained(cache_impl_),
215                             empty));
216 }
217 
TrimDeletedListForTest(bool empty)218 void DiskCacheTestWithCache::TrimDeletedListForTest(bool empty) {
219   RunTaskForTest(base::Bind(&disk_cache::BackendImpl::TrimDeletedListForTest,
220                             base::Unretained(cache_impl_),
221                             empty));
222 }
223 
AddDelay()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 
TearDown()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 
InitMemoryCache()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 
InitDiskCache()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 
CreateBackend(uint32 flags,base::Thread * thread)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