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/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::DiskCacheTestWithCache()
57 simple_cache_impl_(NULL
),
61 type_(net::DISK_CACHE
),
63 simple_cache_mode_(false),
64 simple_cache_wait_for_index_(true),
65 force_creation_(false),
69 use_current_thread_(false),
70 cache_thread_("CacheThread") {
73 DiskCacheTestWithCache::~DiskCacheTestWithCache() {}
75 void DiskCacheTestWithCache::InitCache() {
81 ASSERT_TRUE(NULL
!= cache_
);
83 ASSERT_EQ(0, cache_
->GetEntryCount());
86 // We are expected to leak memory when simulating crashes.
87 void DiskCacheTestWithCache::SimulateCrash() {
88 ASSERT_TRUE(!memory_only_
);
89 net::TestCompletionCallback cb
;
90 int rv
= cache_impl_
->FlushQueueForTest(cb
.callback());
91 ASSERT_EQ(net::OK
, cb
.GetResult(rv
));
92 cache_impl_
->ClearRefCountForTest();
95 EXPECT_TRUE(CheckCacheIntegrity(cache_path_
, new_eviction_
, mask_
));
97 CreateBackend(disk_cache::kNoRandom
, &cache_thread_
);
100 void DiskCacheTestWithCache::SetTestMode() {
101 ASSERT_TRUE(!memory_only_
);
102 cache_impl_
->SetUnitTestMode();
105 void DiskCacheTestWithCache::SetMaxSize(int size
) {
107 if (simple_cache_impl_
)
108 EXPECT_TRUE(simple_cache_impl_
->SetMaxSize(size
));
111 EXPECT_TRUE(cache_impl_
->SetMaxSize(size
));
114 EXPECT_TRUE(mem_cache_
->SetMaxSize(size
));
117 int DiskCacheTestWithCache::OpenEntry(const std::string
& key
,
118 disk_cache::Entry
** entry
) {
119 net::TestCompletionCallback cb
;
120 int rv
= cache_
->OpenEntry(key
, entry
, cb
.callback());
121 return cb
.GetResult(rv
);
124 int DiskCacheTestWithCache::CreateEntry(const std::string
& key
,
125 disk_cache::Entry
** entry
) {
126 net::TestCompletionCallback cb
;
127 int rv
= cache_
->CreateEntry(key
, entry
, cb
.callback());
128 return cb
.GetResult(rv
);
131 int DiskCacheTestWithCache::DoomEntry(const std::string
& key
) {
132 net::TestCompletionCallback cb
;
133 int rv
= cache_
->DoomEntry(key
, cb
.callback());
134 return cb
.GetResult(rv
);
137 int DiskCacheTestWithCache::DoomAllEntries() {
138 net::TestCompletionCallback cb
;
139 int rv
= cache_
->DoomAllEntries(cb
.callback());
140 return cb
.GetResult(rv
);
143 int DiskCacheTestWithCache::DoomEntriesBetween(const base::Time initial_time
,
144 const base::Time end_time
) {
145 net::TestCompletionCallback cb
;
146 int rv
= cache_
->DoomEntriesBetween(initial_time
, end_time
, cb
.callback());
147 return cb
.GetResult(rv
);
150 int DiskCacheTestWithCache::DoomEntriesSince(const base::Time initial_time
) {
151 net::TestCompletionCallback cb
;
152 int rv
= cache_
->DoomEntriesSince(initial_time
, cb
.callback());
153 return cb
.GetResult(rv
);
156 int DiskCacheTestWithCache::OpenNextEntry(void** iter
,
157 disk_cache::Entry
** next_entry
) {
158 net::TestCompletionCallback cb
;
159 int rv
= cache_
->OpenNextEntry(iter
, next_entry
, cb
.callback());
160 return cb
.GetResult(rv
);
163 void DiskCacheTestWithCache::FlushQueueForTest() {
164 if (memory_only_
|| !cache_impl_
)
167 net::TestCompletionCallback cb
;
168 int rv
= cache_impl_
->FlushQueueForTest(cb
.callback());
169 EXPECT_EQ(net::OK
, cb
.GetResult(rv
));
172 void DiskCacheTestWithCache::RunTaskForTest(const base::Closure
& closure
) {
173 if (memory_only_
|| !cache_impl_
) {
178 net::TestCompletionCallback cb
;
179 int rv
= cache_impl_
->RunTaskForTest(closure
, cb
.callback());
180 EXPECT_EQ(net::OK
, cb
.GetResult(rv
));
183 int DiskCacheTestWithCache::ReadData(disk_cache::Entry
* entry
, int index
,
184 int offset
, net::IOBuffer
* buf
, int len
) {
185 net::TestCompletionCallback cb
;
186 int rv
= entry
->ReadData(index
, offset
, buf
, len
, cb
.callback());
187 return cb
.GetResult(rv
);
190 int DiskCacheTestWithCache::WriteData(disk_cache::Entry
* entry
, int index
,
191 int offset
, net::IOBuffer
* buf
, int len
,
193 net::TestCompletionCallback cb
;
194 int rv
= entry
->WriteData(index
, offset
, buf
, len
, cb
.callback(), truncate
);
195 return cb
.GetResult(rv
);
198 int DiskCacheTestWithCache::ReadSparseData(disk_cache::Entry
* entry
,
199 int64 offset
, net::IOBuffer
* buf
,
201 net::TestCompletionCallback cb
;
202 int rv
= entry
->ReadSparseData(offset
, buf
, len
, cb
.callback());
203 return cb
.GetResult(rv
);
206 int DiskCacheTestWithCache::WriteSparseData(disk_cache::Entry
* entry
,
208 net::IOBuffer
* buf
, int len
) {
209 net::TestCompletionCallback cb
;
210 int rv
= entry
->WriteSparseData(offset
, buf
, len
, cb
.callback());
211 return cb
.GetResult(rv
);
214 void DiskCacheTestWithCache::TrimForTest(bool empty
) {
215 RunTaskForTest(base::Bind(&disk_cache::BackendImpl::TrimForTest
,
216 base::Unretained(cache_impl_
),
220 void DiskCacheTestWithCache::TrimDeletedListForTest(bool empty
) {
221 RunTaskForTest(base::Bind(&disk_cache::BackendImpl::TrimDeletedListForTest
,
222 base::Unretained(cache_impl_
),
226 void DiskCacheTestWithCache::AddDelay() {
227 if (simple_cache_mode_
) {
228 // The simple cache uses second resolution for many timeouts, so it's safest
229 // to advance by at least whole seconds before falling back into the normal
230 // disk cache epsilon advance.
231 const base::Time initial_time
= base::Time::Now();
233 base::PlatformThread::YieldCurrentThread();
234 } while (base::Time::Now() -
235 initial_time
< base::TimeDelta::FromSeconds(1));
238 base::Time initial
= base::Time::Now();
239 while (base::Time::Now() <= initial
) {
240 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
244 void DiskCacheTestWithCache::TearDown() {
245 base::RunLoop().RunUntilIdle();
246 disk_cache::SimpleBackendImpl::FlushWorkerPoolForTesting();
247 base::RunLoop().RunUntilIdle();
249 if (cache_thread_
.IsRunning())
250 cache_thread_
.Stop();
252 if (!memory_only_
&& !simple_cache_mode_
&& integrity_
) {
253 EXPECT_TRUE(CheckCacheIntegrity(cache_path_
, new_eviction_
, mask_
));
255 base::RunLoop().RunUntilIdle();
256 disk_cache::SimpleBackendImpl::FlushWorkerPoolForTesting();
257 DiskCacheTest::TearDown();
260 void DiskCacheTestWithCache::InitMemoryCache() {
261 mem_cache_
= new disk_cache::MemBackendImpl(NULL
);
262 cache_
.reset(mem_cache_
);
266 EXPECT_TRUE(mem_cache_
->SetMaxSize(size_
));
268 ASSERT_TRUE(mem_cache_
->Init());
271 void DiskCacheTestWithCache::InitDiskCache() {
273 ASSERT_TRUE(CleanupCacheDir());
275 if (!cache_thread_
.IsRunning()) {
276 ASSERT_TRUE(cache_thread_
.StartWithOptions(
277 base::Thread::Options(base::MessageLoop::TYPE_IO
, 0)));
279 ASSERT_TRUE(cache_thread_
.message_loop() != NULL
);
281 CreateBackend(disk_cache::kNoRandom
, &cache_thread_
);
284 void DiskCacheTestWithCache::CreateBackend(uint32 flags
, base::Thread
* thread
) {
285 scoped_refptr
<base::SingleThreadTaskRunner
> runner
;
286 if (use_current_thread_
)
287 runner
= base::ThreadTaskRunnerHandle::Get();
289 runner
= thread
->task_runner();
291 if (simple_cache_mode_
) {
292 net::TestCompletionCallback cb
;
293 scoped_ptr
<disk_cache::SimpleBackendImpl
> simple_backend(
294 new disk_cache::SimpleBackendImpl(
295 cache_path_
, size_
, type_
, runner
, NULL
));
296 int rv
= simple_backend
->Init(cb
.callback());
297 ASSERT_EQ(net::OK
, cb
.GetResult(rv
));
298 simple_cache_impl_
= simple_backend
.get();
299 cache_
= simple_backend
.PassAs
<disk_cache::Backend
>();
300 if (simple_cache_wait_for_index_
) {
301 net::TestCompletionCallback wait_for_index_cb
;
302 rv
= simple_cache_impl_
->index()->ExecuteWhenReady(
303 wait_for_index_cb
.callback());
304 ASSERT_EQ(net::OK
, wait_for_index_cb
.GetResult(rv
));
310 cache_impl_
= new disk_cache::BackendImpl(cache_path_
, mask_
, runner
, NULL
);
312 cache_impl_
= new disk_cache::BackendImpl(cache_path_
, runner
, NULL
);
313 cache_
.reset(cache_impl_
);
316 EXPECT_TRUE(cache_impl_
->SetMaxSize(size_
));
318 cache_impl_
->SetNewEviction();
319 cache_impl_
->SetType(type_
);
320 cache_impl_
->SetFlags(flags
);
321 net::TestCompletionCallback cb
;
322 int rv
= cache_impl_
->Init(cb
.callback());
323 ASSERT_EQ(net::OK
, cb
.GetResult(rv
));