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.
5 #include "net/disk_cache/disk_cache_test_base.h"
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"
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());
29 DiskCacheTest::~DiskCacheTest() {
32 bool DiskCacheTest::CopyTestCache(const std::string
& name
) {
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
);
40 if (!CleanupCacheDir())
42 return base::CopyDirectory(path
, cache_path_
, false);
45 bool DiskCacheTest::CleanupCacheDir() {
46 return DeleteCache(cache_path_
);
49 void DiskCacheTest::TearDown() {
50 base::RunLoop().RunUntilIdle();
53 DiskCacheTestWithCache::DiskCacheTestWithCache()
55 simple_cache_impl_(NULL
),
59 type_(net::DISK_CACHE
),
61 simple_cache_mode_(false),
62 simple_cache_wait_for_index_(true),
63 force_creation_(false),
67 use_current_thread_(false),
68 cache_thread_("CacheThread") {
71 DiskCacheTestWithCache::~DiskCacheTestWithCache() {}
73 void DiskCacheTestWithCache::InitCache() {
79 ASSERT_TRUE(NULL
!= cache_
);
81 ASSERT_EQ(0, cache_
->GetEntryCount());
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();
93 EXPECT_TRUE(CheckCacheIntegrity(cache_path_
, new_eviction_
, mask_
));
95 CreateBackend(disk_cache::kNoRandom
, &cache_thread_
);
98 void DiskCacheTestWithCache::SetTestMode() {
99 ASSERT_TRUE(!memory_only_
);
100 cache_impl_
->SetUnitTestMode();
103 void DiskCacheTestWithCache::SetMaxSize(int size
) {
105 if (simple_cache_impl_
)
106 EXPECT_TRUE(simple_cache_impl_
->SetMaxSize(size
));
109 EXPECT_TRUE(cache_impl_
->SetMaxSize(size
));
112 EXPECT_TRUE(mem_cache_
->SetMaxSize(size
));
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
);
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
);
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
);
135 int DiskCacheTestWithCache::DoomAllEntries() {
136 net::TestCompletionCallback cb
;
137 int rv
= cache_
->DoomAllEntries(cb
.callback());
138 return cb
.GetResult(rv
);
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
);
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
);
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
);
161 void DiskCacheTestWithCache::FlushQueueForTest() {
162 if (memory_only_
|| !cache_impl_
)
165 net::TestCompletionCallback cb
;
166 int rv
= cache_impl_
->FlushQueueForTest(cb
.callback());
167 EXPECT_EQ(net::OK
, cb
.GetResult(rv
));
170 void DiskCacheTestWithCache::RunTaskForTest(const base::Closure
& closure
) {
171 if (memory_only_
|| !cache_impl_
) {
176 net::TestCompletionCallback cb
;
177 int rv
= cache_impl_
->RunTaskForTest(closure
, cb
.callback());
178 EXPECT_EQ(net::OK
, cb
.GetResult(rv
));
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
);
188 int DiskCacheTestWithCache::WriteData(disk_cache::Entry
* entry
, int index
,
189 int offset
, net::IOBuffer
* buf
, int len
,
191 net::TestCompletionCallback cb
;
192 int rv
= entry
->WriteData(index
, offset
, buf
, len
, cb
.callback(), truncate
);
193 return cb
.GetResult(rv
);
196 int DiskCacheTestWithCache::ReadSparseData(disk_cache::Entry
* entry
,
197 int64 offset
, net::IOBuffer
* buf
,
199 net::TestCompletionCallback cb
;
200 int rv
= entry
->ReadSparseData(offset
, buf
, len
, cb
.callback());
201 return cb
.GetResult(rv
);
204 int DiskCacheTestWithCache::WriteSparseData(disk_cache::Entry
* entry
,
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
);
212 void DiskCacheTestWithCache::TrimForTest(bool empty
) {
213 RunTaskForTest(base::Bind(&disk_cache::BackendImpl::TrimForTest
,
214 base::Unretained(cache_impl_
),
218 void DiskCacheTestWithCache::TrimDeletedListForTest(bool empty
) {
219 RunTaskForTest(base::Bind(&disk_cache::BackendImpl::TrimDeletedListForTest
,
220 base::Unretained(cache_impl_
),
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();
231 base::PlatformThread::YieldCurrentThread();
232 } while (base::Time::Now() -
233 initial_time
< base::TimeDelta::FromSeconds(1));
236 base::Time initial
= base::Time::Now();
237 while (base::Time::Now() <= initial
) {
238 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
242 void DiskCacheTestWithCache::TearDown() {
243 base::RunLoop().RunUntilIdle();
244 disk_cache::SimpleBackendImpl::FlushWorkerPoolForTesting();
245 base::RunLoop().RunUntilIdle();
247 if (cache_thread_
.IsRunning())
248 cache_thread_
.Stop();
250 if (!memory_only_
&& !simple_cache_mode_
&& integrity_
) {
251 EXPECT_TRUE(CheckCacheIntegrity(cache_path_
, new_eviction_
, mask_
));
253 base::RunLoop().RunUntilIdle();
254 disk_cache::SimpleBackendImpl::FlushWorkerPoolForTesting();
255 DiskCacheTest::TearDown();
258 void DiskCacheTestWithCache::InitMemoryCache() {
259 mem_cache_
= new disk_cache::MemBackendImpl(NULL
);
260 cache_
.reset(mem_cache_
);
264 EXPECT_TRUE(mem_cache_
->SetMaxSize(size_
));
266 ASSERT_TRUE(mem_cache_
->Init());
269 void DiskCacheTestWithCache::InitDiskCache() {
271 ASSERT_TRUE(CleanupCacheDir());
273 if (!cache_thread_
.IsRunning()) {
274 ASSERT_TRUE(cache_thread_
.StartWithOptions(
275 base::Thread::Options(base::MessageLoop::TYPE_IO
, 0)));
277 ASSERT_TRUE(cache_thread_
.message_loop() != NULL
);
279 CreateBackend(disk_cache::kNoRandom
, &cache_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();
287 runner
= thread
->message_loop_proxy().get();
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
));
308 cache_impl_
= new disk_cache::BackendImpl(cache_path_
, mask_
, runner
, NULL
);
310 cache_impl_
= new disk_cache::BackendImpl(cache_path_
, runner
, NULL
);
311 cache_
.reset(cache_impl_
);
314 EXPECT_TRUE(cache_impl_
->SetMaxSize(size_
));
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
));