1 // Copyright (c) 2006-2010 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 "net/base/io_buffer.h"
8 #include "net/base/net_errors.h"
9 #include "net/base/test_completion_callback.h"
10 #include "net/disk_cache/backend_impl.h"
11 #include "net/disk_cache/disk_cache_test_util.h"
12 #include "net/disk_cache/mem_backend_impl.h"
13
TearDown()14 void DiskCacheTest::TearDown() {
15 MessageLoop::current()->RunAllPending();
16 }
17
DiskCacheTestWithCache()18 DiskCacheTestWithCache::DiskCacheTestWithCache()
19 : cache_(NULL),
20 cache_impl_(NULL),
21 mem_cache_(NULL),
22 mask_(0),
23 size_(0),
24 type_(net::DISK_CACHE),
25 memory_only_(false),
26 implementation_(false),
27 force_creation_(false),
28 new_eviction_(false),
29 first_cleanup_(true),
30 integrity_(true),
31 use_current_thread_(false),
32 cache_thread_("CacheThread") {
33 }
34
~DiskCacheTestWithCache()35 DiskCacheTestWithCache::~DiskCacheTestWithCache() {}
36
InitCache()37 void DiskCacheTestWithCache::InitCache() {
38 if (mask_ || new_eviction_)
39 implementation_ = true;
40
41 if (memory_only_)
42 InitMemoryCache();
43 else
44 InitDiskCache();
45
46 ASSERT_TRUE(NULL != cache_);
47 if (first_cleanup_)
48 ASSERT_EQ(0, cache_->GetEntryCount());
49 }
50
51 // We are expected to leak memory when simulating crashes.
SimulateCrash()52 void DiskCacheTestWithCache::SimulateCrash() {
53 ASSERT_TRUE(implementation_ && !memory_only_);
54 TestCompletionCallback cb;
55 int rv = cache_impl_->FlushQueueForTest(&cb);
56 ASSERT_EQ(net::OK, cb.GetResult(rv));
57 cache_impl_->ClearRefCountForTest();
58
59 delete cache_impl_;
60 FilePath path = GetCacheFilePath();
61 EXPECT_TRUE(CheckCacheIntegrity(path, new_eviction_));
62
63 InitDiskCacheImpl(path);
64 }
65
SetTestMode()66 void DiskCacheTestWithCache::SetTestMode() {
67 ASSERT_TRUE(implementation_ && !memory_only_);
68 cache_impl_->SetUnitTestMode();
69 }
70
SetMaxSize(int size)71 void DiskCacheTestWithCache::SetMaxSize(int size) {
72 size_ = size;
73 if (cache_impl_)
74 EXPECT_TRUE(cache_impl_->SetMaxSize(size));
75
76 if (mem_cache_)
77 EXPECT_TRUE(mem_cache_->SetMaxSize(size));
78 }
79
OpenEntry(const std::string & key,disk_cache::Entry ** entry)80 int DiskCacheTestWithCache::OpenEntry(const std::string& key,
81 disk_cache::Entry** entry) {
82 TestCompletionCallback cb;
83 int rv = cache_->OpenEntry(key, entry, &cb);
84 return cb.GetResult(rv);
85 }
86
CreateEntry(const std::string & key,disk_cache::Entry ** entry)87 int DiskCacheTestWithCache::CreateEntry(const std::string& key,
88 disk_cache::Entry** entry) {
89 TestCompletionCallback cb;
90 int rv = cache_->CreateEntry(key, entry, &cb);
91 return cb.GetResult(rv);
92 }
93
DoomEntry(const std::string & key)94 int DiskCacheTestWithCache::DoomEntry(const std::string& key) {
95 TestCompletionCallback cb;
96 int rv = cache_->DoomEntry(key, &cb);
97 return cb.GetResult(rv);
98 }
99
DoomAllEntries()100 int DiskCacheTestWithCache::DoomAllEntries() {
101 TestCompletionCallback cb;
102 int rv = cache_->DoomAllEntries(&cb);
103 return cb.GetResult(rv);
104 }
105
DoomEntriesBetween(const base::Time initial_time,const base::Time end_time)106 int DiskCacheTestWithCache::DoomEntriesBetween(const base::Time initial_time,
107 const base::Time end_time) {
108 TestCompletionCallback cb;
109 int rv = cache_->DoomEntriesBetween(initial_time, end_time, &cb);
110 return cb.GetResult(rv);
111 }
112
DoomEntriesSince(const base::Time initial_time)113 int DiskCacheTestWithCache::DoomEntriesSince(const base::Time initial_time) {
114 TestCompletionCallback cb;
115 int rv = cache_->DoomEntriesSince(initial_time, &cb);
116 return cb.GetResult(rv);
117 }
118
OpenNextEntry(void ** iter,disk_cache::Entry ** next_entry)119 int DiskCacheTestWithCache::OpenNextEntry(void** iter,
120 disk_cache::Entry** next_entry) {
121 TestCompletionCallback cb;
122 int rv = cache_->OpenNextEntry(iter, next_entry, &cb);
123 return cb.GetResult(rv);
124 }
125
FlushQueueForTest()126 void DiskCacheTestWithCache::FlushQueueForTest() {
127 if (memory_only_ || !cache_impl_)
128 return;
129
130 TestCompletionCallback cb;
131 int rv = cache_impl_->FlushQueueForTest(&cb);
132 EXPECT_EQ(net::OK, cb.GetResult(rv));
133 }
134
RunTaskForTest(Task * task)135 void DiskCacheTestWithCache::RunTaskForTest(Task* task) {
136 if (memory_only_ || !cache_impl_) {
137 task->Run();
138 delete task;
139 return;
140 }
141
142 TestCompletionCallback cb;
143 int rv = cache_impl_->RunTaskForTest(task, &cb);
144 EXPECT_EQ(net::OK, cb.GetResult(rv));
145 }
146
ReadData(disk_cache::Entry * entry,int index,int offset,net::IOBuffer * buf,int len)147 int DiskCacheTestWithCache::ReadData(disk_cache::Entry* entry, int index,
148 int offset, net::IOBuffer* buf, int len) {
149 TestCompletionCallback cb;
150 int rv = entry->ReadData(index, offset, buf, len, &cb);
151 return cb.GetResult(rv);
152 }
153
154
WriteData(disk_cache::Entry * entry,int index,int offset,net::IOBuffer * buf,int len,bool truncate)155 int DiskCacheTestWithCache::WriteData(disk_cache::Entry* entry, int index,
156 int offset, net::IOBuffer* buf, int len,
157 bool truncate) {
158 TestCompletionCallback cb;
159 int rv = entry->WriteData(index, offset, buf, len, &cb, truncate);
160 return cb.GetResult(rv);
161 }
162
ReadSparseData(disk_cache::Entry * entry,int64 offset,net::IOBuffer * buf,int len)163 int DiskCacheTestWithCache::ReadSparseData(disk_cache::Entry* entry,
164 int64 offset, net::IOBuffer* buf,
165 int len) {
166 TestCompletionCallback cb;
167 int rv = entry->ReadSparseData(offset, buf, len, &cb);
168 return cb.GetResult(rv);
169 }
170
WriteSparseData(disk_cache::Entry * entry,int64 offset,net::IOBuffer * buf,int len)171 int DiskCacheTestWithCache::WriteSparseData(disk_cache::Entry* entry,
172 int64 offset,
173 net::IOBuffer* buf, int len) {
174 TestCompletionCallback cb;
175 int rv = entry->WriteSparseData(offset, buf, len, &cb);
176 return cb.GetResult(rv);
177 }
178
179 // Simple task to run part of a test from the cache thread.
180 class TrimTask : public Task {
181 public:
TrimTask(disk_cache::BackendImpl * backend,bool deleted,bool empty)182 TrimTask(disk_cache::BackendImpl* backend, bool deleted, bool empty)
183 : backend_(backend),
184 deleted_(deleted),
185 empty_(empty) {}
186
Run()187 virtual void Run() {
188 if (deleted_)
189 backend_->TrimDeletedListForTest(empty_);
190 else
191 backend_->TrimForTest(empty_);
192 }
193
194 protected:
195 disk_cache::BackendImpl* backend_;
196 bool deleted_;
197 bool empty_;
198 };
199
TrimForTest(bool empty)200 void DiskCacheTestWithCache::TrimForTest(bool empty) {
201 RunTaskForTest(new TrimTask(cache_impl_, false, empty));
202 }
203
TrimDeletedListForTest(bool empty)204 void DiskCacheTestWithCache::TrimDeletedListForTest(bool empty) {
205 RunTaskForTest(new TrimTask(cache_impl_, true, empty));
206 }
207
TearDown()208 void DiskCacheTestWithCache::TearDown() {
209 MessageLoop::current()->RunAllPending();
210 delete cache_;
211 if (cache_thread_.IsRunning())
212 cache_thread_.Stop();
213
214 if (!memory_only_ && integrity_) {
215 FilePath path = GetCacheFilePath();
216 EXPECT_TRUE(CheckCacheIntegrity(path, new_eviction_));
217 }
218
219 PlatformTest::TearDown();
220 }
221
InitMemoryCache()222 void DiskCacheTestWithCache::InitMemoryCache() {
223 if (!implementation_) {
224 cache_ = disk_cache::MemBackendImpl::CreateBackend(size_, NULL);
225 return;
226 }
227
228 mem_cache_ = new disk_cache::MemBackendImpl(NULL);
229 cache_ = mem_cache_;
230 ASSERT_TRUE(NULL != cache_);
231
232 if (size_)
233 EXPECT_TRUE(mem_cache_->SetMaxSize(size_));
234
235 ASSERT_TRUE(mem_cache_->Init());
236 }
237
InitDiskCache()238 void DiskCacheTestWithCache::InitDiskCache() {
239 FilePath path = GetCacheFilePath();
240 if (first_cleanup_)
241 ASSERT_TRUE(DeleteCache(path));
242
243 if (!cache_thread_.IsRunning()) {
244 EXPECT_TRUE(cache_thread_.StartWithOptions(
245 base::Thread::Options(MessageLoop::TYPE_IO, 0)));
246 }
247 ASSERT_TRUE(cache_thread_.message_loop() != NULL);
248
249 if (implementation_)
250 return InitDiskCacheImpl(path);
251
252 scoped_refptr<base::MessageLoopProxy> thread =
253 use_current_thread_ ? base::MessageLoopProxy::CreateForCurrentThread() :
254 cache_thread_.message_loop_proxy();
255
256 TestCompletionCallback cb;
257 int rv = disk_cache::BackendImpl::CreateBackend(
258 path, force_creation_, size_, type_,
259 disk_cache::kNoRandom, thread, NULL, &cache_, &cb);
260 ASSERT_EQ(net::OK, cb.GetResult(rv));
261 }
262
InitDiskCacheImpl(const FilePath & path)263 void DiskCacheTestWithCache::InitDiskCacheImpl(const FilePath& path) {
264 scoped_refptr<base::MessageLoopProxy> thread =
265 use_current_thread_ ? base::MessageLoopProxy::CreateForCurrentThread() :
266 cache_thread_.message_loop_proxy();
267 if (mask_)
268 cache_impl_ = new disk_cache::BackendImpl(path, mask_, thread, NULL);
269 else
270 cache_impl_ = new disk_cache::BackendImpl(path, thread, NULL);
271
272 cache_ = cache_impl_;
273 ASSERT_TRUE(NULL != cache_);
274
275 if (size_)
276 EXPECT_TRUE(cache_impl_->SetMaxSize(size_));
277
278 if (new_eviction_)
279 cache_impl_->SetNewEviction();
280
281 cache_impl_->SetType(type_);
282 cache_impl_->SetFlags(disk_cache::kNoRandom);
283 TestCompletionCallback cb;
284 int rv = cache_impl_->Init(&cb);
285 ASSERT_EQ(net::OK, cb.GetResult(rv));
286 }
287