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 14 void DiskCacheTest::TearDown() { 15 MessageLoop::current()->RunAllPending(); 16 } 17 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 35 DiskCacheTestWithCache::~DiskCacheTestWithCache() {} 36 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. 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 66 void DiskCacheTestWithCache::SetTestMode() { 67 ASSERT_TRUE(implementation_ && !memory_only_); 68 cache_impl_->SetUnitTestMode(); 69 } 70 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 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 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 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 100 int DiskCacheTestWithCache::DoomAllEntries() { 101 TestCompletionCallback cb; 102 int rv = cache_->DoomAllEntries(&cb); 103 return cb.GetResult(rv); 104 } 105 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 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 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 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 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 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 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 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 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: 182 TrimTask(disk_cache::BackendImpl* backend, bool deleted, bool empty) 183 : backend_(backend), 184 deleted_(deleted), 185 empty_(empty) {} 186 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 200 void DiskCacheTestWithCache::TrimForTest(bool empty) { 201 RunTaskForTest(new TrimTask(cache_impl_, false, empty)); 202 } 203 204 void DiskCacheTestWithCache::TrimDeletedListForTest(bool empty) { 205 RunTaskForTest(new TrimTask(cache_impl_, true, empty)); 206 } 207 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 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 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 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