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/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"
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());
31 DiskCacheTest::~DiskCacheTest() {
34 bool DiskCacheTest::CopyTestCache(const std::string
& name
) {
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
);
42 if (!CleanupCacheDir())
44 return base::CopyDirectory(path
, cache_path_
, false);
47 bool DiskCacheTest::CleanupCacheDir() {
48 return DeleteCache(cache_path_
);
51 void DiskCacheTest::TearDown() {
52 base::RunLoop().RunUntilIdle();
55 DiskCacheTestWithCache::TestIterator::TestIterator(
56 scoped_ptr
<disk_cache::Backend::Iterator
> iterator
)
57 : iterator_(iterator
.Pass()) {
60 DiskCacheTestWithCache::TestIterator::~TestIterator() {}
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
);
69 DiskCacheTestWithCache::DiskCacheTestWithCache()
71 simple_cache_impl_(NULL
),
75 type_(net::DISK_CACHE
),
77 simple_cache_mode_(false),
78 simple_cache_wait_for_index_(true),
79 force_creation_(false),
83 use_current_thread_(false),
84 cache_thread_("CacheThread") {
87 DiskCacheTestWithCache::~DiskCacheTestWithCache() {}
89 void DiskCacheTestWithCache::InitCache() {
95 ASSERT_TRUE(NULL
!= cache_
);
97 ASSERT_EQ(0, cache_
->GetEntryCount());
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();
109 EXPECT_TRUE(CheckCacheIntegrity(cache_path_
, new_eviction_
, mask_
));
111 CreateBackend(disk_cache::kNoRandom
, &cache_thread_
);
114 void DiskCacheTestWithCache::SetTestMode() {
115 ASSERT_TRUE(!memory_only_
);
116 cache_impl_
->SetUnitTestMode();
119 void DiskCacheTestWithCache::SetMaxSize(int size
) {
121 if (simple_cache_impl_
)
122 EXPECT_TRUE(simple_cache_impl_
->SetMaxSize(size
));
125 EXPECT_TRUE(cache_impl_
->SetMaxSize(size
));
128 EXPECT_TRUE(mem_cache_
->SetMaxSize(size
));
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
);
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
);
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
);
151 int DiskCacheTestWithCache::DoomAllEntries() {
152 net::TestCompletionCallback cb
;
153 int rv
= cache_
->DoomAllEntries(cb
.callback());
154 return cb
.GetResult(rv
);
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
);
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
);
170 scoped_ptr
<DiskCacheTestWithCache::TestIterator
>
171 DiskCacheTestWithCache::CreateIterator() {
172 return scoped_ptr
<TestIterator
>(new TestIterator(cache_
->CreateIterator()));
175 void DiskCacheTestWithCache::FlushQueueForTest() {
176 if (memory_only_
|| !cache_impl_
)
179 net::TestCompletionCallback cb
;
180 int rv
= cache_impl_
->FlushQueueForTest(cb
.callback());
181 EXPECT_EQ(net::OK
, cb
.GetResult(rv
));
184 void DiskCacheTestWithCache::RunTaskForTest(const base::Closure
& closure
) {
185 if (memory_only_
|| !cache_impl_
) {
190 net::TestCompletionCallback cb
;
191 int rv
= cache_impl_
->RunTaskForTest(closure
, cb
.callback());
192 EXPECT_EQ(net::OK
, cb
.GetResult(rv
));
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
);
202 int DiskCacheTestWithCache::WriteData(disk_cache::Entry
* entry
, int index
,
203 int offset
, net::IOBuffer
* buf
, int len
,
205 net::TestCompletionCallback cb
;
206 int rv
= entry
->WriteData(index
, offset
, buf
, len
, cb
.callback(), truncate
);
207 return cb
.GetResult(rv
);
210 int DiskCacheTestWithCache::ReadSparseData(disk_cache::Entry
* entry
,
211 int64 offset
, net::IOBuffer
* buf
,
213 net::TestCompletionCallback cb
;
214 int rv
= entry
->ReadSparseData(offset
, buf
, len
, cb
.callback());
215 return cb
.GetResult(rv
);
218 int DiskCacheTestWithCache::WriteSparseData(disk_cache::Entry
* entry
,
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
);
226 void DiskCacheTestWithCache::TrimForTest(bool empty
) {
227 RunTaskForTest(base::Bind(&disk_cache::BackendImpl::TrimForTest
,
228 base::Unretained(cache_impl_
),
232 void DiskCacheTestWithCache::TrimDeletedListForTest(bool empty
) {
233 RunTaskForTest(base::Bind(&disk_cache::BackendImpl::TrimDeletedListForTest
,
234 base::Unretained(cache_impl_
),
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();
245 base::PlatformThread::YieldCurrentThread();
246 } while (base::Time::Now() -
247 initial_time
< base::TimeDelta::FromSeconds(1));
250 base::Time initial
= base::Time::Now();
251 while (base::Time::Now() <= initial
) {
252 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
256 void DiskCacheTestWithCache::TearDown() {
257 base::RunLoop().RunUntilIdle();
258 disk_cache::SimpleBackendImpl::FlushWorkerPoolForTesting();
259 base::RunLoop().RunUntilIdle();
261 if (cache_thread_
.IsRunning())
262 cache_thread_
.Stop();
264 if (!memory_only_
&& !simple_cache_mode_
&& integrity_
) {
265 EXPECT_TRUE(CheckCacheIntegrity(cache_path_
, new_eviction_
, mask_
));
267 base::RunLoop().RunUntilIdle();
268 disk_cache::SimpleBackendImpl::FlushWorkerPoolForTesting();
269 DiskCacheTest::TearDown();
272 void DiskCacheTestWithCache::InitMemoryCache() {
273 mem_cache_
= new disk_cache::MemBackendImpl(NULL
);
274 cache_
.reset(mem_cache_
);
278 EXPECT_TRUE(mem_cache_
->SetMaxSize(size_
));
280 ASSERT_TRUE(mem_cache_
->Init());
283 void DiskCacheTestWithCache::InitDiskCache() {
285 ASSERT_TRUE(CleanupCacheDir());
287 if (!cache_thread_
.IsRunning()) {
288 ASSERT_TRUE(cache_thread_
.StartWithOptions(
289 base::Thread::Options(base::MessageLoop::TYPE_IO
, 0)));
291 ASSERT_TRUE(cache_thread_
.message_loop() != NULL
);
293 CreateBackend(disk_cache::kNoRandom
, &cache_thread_
);
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();
301 runner
= thread
->task_runner();
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
.Pass();
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
));
322 cache_impl_
= new disk_cache::BackendImpl(cache_path_
, mask_
, runner
, NULL
);
324 cache_impl_
= new disk_cache::BackendImpl(cache_path_
, runner
, NULL
);
325 cache_
.reset(cache_impl_
);
328 EXPECT_TRUE(cache_impl_
->SetMaxSize(size_
));
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
));