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 "net/base/io_buffer.h" 11 #include "net/base/net_errors.h" 12 #include "net/base/test_completion_callback.h" 13 #include "net/disk_cache/backend_impl.h" 14 #include "net/disk_cache/cache_util.h" 15 #include "net/disk_cache/disk_cache.h" 16 #include "net/disk_cache/disk_cache_test_util.h" 17 #include "net/disk_cache/mem_backend_impl.h" 18 #include "net/disk_cache/simple/simple_backend_impl.h" 19 #include "net/disk_cache/simple/simple_index.h" 20 21 DiskCacheTest::DiskCacheTest() { 22 CHECK(temp_dir_.CreateUniqueTempDir()); 23 cache_path_ = temp_dir_.path(); 24 if (!base::MessageLoop::current()) 25 message_loop_.reset(new base::MessageLoopForIO()); 26 } 27 28 DiskCacheTest::~DiskCacheTest() { 29 } 30 31 bool DiskCacheTest::CopyTestCache(const std::string& name) { 32 base::FilePath path; 33 PathService::Get(base::DIR_SOURCE_ROOT, &path); 34 path = path.AppendASCII("net"); 35 path = path.AppendASCII("data"); 36 path = path.AppendASCII("cache_tests"); 37 path = path.AppendASCII(name); 38 39 if (!CleanupCacheDir()) 40 return false; 41 return base::CopyDirectory(path, cache_path_, false); 42 } 43 44 bool DiskCacheTest::CleanupCacheDir() { 45 return DeleteCache(cache_path_); 46 } 47 48 void DiskCacheTest::TearDown() { 49 base::RunLoop().RunUntilIdle(); 50 } 51 52 DiskCacheTestWithCache::DiskCacheTestWithCache() 53 : cache_impl_(NULL), 54 simple_cache_impl_(NULL), 55 mem_cache_(NULL), 56 mask_(0), 57 size_(0), 58 type_(net::DISK_CACHE), 59 memory_only_(false), 60 simple_cache_mode_(false), 61 simple_cache_wait_for_index_(true), 62 force_creation_(false), 63 new_eviction_(false), 64 first_cleanup_(true), 65 integrity_(true), 66 use_current_thread_(false), 67 cache_thread_("CacheThread") { 68 } 69 70 DiskCacheTestWithCache::~DiskCacheTestWithCache() {} 71 72 void DiskCacheTestWithCache::InitCache() { 73 if (memory_only_) 74 InitMemoryCache(); 75 else 76 InitDiskCache(); 77 78 ASSERT_TRUE(NULL != cache_); 79 if (first_cleanup_) 80 ASSERT_EQ(0, cache_->GetEntryCount()); 81 } 82 83 // We are expected to leak memory when simulating crashes. 84 void DiskCacheTestWithCache::SimulateCrash() { 85 ASSERT_TRUE(!memory_only_); 86 net::TestCompletionCallback cb; 87 int rv = cache_impl_->FlushQueueForTest(cb.callback()); 88 ASSERT_EQ(net::OK, cb.GetResult(rv)); 89 cache_impl_->ClearRefCountForTest(); 90 91 cache_.reset(); 92 EXPECT_TRUE(CheckCacheIntegrity(cache_path_, new_eviction_, mask_)); 93 94 CreateBackend(disk_cache::kNoRandom, &cache_thread_); 95 } 96 97 void DiskCacheTestWithCache::SetTestMode() { 98 ASSERT_TRUE(!memory_only_); 99 cache_impl_->SetUnitTestMode(); 100 } 101 102 void DiskCacheTestWithCache::SetMaxSize(int size) { 103 size_ = size; 104 if (simple_cache_impl_) 105 EXPECT_TRUE(simple_cache_impl_->SetMaxSize(size)); 106 107 if (cache_impl_) 108 EXPECT_TRUE(cache_impl_->SetMaxSize(size)); 109 110 if (mem_cache_) 111 EXPECT_TRUE(mem_cache_->SetMaxSize(size)); 112 } 113 114 int DiskCacheTestWithCache::OpenEntry(const std::string& key, 115 disk_cache::Entry** entry) { 116 net::TestCompletionCallback cb; 117 int rv = cache_->OpenEntry(key, entry, cb.callback()); 118 return cb.GetResult(rv); 119 } 120 121 int DiskCacheTestWithCache::CreateEntry(const std::string& key, 122 disk_cache::Entry** entry) { 123 net::TestCompletionCallback cb; 124 int rv = cache_->CreateEntry(key, entry, cb.callback()); 125 return cb.GetResult(rv); 126 } 127 128 int DiskCacheTestWithCache::DoomEntry(const std::string& key) { 129 net::TestCompletionCallback cb; 130 int rv = cache_->DoomEntry(key, cb.callback()); 131 return cb.GetResult(rv); 132 } 133 134 int DiskCacheTestWithCache::DoomAllEntries() { 135 net::TestCompletionCallback cb; 136 int rv = cache_->DoomAllEntries(cb.callback()); 137 return cb.GetResult(rv); 138 } 139 140 int DiskCacheTestWithCache::DoomEntriesBetween(const base::Time initial_time, 141 const base::Time end_time) { 142 net::TestCompletionCallback cb; 143 int rv = cache_->DoomEntriesBetween(initial_time, end_time, cb.callback()); 144 return cb.GetResult(rv); 145 } 146 147 int DiskCacheTestWithCache::DoomEntriesSince(const base::Time initial_time) { 148 net::TestCompletionCallback cb; 149 int rv = cache_->DoomEntriesSince(initial_time, cb.callback()); 150 return cb.GetResult(rv); 151 } 152 153 int DiskCacheTestWithCache::OpenNextEntry(void** iter, 154 disk_cache::Entry** next_entry) { 155 net::TestCompletionCallback cb; 156 int rv = cache_->OpenNextEntry(iter, next_entry, cb.callback()); 157 return cb.GetResult(rv); 158 } 159 160 void DiskCacheTestWithCache::FlushQueueForTest() { 161 if (memory_only_ || !cache_impl_) 162 return; 163 164 net::TestCompletionCallback cb; 165 int rv = cache_impl_->FlushQueueForTest(cb.callback()); 166 EXPECT_EQ(net::OK, cb.GetResult(rv)); 167 } 168 169 void DiskCacheTestWithCache::RunTaskForTest(const base::Closure& closure) { 170 if (memory_only_ || !cache_impl_) { 171 closure.Run(); 172 return; 173 } 174 175 net::TestCompletionCallback cb; 176 int rv = cache_impl_->RunTaskForTest(closure, cb.callback()); 177 EXPECT_EQ(net::OK, cb.GetResult(rv)); 178 } 179 180 int DiskCacheTestWithCache::ReadData(disk_cache::Entry* entry, int index, 181 int offset, net::IOBuffer* buf, int len) { 182 net::TestCompletionCallback cb; 183 int rv = entry->ReadData(index, offset, buf, len, cb.callback()); 184 return cb.GetResult(rv); 185 } 186 187 int DiskCacheTestWithCache::WriteData(disk_cache::Entry* entry, int index, 188 int offset, net::IOBuffer* buf, int len, 189 bool truncate) { 190 net::TestCompletionCallback cb; 191 int rv = entry->WriteData(index, offset, buf, len, cb.callback(), truncate); 192 return cb.GetResult(rv); 193 } 194 195 int DiskCacheTestWithCache::ReadSparseData(disk_cache::Entry* entry, 196 int64 offset, net::IOBuffer* buf, 197 int len) { 198 net::TestCompletionCallback cb; 199 int rv = entry->ReadSparseData(offset, buf, len, cb.callback()); 200 return cb.GetResult(rv); 201 } 202 203 int DiskCacheTestWithCache::WriteSparseData(disk_cache::Entry* entry, 204 int64 offset, 205 net::IOBuffer* buf, int len) { 206 net::TestCompletionCallback cb; 207 int rv = entry->WriteSparseData(offset, buf, len, cb.callback()); 208 return cb.GetResult(rv); 209 } 210 211 void DiskCacheTestWithCache::TrimForTest(bool empty) { 212 RunTaskForTest(base::Bind(&disk_cache::BackendImpl::TrimForTest, 213 base::Unretained(cache_impl_), 214 empty)); 215 } 216 217 void DiskCacheTestWithCache::TrimDeletedListForTest(bool empty) { 218 RunTaskForTest(base::Bind(&disk_cache::BackendImpl::TrimDeletedListForTest, 219 base::Unretained(cache_impl_), 220 empty)); 221 } 222 223 void DiskCacheTestWithCache::AddDelay() { 224 base::Time initial = base::Time::Now(); 225 while (base::Time::Now() <= initial) { 226 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); 227 }; 228 } 229 230 void DiskCacheTestWithCache::TearDown() { 231 base::RunLoop().RunUntilIdle(); 232 cache_.reset(); 233 if (cache_thread_.IsRunning()) 234 cache_thread_.Stop(); 235 236 if (!memory_only_ && !simple_cache_mode_ && integrity_) { 237 EXPECT_TRUE(CheckCacheIntegrity(cache_path_, new_eviction_, mask_)); 238 } 239 240 PlatformTest::TearDown(); 241 } 242 243 void DiskCacheTestWithCache::InitMemoryCache() { 244 mem_cache_ = new disk_cache::MemBackendImpl(NULL); 245 cache_.reset(mem_cache_); 246 ASSERT_TRUE(cache_); 247 248 if (size_) 249 EXPECT_TRUE(mem_cache_->SetMaxSize(size_)); 250 251 ASSERT_TRUE(mem_cache_->Init()); 252 } 253 254 void DiskCacheTestWithCache::InitDiskCache() { 255 if (first_cleanup_) 256 ASSERT_TRUE(CleanupCacheDir()); 257 258 if (!cache_thread_.IsRunning()) { 259 ASSERT_TRUE(cache_thread_.StartWithOptions( 260 base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); 261 } 262 ASSERT_TRUE(cache_thread_.message_loop() != NULL); 263 264 CreateBackend(disk_cache::kNoRandom, &cache_thread_); 265 } 266 267 void DiskCacheTestWithCache::CreateBackend(uint32 flags, base::Thread* thread) { 268 base::MessageLoopProxy* runner; 269 if (use_current_thread_) 270 runner = base::MessageLoopProxy::current().get(); 271 else 272 runner = thread->message_loop_proxy().get(); 273 274 if (simple_cache_mode_) { 275 net::TestCompletionCallback cb; 276 scoped_ptr<disk_cache::SimpleBackendImpl> simple_backend( 277 new disk_cache::SimpleBackendImpl( 278 cache_path_, size_, type_, make_scoped_refptr(runner).get(), NULL)); 279 int rv = simple_backend->Init(cb.callback()); 280 ASSERT_EQ(net::OK, cb.GetResult(rv)); 281 simple_cache_impl_ = simple_backend.get(); 282 cache_ = simple_backend.PassAs<disk_cache::Backend>(); 283 if (simple_cache_wait_for_index_) { 284 net::TestCompletionCallback wait_for_index_cb; 285 rv = simple_cache_impl_->index()->ExecuteWhenReady( 286 wait_for_index_cb.callback()); 287 ASSERT_EQ(net::OK, wait_for_index_cb.GetResult(rv)); 288 } 289 return; 290 } 291 292 if (mask_) 293 cache_impl_ = new disk_cache::BackendImpl(cache_path_, mask_, runner, NULL); 294 else 295 cache_impl_ = new disk_cache::BackendImpl(cache_path_, runner, NULL); 296 cache_.reset(cache_impl_); 297 ASSERT_TRUE(cache_); 298 if (size_) 299 EXPECT_TRUE(cache_impl_->SetMaxSize(size_)); 300 if (new_eviction_) 301 cache_impl_->SetNewEviction(); 302 cache_impl_->SetType(type_); 303 cache_impl_->SetFlags(flags); 304 net::TestCompletionCallback cb; 305 int rv = cache_impl_->Init(cb.callback()); 306 ASSERT_EQ(net::OK, cb.GetResult(rv)); 307 } 308