OLD | NEW |
1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/basictypes.h" | 5 #include "base/basictypes.h" |
6 #include "base/file_util.h" | 6 #include "base/file_util.h" |
7 #include "base/path_service.h" | 7 #include "base/path_service.h" |
8 #include "base/platform_thread.h" | 8 #include "base/platform_thread.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "base/thread.h" |
10 #include "net/base/io_buffer.h" | 11 #include "net/base/io_buffer.h" |
11 #include "net/base/net_errors.h" | 12 #include "net/base/net_errors.h" |
12 #include "net/base/test_completion_callback.h" | 13 #include "net/base/test_completion_callback.h" |
13 #include "net/disk_cache/backend_impl.h" | 14 #include "net/disk_cache/backend_impl.h" |
14 #include "net/disk_cache/disk_cache_test_base.h" | 15 #include "net/disk_cache/disk_cache_test_base.h" |
15 #include "net/disk_cache/disk_cache_test_util.h" | 16 #include "net/disk_cache/disk_cache_test_util.h" |
16 #include "net/disk_cache/histogram_macros.h" | 17 #include "net/disk_cache/histogram_macros.h" |
17 #include "net/disk_cache/mapped_file.h" | 18 #include "net/disk_cache/mapped_file.h" |
| 19 #include "net/disk_cache/mem_backend_impl.h" |
18 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
19 | 21 |
20 using base::Time; | 22 using base::Time; |
21 | 23 |
22 namespace { | 24 namespace { |
23 | 25 |
24 // Copies a set of cache files from the data folder to the test folder. | 26 // Copies a set of cache files from the data folder to the test folder. |
25 bool CopyTestCache(const std::wstring& name) { | 27 bool CopyTestCache(const std::wstring& name) { |
26 FilePath path; | 28 FilePath path; |
27 PathService::Get(base::DIR_SOURCE_ROOT, &path); | 29 PathService::Get(base::DIR_SOURCE_ROOT, &path); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 TEST_F(DiskCacheBackendTest, NewEvictionKeying) { | 182 TEST_F(DiskCacheBackendTest, NewEvictionKeying) { |
181 SetNewEviction(); | 183 SetNewEviction(); |
182 BackendKeying(); | 184 BackendKeying(); |
183 } | 185 } |
184 | 186 |
185 TEST_F(DiskCacheBackendTest, MemoryOnlyKeying) { | 187 TEST_F(DiskCacheBackendTest, MemoryOnlyKeying) { |
186 SetMemoryOnlyMode(); | 188 SetMemoryOnlyMode(); |
187 BackendKeying(); | 189 BackendKeying(); |
188 } | 190 } |
189 | 191 |
| 192 TEST_F(DiskCacheTest, CreateBackend) { |
| 193 TestCompletionCallback cb; |
| 194 |
| 195 { |
| 196 FilePath path = GetCacheFilePath(); |
| 197 ASSERT_TRUE(DeleteCache(path)); |
| 198 base::Thread cache_thread("CacheThread"); |
| 199 ASSERT_TRUE(cache_thread.StartWithOptions( |
| 200 base::Thread::Options(MessageLoop::TYPE_IO, 0))); |
| 201 |
| 202 // Test the private factory methods. |
| 203 disk_cache::Backend* cache = NULL; |
| 204 int rv = disk_cache::BackendImpl::CreateBackend( |
| 205 path, false, 0, net::DISK_CACHE, disk_cache::kNoRandom, |
| 206 cache_thread.message_loop_proxy(), &cache, &cb); |
| 207 ASSERT_EQ(net::OK, cb.GetResult(rv)); |
| 208 ASSERT_TRUE(cache); |
| 209 delete cache; |
| 210 |
| 211 cache = disk_cache::MemBackendImpl::CreateBackend(0); |
| 212 ASSERT_TRUE(cache); |
| 213 delete cache; |
| 214 cache = NULL; |
| 215 |
| 216 // Now test the public API. |
| 217 rv = disk_cache::CreateCacheBackend(net::DISK_CACHE, path, 0, false, |
| 218 cache_thread.message_loop_proxy(), |
| 219 &cache, &cb); |
| 220 ASSERT_EQ(net::OK, cb.GetResult(rv)); |
| 221 ASSERT_TRUE(cache); |
| 222 delete cache; |
| 223 cache = NULL; |
| 224 |
| 225 rv = disk_cache::CreateCacheBackend(net::MEMORY_CACHE, FilePath(), 0, false, |
| 226 NULL, &cache, &cb); |
| 227 ASSERT_EQ(net::OK, cb.GetResult(rv)); |
| 228 ASSERT_TRUE(cache); |
| 229 delete cache; |
| 230 } |
| 231 |
| 232 MessageLoop::current()->RunAllPending(); |
| 233 } |
| 234 |
190 TEST_F(DiskCacheBackendTest, ExternalFiles) { | 235 TEST_F(DiskCacheBackendTest, ExternalFiles) { |
191 InitCache(); | 236 InitCache(); |
192 // First, lets create a file on the folder. | 237 // First, lets create a file on the folder. |
193 FilePath filename = GetCacheFilePath().AppendASCII("f_000001"); | 238 FilePath filename = GetCacheFilePath().AppendASCII("f_000001"); |
194 | 239 |
195 const int kSize = 50; | 240 const int kSize = 50; |
196 scoped_refptr<net::IOBuffer> buffer1 = new net::IOBuffer(kSize); | 241 scoped_refptr<net::IOBuffer> buffer1 = new net::IOBuffer(kSize); |
197 CacheTestFillBuffer(buffer1->data(), kSize, false); | 242 CacheTestFillBuffer(buffer1->data(), kSize, false); |
198 ASSERT_EQ(kSize, file_util::WriteFile(filename, buffer1->data(), kSize)); | 243 ASSERT_EQ(kSize, file_util::WriteFile(filename, buffer1->data(), kSize)); |
199 | 244 |
200 // Now let's create a file with the cache. | 245 // Now let's create a file with the cache. |
201 disk_cache::Entry* entry; | 246 disk_cache::Entry* entry; |
202 ASSERT_EQ(net::OK, CreateEntry("key", &entry)); | 247 ASSERT_EQ(net::OK, CreateEntry("key", &entry)); |
203 ASSERT_EQ(0, entry->WriteData(0, 20000, buffer1, 0, NULL, false)); | 248 ASSERT_EQ(0, entry->WriteData(0, 20000, buffer1, 0, NULL, false)); |
204 entry->Close(); | 249 entry->Close(); |
205 | 250 |
206 // And verify that the first file is still there. | 251 // And verify that the first file is still there. |
207 scoped_refptr<net::IOBuffer> buffer2 = new net::IOBuffer(kSize); | 252 scoped_refptr<net::IOBuffer> buffer2 = new net::IOBuffer(kSize); |
208 ASSERT_EQ(kSize, file_util::ReadFile(filename, buffer2->data(), kSize)); | 253 ASSERT_EQ(kSize, file_util::ReadFile(filename, buffer2->data(), kSize)); |
209 EXPECT_EQ(0, memcmp(buffer1->data(), buffer2->data(), kSize)); | 254 EXPECT_EQ(0, memcmp(buffer1->data(), buffer2->data(), kSize)); |
210 } | 255 } |
211 | 256 |
212 TEST_F(DiskCacheTest, ShutdownWithPendingIO) { | 257 TEST_F(DiskCacheTest, ShutdownWithPendingIO) { |
213 TestCompletionCallback callback; | 258 TestCompletionCallback callback; |
214 | 259 |
215 { | 260 { |
216 FilePath path = GetCacheFilePath(); | 261 FilePath path = GetCacheFilePath(); |
217 ASSERT_TRUE(DeleteCache(path)); | 262 ASSERT_TRUE(DeleteCache(path)); |
| 263 base::Thread cache_thread("CacheThread"); |
| 264 ASSERT_TRUE(cache_thread.StartWithOptions( |
| 265 base::Thread::Options(MessageLoop::TYPE_IO, 0))); |
218 | 266 |
219 disk_cache::Backend* cache = | 267 disk_cache::Backend* cache; |
220 disk_cache::CreateCacheBackend(path, false, 0, net::DISK_CACHE); | 268 int rv = disk_cache::BackendImpl::CreateBackend( |
| 269 path, false, 0, net::DISK_CACHE, disk_cache::kNoRandom, |
| 270 cache_thread.message_loop_proxy(), &cache, &callback); |
| 271 ASSERT_EQ(net::OK, callback.GetResult(rv)); |
221 | 272 |
222 disk_cache::Entry* entry; | 273 disk_cache::Entry* entry; |
223 ASSERT_TRUE(cache->CreateEntry("some key", &entry)); | 274 rv = cache->CreateEntry("some key", &entry, &callback); |
| 275 ASSERT_EQ(net::OK, callback.GetResult(rv)); |
224 | 276 |
225 const int kSize = 25000; | 277 const int kSize = 25000; |
226 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kSize); | 278 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kSize); |
227 CacheTestFillBuffer(buffer->data(), kSize, false); | 279 CacheTestFillBuffer(buffer->data(), kSize, false); |
228 | 280 |
229 for (int i = 0; i < 10 * 1024 * 1024; i += 64 * 1024) { | 281 for (int i = 0; i < 10 * 1024 * 1024; i += 64 * 1024) { |
230 int rv = entry->WriteData(0, i, buffer, kSize, &callback, false); | 282 int rv = entry->WriteData(0, i, buffer, kSize, &callback, false); |
231 if (rv == net::ERR_IO_PENDING) | 283 if (rv == net::ERR_IO_PENDING) |
232 break; | 284 break; |
233 EXPECT_EQ(kSize, rv); | 285 EXPECT_EQ(kSize, rv); |
234 } | 286 } |
235 | 287 |
236 entry->Close(); | 288 entry->Close(); |
237 | 289 |
238 // The cache destructor will see one pending operation here. | 290 // The cache destructor will see one pending operation here. |
239 delete cache; | 291 delete cache; |
240 } | 292 } |
241 | 293 |
242 MessageLoop::current()->RunAllPending(); | 294 MessageLoop::current()->RunAllPending(); |
243 } | 295 } |
244 | 296 |
245 TEST_F(DiskCacheTest, TruncatedIndex) { | 297 TEST_F(DiskCacheTest, TruncatedIndex) { |
246 FilePath path = GetCacheFilePath(); | 298 FilePath path = GetCacheFilePath(); |
247 ASSERT_TRUE(DeleteCache(path)); | 299 ASSERT_TRUE(DeleteCache(path)); |
248 FilePath index = path.AppendASCII("index"); | 300 FilePath index = path.AppendASCII("index"); |
249 ASSERT_EQ(5, file_util::WriteFile(index, "hello", 5)); | 301 ASSERT_EQ(5, file_util::WriteFile(index, "hello", 5)); |
250 scoped_ptr<disk_cache::Backend> backend; | 302 |
251 backend.reset(disk_cache::BackendImpl::CreateBackend(path, false, 0, | 303 base::Thread cache_thread("CacheThread"); |
252 net::DISK_CACHE, | 304 ASSERT_TRUE(cache_thread.StartWithOptions( |
253 disk_cache::kNone)); | 305 base::Thread::Options(MessageLoop::TYPE_IO, 0))); |
254 ASSERT_TRUE(backend.get() == NULL); | 306 TestCompletionCallback cb; |
| 307 |
| 308 disk_cache::Backend* backend = NULL; |
| 309 int rv = disk_cache::BackendImpl::CreateBackend( |
| 310 path, false, 0, net::DISK_CACHE, disk_cache::kNone, |
| 311 cache_thread.message_loop_proxy(), &backend, &cb); |
| 312 ASSERT_NE(net::OK, cb.GetResult(rv)); |
| 313 |
| 314 ASSERT_TRUE(backend == NULL); |
| 315 delete backend; |
255 } | 316 } |
256 | 317 |
257 void DiskCacheBackendTest::BackendSetSize() { | 318 void DiskCacheBackendTest::BackendSetSize() { |
258 SetDirectMode(); | 319 SetDirectMode(); |
259 const int cache_size = 0x10000; // 64 kB | 320 const int cache_size = 0x10000; // 64 kB |
260 SetMaxSize(cache_size); | 321 SetMaxSize(cache_size); |
261 InitCache(); | 322 InitCache(); |
262 | 323 |
263 std::string first("some key"); | 324 std::string first("some key"); |
264 std::string second("something else"); | 325 std::string second("something else"); |
(...skipping 816 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1081 TEST_F(DiskCacheBackendTest, RecoverRemove) { | 1142 TEST_F(DiskCacheBackendTest, RecoverRemove) { |
1082 BackendRecoverRemove(); | 1143 BackendRecoverRemove(); |
1083 } | 1144 } |
1084 | 1145 |
1085 TEST_F(DiskCacheBackendTest, NewEvictionRecoverRemove) { | 1146 TEST_F(DiskCacheBackendTest, NewEvictionRecoverRemove) { |
1086 SetNewEviction(); | 1147 SetNewEviction(); |
1087 BackendRecoverRemove(); | 1148 BackendRecoverRemove(); |
1088 } | 1149 } |
1089 | 1150 |
1090 // Tests dealing with cache files that cannot be recovered. | 1151 // Tests dealing with cache files that cannot be recovered. |
1091 TEST_F(DiskCacheTest, Backend_DeleteOld) { | 1152 TEST_F(DiskCacheTest, DeleteOld) { |
1092 ASSERT_TRUE(CopyTestCache(L"wrong_version")); | 1153 ASSERT_TRUE(CopyTestCache(L"wrong_version")); |
1093 FilePath path = GetCacheFilePath(); | 1154 FilePath path = GetCacheFilePath(); |
1094 scoped_ptr<disk_cache::Backend> cache; | 1155 base::Thread cache_thread("CacheThread"); |
1095 cache.reset(disk_cache::CreateCacheBackend(path, true, 0, net::DISK_CACHE)); | 1156 ASSERT_TRUE(cache_thread.StartWithOptions( |
| 1157 base::Thread::Options(MessageLoop::TYPE_IO, 0))); |
| 1158 TestCompletionCallback cb; |
| 1159 |
| 1160 disk_cache::Backend* cache; |
| 1161 int rv = disk_cache::BackendImpl::CreateBackend( |
| 1162 path, true, 0, net::DISK_CACHE, disk_cache::kNoRandom, |
| 1163 cache_thread.message_loop_proxy(), &cache, &cb); |
| 1164 ASSERT_EQ(net::OK, cb.GetResult(rv)); |
1096 | 1165 |
1097 MessageLoopHelper helper; | 1166 MessageLoopHelper helper; |
1098 | 1167 |
1099 ASSERT_TRUE(NULL != cache.get()); | 1168 ASSERT_TRUE(NULL != cache); |
1100 ASSERT_EQ(0, cache->GetEntryCount()); | 1169 ASSERT_EQ(0, cache->GetEntryCount()); |
1101 | 1170 |
1102 // Wait for a callback that never comes... about 2 secs :). The message loop | 1171 delete cache; |
1103 // has to run to allow destruction of the cleaner thread. | |
1104 helper.WaitUntilCacheIoFinished(1); | |
1105 } | 1172 } |
1106 | 1173 |
1107 // We want to be able to deal with messed up entries on disk. | 1174 // We want to be able to deal with messed up entries on disk. |
1108 void DiskCacheBackendTest::BackendInvalidEntry2() { | 1175 void DiskCacheBackendTest::BackendInvalidEntry2() { |
1109 ASSERT_TRUE(CopyTestCache(L"bad_entry")); | 1176 ASSERT_TRUE(CopyTestCache(L"bad_entry")); |
1110 DisableFirstCleanup(); | 1177 DisableFirstCleanup(); |
1111 InitCache(); | 1178 InitCache(); |
1112 | 1179 |
1113 disk_cache::Entry *entry1, *entry2; | 1180 disk_cache::Entry *entry1, *entry2; |
1114 ASSERT_EQ(net::OK, OpenEntry("the first key", &entry1)); | 1181 ASSERT_EQ(net::OK, OpenEntry("the first key", &entry1)); |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1436 InitCache(); | 1503 InitCache(); |
1437 BackendDisable4(); | 1504 BackendDisable4(); |
1438 } | 1505 } |
1439 | 1506 |
1440 TEST_F(DiskCacheTest, Backend_UsageStats) { | 1507 TEST_F(DiskCacheTest, Backend_UsageStats) { |
1441 MessageLoopHelper helper; | 1508 MessageLoopHelper helper; |
1442 | 1509 |
1443 FilePath path = GetCacheFilePath(); | 1510 FilePath path = GetCacheFilePath(); |
1444 ASSERT_TRUE(DeleteCache(path)); | 1511 ASSERT_TRUE(DeleteCache(path)); |
1445 scoped_ptr<disk_cache::BackendImpl> cache; | 1512 scoped_ptr<disk_cache::BackendImpl> cache; |
1446 cache.reset(new disk_cache::BackendImpl(path)); | 1513 cache.reset(new disk_cache::BackendImpl( |
| 1514 path, base::MessageLoopProxy::CreateForCurrentThread())); |
1447 ASSERT_TRUE(NULL != cache.get()); | 1515 ASSERT_TRUE(NULL != cache.get()); |
1448 cache->SetUnitTestMode(); | 1516 cache->SetUnitTestMode(); |
1449 ASSERT_TRUE(cache->Init()); | 1517 ASSERT_TRUE(cache->Init()); |
1450 | 1518 |
1451 // Wait for a callback that never comes... about 2 secs :). The message loop | 1519 // Wait for a callback that never comes... about 2 secs :). The message loop |
1452 // has to run to allow invocation of the usage timer. | 1520 // has to run to allow invocation of the usage timer. |
1453 helper.WaitUntilCacheIoFinished(1); | 1521 helper.WaitUntilCacheIoFinished(1); |
1454 } | 1522 } |
1455 | 1523 |
1456 void DiskCacheBackendTest::BackendDoomAll() { | 1524 void DiskCacheBackendTest::BackendDoomAll() { |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1539 InitCache(); | 1607 InitCache(); |
1540 BackendDoomAll2(); | 1608 BackendDoomAll2(); |
1541 } | 1609 } |
1542 | 1610 |
1543 // We should be able to create the same entry on multiple simultaneous instances | 1611 // We should be able to create the same entry on multiple simultaneous instances |
1544 // of the cache. | 1612 // of the cache. |
1545 TEST_F(DiskCacheTest, MultipleInstances) { | 1613 TEST_F(DiskCacheTest, MultipleInstances) { |
1546 ScopedTestCache store1; | 1614 ScopedTestCache store1; |
1547 ScopedTestCache store2("cache_test2"); | 1615 ScopedTestCache store2("cache_test2"); |
1548 ScopedTestCache store3("cache_test3"); | 1616 ScopedTestCache store3("cache_test3"); |
| 1617 base::Thread cache_thread("CacheThread"); |
| 1618 ASSERT_TRUE(cache_thread.StartWithOptions( |
| 1619 base::Thread::Options(MessageLoop::TYPE_IO, 0))); |
| 1620 TestCompletionCallback cb; |
1549 | 1621 |
1550 const int kNumberOfCaches = 2; | 1622 const int kNumberOfCaches = 2; |
1551 scoped_ptr<disk_cache::Backend> cache[kNumberOfCaches]; | 1623 disk_cache::Backend* cache[kNumberOfCaches]; |
1552 | 1624 |
1553 cache[0].reset(disk_cache::CreateCacheBackend(store1.path(), false, 0, | 1625 int rv = disk_cache::BackendImpl::CreateBackend( |
1554 net::DISK_CACHE)); | 1626 store1.path(), false, 0, net::DISK_CACHE, disk_cache::kNone, |
1555 cache[1].reset(disk_cache::CreateCacheBackend(store2.path(), false, 0, | 1627 cache_thread.message_loop_proxy(), &cache[0], &cb); |
1556 net::MEDIA_CACHE)); | 1628 ASSERT_EQ(net::OK, cb.GetResult(rv)); |
| 1629 rv = disk_cache::BackendImpl::CreateBackend( |
| 1630 store2.path(), false, 0, net::MEDIA_CACHE, disk_cache::kNone, |
| 1631 cache_thread.message_loop_proxy(), &cache[1], &cb); |
| 1632 ASSERT_EQ(net::OK, cb.GetResult(rv)); |
1557 | 1633 |
1558 ASSERT_TRUE(cache[0].get() != NULL && cache[1].get() != NULL); | 1634 ASSERT_TRUE(cache[0] != NULL && cache[1] != NULL); |
1559 | 1635 |
1560 std::string key("the first key"); | 1636 std::string key("the first key"); |
1561 disk_cache::Entry* entry; | 1637 disk_cache::Entry* entry; |
1562 for (int i = 0; i < kNumberOfCaches; i++) { | 1638 for (int i = 0; i < kNumberOfCaches; i++) { |
1563 ASSERT_TRUE(cache[i]->CreateEntry(key, &entry)); | 1639 rv = cache[i]->CreateEntry(key, &entry, &cb); |
| 1640 ASSERT_EQ(net::OK, cb.GetResult(rv)); |
1564 entry->Close(); | 1641 entry->Close(); |
1565 } | 1642 } |
| 1643 delete cache[0]; |
| 1644 delete cache[1]; |
1566 } | 1645 } |
1567 | 1646 |
1568 // Test the six regions of the curve that determines the max cache size. | 1647 // Test the six regions of the curve that determines the max cache size. |
1569 TEST_F(DiskCacheTest, AutomaticMaxSize) { | 1648 TEST_F(DiskCacheTest, AutomaticMaxSize) { |
1570 const int kDefaultSize = 80 * 1024 * 1024; | 1649 const int kDefaultSize = 80 * 1024 * 1024; |
1571 int64 large_size = kDefaultSize; | 1650 int64 large_size = kDefaultSize; |
1572 int64 largest_size = kint32max; | 1651 int64 largest_size = kint32max; |
1573 | 1652 |
1574 // Region 1: expected = available * 0.8 | 1653 // Region 1: expected = available * 0.8 |
1575 EXPECT_EQ((kDefaultSize - 1) * 8 / 10, | 1654 EXPECT_EQ((kDefaultSize - 1) * 8 / 10, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1618 // another. | 1697 // another. |
1619 TEST_F(DiskCacheBackendTest, Histograms) { | 1698 TEST_F(DiskCacheBackendTest, Histograms) { |
1620 SetDirectMode(); | 1699 SetDirectMode(); |
1621 InitCache(); | 1700 InitCache(); |
1622 disk_cache::BackendImpl* backend_ = cache_impl_; // Needed be the macro. | 1701 disk_cache::BackendImpl* backend_ = cache_impl_; // Needed be the macro. |
1623 | 1702 |
1624 for (int i = 1; i < 3; i++) { | 1703 for (int i = 1; i < 3; i++) { |
1625 CACHE_UMA(HOURS, "FillupTime", i, 28); | 1704 CACHE_UMA(HOURS, "FillupTime", i, 28); |
1626 } | 1705 } |
1627 } | 1706 } |
OLD | NEW |