Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / net / disk_cache / backend_unittest.cc
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 "base/basictypes.h"
6 #include "base/files/file_util.h"
7 #include "base/metrics/field_trial.h"
8 #include "base/port.h"
9 #include "base/strings/string_util.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "base/threading/platform_thread.h"
14 #include "base/threading/thread_restrictions.h"
15 #include "net/base/cache_type.h"
16 #include "net/base/io_buffer.h"
17 #include "net/base/net_errors.h"
18 #include "net/base/test_completion_callback.h"
19 #include "net/disk_cache/blockfile/backend_impl.h"
20 #include "net/disk_cache/blockfile/entry_impl.h"
21 #include "net/disk_cache/blockfile/experiments.h"
22 #include "net/disk_cache/blockfile/histogram_macros.h"
23 #include "net/disk_cache/blockfile/mapped_file.h"
24 #include "net/disk_cache/cache_util.h"
25 #include "net/disk_cache/disk_cache_test_base.h"
26 #include "net/disk_cache/disk_cache_test_util.h"
27 #include "net/disk_cache/memory/mem_backend_impl.h"
28 #include "net/disk_cache/simple/simple_backend_impl.h"
29 #include "net/disk_cache/simple/simple_entry_format.h"
30 #include "net/disk_cache/simple/simple_test_util.h"
31 #include "net/disk_cache/simple/simple_util.h"
32 #include "testing/gtest/include/gtest/gtest.h"
33
34 #if defined(OS_WIN)
35 #include "base/win/scoped_handle.h"
36 #endif
37
38 // Provide a BackendImpl object to macros from histogram_macros.h.
39 #define CACHE_UMA_BACKEND_IMPL_OBJ backend_
40
41 using base::Time;
42
43 namespace {
44
45 const char kExistingEntryKey[] = "existing entry key";
46
47 scoped_ptr<disk_cache::BackendImpl> CreateExistingEntryCache(
48     const base::Thread& cache_thread,
49     base::FilePath& cache_path) {
50   net::TestCompletionCallback cb;
51
52   scoped_ptr<disk_cache::BackendImpl> cache(new disk_cache::BackendImpl(
53       cache_path, cache_thread.message_loop_proxy(), NULL));
54   int rv = cache->Init(cb.callback());
55   if (cb.GetResult(rv) != net::OK)
56     return scoped_ptr<disk_cache::BackendImpl>();
57
58   disk_cache::Entry* entry = NULL;
59   rv = cache->CreateEntry(kExistingEntryKey, &entry, cb.callback());
60   if (cb.GetResult(rv) != net::OK)
61     return scoped_ptr<disk_cache::BackendImpl>();
62   entry->Close();
63
64   return cache.Pass();
65 }
66
67 }  // namespace
68
69 // Tests that can run with different types of caches.
70 class DiskCacheBackendTest : public DiskCacheTestWithCache {
71  protected:
72   // Some utility methods:
73
74   // Perform IO operations on the cache until there is pending IO.
75   int GeneratePendingIO(net::TestCompletionCallback* cb);
76
77   // Adds 5 sparse entries. |doomed_start| and |doomed_end| if not NULL,
78   // will be filled with times, used by DoomEntriesSince and DoomEntriesBetween.
79   // There are 4 entries after doomed_start and 2 after doomed_end.
80   void InitSparseCache(base::Time* doomed_start, base::Time* doomed_end);
81
82   bool CreateSetOfRandomEntries(std::set<std::string>* key_pool);
83   bool EnumerateAndMatchKeys(int max_to_open,
84                              TestIterator* iter,
85                              std::set<std::string>* keys_to_match,
86                              size_t* count);
87
88   // Actual tests:
89   void BackendBasics();
90   void BackendKeying();
91   void BackendShutdownWithPendingFileIO(bool fast);
92   void BackendShutdownWithPendingIO(bool fast);
93   void BackendShutdownWithPendingCreate(bool fast);
94   void BackendSetSize();
95   void BackendLoad();
96   void BackendChain();
97   void BackendValidEntry();
98   void BackendInvalidEntry();
99   void BackendInvalidEntryRead();
100   void BackendInvalidEntryWithLoad();
101   void BackendTrimInvalidEntry();
102   void BackendTrimInvalidEntry2();
103   void BackendEnumerations();
104   void BackendEnumerations2();
105   void BackendInvalidEntryEnumeration();
106   void BackendFixEnumerators();
107   void BackendDoomRecent();
108   void BackendDoomBetween();
109   void BackendTransaction(const std::string& name, int num_entries, bool load);
110   void BackendRecoverInsert();
111   void BackendRecoverRemove();
112   void BackendRecoverWithEviction();
113   void BackendInvalidEntry2();
114   void BackendInvalidEntry3();
115   void BackendInvalidEntry7();
116   void BackendInvalidEntry8();
117   void BackendInvalidEntry9(bool eviction);
118   void BackendInvalidEntry10(bool eviction);
119   void BackendInvalidEntry11(bool eviction);
120   void BackendTrimInvalidEntry12();
121   void BackendDoomAll();
122   void BackendDoomAll2();
123   void BackendInvalidRankings();
124   void BackendInvalidRankings2();
125   void BackendDisable();
126   void BackendDisable2();
127   void BackendDisable3();
128   void BackendDisable4();
129 };
130
131 int DiskCacheBackendTest::GeneratePendingIO(net::TestCompletionCallback* cb) {
132   if (!use_current_thread_) {
133     ADD_FAILURE();
134     return net::ERR_FAILED;
135   }
136
137   disk_cache::Entry* entry;
138   int rv = cache_->CreateEntry("some key", &entry, cb->callback());
139   if (cb->GetResult(rv) != net::OK)
140     return net::ERR_CACHE_CREATE_FAILURE;
141
142   const int kSize = 25000;
143   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
144   CacheTestFillBuffer(buffer->data(), kSize, false);
145
146   for (int i = 0; i < 10 * 1024 * 1024; i += 64 * 1024) {
147     // We are using the current thread as the cache thread because we want to
148     // be able to call directly this method to make sure that the OS (instead
149     // of us switching thread) is returning IO pending.
150     if (!simple_cache_mode_) {
151       rv = static_cast<disk_cache::EntryImpl*>(entry)->WriteDataImpl(
152           0, i, buffer.get(), kSize, cb->callback(), false);
153     } else {
154       rv = entry->WriteData(0, i, buffer.get(), kSize, cb->callback(), false);
155     }
156
157     if (rv == net::ERR_IO_PENDING)
158       break;
159     if (rv != kSize)
160       rv = net::ERR_FAILED;
161   }
162
163   // Don't call Close() to avoid going through the queue or we'll deadlock
164   // waiting for the operation to finish.
165   if (!simple_cache_mode_)
166     static_cast<disk_cache::EntryImpl*>(entry)->Release();
167   else
168     entry->Close();
169
170   return rv;
171 }
172
173 void DiskCacheBackendTest::InitSparseCache(base::Time* doomed_start,
174                                            base::Time* doomed_end) {
175   InitCache();
176
177   const int kSize = 50;
178   // This must be greater then MemEntryImpl::kMaxSparseEntrySize.
179   const int kOffset = 10 + 1024 * 1024;
180
181   disk_cache::Entry* entry0 = NULL;
182   disk_cache::Entry* entry1 = NULL;
183   disk_cache::Entry* entry2 = NULL;
184
185   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
186   CacheTestFillBuffer(buffer->data(), kSize, false);
187
188   ASSERT_EQ(net::OK, CreateEntry("zeroth", &entry0));
189   ASSERT_EQ(kSize, WriteSparseData(entry0, 0, buffer.get(), kSize));
190   ASSERT_EQ(kSize,
191             WriteSparseData(entry0, kOffset + kSize, buffer.get(), kSize));
192   entry0->Close();
193
194   FlushQueueForTest();
195   AddDelay();
196   if (doomed_start)
197     *doomed_start = base::Time::Now();
198
199   // Order in rankings list:
200   // first_part1, first_part2, second_part1, second_part2
201   ASSERT_EQ(net::OK, CreateEntry("first", &entry1));
202   ASSERT_EQ(kSize, WriteSparseData(entry1, 0, buffer.get(), kSize));
203   ASSERT_EQ(kSize,
204             WriteSparseData(entry1, kOffset + kSize, buffer.get(), kSize));
205   entry1->Close();
206
207   ASSERT_EQ(net::OK, CreateEntry("second", &entry2));
208   ASSERT_EQ(kSize, WriteSparseData(entry2, 0, buffer.get(), kSize));
209   ASSERT_EQ(kSize,
210             WriteSparseData(entry2, kOffset + kSize, buffer.get(), kSize));
211   entry2->Close();
212
213   FlushQueueForTest();
214   AddDelay();
215   if (doomed_end)
216     *doomed_end = base::Time::Now();
217
218   // Order in rankings list:
219   // third_part1, fourth_part1, third_part2, fourth_part2
220   disk_cache::Entry* entry3 = NULL;
221   disk_cache::Entry* entry4 = NULL;
222   ASSERT_EQ(net::OK, CreateEntry("third", &entry3));
223   ASSERT_EQ(kSize, WriteSparseData(entry3, 0, buffer.get(), kSize));
224   ASSERT_EQ(net::OK, CreateEntry("fourth", &entry4));
225   ASSERT_EQ(kSize, WriteSparseData(entry4, 0, buffer.get(), kSize));
226   ASSERT_EQ(kSize,
227             WriteSparseData(entry3, kOffset + kSize, buffer.get(), kSize));
228   ASSERT_EQ(kSize,
229             WriteSparseData(entry4, kOffset + kSize, buffer.get(), kSize));
230   entry3->Close();
231   entry4->Close();
232
233   FlushQueueForTest();
234   AddDelay();
235 }
236
237 // Creates entries based on random keys. Stores these keys in |key_pool|.
238 bool DiskCacheBackendTest::CreateSetOfRandomEntries(
239     std::set<std::string>* key_pool) {
240   const int kNumEntries = 10;
241
242   for (int i = 0; i < kNumEntries; ++i) {
243     std::string key = GenerateKey(true);
244     disk_cache::Entry* entry;
245     if (CreateEntry(key, &entry) != net::OK)
246       return false;
247     key_pool->insert(key);
248     entry->Close();
249   }
250   return key_pool->size() == implicit_cast<size_t>(cache_->GetEntryCount());
251 }
252
253 // Performs iteration over the backend and checks that the keys of entries
254 // opened are in |keys_to_match|, then erases them. Up to |max_to_open| entries
255 // will be opened, if it is positive. Otherwise, iteration will continue until
256 // OpenNextEntry stops returning net::OK.
257 bool DiskCacheBackendTest::EnumerateAndMatchKeys(
258     int max_to_open,
259     TestIterator* iter,
260     std::set<std::string>* keys_to_match,
261     size_t* count) {
262   disk_cache::Entry* entry;
263
264   if (!iter)
265     return false;
266   while (iter->OpenNextEntry(&entry) == net::OK) {
267     if (!entry)
268       return false;
269     EXPECT_EQ(1U, keys_to_match->erase(entry->GetKey()));
270     entry->Close();
271     ++(*count);
272     if (max_to_open >= 0 && implicit_cast<int>(*count) >= max_to_open)
273       break;
274   };
275
276   return true;
277 }
278
279 void DiskCacheBackendTest::BackendBasics() {
280   InitCache();
281   disk_cache::Entry *entry1 = NULL, *entry2 = NULL;
282   EXPECT_NE(net::OK, OpenEntry("the first key", &entry1));
283   ASSERT_EQ(net::OK, CreateEntry("the first key", &entry1));
284   ASSERT_TRUE(NULL != entry1);
285   entry1->Close();
286   entry1 = NULL;
287
288   ASSERT_EQ(net::OK, OpenEntry("the first key", &entry1));
289   ASSERT_TRUE(NULL != entry1);
290   entry1->Close();
291   entry1 = NULL;
292
293   EXPECT_NE(net::OK, CreateEntry("the first key", &entry1));
294   ASSERT_EQ(net::OK, OpenEntry("the first key", &entry1));
295   EXPECT_NE(net::OK, OpenEntry("some other key", &entry2));
296   ASSERT_EQ(net::OK, CreateEntry("some other key", &entry2));
297   ASSERT_TRUE(NULL != entry1);
298   ASSERT_TRUE(NULL != entry2);
299   EXPECT_EQ(2, cache_->GetEntryCount());
300
301   disk_cache::Entry* entry3 = NULL;
302   ASSERT_EQ(net::OK, OpenEntry("some other key", &entry3));
303   ASSERT_TRUE(NULL != entry3);
304   EXPECT_TRUE(entry2 == entry3);
305   EXPECT_EQ(2, cache_->GetEntryCount());
306
307   EXPECT_EQ(net::OK, DoomEntry("some other key"));
308   EXPECT_EQ(1, cache_->GetEntryCount());
309   entry1->Close();
310   entry2->Close();
311   entry3->Close();
312
313   EXPECT_EQ(net::OK, DoomEntry("the first key"));
314   EXPECT_EQ(0, cache_->GetEntryCount());
315
316   ASSERT_EQ(net::OK, CreateEntry("the first key", &entry1));
317   ASSERT_EQ(net::OK, CreateEntry("some other key", &entry2));
318   entry1->Doom();
319   entry1->Close();
320   EXPECT_EQ(net::OK, DoomEntry("some other key"));
321   EXPECT_EQ(0, cache_->GetEntryCount());
322   entry2->Close();
323 }
324
325 TEST_F(DiskCacheBackendTest, Basics) {
326   BackendBasics();
327 }
328
329 TEST_F(DiskCacheBackendTest, NewEvictionBasics) {
330   SetNewEviction();
331   BackendBasics();
332 }
333
334 TEST_F(DiskCacheBackendTest, MemoryOnlyBasics) {
335   SetMemoryOnlyMode();
336   BackendBasics();
337 }
338
339 TEST_F(DiskCacheBackendTest, AppCacheBasics) {
340   SetCacheType(net::APP_CACHE);
341   BackendBasics();
342 }
343
344 TEST_F(DiskCacheBackendTest, ShaderCacheBasics) {
345   SetCacheType(net::SHADER_CACHE);
346   BackendBasics();
347 }
348
349 void DiskCacheBackendTest::BackendKeying() {
350   InitCache();
351   const char* kName1 = "the first key";
352   const char* kName2 = "the first Key";
353   disk_cache::Entry *entry1, *entry2;
354   ASSERT_EQ(net::OK, CreateEntry(kName1, &entry1));
355
356   ASSERT_EQ(net::OK, CreateEntry(kName2, &entry2));
357   EXPECT_TRUE(entry1 != entry2) << "Case sensitive";
358   entry2->Close();
359
360   char buffer[30];
361   base::strlcpy(buffer, kName1, arraysize(buffer));
362   ASSERT_EQ(net::OK, OpenEntry(buffer, &entry2));
363   EXPECT_TRUE(entry1 == entry2);
364   entry2->Close();
365
366   base::strlcpy(buffer + 1, kName1, arraysize(buffer) - 1);
367   ASSERT_EQ(net::OK, OpenEntry(buffer + 1, &entry2));
368   EXPECT_TRUE(entry1 == entry2);
369   entry2->Close();
370
371   base::strlcpy(buffer + 3,  kName1, arraysize(buffer) - 3);
372   ASSERT_EQ(net::OK, OpenEntry(buffer + 3, &entry2));
373   EXPECT_TRUE(entry1 == entry2);
374   entry2->Close();
375
376   // Now verify long keys.
377   char buffer2[20000];
378   memset(buffer2, 's', sizeof(buffer2));
379   buffer2[1023] = '\0';
380   ASSERT_EQ(net::OK, CreateEntry(buffer2, &entry2)) << "key on block file";
381   entry2->Close();
382
383   buffer2[1023] = 'g';
384   buffer2[19999] = '\0';
385   ASSERT_EQ(net::OK, CreateEntry(buffer2, &entry2)) << "key on external file";
386   entry2->Close();
387   entry1->Close();
388 }
389
390 TEST_F(DiskCacheBackendTest, Keying) {
391   BackendKeying();
392 }
393
394 TEST_F(DiskCacheBackendTest, NewEvictionKeying) {
395   SetNewEviction();
396   BackendKeying();
397 }
398
399 TEST_F(DiskCacheBackendTest, MemoryOnlyKeying) {
400   SetMemoryOnlyMode();
401   BackendKeying();
402 }
403
404 TEST_F(DiskCacheBackendTest, AppCacheKeying) {
405   SetCacheType(net::APP_CACHE);
406   BackendKeying();
407 }
408
409 TEST_F(DiskCacheBackendTest, ShaderCacheKeying) {
410   SetCacheType(net::SHADER_CACHE);
411   BackendKeying();
412 }
413
414 TEST_F(DiskCacheTest, CreateBackend) {
415   net::TestCompletionCallback cb;
416
417   {
418     ASSERT_TRUE(CleanupCacheDir());
419     base::Thread cache_thread("CacheThread");
420     ASSERT_TRUE(cache_thread.StartWithOptions(
421         base::Thread::Options(base::MessageLoop::TYPE_IO, 0)));
422
423     // Test the private factory method(s).
424     scoped_ptr<disk_cache::Backend> cache;
425     cache = disk_cache::MemBackendImpl::CreateBackend(0, NULL);
426     ASSERT_TRUE(cache.get());
427     cache.reset();
428
429     // Now test the public API.
430     int rv = disk_cache::CreateCacheBackend(net::DISK_CACHE,
431                                             net::CACHE_BACKEND_DEFAULT,
432                                             cache_path_,
433                                             0,
434                                             false,
435                                             cache_thread.task_runner(),
436                                             NULL,
437                                             &cache,
438                                             cb.callback());
439     ASSERT_EQ(net::OK, cb.GetResult(rv));
440     ASSERT_TRUE(cache.get());
441     cache.reset();
442
443     rv = disk_cache::CreateCacheBackend(net::MEMORY_CACHE,
444                                         net::CACHE_BACKEND_DEFAULT,
445                                         base::FilePath(), 0,
446                                         false, NULL, NULL, &cache,
447                                         cb.callback());
448     ASSERT_EQ(net::OK, cb.GetResult(rv));
449     ASSERT_TRUE(cache.get());
450     cache.reset();
451   }
452
453   base::MessageLoop::current()->RunUntilIdle();
454 }
455
456 // Tests that |BackendImpl| fails to initialize with a missing file.
457 TEST_F(DiskCacheBackendTest, CreateBackend_MissingFile) {
458   ASSERT_TRUE(CopyTestCache("bad_entry"));
459   base::FilePath filename = cache_path_.AppendASCII("data_1");
460   base::DeleteFile(filename, false);
461   base::Thread cache_thread("CacheThread");
462   ASSERT_TRUE(cache_thread.StartWithOptions(
463       base::Thread::Options(base::MessageLoop::TYPE_IO, 0)));
464   net::TestCompletionCallback cb;
465
466   bool prev = base::ThreadRestrictions::SetIOAllowed(false);
467   scoped_ptr<disk_cache::BackendImpl> cache(new disk_cache::BackendImpl(
468       cache_path_, cache_thread.task_runner(), NULL));
469   int rv = cache->Init(cb.callback());
470   EXPECT_EQ(net::ERR_FAILED, cb.GetResult(rv));
471   base::ThreadRestrictions::SetIOAllowed(prev);
472
473   cache.reset();
474   DisableIntegrityCheck();
475 }
476
477 TEST_F(DiskCacheBackendTest, ExternalFiles) {
478   InitCache();
479   // First, let's create a file on the folder.
480   base::FilePath filename = cache_path_.AppendASCII("f_000001");
481
482   const int kSize = 50;
483   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
484   CacheTestFillBuffer(buffer1->data(), kSize, false);
485   ASSERT_EQ(kSize, base::WriteFile(filename, buffer1->data(), kSize));
486
487   // Now let's create a file with the cache.
488   disk_cache::Entry* entry;
489   ASSERT_EQ(net::OK, CreateEntry("key", &entry));
490   ASSERT_EQ(0, WriteData(entry, 0, 20000, buffer1.get(), 0, false));
491   entry->Close();
492
493   // And verify that the first file is still there.
494   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize));
495   ASSERT_EQ(kSize, base::ReadFile(filename, buffer2->data(), kSize));
496   EXPECT_EQ(0, memcmp(buffer1->data(), buffer2->data(), kSize));
497 }
498
499 // Tests that we deal with file-level pending operations at destruction time.
500 void DiskCacheBackendTest::BackendShutdownWithPendingFileIO(bool fast) {
501   ASSERT_TRUE(CleanupCacheDir());
502   uint32 flags = disk_cache::kNoBuffering;
503   if (!fast)
504     flags |= disk_cache::kNoRandom;
505
506   UseCurrentThread();
507   CreateBackend(flags, NULL);
508
509   net::TestCompletionCallback cb;
510   int rv = GeneratePendingIO(&cb);
511
512   // The cache destructor will see one pending operation here.
513   cache_.reset();
514
515   if (rv == net::ERR_IO_PENDING) {
516     if (fast || simple_cache_mode_)
517       EXPECT_FALSE(cb.have_result());
518     else
519       EXPECT_TRUE(cb.have_result());
520   }
521
522   base::MessageLoop::current()->RunUntilIdle();
523
524 #if !defined(OS_IOS)
525   // Wait for the actual operation to complete, or we'll keep a file handle that
526   // may cause issues later. Note that on iOS systems even though this test
527   // uses a single thread, the actual IO is posted to a worker thread and the
528   // cache destructor breaks the link to reach cb when the operation completes.
529   rv = cb.GetResult(rv);
530 #endif
531 }
532
533 TEST_F(DiskCacheBackendTest, ShutdownWithPendingFileIO) {
534   BackendShutdownWithPendingFileIO(false);
535 }
536
537 // Here and below, tests that simulate crashes are not compiled in LeakSanitizer
538 // builds because they contain a lot of intentional memory leaks.
539 // The wrapper scripts used to run tests under Valgrind Memcheck will also
540 // disable these tests. See:
541 // tools/valgrind/gtest_exclude/net_unittests.gtest-memcheck.txt
542 #if !defined(LEAK_SANITIZER)
543 // We'll be leaking from this test.
544 TEST_F(DiskCacheBackendTest, ShutdownWithPendingFileIO_Fast) {
545   // The integrity test sets kNoRandom so there's a version mismatch if we don't
546   // force new eviction.
547   SetNewEviction();
548   BackendShutdownWithPendingFileIO(true);
549 }
550 #endif
551
552 // See crbug.com/330074
553 #if !defined(OS_IOS)
554 // Tests that one cache instance is not affected by another one going away.
555 TEST_F(DiskCacheBackendTest, MultipleInstancesWithPendingFileIO) {
556   base::ScopedTempDir store;
557   ASSERT_TRUE(store.CreateUniqueTempDir());
558
559   net::TestCompletionCallback cb;
560   scoped_ptr<disk_cache::Backend> extra_cache;
561   int rv = disk_cache::CreateCacheBackend(net::DISK_CACHE,
562                                           net::CACHE_BACKEND_DEFAULT,
563                                           store.path(),
564                                           0,
565                                           false,
566                                           base::ThreadTaskRunnerHandle::Get(),
567                                           NULL,
568                                           &extra_cache,
569                                           cb.callback());
570   ASSERT_EQ(net::OK, cb.GetResult(rv));
571   ASSERT_TRUE(extra_cache.get() != NULL);
572
573   ASSERT_TRUE(CleanupCacheDir());
574   SetNewEviction();  // Match the expected behavior for integrity verification.
575   UseCurrentThread();
576
577   CreateBackend(disk_cache::kNoBuffering, NULL);
578   rv = GeneratePendingIO(&cb);
579
580   // cache_ has a pending operation, and extra_cache will go away.
581   extra_cache.reset();
582
583   if (rv == net::ERR_IO_PENDING)
584     EXPECT_FALSE(cb.have_result());
585
586   base::MessageLoop::current()->RunUntilIdle();
587
588   // Wait for the actual operation to complete, or we'll keep a file handle that
589   // may cause issues later.
590   rv = cb.GetResult(rv);
591 }
592 #endif
593
594 // Tests that we deal with background-thread pending operations.
595 void DiskCacheBackendTest::BackendShutdownWithPendingIO(bool fast) {
596   net::TestCompletionCallback cb;
597
598   {
599     ASSERT_TRUE(CleanupCacheDir());
600     base::Thread cache_thread("CacheThread");
601     ASSERT_TRUE(cache_thread.StartWithOptions(
602         base::Thread::Options(base::MessageLoop::TYPE_IO, 0)));
603
604     uint32 flags = disk_cache::kNoBuffering;
605     if (!fast)
606       flags |= disk_cache::kNoRandom;
607
608     CreateBackend(flags, &cache_thread);
609
610     disk_cache::Entry* entry;
611     int rv = cache_->CreateEntry("some key", &entry, cb.callback());
612     ASSERT_EQ(net::OK, cb.GetResult(rv));
613
614     entry->Close();
615
616     // The cache destructor will see one pending operation here.
617     cache_.reset();
618   }
619
620   base::MessageLoop::current()->RunUntilIdle();
621 }
622
623 TEST_F(DiskCacheBackendTest, ShutdownWithPendingIO) {
624   BackendShutdownWithPendingIO(false);
625 }
626
627 #if !defined(LEAK_SANITIZER)
628 // We'll be leaking from this test.
629 TEST_F(DiskCacheBackendTest, ShutdownWithPendingIO_Fast) {
630   // The integrity test sets kNoRandom so there's a version mismatch if we don't
631   // force new eviction.
632   SetNewEviction();
633   BackendShutdownWithPendingIO(true);
634 }
635 #endif
636
637 // Tests that we deal with create-type pending operations.
638 void DiskCacheBackendTest::BackendShutdownWithPendingCreate(bool fast) {
639   net::TestCompletionCallback cb;
640
641   {
642     ASSERT_TRUE(CleanupCacheDir());
643     base::Thread cache_thread("CacheThread");
644     ASSERT_TRUE(cache_thread.StartWithOptions(
645         base::Thread::Options(base::MessageLoop::TYPE_IO, 0)));
646
647     disk_cache::BackendFlags flags =
648       fast ? disk_cache::kNone : disk_cache::kNoRandom;
649     CreateBackend(flags, &cache_thread);
650
651     disk_cache::Entry* entry;
652     int rv = cache_->CreateEntry("some key", &entry, cb.callback());
653     ASSERT_EQ(net::ERR_IO_PENDING, rv);
654
655     cache_.reset();
656     EXPECT_FALSE(cb.have_result());
657   }
658
659   base::MessageLoop::current()->RunUntilIdle();
660 }
661
662 TEST_F(DiskCacheBackendTest, ShutdownWithPendingCreate) {
663   BackendShutdownWithPendingCreate(false);
664 }
665
666 #if !defined(LEAK_SANITIZER)
667 // We'll be leaking an entry from this test.
668 TEST_F(DiskCacheBackendTest, ShutdownWithPendingCreate_Fast) {
669   // The integrity test sets kNoRandom so there's a version mismatch if we don't
670   // force new eviction.
671   SetNewEviction();
672   BackendShutdownWithPendingCreate(true);
673 }
674 #endif
675
676 // Disabled on android since this test requires cache creator to create
677 // blockfile caches.
678 #if !defined(OS_ANDROID)
679 TEST_F(DiskCacheTest, TruncatedIndex) {
680   ASSERT_TRUE(CleanupCacheDir());
681   base::FilePath index = cache_path_.AppendASCII("index");
682   ASSERT_EQ(5, base::WriteFile(index, "hello", 5));
683
684   base::Thread cache_thread("CacheThread");
685   ASSERT_TRUE(cache_thread.StartWithOptions(
686       base::Thread::Options(base::MessageLoop::TYPE_IO, 0)));
687   net::TestCompletionCallback cb;
688
689   scoped_ptr<disk_cache::Backend> backend;
690   int rv = disk_cache::CreateCacheBackend(net::DISK_CACHE,
691                                           net::CACHE_BACKEND_BLOCKFILE,
692                                           cache_path_,
693                                           0,
694                                           false,
695                                           cache_thread.task_runner(),
696                                           NULL,
697                                           &backend,
698                                           cb.callback());
699   ASSERT_NE(net::OK, cb.GetResult(rv));
700
701   ASSERT_FALSE(backend);
702 }
703 #endif
704
705 void DiskCacheBackendTest::BackendSetSize() {
706   const int cache_size = 0x10000;  // 64 kB
707   SetMaxSize(cache_size);
708   InitCache();
709
710   std::string first("some key");
711   std::string second("something else");
712   disk_cache::Entry* entry;
713   ASSERT_EQ(net::OK, CreateEntry(first, &entry));
714
715   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(cache_size));
716   memset(buffer->data(), 0, cache_size);
717   EXPECT_EQ(cache_size / 10,
718             WriteData(entry, 0, 0, buffer.get(), cache_size / 10, false))
719       << "normal file";
720
721   EXPECT_EQ(net::ERR_FAILED,
722             WriteData(entry, 1, 0, buffer.get(), cache_size / 5, false))
723       << "file size above the limit";
724
725   // By doubling the total size, we make this file cacheable.
726   SetMaxSize(cache_size * 2);
727   EXPECT_EQ(cache_size / 5,
728             WriteData(entry, 1, 0, buffer.get(), cache_size / 5, false));
729
730   // Let's fill up the cache!.
731   SetMaxSize(cache_size * 10);
732   EXPECT_EQ(cache_size * 3 / 4,
733             WriteData(entry, 0, 0, buffer.get(), cache_size * 3 / 4, false));
734   entry->Close();
735   FlushQueueForTest();
736
737   SetMaxSize(cache_size);
738
739   // The cache is 95% full.
740
741   ASSERT_EQ(net::OK, CreateEntry(second, &entry));
742   EXPECT_EQ(cache_size / 10,
743             WriteData(entry, 0, 0, buffer.get(), cache_size / 10, false));
744
745   disk_cache::Entry* entry2;
746   ASSERT_EQ(net::OK, CreateEntry("an extra key", &entry2));
747   EXPECT_EQ(cache_size / 10,
748             WriteData(entry2, 0, 0, buffer.get(), cache_size / 10, false));
749   entry2->Close();  // This will trigger the cache trim.
750
751   EXPECT_NE(net::OK, OpenEntry(first, &entry2));
752
753   FlushQueueForTest();  // Make sure that we are done trimming the cache.
754   FlushQueueForTest();  // We may have posted two tasks to evict stuff.
755
756   entry->Close();
757   ASSERT_EQ(net::OK, OpenEntry(second, &entry));
758   EXPECT_EQ(cache_size / 10, entry->GetDataSize(0));
759   entry->Close();
760 }
761
762 TEST_F(DiskCacheBackendTest, SetSize) {
763   BackendSetSize();
764 }
765
766 TEST_F(DiskCacheBackendTest, NewEvictionSetSize) {
767   SetNewEviction();
768   BackendSetSize();
769 }
770
771 TEST_F(DiskCacheBackendTest, MemoryOnlySetSize) {
772   SetMemoryOnlyMode();
773   BackendSetSize();
774 }
775
776 void DiskCacheBackendTest::BackendLoad() {
777   InitCache();
778   int seed = static_cast<int>(Time::Now().ToInternalValue());
779   srand(seed);
780
781   disk_cache::Entry* entries[100];
782   for (int i = 0; i < 100; i++) {
783     std::string key = GenerateKey(true);
784     ASSERT_EQ(net::OK, CreateEntry(key, &entries[i]));
785   }
786   EXPECT_EQ(100, cache_->GetEntryCount());
787
788   for (int i = 0; i < 100; i++) {
789     int source1 = rand() % 100;
790     int source2 = rand() % 100;
791     disk_cache::Entry* temp = entries[source1];
792     entries[source1] = entries[source2];
793     entries[source2] = temp;
794   }
795
796   for (int i = 0; i < 100; i++) {
797     disk_cache::Entry* entry;
798     ASSERT_EQ(net::OK, OpenEntry(entries[i]->GetKey(), &entry));
799     EXPECT_TRUE(entry == entries[i]);
800     entry->Close();
801     entries[i]->Doom();
802     entries[i]->Close();
803   }
804   FlushQueueForTest();
805   EXPECT_EQ(0, cache_->GetEntryCount());
806 }
807
808 TEST_F(DiskCacheBackendTest, Load) {
809   // Work with a tiny index table (16 entries)
810   SetMask(0xf);
811   SetMaxSize(0x100000);
812   BackendLoad();
813 }
814
815 TEST_F(DiskCacheBackendTest, NewEvictionLoad) {
816   SetNewEviction();
817   // Work with a tiny index table (16 entries)
818   SetMask(0xf);
819   SetMaxSize(0x100000);
820   BackendLoad();
821 }
822
823 TEST_F(DiskCacheBackendTest, MemoryOnlyLoad) {
824   SetMaxSize(0x100000);
825   SetMemoryOnlyMode();
826   BackendLoad();
827 }
828
829 TEST_F(DiskCacheBackendTest, AppCacheLoad) {
830   SetCacheType(net::APP_CACHE);
831   // Work with a tiny index table (16 entries)
832   SetMask(0xf);
833   SetMaxSize(0x100000);
834   BackendLoad();
835 }
836
837 TEST_F(DiskCacheBackendTest, ShaderCacheLoad) {
838   SetCacheType(net::SHADER_CACHE);
839   // Work with a tiny index table (16 entries)
840   SetMask(0xf);
841   SetMaxSize(0x100000);
842   BackendLoad();
843 }
844
845 // Tests the chaining of an entry to the current head.
846 void DiskCacheBackendTest::BackendChain() {
847   SetMask(0x1);  // 2-entry table.
848   SetMaxSize(0x3000);  // 12 kB.
849   InitCache();
850
851   disk_cache::Entry* entry;
852   ASSERT_EQ(net::OK, CreateEntry("The first key", &entry));
853   entry->Close();
854   ASSERT_EQ(net::OK, CreateEntry("The Second key", &entry));
855   entry->Close();
856 }
857
858 TEST_F(DiskCacheBackendTest, Chain) {
859   BackendChain();
860 }
861
862 TEST_F(DiskCacheBackendTest, NewEvictionChain) {
863   SetNewEviction();
864   BackendChain();
865 }
866
867 TEST_F(DiskCacheBackendTest, AppCacheChain) {
868   SetCacheType(net::APP_CACHE);
869   BackendChain();
870 }
871
872 TEST_F(DiskCacheBackendTest, ShaderCacheChain) {
873   SetCacheType(net::SHADER_CACHE);
874   BackendChain();
875 }
876
877 TEST_F(DiskCacheBackendTest, NewEvictionTrim) {
878   SetNewEviction();
879   InitCache();
880
881   disk_cache::Entry* entry;
882   for (int i = 0; i < 100; i++) {
883     std::string name(base::StringPrintf("Key %d", i));
884     ASSERT_EQ(net::OK, CreateEntry(name, &entry));
885     entry->Close();
886     if (i < 90) {
887       // Entries 0 to 89 are in list 1; 90 to 99 are in list 0.
888       ASSERT_EQ(net::OK, OpenEntry(name, &entry));
889       entry->Close();
890     }
891   }
892
893   // The first eviction must come from list 1 (10% limit), the second must come
894   // from list 0.
895   TrimForTest(false);
896   EXPECT_NE(net::OK, OpenEntry("Key 0", &entry));
897   TrimForTest(false);
898   EXPECT_NE(net::OK, OpenEntry("Key 90", &entry));
899
900   // Double check that we still have the list tails.
901   ASSERT_EQ(net::OK, OpenEntry("Key 1", &entry));
902   entry->Close();
903   ASSERT_EQ(net::OK, OpenEntry("Key 91", &entry));
904   entry->Close();
905 }
906
907 // Before looking for invalid entries, let's check a valid entry.
908 void DiskCacheBackendTest::BackendValidEntry() {
909   InitCache();
910
911   std::string key("Some key");
912   disk_cache::Entry* entry;
913   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
914
915   const int kSize = 50;
916   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
917   memset(buffer1->data(), 0, kSize);
918   base::strlcpy(buffer1->data(), "And the data to save", kSize);
919   EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer1.get(), kSize, false));
920   entry->Close();
921   SimulateCrash();
922
923   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
924
925   scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize));
926   memset(buffer2->data(), 0, kSize);
927   EXPECT_EQ(kSize, ReadData(entry, 0, 0, buffer2.get(), kSize));
928   entry->Close();
929   EXPECT_STREQ(buffer1->data(), buffer2->data());
930 }
931
932 TEST_F(DiskCacheBackendTest, ValidEntry) {
933   BackendValidEntry();
934 }
935
936 TEST_F(DiskCacheBackendTest, NewEvictionValidEntry) {
937   SetNewEviction();
938   BackendValidEntry();
939 }
940
941 // The same logic of the previous test (ValidEntry), but this time force the
942 // entry to be invalid, simulating a crash in the middle.
943 // We'll be leaking memory from this test.
944 void DiskCacheBackendTest::BackendInvalidEntry() {
945   InitCache();
946
947   std::string key("Some key");
948   disk_cache::Entry* entry;
949   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
950
951   const int kSize = 50;
952   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
953   memset(buffer->data(), 0, kSize);
954   base::strlcpy(buffer->data(), "And the data to save", kSize);
955   EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, false));
956   SimulateCrash();
957
958   EXPECT_NE(net::OK, OpenEntry(key, &entry));
959   EXPECT_EQ(0, cache_->GetEntryCount());
960 }
961
962 #if !defined(LEAK_SANITIZER)
963 // We'll be leaking memory from this test.
964 TEST_F(DiskCacheBackendTest, InvalidEntry) {
965   BackendInvalidEntry();
966 }
967
968 // We'll be leaking memory from this test.
969 TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry) {
970   SetNewEviction();
971   BackendInvalidEntry();
972 }
973
974 // We'll be leaking memory from this test.
975 TEST_F(DiskCacheBackendTest, AppCacheInvalidEntry) {
976   SetCacheType(net::APP_CACHE);
977   BackendInvalidEntry();
978 }
979
980 // We'll be leaking memory from this test.
981 TEST_F(DiskCacheBackendTest, ShaderCacheInvalidEntry) {
982   SetCacheType(net::SHADER_CACHE);
983   BackendInvalidEntry();
984 }
985
986 // Almost the same test, but this time crash the cache after reading an entry.
987 // We'll be leaking memory from this test.
988 void DiskCacheBackendTest::BackendInvalidEntryRead() {
989   InitCache();
990
991   std::string key("Some key");
992   disk_cache::Entry* entry;
993   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
994
995   const int kSize = 50;
996   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
997   memset(buffer->data(), 0, kSize);
998   base::strlcpy(buffer->data(), "And the data to save", kSize);
999   EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, false));
1000   entry->Close();
1001   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
1002   EXPECT_EQ(kSize, ReadData(entry, 0, 0, buffer.get(), kSize));
1003
1004   SimulateCrash();
1005
1006   if (type_ == net::APP_CACHE) {
1007     // Reading an entry and crashing should not make it dirty.
1008     ASSERT_EQ(net::OK, OpenEntry(key, &entry));
1009     EXPECT_EQ(1, cache_->GetEntryCount());
1010     entry->Close();
1011   } else {
1012     EXPECT_NE(net::OK, OpenEntry(key, &entry));
1013     EXPECT_EQ(0, cache_->GetEntryCount());
1014   }
1015 }
1016
1017 // We'll be leaking memory from this test.
1018 TEST_F(DiskCacheBackendTest, InvalidEntryRead) {
1019   BackendInvalidEntryRead();
1020 }
1021
1022 // We'll be leaking memory from this test.
1023 TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntryRead) {
1024   SetNewEviction();
1025   BackendInvalidEntryRead();
1026 }
1027
1028 // We'll be leaking memory from this test.
1029 TEST_F(DiskCacheBackendTest, AppCacheInvalidEntryRead) {
1030   SetCacheType(net::APP_CACHE);
1031   BackendInvalidEntryRead();
1032 }
1033
1034 // We'll be leaking memory from this test.
1035 TEST_F(DiskCacheBackendTest, ShaderCacheInvalidEntryRead) {
1036   SetCacheType(net::SHADER_CACHE);
1037   BackendInvalidEntryRead();
1038 }
1039
1040 // We'll be leaking memory from this test.
1041 void DiskCacheBackendTest::BackendInvalidEntryWithLoad() {
1042   // Work with a tiny index table (16 entries)
1043   SetMask(0xf);
1044   SetMaxSize(0x100000);
1045   InitCache();
1046
1047   int seed = static_cast<int>(Time::Now().ToInternalValue());
1048   srand(seed);
1049
1050   const int kNumEntries = 100;
1051   disk_cache::Entry* entries[kNumEntries];
1052   for (int i = 0; i < kNumEntries; i++) {
1053     std::string key = GenerateKey(true);
1054     ASSERT_EQ(net::OK, CreateEntry(key, &entries[i]));
1055   }
1056   EXPECT_EQ(kNumEntries, cache_->GetEntryCount());
1057
1058   for (int i = 0; i < kNumEntries; i++) {
1059     int source1 = rand() % kNumEntries;
1060     int source2 = rand() % kNumEntries;
1061     disk_cache::Entry* temp = entries[source1];
1062     entries[source1] = entries[source2];
1063     entries[source2] = temp;
1064   }
1065
1066   std::string keys[kNumEntries];
1067   for (int i = 0; i < kNumEntries; i++) {
1068     keys[i] = entries[i]->GetKey();
1069     if (i < kNumEntries / 2)
1070       entries[i]->Close();
1071   }
1072
1073   SimulateCrash();
1074
1075   for (int i = kNumEntries / 2; i < kNumEntries; i++) {
1076     disk_cache::Entry* entry;
1077     EXPECT_NE(net::OK, OpenEntry(keys[i], &entry));
1078   }
1079
1080   for (int i = 0; i < kNumEntries / 2; i++) {
1081     disk_cache::Entry* entry;
1082     ASSERT_EQ(net::OK, OpenEntry(keys[i], &entry));
1083     entry->Close();
1084   }
1085
1086   EXPECT_EQ(kNumEntries / 2, cache_->GetEntryCount());
1087 }
1088
1089 // We'll be leaking memory from this test.
1090 TEST_F(DiskCacheBackendTest, InvalidEntryWithLoad) {
1091   BackendInvalidEntryWithLoad();
1092 }
1093
1094 // We'll be leaking memory from this test.
1095 TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntryWithLoad) {
1096   SetNewEviction();
1097   BackendInvalidEntryWithLoad();
1098 }
1099
1100 // We'll be leaking memory from this test.
1101 TEST_F(DiskCacheBackendTest, AppCacheInvalidEntryWithLoad) {
1102   SetCacheType(net::APP_CACHE);
1103   BackendInvalidEntryWithLoad();
1104 }
1105
1106 // We'll be leaking memory from this test.
1107 TEST_F(DiskCacheBackendTest, ShaderCacheInvalidEntryWithLoad) {
1108   SetCacheType(net::SHADER_CACHE);
1109   BackendInvalidEntryWithLoad();
1110 }
1111
1112 // We'll be leaking memory from this test.
1113 void DiskCacheBackendTest::BackendTrimInvalidEntry() {
1114   const int kSize = 0x3000;  // 12 kB
1115   SetMaxSize(kSize * 10);
1116   InitCache();
1117
1118   std::string first("some key");
1119   std::string second("something else");
1120   disk_cache::Entry* entry;
1121   ASSERT_EQ(net::OK, CreateEntry(first, &entry));
1122
1123   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
1124   memset(buffer->data(), 0, kSize);
1125   EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, false));
1126
1127   // Simulate a crash.
1128   SimulateCrash();
1129
1130   ASSERT_EQ(net::OK, CreateEntry(second, &entry));
1131   EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, false));
1132
1133   EXPECT_EQ(2, cache_->GetEntryCount());
1134   SetMaxSize(kSize);
1135   entry->Close();  // Trim the cache.
1136   FlushQueueForTest();
1137
1138   // If we evicted the entry in less than 20mS, we have one entry in the cache;
1139   // if it took more than that, we posted a task and we'll delete the second
1140   // entry too.
1141   base::MessageLoop::current()->RunUntilIdle();
1142
1143   // This may be not thread-safe in general, but for now it's OK so add some
1144   // ThreadSanitizer annotations to ignore data races on cache_.
1145   // See http://crbug.com/55970
1146   ANNOTATE_IGNORE_READS_BEGIN();
1147   EXPECT_GE(1, cache_->GetEntryCount());
1148   ANNOTATE_IGNORE_READS_END();
1149
1150   EXPECT_NE(net::OK, OpenEntry(first, &entry));
1151 }
1152
1153 // We'll be leaking memory from this test.
1154 TEST_F(DiskCacheBackendTest, TrimInvalidEntry) {
1155   BackendTrimInvalidEntry();
1156 }
1157
1158 // We'll be leaking memory from this test.
1159 TEST_F(DiskCacheBackendTest, NewEvictionTrimInvalidEntry) {
1160   SetNewEviction();
1161   BackendTrimInvalidEntry();
1162 }
1163
1164 // We'll be leaking memory from this test.
1165 void DiskCacheBackendTest::BackendTrimInvalidEntry2() {
1166   SetMask(0xf);  // 16-entry table.
1167
1168   const int kSize = 0x3000;  // 12 kB
1169   SetMaxSize(kSize * 40);
1170   InitCache();
1171
1172   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
1173   memset(buffer->data(), 0, kSize);
1174   disk_cache::Entry* entry;
1175
1176   // Writing 32 entries to this cache chains most of them.
1177   for (int i = 0; i < 32; i++) {
1178     std::string key(base::StringPrintf("some key %d", i));
1179     ASSERT_EQ(net::OK, CreateEntry(key, &entry));
1180     EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, false));
1181     entry->Close();
1182     ASSERT_EQ(net::OK, OpenEntry(key, &entry));
1183     // Note that we are not closing the entries.
1184   }
1185
1186   // Simulate a crash.
1187   SimulateCrash();
1188
1189   ASSERT_EQ(net::OK, CreateEntry("Something else", &entry));
1190   EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, false));
1191
1192   FlushQueueForTest();
1193   EXPECT_EQ(33, cache_->GetEntryCount());
1194   SetMaxSize(kSize);
1195
1196   // For the new eviction code, all corrupt entries are on the second list so
1197   // they are not going away that easy.
1198   if (new_eviction_) {
1199     EXPECT_EQ(net::OK, DoomAllEntries());
1200   }
1201
1202   entry->Close();  // Trim the cache.
1203   FlushQueueForTest();
1204
1205   // We may abort the eviction before cleaning up everything.
1206   base::MessageLoop::current()->RunUntilIdle();
1207   FlushQueueForTest();
1208   // If it's not clear enough: we may still have eviction tasks running at this
1209   // time, so the number of entries is changing while we read it.
1210   ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN();
1211   EXPECT_GE(30, cache_->GetEntryCount());
1212   ANNOTATE_IGNORE_READS_AND_WRITES_END();
1213 }
1214
1215 // We'll be leaking memory from this test.
1216 TEST_F(DiskCacheBackendTest, TrimInvalidEntry2) {
1217   BackendTrimInvalidEntry2();
1218 }
1219
1220 // We'll be leaking memory from this test.
1221 TEST_F(DiskCacheBackendTest, NewEvictionTrimInvalidEntry2) {
1222   SetNewEviction();
1223   BackendTrimInvalidEntry2();
1224 }
1225 #endif  // !defined(LEAK_SANITIZER)
1226
1227 void DiskCacheBackendTest::BackendEnumerations() {
1228   InitCache();
1229   Time initial = Time::Now();
1230
1231   const int kNumEntries = 100;
1232   for (int i = 0; i < kNumEntries; i++) {
1233     std::string key = GenerateKey(true);
1234     disk_cache::Entry* entry;
1235     ASSERT_EQ(net::OK, CreateEntry(key, &entry));
1236     entry->Close();
1237   }
1238   EXPECT_EQ(kNumEntries, cache_->GetEntryCount());
1239   Time final = Time::Now();
1240
1241   disk_cache::Entry* entry;
1242   scoped_ptr<TestIterator> iter = CreateIterator();
1243   int count = 0;
1244   Time last_modified[kNumEntries];
1245   Time last_used[kNumEntries];
1246   while (iter->OpenNextEntry(&entry) == net::OK) {
1247     ASSERT_TRUE(NULL != entry);
1248     if (count < kNumEntries) {
1249       last_modified[count] = entry->GetLastModified();
1250       last_used[count] = entry->GetLastUsed();
1251       EXPECT_TRUE(initial <= last_modified[count]);
1252       EXPECT_TRUE(final >= last_modified[count]);
1253     }
1254
1255     entry->Close();
1256     count++;
1257   };
1258   EXPECT_EQ(kNumEntries, count);
1259
1260   iter = CreateIterator();
1261   count = 0;
1262   // The previous enumeration should not have changed the timestamps.
1263   while (iter->OpenNextEntry(&entry) == net::OK) {
1264     ASSERT_TRUE(NULL != entry);
1265     if (count < kNumEntries) {
1266       EXPECT_TRUE(last_modified[count] == entry->GetLastModified());
1267       EXPECT_TRUE(last_used[count] == entry->GetLastUsed());
1268     }
1269     entry->Close();
1270     count++;
1271   };
1272   EXPECT_EQ(kNumEntries, count);
1273 }
1274
1275 TEST_F(DiskCacheBackendTest, Enumerations) {
1276   BackendEnumerations();
1277 }
1278
1279 TEST_F(DiskCacheBackendTest, NewEvictionEnumerations) {
1280   SetNewEviction();
1281   BackendEnumerations();
1282 }
1283
1284 TEST_F(DiskCacheBackendTest, MemoryOnlyEnumerations) {
1285   SetMemoryOnlyMode();
1286   BackendEnumerations();
1287 }
1288
1289 TEST_F(DiskCacheBackendTest, ShaderCacheEnumerations) {
1290   SetCacheType(net::SHADER_CACHE);
1291   BackendEnumerations();
1292 }
1293
1294 TEST_F(DiskCacheBackendTest, AppCacheEnumerations) {
1295   SetCacheType(net::APP_CACHE);
1296   BackendEnumerations();
1297 }
1298
1299 // Verifies enumerations while entries are open.
1300 void DiskCacheBackendTest::BackendEnumerations2() {
1301   InitCache();
1302   const std::string first("first");
1303   const std::string second("second");
1304   disk_cache::Entry *entry1, *entry2;
1305   ASSERT_EQ(net::OK, CreateEntry(first, &entry1));
1306   entry1->Close();
1307   ASSERT_EQ(net::OK, CreateEntry(second, &entry2));
1308   entry2->Close();
1309   FlushQueueForTest();
1310
1311   // Make sure that the timestamp is not the same.
1312   AddDelay();
1313   ASSERT_EQ(net::OK, OpenEntry(second, &entry1));
1314   scoped_ptr<TestIterator> iter = CreateIterator();
1315   ASSERT_EQ(net::OK, iter->OpenNextEntry(&entry2));
1316   EXPECT_EQ(entry2->GetKey(), second);
1317
1318   // Two entries and the iterator pointing at "first".
1319   entry1->Close();
1320   entry2->Close();
1321
1322   // The iterator should still be valid, so we should not crash.
1323   ASSERT_EQ(net::OK, iter->OpenNextEntry(&entry2));
1324   EXPECT_EQ(entry2->GetKey(), first);
1325   entry2->Close();
1326   iter = CreateIterator();
1327
1328   // Modify the oldest entry and get the newest element.
1329   ASSERT_EQ(net::OK, OpenEntry(first, &entry1));
1330   EXPECT_EQ(0, WriteData(entry1, 0, 200, NULL, 0, false));
1331   ASSERT_EQ(net::OK, iter->OpenNextEntry(&entry2));
1332   if (type_ == net::APP_CACHE) {
1333     // The list is not updated.
1334     EXPECT_EQ(entry2->GetKey(), second);
1335   } else {
1336     EXPECT_EQ(entry2->GetKey(), first);
1337   }
1338
1339   entry1->Close();
1340   entry2->Close();
1341 }
1342
1343 TEST_F(DiskCacheBackendTest, Enumerations2) {
1344   BackendEnumerations2();
1345 }
1346
1347 TEST_F(DiskCacheBackendTest, NewEvictionEnumerations2) {
1348   SetNewEviction();
1349   BackendEnumerations2();
1350 }
1351
1352 TEST_F(DiskCacheBackendTest, MemoryOnlyEnumerations2) {
1353   SetMemoryOnlyMode();
1354   BackendEnumerations2();
1355 }
1356
1357 TEST_F(DiskCacheBackendTest, AppCacheEnumerations2) {
1358   SetCacheType(net::APP_CACHE);
1359   BackendEnumerations2();
1360 }
1361
1362 TEST_F(DiskCacheBackendTest, ShaderCacheEnumerations2) {
1363   SetCacheType(net::SHADER_CACHE);
1364   BackendEnumerations2();
1365 }
1366
1367 // Verify that ReadData calls do not update the LRU cache
1368 // when using the SHADER_CACHE type.
1369 TEST_F(DiskCacheBackendTest, ShaderCacheEnumerationReadData) {
1370   SetCacheType(net::SHADER_CACHE);
1371   InitCache();
1372   const std::string first("first");
1373   const std::string second("second");
1374   disk_cache::Entry *entry1, *entry2;
1375   const int kSize = 50;
1376   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
1377
1378   ASSERT_EQ(net::OK, CreateEntry(first, &entry1));
1379   memset(buffer1->data(), 0, kSize);
1380   base::strlcpy(buffer1->data(), "And the data to save", kSize);
1381   EXPECT_EQ(kSize, WriteData(entry1, 0, 0, buffer1.get(), kSize, false));
1382
1383   ASSERT_EQ(net::OK, CreateEntry(second, &entry2));
1384   entry2->Close();
1385
1386   FlushQueueForTest();
1387
1388   // Make sure that the timestamp is not the same.
1389   AddDelay();
1390
1391   // Read from the last item in the LRU.
1392   EXPECT_EQ(kSize, ReadData(entry1, 0, 0, buffer1.get(), kSize));
1393   entry1->Close();
1394
1395   scoped_ptr<TestIterator> iter = CreateIterator();
1396   ASSERT_EQ(net::OK, iter->OpenNextEntry(&entry2));
1397   EXPECT_EQ(entry2->GetKey(), second);
1398   entry2->Close();
1399 }
1400
1401 #if !defined(LEAK_SANITIZER)
1402 // Verify handling of invalid entries while doing enumerations.
1403 // We'll be leaking memory from this test.
1404 void DiskCacheBackendTest::BackendInvalidEntryEnumeration() {
1405   InitCache();
1406
1407   std::string key("Some key");
1408   disk_cache::Entry *entry, *entry1, *entry2;
1409   ASSERT_EQ(net::OK, CreateEntry(key, &entry1));
1410
1411   const int kSize = 50;
1412   scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize));
1413   memset(buffer1->data(), 0, kSize);
1414   base::strlcpy(buffer1->data(), "And the data to save", kSize);
1415   EXPECT_EQ(kSize, WriteData(entry1, 0, 0, buffer1.get(), kSize, false));
1416   entry1->Close();
1417   ASSERT_EQ(net::OK, OpenEntry(key, &entry1));
1418   EXPECT_EQ(kSize, ReadData(entry1, 0, 0, buffer1.get(), kSize));
1419
1420   std::string key2("Another key");
1421   ASSERT_EQ(net::OK, CreateEntry(key2, &entry2));
1422   entry2->Close();
1423   ASSERT_EQ(2, cache_->GetEntryCount());
1424
1425   SimulateCrash();
1426
1427   scoped_ptr<TestIterator> iter = CreateIterator();
1428   int count = 0;
1429   while (iter->OpenNextEntry(&entry) == net::OK) {
1430     ASSERT_TRUE(NULL != entry);
1431     EXPECT_EQ(key2, entry->GetKey());
1432     entry->Close();
1433     count++;
1434   };
1435   EXPECT_EQ(1, count);
1436   EXPECT_EQ(1, cache_->GetEntryCount());
1437 }
1438
1439 // We'll be leaking memory from this test.
1440 TEST_F(DiskCacheBackendTest, InvalidEntryEnumeration) {
1441   BackendInvalidEntryEnumeration();
1442 }
1443
1444 // We'll be leaking memory from this test.
1445 TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntryEnumeration) {
1446   SetNewEviction();
1447   BackendInvalidEntryEnumeration();
1448 }
1449 #endif  // !defined(LEAK_SANITIZER)
1450
1451 // Tests that if for some reason entries are modified close to existing cache
1452 // iterators, we don't generate fatal errors or reset the cache.
1453 void DiskCacheBackendTest::BackendFixEnumerators() {
1454   InitCache();
1455
1456   int seed = static_cast<int>(Time::Now().ToInternalValue());
1457   srand(seed);
1458
1459   const int kNumEntries = 10;
1460   for (int i = 0; i < kNumEntries; i++) {
1461     std::string key = GenerateKey(true);
1462     disk_cache::Entry* entry;
1463     ASSERT_EQ(net::OK, CreateEntry(key, &entry));
1464     entry->Close();
1465   }
1466   EXPECT_EQ(kNumEntries, cache_->GetEntryCount());
1467
1468   disk_cache::Entry *entry1, *entry2;
1469   scoped_ptr<TestIterator> iter1 = CreateIterator(), iter2 = CreateIterator();
1470   ASSERT_EQ(net::OK, iter1->OpenNextEntry(&entry1));
1471   ASSERT_TRUE(NULL != entry1);
1472   entry1->Close();
1473   entry1 = NULL;
1474
1475   // Let's go to the middle of the list.
1476   for (int i = 0; i < kNumEntries / 2; i++) {
1477     if (entry1)
1478       entry1->Close();
1479     ASSERT_EQ(net::OK, iter1->OpenNextEntry(&entry1));
1480     ASSERT_TRUE(NULL != entry1);
1481
1482     ASSERT_EQ(net::OK, iter2->OpenNextEntry(&entry2));
1483     ASSERT_TRUE(NULL != entry2);
1484     entry2->Close();
1485   }
1486
1487   // Messing up with entry1 will modify entry2->next.
1488   entry1->Doom();
1489   ASSERT_EQ(net::OK, iter2->OpenNextEntry(&entry2));
1490   ASSERT_TRUE(NULL != entry2);
1491
1492   // The link entry2->entry1 should be broken.
1493   EXPECT_NE(entry2->GetKey(), entry1->GetKey());
1494   entry1->Close();
1495   entry2->Close();
1496
1497   // And the second iterator should keep working.
1498   ASSERT_EQ(net::OK, iter2->OpenNextEntry(&entry2));
1499   ASSERT_TRUE(NULL != entry2);
1500   entry2->Close();
1501 }
1502
1503 TEST_F(DiskCacheBackendTest, FixEnumerators) {
1504   BackendFixEnumerators();
1505 }
1506
1507 TEST_F(DiskCacheBackendTest, NewEvictionFixEnumerators) {
1508   SetNewEviction();
1509   BackendFixEnumerators();
1510 }
1511
1512 void DiskCacheBackendTest::BackendDoomRecent() {
1513   InitCache();
1514
1515   disk_cache::Entry *entry;
1516   ASSERT_EQ(net::OK, CreateEntry("first", &entry));
1517   entry->Close();
1518   ASSERT_EQ(net::OK, CreateEntry("second", &entry));
1519   entry->Close();
1520   FlushQueueForTest();
1521
1522   AddDelay();
1523   Time middle = Time::Now();
1524
1525   ASSERT_EQ(net::OK, CreateEntry("third", &entry));
1526   entry->Close();
1527   ASSERT_EQ(net::OK, CreateEntry("fourth", &entry));
1528   entry->Close();
1529   FlushQueueForTest();
1530
1531   AddDelay();
1532   Time final = Time::Now();
1533
1534   ASSERT_EQ(4, cache_->GetEntryCount());
1535   EXPECT_EQ(net::OK, DoomEntriesSince(final));
1536   ASSERT_EQ(4, cache_->GetEntryCount());
1537
1538   EXPECT_EQ(net::OK, DoomEntriesSince(middle));
1539   ASSERT_EQ(2, cache_->GetEntryCount());
1540
1541   ASSERT_EQ(net::OK, OpenEntry("second", &entry));
1542   entry->Close();
1543 }
1544
1545 TEST_F(DiskCacheBackendTest, DoomRecent) {
1546   BackendDoomRecent();
1547 }
1548
1549 TEST_F(DiskCacheBackendTest, NewEvictionDoomRecent) {
1550   SetNewEviction();
1551   BackendDoomRecent();
1552 }
1553
1554 TEST_F(DiskCacheBackendTest, MemoryOnlyDoomRecent) {
1555   SetMemoryOnlyMode();
1556   BackendDoomRecent();
1557 }
1558
1559 TEST_F(DiskCacheBackendTest, MemoryOnlyDoomEntriesSinceSparse) {
1560   SetMemoryOnlyMode();
1561   base::Time start;
1562   InitSparseCache(&start, NULL);
1563   DoomEntriesSince(start);
1564   EXPECT_EQ(1, cache_->GetEntryCount());
1565 }
1566
1567 TEST_F(DiskCacheBackendTest, DoomEntriesSinceSparse) {
1568   base::Time start;
1569   InitSparseCache(&start, NULL);
1570   DoomEntriesSince(start);
1571   // NOTE: BackendImpl counts child entries in its GetEntryCount(), while
1572   // MemBackendImpl does not. Thats why expected value differs here from
1573   // MemoryOnlyDoomEntriesSinceSparse.
1574   EXPECT_EQ(3, cache_->GetEntryCount());
1575 }
1576
1577 TEST_F(DiskCacheBackendTest, MemoryOnlyDoomAllSparse) {
1578   SetMemoryOnlyMode();
1579   InitSparseCache(NULL, NULL);
1580   EXPECT_EQ(net::OK, DoomAllEntries());
1581   EXPECT_EQ(0, cache_->GetEntryCount());
1582 }
1583
1584 TEST_F(DiskCacheBackendTest, DoomAllSparse) {
1585   InitSparseCache(NULL, NULL);
1586   EXPECT_EQ(net::OK, DoomAllEntries());
1587   EXPECT_EQ(0, cache_->GetEntryCount());
1588 }
1589
1590 void DiskCacheBackendTest::BackendDoomBetween() {
1591   InitCache();
1592
1593   disk_cache::Entry *entry;
1594   ASSERT_EQ(net::OK, CreateEntry("first", &entry));
1595   entry->Close();
1596   FlushQueueForTest();
1597
1598   AddDelay();
1599   Time middle_start = Time::Now();
1600
1601   ASSERT_EQ(net::OK, CreateEntry("second", &entry));
1602   entry->Close();
1603   ASSERT_EQ(net::OK, CreateEntry("third", &entry));
1604   entry->Close();
1605   FlushQueueForTest();
1606
1607   AddDelay();
1608   Time middle_end = Time::Now();
1609
1610   ASSERT_EQ(net::OK, CreateEntry("fourth", &entry));
1611   entry->Close();
1612   ASSERT_EQ(net::OK, OpenEntry("fourth", &entry));
1613   entry->Close();
1614   FlushQueueForTest();
1615
1616   AddDelay();
1617   Time final = Time::Now();
1618
1619   ASSERT_EQ(4, cache_->GetEntryCount());
1620   EXPECT_EQ(net::OK, DoomEntriesBetween(middle_start, middle_end));
1621   ASSERT_EQ(2, cache_->GetEntryCount());
1622
1623   ASSERT_EQ(net::OK, OpenEntry("fourth", &entry));
1624   entry->Close();
1625
1626   EXPECT_EQ(net::OK, DoomEntriesBetween(middle_start, final));
1627   ASSERT_EQ(1, cache_->GetEntryCount());
1628
1629   ASSERT_EQ(net::OK, OpenEntry("first", &entry));
1630   entry->Close();
1631 }
1632
1633 TEST_F(DiskCacheBackendTest, DoomBetween) {
1634   BackendDoomBetween();
1635 }
1636
1637 TEST_F(DiskCacheBackendTest, NewEvictionDoomBetween) {
1638   SetNewEviction();
1639   BackendDoomBetween();
1640 }
1641
1642 TEST_F(DiskCacheBackendTest, MemoryOnlyDoomBetween) {
1643   SetMemoryOnlyMode();
1644   BackendDoomBetween();
1645 }
1646
1647 TEST_F(DiskCacheBackendTest, MemoryOnlyDoomEntriesBetweenSparse) {
1648   SetMemoryOnlyMode();
1649   base::Time start, end;
1650   InitSparseCache(&start, &end);
1651   DoomEntriesBetween(start, end);
1652   EXPECT_EQ(3, cache_->GetEntryCount());
1653
1654   start = end;
1655   end = base::Time::Now();
1656   DoomEntriesBetween(start, end);
1657   EXPECT_EQ(1, cache_->GetEntryCount());
1658 }
1659
1660 TEST_F(DiskCacheBackendTest, DoomEntriesBetweenSparse) {
1661   base::Time start, end;
1662   InitSparseCache(&start, &end);
1663   DoomEntriesBetween(start, end);
1664   EXPECT_EQ(9, cache_->GetEntryCount());
1665
1666   start = end;
1667   end = base::Time::Now();
1668   DoomEntriesBetween(start, end);
1669   EXPECT_EQ(3, cache_->GetEntryCount());
1670 }
1671
1672 void DiskCacheBackendTest::BackendTransaction(const std::string& name,
1673                                               int num_entries, bool load) {
1674   success_ = false;
1675   ASSERT_TRUE(CopyTestCache(name));
1676   DisableFirstCleanup();
1677
1678   uint32 mask;
1679   if (load) {
1680     mask = 0xf;
1681     SetMaxSize(0x100000);
1682   } else {
1683     // Clear the settings from the previous run.
1684     mask = 0;
1685     SetMaxSize(0);
1686   }
1687   SetMask(mask);
1688
1689   InitCache();
1690   ASSERT_EQ(num_entries + 1, cache_->GetEntryCount());
1691
1692   std::string key("the first key");
1693   disk_cache::Entry* entry1;
1694   ASSERT_NE(net::OK, OpenEntry(key, &entry1));
1695
1696   int actual = cache_->GetEntryCount();
1697   if (num_entries != actual) {
1698     ASSERT_TRUE(load);
1699     // If there is a heavy load, inserting an entry will make another entry
1700     // dirty (on the hash bucket) so two entries are removed.
1701     ASSERT_EQ(num_entries - 1, actual);
1702   }
1703
1704   cache_.reset();
1705   cache_impl_ = NULL;
1706
1707   ASSERT_TRUE(CheckCacheIntegrity(cache_path_, new_eviction_, mask));
1708   success_ = true;
1709 }
1710
1711 void DiskCacheBackendTest::BackendRecoverInsert() {
1712   // Tests with an empty cache.
1713   BackendTransaction("insert_empty1", 0, false);
1714   ASSERT_TRUE(success_) << "insert_empty1";
1715   BackendTransaction("insert_empty2", 0, false);
1716   ASSERT_TRUE(success_) << "insert_empty2";
1717   BackendTransaction("insert_empty3", 0, false);
1718   ASSERT_TRUE(success_) << "insert_empty3";
1719
1720   // Tests with one entry on the cache.
1721   BackendTransaction("insert_one1", 1, false);
1722   ASSERT_TRUE(success_) << "insert_one1";
1723   BackendTransaction("insert_one2", 1, false);
1724   ASSERT_TRUE(success_) << "insert_one2";
1725   BackendTransaction("insert_one3", 1, false);
1726   ASSERT_TRUE(success_) << "insert_one3";
1727
1728   // Tests with one hundred entries on the cache, tiny index.
1729   BackendTransaction("insert_load1", 100, true);
1730   ASSERT_TRUE(success_) << "insert_load1";
1731   BackendTransaction("insert_load2", 100, true);
1732   ASSERT_TRUE(success_) << "insert_load2";
1733 }
1734
1735 TEST_F(DiskCacheBackendTest, RecoverInsert) {
1736   BackendRecoverInsert();
1737 }
1738
1739 TEST_F(DiskCacheBackendTest, NewEvictionRecoverInsert) {
1740   SetNewEviction();
1741   BackendRecoverInsert();
1742 }
1743
1744 void DiskCacheBackendTest::BackendRecoverRemove() {
1745   // Removing the only element.
1746   BackendTransaction("remove_one1", 0, false);
1747   ASSERT_TRUE(success_) << "remove_one1";
1748   BackendTransaction("remove_one2", 0, false);
1749   ASSERT_TRUE(success_) << "remove_one2";
1750   BackendTransaction("remove_one3", 0, false);
1751   ASSERT_TRUE(success_) << "remove_one3";
1752
1753   // Removing the head.
1754   BackendTransaction("remove_head1", 1, false);
1755   ASSERT_TRUE(success_) << "remove_head1";
1756   BackendTransaction("remove_head2", 1, false);
1757   ASSERT_TRUE(success_) << "remove_head2";
1758   BackendTransaction("remove_head3", 1, false);
1759   ASSERT_TRUE(success_) << "remove_head3";
1760
1761   // Removing the tail.
1762   BackendTransaction("remove_tail1", 1, false);
1763   ASSERT_TRUE(success_) << "remove_tail1";
1764   BackendTransaction("remove_tail2", 1, false);
1765   ASSERT_TRUE(success_) << "remove_tail2";
1766   BackendTransaction("remove_tail3", 1, false);
1767   ASSERT_TRUE(success_) << "remove_tail3";
1768
1769   // Removing with one hundred entries on the cache, tiny index.
1770   BackendTransaction("remove_load1", 100, true);
1771   ASSERT_TRUE(success_) << "remove_load1";
1772   BackendTransaction("remove_load2", 100, true);
1773   ASSERT_TRUE(success_) << "remove_load2";
1774   BackendTransaction("remove_load3", 100, true);
1775   ASSERT_TRUE(success_) << "remove_load3";
1776
1777   // This case cannot be reverted.
1778   BackendTransaction("remove_one4", 0, false);
1779   ASSERT_TRUE(success_) << "remove_one4";
1780   BackendTransaction("remove_head4", 1, false);
1781   ASSERT_TRUE(success_) << "remove_head4";
1782 }
1783
1784 #if defined(OS_WIN)
1785 // http://crbug.com/396392
1786 #define MAYBE_RecoverRemove DISABLED_RecoverRemove
1787 #else
1788 #define MAYBE_RecoverRemove RecoverRemove
1789 #endif
1790 TEST_F(DiskCacheBackendTest, MAYBE_RecoverRemove) {
1791   BackendRecoverRemove();
1792 }
1793
1794 #if defined(OS_WIN)
1795 // http://crbug.com/396392
1796 #define MAYBE_NewEvictionRecoverRemove DISABLED_NewEvictionRecoverRemove
1797 #else
1798 #define MAYBE_NewEvictionRecoverRemove NewEvictionRecoverRemove
1799 #endif
1800 TEST_F(DiskCacheBackendTest, MAYBE_NewEvictionRecoverRemove) {
1801   SetNewEviction();
1802   BackendRecoverRemove();
1803 }
1804
1805 void DiskCacheBackendTest::BackendRecoverWithEviction() {
1806   success_ = false;
1807   ASSERT_TRUE(CopyTestCache("insert_load1"));
1808   DisableFirstCleanup();
1809
1810   SetMask(0xf);
1811   SetMaxSize(0x1000);
1812
1813   // We should not crash here.
1814   InitCache();
1815   DisableIntegrityCheck();
1816 }
1817
1818 TEST_F(DiskCacheBackendTest, RecoverWithEviction) {
1819   BackendRecoverWithEviction();
1820 }
1821
1822 TEST_F(DiskCacheBackendTest, NewEvictionRecoverWithEviction) {
1823   SetNewEviction();
1824   BackendRecoverWithEviction();
1825 }
1826
1827 // Tests that the |BackendImpl| fails to start with the wrong cache version.
1828 TEST_F(DiskCacheTest, WrongVersion) {
1829   ASSERT_TRUE(CopyTestCache("wrong_version"));
1830   base::Thread cache_thread("CacheThread");
1831   ASSERT_TRUE(cache_thread.StartWithOptions(
1832       base::Thread::Options(base::MessageLoop::TYPE_IO, 0)));
1833   net::TestCompletionCallback cb;
1834
1835   scoped_ptr<disk_cache::BackendImpl> cache(new disk_cache::BackendImpl(
1836       cache_path_, cache_thread.task_runner(), NULL));
1837   int rv = cache->Init(cb.callback());
1838   ASSERT_EQ(net::ERR_FAILED, cb.GetResult(rv));
1839 }
1840
1841 class BadEntropyProvider : public base::FieldTrial::EntropyProvider {
1842  public:
1843   virtual ~BadEntropyProvider() {}
1844
1845   virtual double GetEntropyForTrial(const std::string& trial_name,
1846                                     uint32 randomization_seed) const OVERRIDE {
1847     return 0.5;
1848   }
1849 };
1850
1851 // Tests that the disk cache successfully joins the control group, dropping the
1852 // existing cache in favour of a new empty cache.
1853 // Disabled on android since this test requires cache creator to create
1854 // blockfile caches.
1855 #if !defined(OS_ANDROID)
1856 TEST_F(DiskCacheTest, SimpleCacheControlJoin) {
1857   base::Thread cache_thread("CacheThread");
1858   ASSERT_TRUE(cache_thread.StartWithOptions(
1859                   base::Thread::Options(base::MessageLoop::TYPE_IO, 0)));
1860
1861   scoped_ptr<disk_cache::BackendImpl> cache =
1862       CreateExistingEntryCache(cache_thread, cache_path_);
1863   ASSERT_TRUE(cache.get());
1864   cache.reset();
1865
1866   // Instantiate the SimpleCacheTrial, forcing this run into the
1867   // ExperimentControl group.
1868   base::FieldTrialList field_trial_list(new BadEntropyProvider());
1869   base::FieldTrialList::CreateFieldTrial("SimpleCacheTrial",
1870                                          "ExperimentControl");
1871   net::TestCompletionCallback cb;
1872   scoped_ptr<disk_cache::Backend> base_cache;
1873   int rv = disk_cache::CreateCacheBackend(net::DISK_CACHE,
1874                                           net::CACHE_BACKEND_BLOCKFILE,
1875                                           cache_path_,
1876                                           0,
1877                                           true,
1878                                           cache_thread.task_runner(),
1879                                           NULL,
1880                                           &base_cache,
1881                                           cb.callback());
1882   ASSERT_EQ(net::OK, cb.GetResult(rv));
1883   EXPECT_EQ(0, base_cache->GetEntryCount());
1884 }
1885 #endif
1886
1887 // Tests that the disk cache can restart in the control group preserving
1888 // existing entries.
1889 TEST_F(DiskCacheTest, SimpleCacheControlRestart) {
1890   // Instantiate the SimpleCacheTrial, forcing this run into the
1891   // ExperimentControl group.
1892   base::FieldTrialList field_trial_list(new BadEntropyProvider());
1893   base::FieldTrialList::CreateFieldTrial("SimpleCacheTrial",
1894                                          "ExperimentControl");
1895
1896   base::Thread cache_thread("CacheThread");
1897   ASSERT_TRUE(cache_thread.StartWithOptions(
1898                   base::Thread::Options(base::MessageLoop::TYPE_IO, 0)));
1899
1900   scoped_ptr<disk_cache::BackendImpl> cache =
1901       CreateExistingEntryCache(cache_thread, cache_path_);
1902   ASSERT_TRUE(cache.get());
1903
1904   net::TestCompletionCallback cb;
1905
1906   const int kRestartCount = 5;
1907   for (int i = 0; i < kRestartCount; ++i) {
1908     cache.reset(new disk_cache::BackendImpl(
1909         cache_path_, cache_thread.message_loop_proxy(), NULL));
1910     int rv = cache->Init(cb.callback());
1911     ASSERT_EQ(net::OK, cb.GetResult(rv));
1912     EXPECT_EQ(1, cache->GetEntryCount());
1913
1914     disk_cache::Entry* entry = NULL;
1915     rv = cache->OpenEntry(kExistingEntryKey, &entry, cb.callback());
1916     EXPECT_EQ(net::OK, cb.GetResult(rv));
1917     EXPECT_TRUE(entry);
1918     entry->Close();
1919   }
1920 }
1921
1922 // Tests that the disk cache can leave the control group preserving existing
1923 // entries.
1924 TEST_F(DiskCacheTest, SimpleCacheControlLeave) {
1925   base::Thread cache_thread("CacheThread");
1926   ASSERT_TRUE(cache_thread.StartWithOptions(
1927       base::Thread::Options(base::MessageLoop::TYPE_IO, 0)));
1928
1929   {
1930     // Instantiate the SimpleCacheTrial, forcing this run into the
1931     // ExperimentControl group.
1932     base::FieldTrialList field_trial_list(new BadEntropyProvider());
1933     base::FieldTrialList::CreateFieldTrial("SimpleCacheTrial",
1934                                            "ExperimentControl");
1935
1936     scoped_ptr<disk_cache::BackendImpl> cache =
1937         CreateExistingEntryCache(cache_thread, cache_path_);
1938     ASSERT_TRUE(cache.get());
1939   }
1940
1941   // Instantiate the SimpleCacheTrial, forcing this run into the
1942   // ExperimentNo group.
1943   base::FieldTrialList field_trial_list(new BadEntropyProvider());
1944   base::FieldTrialList::CreateFieldTrial("SimpleCacheTrial", "ExperimentNo");
1945   net::TestCompletionCallback cb;
1946
1947   const int kRestartCount = 5;
1948   for (int i = 0; i < kRestartCount; ++i) {
1949     scoped_ptr<disk_cache::BackendImpl> cache(new disk_cache::BackendImpl(
1950         cache_path_, cache_thread.message_loop_proxy(), NULL));
1951     int rv = cache->Init(cb.callback());
1952     ASSERT_EQ(net::OK, cb.GetResult(rv));
1953     EXPECT_EQ(1, cache->GetEntryCount());
1954
1955     disk_cache::Entry* entry = NULL;
1956     rv = cache->OpenEntry(kExistingEntryKey, &entry, cb.callback());
1957     EXPECT_EQ(net::OK, cb.GetResult(rv));
1958     EXPECT_TRUE(entry);
1959     entry->Close();
1960   }
1961 }
1962
1963 // Tests that the cache is properly restarted on recovery error.
1964 // Disabled on android since this test requires cache creator to create
1965 // blockfile caches.
1966 #if !defined(OS_ANDROID)
1967 TEST_F(DiskCacheBackendTest, DeleteOld) {
1968   ASSERT_TRUE(CopyTestCache("wrong_version"));
1969   SetNewEviction();
1970   base::Thread cache_thread("CacheThread");
1971   ASSERT_TRUE(cache_thread.StartWithOptions(
1972       base::Thread::Options(base::MessageLoop::TYPE_IO, 0)));
1973
1974   net::TestCompletionCallback cb;
1975   bool prev = base::ThreadRestrictions::SetIOAllowed(false);
1976   base::FilePath path(cache_path_);
1977   int rv = disk_cache::CreateCacheBackend(net::DISK_CACHE,
1978                                           net::CACHE_BACKEND_BLOCKFILE,
1979                                           path,
1980                                           0,
1981                                           true,
1982                                           cache_thread.task_runner(),
1983                                           NULL,
1984                                           &cache_,
1985                                           cb.callback());
1986   path.clear();  // Make sure path was captured by the previous call.
1987   ASSERT_EQ(net::OK, cb.GetResult(rv));
1988   base::ThreadRestrictions::SetIOAllowed(prev);
1989   cache_.reset();
1990   EXPECT_TRUE(CheckCacheIntegrity(cache_path_, new_eviction_, mask_));
1991 }
1992 #endif
1993
1994 // We want to be able to deal with messed up entries on disk.
1995 void DiskCacheBackendTest::BackendInvalidEntry2() {
1996   ASSERT_TRUE(CopyTestCache("bad_entry"));
1997   DisableFirstCleanup();
1998   InitCache();
1999
2000   disk_cache::Entry *entry1, *entry2;
2001   ASSERT_EQ(net::OK, OpenEntry("the first key", &entry1));
2002   EXPECT_NE(net::OK, OpenEntry("some other key", &entry2));
2003   entry1->Close();
2004
2005   // CheckCacheIntegrity will fail at this point.
2006   DisableIntegrityCheck();
2007 }
2008
2009 TEST_F(DiskCacheBackendTest, InvalidEntry2) {
2010   BackendInvalidEntry2();
2011 }
2012
2013 TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry2) {
2014   SetNewEviction();
2015   BackendInvalidEntry2();
2016 }
2017
2018 // Tests that we don't crash or hang when enumerating this cache.
2019 void DiskCacheBackendTest::BackendInvalidEntry3() {
2020   SetMask(0x1);  // 2-entry table.
2021   SetMaxSize(0x3000);  // 12 kB.
2022   DisableFirstCleanup();
2023   InitCache();
2024
2025   disk_cache::Entry* entry;
2026   scoped_ptr<TestIterator> iter = CreateIterator();
2027   while (iter->OpenNextEntry(&entry) == net::OK) {
2028     entry->Close();
2029   }
2030 }
2031
2032 TEST_F(DiskCacheBackendTest, InvalidEntry3) {
2033   ASSERT_TRUE(CopyTestCache("dirty_entry3"));
2034   BackendInvalidEntry3();
2035 }
2036
2037 TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry3) {
2038   ASSERT_TRUE(CopyTestCache("dirty_entry4"));
2039   SetNewEviction();
2040   BackendInvalidEntry3();
2041   DisableIntegrityCheck();
2042 }
2043
2044 // Test that we handle a dirty entry on the LRU list, already replaced with
2045 // the same key, and with hash collisions.
2046 TEST_F(DiskCacheBackendTest, InvalidEntry4) {
2047   ASSERT_TRUE(CopyTestCache("dirty_entry3"));
2048   SetMask(0x1);  // 2-entry table.
2049   SetMaxSize(0x3000);  // 12 kB.
2050   DisableFirstCleanup();
2051   InitCache();
2052
2053   TrimForTest(false);
2054 }
2055
2056 // Test that we handle a dirty entry on the deleted list, already replaced with
2057 // the same key, and with hash collisions.
2058 TEST_F(DiskCacheBackendTest, InvalidEntry5) {
2059   ASSERT_TRUE(CopyTestCache("dirty_entry4"));
2060   SetNewEviction();
2061   SetMask(0x1);  // 2-entry table.
2062   SetMaxSize(0x3000);  // 12 kB.
2063   DisableFirstCleanup();
2064   InitCache();
2065
2066   TrimDeletedListForTest(false);
2067 }
2068
2069 TEST_F(DiskCacheBackendTest, InvalidEntry6) {
2070   ASSERT_TRUE(CopyTestCache("dirty_entry5"));
2071   SetMask(0x1);  // 2-entry table.
2072   SetMaxSize(0x3000);  // 12 kB.
2073   DisableFirstCleanup();
2074   InitCache();
2075
2076   // There is a dirty entry (but marked as clean) at the end, pointing to a
2077   // deleted entry through the hash collision list. We should not re-insert the
2078   // deleted entry into the index table.
2079
2080   TrimForTest(false);
2081   // The cache should be clean (as detected by CheckCacheIntegrity).
2082 }
2083
2084 // Tests that we don't hang when there is a loop on the hash collision list.
2085 // The test cache could be a result of bug 69135.
2086 TEST_F(DiskCacheBackendTest, BadNextEntry1) {
2087   ASSERT_TRUE(CopyTestCache("list_loop2"));
2088   SetMask(0x1);  // 2-entry table.
2089   SetMaxSize(0x3000);  // 12 kB.
2090   DisableFirstCleanup();
2091   InitCache();
2092
2093   // The second entry points at itselft, and the first entry is not accessible
2094   // though the index, but it is at the head of the LRU.
2095
2096   disk_cache::Entry* entry;
2097   ASSERT_EQ(net::OK, CreateEntry("The first key", &entry));
2098   entry->Close();
2099
2100   TrimForTest(false);
2101   TrimForTest(false);
2102   ASSERT_EQ(net::OK, OpenEntry("The first key", &entry));
2103   entry->Close();
2104   EXPECT_EQ(1, cache_->GetEntryCount());
2105 }
2106
2107 // Tests that we don't hang when there is a loop on the hash collision list.
2108 // The test cache could be a result of bug 69135.
2109 TEST_F(DiskCacheBackendTest, BadNextEntry2) {
2110   ASSERT_TRUE(CopyTestCache("list_loop3"));
2111   SetMask(0x1);  // 2-entry table.
2112   SetMaxSize(0x3000);  // 12 kB.
2113   DisableFirstCleanup();
2114   InitCache();
2115
2116   // There is a wide loop of 5 entries.
2117
2118   disk_cache::Entry* entry;
2119   ASSERT_NE(net::OK, OpenEntry("Not present key", &entry));
2120 }
2121
2122 TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry6) {
2123   ASSERT_TRUE(CopyTestCache("bad_rankings3"));
2124   DisableFirstCleanup();
2125   SetNewEviction();
2126   InitCache();
2127
2128   // The second entry is dirty, but removing it should not corrupt the list.
2129   disk_cache::Entry* entry;
2130   ASSERT_NE(net::OK, OpenEntry("the second key", &entry));
2131   ASSERT_EQ(net::OK, OpenEntry("the first key", &entry));
2132
2133   // This should not delete the cache.
2134   entry->Doom();
2135   FlushQueueForTest();
2136   entry->Close();
2137
2138   ASSERT_EQ(net::OK, OpenEntry("some other key", &entry));
2139   entry->Close();
2140 }
2141
2142 // Tests handling of corrupt entries by keeping the rankings node around, with
2143 // a fatal failure.
2144 void DiskCacheBackendTest::BackendInvalidEntry7() {
2145   const int kSize = 0x3000;  // 12 kB.
2146   SetMaxSize(kSize * 10);
2147   InitCache();
2148
2149   std::string first("some key");
2150   std::string second("something else");
2151   disk_cache::Entry* entry;
2152   ASSERT_EQ(net::OK, CreateEntry(first, &entry));
2153   entry->Close();
2154   ASSERT_EQ(net::OK, CreateEntry(second, &entry));
2155
2156   // Corrupt this entry.
2157   disk_cache::EntryImpl* entry_impl =
2158       static_cast<disk_cache::EntryImpl*>(entry);
2159
2160   entry_impl->rankings()->Data()->next = 0;
2161   entry_impl->rankings()->Store();
2162   entry->Close();
2163   FlushQueueForTest();
2164   EXPECT_EQ(2, cache_->GetEntryCount());
2165
2166   // This should detect the bad entry.
2167   EXPECT_NE(net::OK, OpenEntry(second, &entry));
2168   EXPECT_EQ(1, cache_->GetEntryCount());
2169
2170   // We should delete the cache. The list still has a corrupt node.
2171   scoped_ptr<TestIterator> iter = CreateIterator();
2172   EXPECT_NE(net::OK, iter->OpenNextEntry(&entry));
2173   FlushQueueForTest();
2174   EXPECT_EQ(0, cache_->GetEntryCount());
2175 }
2176
2177 TEST_F(DiskCacheBackendTest, InvalidEntry7) {
2178   BackendInvalidEntry7();
2179 }
2180
2181 TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry7) {
2182   SetNewEviction();
2183   BackendInvalidEntry7();
2184 }
2185
2186 // Tests handling of corrupt entries by keeping the rankings node around, with
2187 // a non fatal failure.
2188 void DiskCacheBackendTest::BackendInvalidEntry8() {
2189   const int kSize = 0x3000;  // 12 kB
2190   SetMaxSize(kSize * 10);
2191   InitCache();
2192
2193   std::string first("some key");
2194   std::string second("something else");
2195   disk_cache::Entry* entry;
2196   ASSERT_EQ(net::OK, CreateEntry(first, &entry));
2197   entry->Close();
2198   ASSERT_EQ(net::OK, CreateEntry(second, &entry));
2199
2200   // Corrupt this entry.
2201   disk_cache::EntryImpl* entry_impl =
2202       static_cast<disk_cache::EntryImpl*>(entry);
2203
2204   entry_impl->rankings()->Data()->contents = 0;
2205   entry_impl->rankings()->Store();
2206   entry->Close();
2207   FlushQueueForTest();
2208   EXPECT_EQ(2, cache_->GetEntryCount());
2209
2210   // This should detect the bad entry.
2211   EXPECT_NE(net::OK, OpenEntry(second, &entry));
2212   EXPECT_EQ(1, cache_->GetEntryCount());
2213
2214   // We should not delete the cache.
2215   scoped_ptr<TestIterator> iter = CreateIterator();
2216   ASSERT_EQ(net::OK, iter->OpenNextEntry(&entry));
2217   entry->Close();
2218   EXPECT_NE(net::OK, iter->OpenNextEntry(&entry));
2219   EXPECT_EQ(1, cache_->GetEntryCount());
2220 }
2221
2222 TEST_F(DiskCacheBackendTest, InvalidEntry8) {
2223   BackendInvalidEntry8();
2224 }
2225
2226 TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry8) {
2227   SetNewEviction();
2228   BackendInvalidEntry8();
2229 }
2230
2231 // Tests handling of corrupt entries detected by enumerations. Note that these
2232 // tests (xx9 to xx11) are basically just going though slightly different
2233 // codepaths so they are tighlty coupled with the code, but that is better than
2234 // not testing error handling code.
2235 void DiskCacheBackendTest::BackendInvalidEntry9(bool eviction) {
2236   const int kSize = 0x3000;  // 12 kB.
2237   SetMaxSize(kSize * 10);
2238   InitCache();
2239
2240   std::string first("some key");
2241   std::string second("something else");
2242   disk_cache::Entry* entry;
2243   ASSERT_EQ(net::OK, CreateEntry(first, &entry));
2244   entry->Close();
2245   ASSERT_EQ(net::OK, CreateEntry(second, &entry));
2246
2247   // Corrupt this entry.
2248   disk_cache::EntryImpl* entry_impl =
2249       static_cast<disk_cache::EntryImpl*>(entry);
2250
2251   entry_impl->entry()->Data()->state = 0xbad;
2252   entry_impl->entry()->Store();
2253   entry->Close();
2254   FlushQueueForTest();
2255   EXPECT_EQ(2, cache_->GetEntryCount());
2256
2257   if (eviction) {
2258     TrimForTest(false);
2259     EXPECT_EQ(1, cache_->GetEntryCount());
2260     TrimForTest(false);
2261     EXPECT_EQ(1, cache_->GetEntryCount());
2262   } else {
2263     // We should detect the problem through the list, but we should not delete
2264     // the entry, just fail the iteration.
2265     scoped_ptr<TestIterator> iter = CreateIterator();
2266     EXPECT_NE(net::OK, iter->OpenNextEntry(&entry));
2267
2268     // Now a full iteration will work, and return one entry.
2269     ASSERT_EQ(net::OK, iter->OpenNextEntry(&entry));
2270     entry->Close();
2271     EXPECT_NE(net::OK, iter->OpenNextEntry(&entry));
2272
2273     // This should detect what's left of the bad entry.
2274     EXPECT_NE(net::OK, OpenEntry(second, &entry));
2275     EXPECT_EQ(2, cache_->GetEntryCount());
2276   }
2277   DisableIntegrityCheck();
2278 }
2279
2280 TEST_F(DiskCacheBackendTest, InvalidEntry9) {
2281   BackendInvalidEntry9(false);
2282 }
2283
2284 TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry9) {
2285   SetNewEviction();
2286   BackendInvalidEntry9(false);
2287 }
2288
2289 TEST_F(DiskCacheBackendTest, TrimInvalidEntry9) {
2290   BackendInvalidEntry9(true);
2291 }
2292
2293 TEST_F(DiskCacheBackendTest, NewEvictionTrimInvalidEntry9) {
2294   SetNewEviction();
2295   BackendInvalidEntry9(true);
2296 }
2297
2298 // Tests handling of corrupt entries detected by enumerations.
2299 void DiskCacheBackendTest::BackendInvalidEntry10(bool eviction) {
2300   const int kSize = 0x3000;  // 12 kB.
2301   SetMaxSize(kSize * 10);
2302   SetNewEviction();
2303   InitCache();
2304
2305   std::string first("some key");
2306   std::string second("something else");
2307   disk_cache::Entry* entry;
2308   ASSERT_EQ(net::OK, CreateEntry(first, &entry));
2309   entry->Close();
2310   ASSERT_EQ(net::OK, OpenEntry(first, &entry));
2311   EXPECT_EQ(0, WriteData(entry, 0, 200, NULL, 0, false));
2312   entry->Close();
2313   ASSERT_EQ(net::OK, CreateEntry(second, &entry));
2314
2315   // Corrupt this entry.
2316   disk_cache::EntryImpl* entry_impl =
2317       static_cast<disk_cache::EntryImpl*>(entry);
2318
2319   entry_impl->entry()->Data()->state = 0xbad;
2320   entry_impl->entry()->Store();
2321   entry->Close();
2322   ASSERT_EQ(net::OK, CreateEntry("third", &entry));
2323   entry->Close();
2324   EXPECT_EQ(3, cache_->GetEntryCount());
2325
2326   // We have:
2327   // List 0: third -> second (bad).
2328   // List 1: first.
2329
2330   if (eviction) {
2331     // Detection order: second -> first -> third.
2332     TrimForTest(false);
2333     EXPECT_EQ(3, cache_->GetEntryCount());
2334     TrimForTest(false);
2335     EXPECT_EQ(2, cache_->GetEntryCount());
2336     TrimForTest(false);
2337     EXPECT_EQ(1, cache_->GetEntryCount());
2338   } else {
2339     // Detection order: third -> second -> first.
2340     // We should detect the problem through the list, but we should not delete
2341     // the entry.
2342     scoped_ptr<TestIterator> iter = CreateIterator();
2343     ASSERT_EQ(net::OK, iter->OpenNextEntry(&entry));
2344     entry->Close();
2345     ASSERT_EQ(net::OK, iter->OpenNextEntry(&entry));
2346     EXPECT_EQ(first, entry->GetKey());
2347     entry->Close();
2348     EXPECT_NE(net::OK, iter->OpenNextEntry(&entry));
2349   }
2350   DisableIntegrityCheck();
2351 }
2352
2353 TEST_F(DiskCacheBackendTest, InvalidEntry10) {
2354   BackendInvalidEntry10(false);
2355 }
2356
2357 TEST_F(DiskCacheBackendTest, TrimInvalidEntry10) {
2358   BackendInvalidEntry10(true);
2359 }
2360
2361 // Tests handling of corrupt entries detected by enumerations.
2362 void DiskCacheBackendTest::BackendInvalidEntry11(bool eviction) {
2363   const int kSize = 0x3000;  // 12 kB.
2364   SetMaxSize(kSize * 10);
2365   SetNewEviction();
2366   InitCache();
2367
2368   std::string first("some key");
2369   std::string second("something else");
2370   disk_cache::Entry* entry;
2371   ASSERT_EQ(net::OK, CreateEntry(first, &entry));
2372   entry->Close();
2373   ASSERT_EQ(net::OK, OpenEntry(first, &entry));
2374   EXPECT_EQ(0, WriteData(entry, 0, 200, NULL, 0, false));
2375   entry->Close();
2376   ASSERT_EQ(net::OK, CreateEntry(second, &entry));
2377   entry->Close();
2378   ASSERT_EQ(net::OK, OpenEntry(second, &entry));
2379   EXPECT_EQ(0, WriteData(entry, 0, 200, NULL, 0, false));
2380
2381   // Corrupt this entry.
2382   disk_cache::EntryImpl* entry_impl =
2383       static_cast<disk_cache::EntryImpl*>(entry);
2384
2385   entry_impl->entry()->Data()->state = 0xbad;
2386   entry_impl->entry()->Store();
2387   entry->Close();
2388   ASSERT_EQ(net::OK, CreateEntry("third", &entry));
2389   entry->Close();
2390   FlushQueueForTest();
2391   EXPECT_EQ(3, cache_->GetEntryCount());
2392
2393   // We have:
2394   // List 0: third.
2395   // List 1: second (bad) -> first.
2396
2397   if (eviction) {
2398     // Detection order: third -> first -> second.
2399     TrimForTest(false);
2400     EXPECT_EQ(2, cache_->GetEntryCount());
2401     TrimForTest(false);
2402     EXPECT_EQ(1, cache_->GetEntryCount());
2403     TrimForTest(false);
2404     EXPECT_EQ(1, cache_->GetEntryCount());
2405   } else {
2406     // Detection order: third -> second.
2407     // We should detect the problem through the list, but we should not delete
2408     // the entry, just fail the iteration.
2409     scoped_ptr<TestIterator> iter = CreateIterator();
2410     ASSERT_EQ(net::OK, iter->OpenNextEntry(&entry));
2411     entry->Close();
2412     EXPECT_NE(net::OK, iter->OpenNextEntry(&entry));
2413
2414     // Now a full iteration will work, and return two entries.
2415     ASSERT_EQ(net::OK, iter->OpenNextEntry(&entry));
2416     entry->Close();
2417     ASSERT_EQ(net::OK, iter->OpenNextEntry(&entry));
2418     entry->Close();
2419     EXPECT_NE(net::OK, iter->OpenNextEntry(&entry));
2420   }
2421   DisableIntegrityCheck();
2422 }
2423
2424 TEST_F(DiskCacheBackendTest, InvalidEntry11) {
2425   BackendInvalidEntry11(false);
2426 }
2427
2428 TEST_F(DiskCacheBackendTest, TrimInvalidEntry11) {
2429   BackendInvalidEntry11(true);
2430 }
2431
2432 // Tests handling of corrupt entries in the middle of a long eviction run.
2433 void DiskCacheBackendTest::BackendTrimInvalidEntry12() {
2434   const int kSize = 0x3000;  // 12 kB
2435   SetMaxSize(kSize * 10);
2436   InitCache();
2437
2438   std::string first("some key");
2439   std::string second("something else");
2440   disk_cache::Entry* entry;
2441   ASSERT_EQ(net::OK, CreateEntry(first, &entry));
2442   entry->Close();
2443   ASSERT_EQ(net::OK, CreateEntry(second, &entry));
2444
2445   // Corrupt this entry.
2446   disk_cache::EntryImpl* entry_impl =
2447       static_cast<disk_cache::EntryImpl*>(entry);
2448
2449   entry_impl->entry()->Data()->state = 0xbad;
2450   entry_impl->entry()->Store();
2451   entry->Close();
2452   ASSERT_EQ(net::OK, CreateEntry("third", &entry));
2453   entry->Close();
2454   ASSERT_EQ(net::OK, CreateEntry("fourth", &entry));
2455   TrimForTest(true);
2456   EXPECT_EQ(1, cache_->GetEntryCount());
2457   entry->Close();
2458   DisableIntegrityCheck();
2459 }
2460
2461 TEST_F(DiskCacheBackendTest, TrimInvalidEntry12) {
2462   BackendTrimInvalidEntry12();
2463 }
2464
2465 TEST_F(DiskCacheBackendTest, NewEvictionTrimInvalidEntry12) {
2466   SetNewEviction();
2467   BackendTrimInvalidEntry12();
2468 }
2469
2470 // We want to be able to deal with messed up entries on disk.
2471 void DiskCacheBackendTest::BackendInvalidRankings2() {
2472   ASSERT_TRUE(CopyTestCache("bad_rankings"));
2473   DisableFirstCleanup();
2474   InitCache();
2475
2476   disk_cache::Entry *entry1, *entry2;
2477   EXPECT_NE(net::OK, OpenEntry("the first key", &entry1));
2478   ASSERT_EQ(net::OK, OpenEntry("some other key", &entry2));
2479   entry2->Close();
2480
2481   // CheckCacheIntegrity will fail at this point.
2482   DisableIntegrityCheck();
2483 }
2484
2485 TEST_F(DiskCacheBackendTest, InvalidRankings2) {
2486   BackendInvalidRankings2();
2487 }
2488
2489 TEST_F(DiskCacheBackendTest, NewEvictionInvalidRankings2) {
2490   SetNewEviction();
2491   BackendInvalidRankings2();
2492 }
2493
2494 // If the LRU is corrupt, we delete the cache.
2495 void DiskCacheBackendTest::BackendInvalidRankings() {
2496   disk_cache::Entry* entry;
2497   scoped_ptr<TestIterator> iter = CreateIterator();
2498   ASSERT_EQ(net::OK, iter->OpenNextEntry(&entry));
2499   entry->Close();
2500   EXPECT_EQ(2, cache_->GetEntryCount());
2501
2502   EXPECT_NE(net::OK, iter->OpenNextEntry(&entry));
2503   FlushQueueForTest();  // Allow the restart to finish.
2504   EXPECT_EQ(0, cache_->GetEntryCount());
2505 }
2506
2507 TEST_F(DiskCacheBackendTest, InvalidRankingsSuccess) {
2508   ASSERT_TRUE(CopyTestCache("bad_rankings"));
2509   DisableFirstCleanup();
2510   InitCache();
2511   BackendInvalidRankings();
2512 }
2513
2514 TEST_F(DiskCacheBackendTest, NewEvictionInvalidRankingsSuccess) {
2515   ASSERT_TRUE(CopyTestCache("bad_rankings"));
2516   DisableFirstCleanup();
2517   SetNewEviction();
2518   InitCache();
2519   BackendInvalidRankings();
2520 }
2521
2522 TEST_F(DiskCacheBackendTest, InvalidRankingsFailure) {
2523   ASSERT_TRUE(CopyTestCache("bad_rankings"));
2524   DisableFirstCleanup();
2525   InitCache();
2526   SetTestMode();  // Fail cache reinitialization.
2527   BackendInvalidRankings();
2528 }
2529
2530 TEST_F(DiskCacheBackendTest, NewEvictionInvalidRankingsFailure) {
2531   ASSERT_TRUE(CopyTestCache("bad_rankings"));
2532   DisableFirstCleanup();
2533   SetNewEviction();
2534   InitCache();
2535   SetTestMode();  // Fail cache reinitialization.
2536   BackendInvalidRankings();
2537 }
2538
2539 // If the LRU is corrupt and we have open entries, we disable the cache.
2540 void DiskCacheBackendTest::BackendDisable() {
2541   disk_cache::Entry *entry1, *entry2;
2542   scoped_ptr<TestIterator> iter = CreateIterator();
2543   ASSERT_EQ(net::OK, iter->OpenNextEntry(&entry1));
2544
2545   EXPECT_NE(net::OK, iter->OpenNextEntry(&entry2));
2546   EXPECT_EQ(0, cache_->GetEntryCount());
2547   EXPECT_NE(net::OK, CreateEntry("Something new", &entry2));
2548
2549   entry1->Close();
2550   FlushQueueForTest();  // Flushing the Close posts a task to restart the cache.
2551   FlushQueueForTest();  // This one actually allows that task to complete.
2552
2553   EXPECT_EQ(0, cache_->GetEntryCount());
2554 }
2555
2556 TEST_F(DiskCacheBackendTest, DisableSuccess) {
2557   ASSERT_TRUE(CopyTestCache("bad_rankings"));
2558   DisableFirstCleanup();
2559   InitCache();
2560   BackendDisable();
2561 }
2562
2563 TEST_F(DiskCacheBackendTest, NewEvictionDisableSuccess) {
2564   ASSERT_TRUE(CopyTestCache("bad_rankings"));
2565   DisableFirstCleanup();
2566   SetNewEviction();
2567   InitCache();
2568   BackendDisable();
2569 }
2570
2571 TEST_F(DiskCacheBackendTest, DisableFailure) {
2572   ASSERT_TRUE(CopyTestCache("bad_rankings"));
2573   DisableFirstCleanup();
2574   InitCache();
2575   SetTestMode();  // Fail cache reinitialization.
2576   BackendDisable();
2577 }
2578
2579 TEST_F(DiskCacheBackendTest, NewEvictionDisableFailure) {
2580   ASSERT_TRUE(CopyTestCache("bad_rankings"));
2581   DisableFirstCleanup();
2582   SetNewEviction();
2583   InitCache();
2584   SetTestMode();  // Fail cache reinitialization.
2585   BackendDisable();
2586 }
2587
2588 // This is another type of corruption on the LRU; disable the cache.
2589 void DiskCacheBackendTest::BackendDisable2() {
2590   EXPECT_EQ(8, cache_->GetEntryCount());
2591
2592   disk_cache::Entry* entry;
2593   scoped_ptr<TestIterator> iter = CreateIterator();
2594   int count = 0;
2595   while (iter->OpenNextEntry(&entry) == net::OK) {
2596     ASSERT_TRUE(NULL != entry);
2597     entry->Close();
2598     count++;
2599     ASSERT_LT(count, 9);
2600   };
2601
2602   FlushQueueForTest();
2603   EXPECT_EQ(0, cache_->GetEntryCount());
2604 }
2605
2606 TEST_F(DiskCacheBackendTest, DisableSuccess2) {
2607   ASSERT_TRUE(CopyTestCache("list_loop"));
2608   DisableFirstCleanup();
2609   InitCache();
2610   BackendDisable2();
2611 }
2612
2613 TEST_F(DiskCacheBackendTest, NewEvictionDisableSuccess2) {
2614   ASSERT_TRUE(CopyTestCache("list_loop"));
2615   DisableFirstCleanup();
2616   SetNewEviction();
2617   InitCache();
2618   BackendDisable2();
2619 }
2620
2621 TEST_F(DiskCacheBackendTest, DisableFailure2) {
2622   ASSERT_TRUE(CopyTestCache("list_loop"));
2623   DisableFirstCleanup();
2624   InitCache();
2625   SetTestMode();  // Fail cache reinitialization.
2626   BackendDisable2();
2627 }
2628
2629 TEST_F(DiskCacheBackendTest, NewEvictionDisableFailure2) {
2630   ASSERT_TRUE(CopyTestCache("list_loop"));
2631   DisableFirstCleanup();
2632   SetNewEviction();
2633   InitCache();
2634   SetTestMode();  // Fail cache reinitialization.
2635   BackendDisable2();
2636 }
2637
2638 // If the index size changes when we disable the cache, we should not crash.
2639 void DiskCacheBackendTest::BackendDisable3() {
2640   disk_cache::Entry *entry1, *entry2;
2641   scoped_ptr<TestIterator> iter = CreateIterator();
2642   EXPECT_EQ(2, cache_->GetEntryCount());
2643   ASSERT_EQ(net::OK, iter->OpenNextEntry(&entry1));
2644   entry1->Close();
2645
2646   EXPECT_NE(net::OK, iter->OpenNextEntry(&entry2));
2647   FlushQueueForTest();
2648
2649   ASSERT_EQ(net::OK, CreateEntry("Something new", &entry2));
2650   entry2->Close();
2651
2652   EXPECT_EQ(1, cache_->GetEntryCount());
2653 }
2654
2655 TEST_F(DiskCacheBackendTest, DisableSuccess3) {
2656   ASSERT_TRUE(CopyTestCache("bad_rankings2"));
2657   DisableFirstCleanup();
2658   SetMaxSize(20 * 1024 * 1024);
2659   InitCache();
2660   BackendDisable3();
2661 }
2662
2663 TEST_F(DiskCacheBackendTest, NewEvictionDisableSuccess3) {
2664   ASSERT_TRUE(CopyTestCache("bad_rankings2"));
2665   DisableFirstCleanup();
2666   SetMaxSize(20 * 1024 * 1024);
2667   SetNewEviction();
2668   InitCache();
2669   BackendDisable3();
2670 }
2671
2672 // If we disable the cache, already open entries should work as far as possible.
2673 void DiskCacheBackendTest::BackendDisable4() {
2674   disk_cache::Entry *entry1, *entry2, *entry3, *entry4;
2675   scoped_ptr<TestIterator> iter = CreateIterator();
2676   ASSERT_EQ(net::OK, iter->OpenNextEntry(&entry1));
2677
2678   char key2[2000];
2679   char key3[20000];
2680   CacheTestFillBuffer(key2, sizeof(key2), true);
2681   CacheTestFillBuffer(key3, sizeof(key3), true);
2682   key2[sizeof(key2) - 1] = '\0';
2683   key3[sizeof(key3) - 1] = '\0';
2684   ASSERT_EQ(net::OK, CreateEntry(key2, &entry2));
2685   ASSERT_EQ(net::OK, CreateEntry(key3, &entry3));
2686
2687   const int kBufSize = 20000;
2688   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kBufSize));
2689   memset(buf->data(), 0, kBufSize);
2690   EXPECT_EQ(100, WriteData(entry2, 0, 0, buf.get(), 100, false));
2691   EXPECT_EQ(kBufSize, WriteData(entry3, 0, 0, buf.get(), kBufSize, false));
2692
2693   // This line should disable the cache but not delete it.
2694   EXPECT_NE(net::OK, iter->OpenNextEntry(&entry4));
2695   EXPECT_EQ(0, cache_->GetEntryCount());
2696
2697   EXPECT_NE(net::OK, CreateEntry("cache is disabled", &entry4));
2698
2699   EXPECT_EQ(100, ReadData(entry2, 0, 0, buf.get(), 100));
2700   EXPECT_EQ(100, WriteData(entry2, 0, 0, buf.get(), 100, false));
2701   EXPECT_EQ(100, WriteData(entry2, 1, 0, buf.get(), 100, false));
2702
2703   EXPECT_EQ(kBufSize, ReadData(entry3, 0, 0, buf.get(), kBufSize));
2704   EXPECT_EQ(kBufSize, WriteData(entry3, 0, 0, buf.get(), kBufSize, false));
2705   EXPECT_EQ(kBufSize, WriteData(entry3, 1, 0, buf.get(), kBufSize, false));
2706
2707   std::string key = entry2->GetKey();
2708   EXPECT_EQ(sizeof(key2) - 1, key.size());
2709   key = entry3->GetKey();
2710   EXPECT_EQ(sizeof(key3) - 1, key.size());
2711
2712   entry1->Close();
2713   entry2->Close();
2714   entry3->Close();
2715   FlushQueueForTest();  // Flushing the Close posts a task to restart the cache.
2716   FlushQueueForTest();  // This one actually allows that task to complete.
2717
2718   EXPECT_EQ(0, cache_->GetEntryCount());
2719 }
2720
2721 TEST_F(DiskCacheBackendTest, DisableSuccess4) {
2722   ASSERT_TRUE(CopyTestCache("bad_rankings"));
2723   DisableFirstCleanup();
2724   InitCache();
2725   BackendDisable4();
2726 }
2727
2728 TEST_F(DiskCacheBackendTest, NewEvictionDisableSuccess4) {
2729   ASSERT_TRUE(CopyTestCache("bad_rankings"));
2730   DisableFirstCleanup();
2731   SetNewEviction();
2732   InitCache();
2733   BackendDisable4();
2734 }
2735
2736 TEST_F(DiskCacheTest, Backend_UsageStatsTimer) {
2737   MessageLoopHelper helper;
2738
2739   ASSERT_TRUE(CleanupCacheDir());
2740   scoped_ptr<disk_cache::BackendImpl> cache;
2741   cache.reset(new disk_cache::BackendImpl(
2742       cache_path_, base::ThreadTaskRunnerHandle::Get(), NULL));
2743   ASSERT_TRUE(NULL != cache.get());
2744   cache->SetUnitTestMode();
2745   ASSERT_EQ(net::OK, cache->SyncInit());
2746
2747   // Wait for a callback that never comes... about 2 secs :). The message loop
2748   // has to run to allow invocation of the usage timer.
2749   helper.WaitUntilCacheIoFinished(1);
2750 }
2751
2752 TEST_F(DiskCacheBackendTest, TimerNotCreated) {
2753   ASSERT_TRUE(CopyTestCache("wrong_version"));
2754
2755   scoped_ptr<disk_cache::BackendImpl> cache;
2756   cache.reset(new disk_cache::BackendImpl(
2757       cache_path_, base::ThreadTaskRunnerHandle::Get(), NULL));
2758   ASSERT_TRUE(NULL != cache.get());
2759   cache->SetUnitTestMode();
2760   ASSERT_NE(net::OK, cache->SyncInit());
2761
2762   ASSERT_TRUE(NULL == cache->GetTimerForTest());
2763
2764   DisableIntegrityCheck();
2765 }
2766
2767 TEST_F(DiskCacheBackendTest, Backend_UsageStats) {
2768   InitCache();
2769   disk_cache::Entry* entry;
2770   ASSERT_EQ(net::OK, CreateEntry("key", &entry));
2771   entry->Close();
2772   FlushQueueForTest();
2773
2774   disk_cache::StatsItems stats;
2775   cache_->GetStats(&stats);
2776   EXPECT_FALSE(stats.empty());
2777
2778   disk_cache::StatsItems::value_type hits("Create hit", "0x1");
2779   EXPECT_EQ(1, std::count(stats.begin(), stats.end(), hits));
2780
2781   cache_.reset();
2782
2783   // Now open the cache and verify that the stats are still there.
2784   DisableFirstCleanup();
2785   InitCache();
2786   EXPECT_EQ(1, cache_->GetEntryCount());
2787
2788   stats.clear();
2789   cache_->GetStats(&stats);
2790   EXPECT_FALSE(stats.empty());
2791
2792   EXPECT_EQ(1, std::count(stats.begin(), stats.end(), hits));
2793 }
2794
2795 void DiskCacheBackendTest::BackendDoomAll() {
2796   InitCache();
2797
2798   disk_cache::Entry *entry1, *entry2;
2799   ASSERT_EQ(net::OK, CreateEntry("first", &entry1));
2800   ASSERT_EQ(net::OK, CreateEntry("second", &entry2));
2801   entry1->Close();
2802   entry2->Close();
2803
2804   ASSERT_EQ(net::OK, CreateEntry("third", &entry1));
2805   ASSERT_EQ(net::OK, CreateEntry("fourth", &entry2));
2806
2807   ASSERT_EQ(4, cache_->GetEntryCount());
2808   EXPECT_EQ(net::OK, DoomAllEntries());
2809   ASSERT_EQ(0, cache_->GetEntryCount());
2810
2811   // We should stop posting tasks at some point (if we post any).
2812   base::MessageLoop::current()->RunUntilIdle();
2813
2814   disk_cache::Entry *entry3, *entry4;
2815   EXPECT_NE(net::OK, OpenEntry("third", &entry3));
2816   ASSERT_EQ(net::OK, CreateEntry("third", &entry3));
2817   ASSERT_EQ(net::OK, CreateEntry("fourth", &entry4));
2818
2819   EXPECT_EQ(net::OK, DoomAllEntries());
2820   ASSERT_EQ(0, cache_->GetEntryCount());
2821
2822   entry1->Close();
2823   entry2->Close();
2824   entry3->Doom();  // The entry should be already doomed, but this must work.
2825   entry3->Close();
2826   entry4->Close();
2827
2828   // Now try with all references released.
2829   ASSERT_EQ(net::OK, CreateEntry("third", &entry1));
2830   ASSERT_EQ(net::OK, CreateEntry("fourth", &entry2));
2831   entry1->Close();
2832   entry2->Close();
2833
2834   ASSERT_EQ(2, cache_->GetEntryCount());
2835   EXPECT_EQ(net::OK, DoomAllEntries());
2836   ASSERT_EQ(0, cache_->GetEntryCount());
2837
2838   EXPECT_EQ(net::OK, DoomAllEntries());
2839 }
2840
2841 TEST_F(DiskCacheBackendTest, DoomAll) {
2842   BackendDoomAll();
2843 }
2844
2845 TEST_F(DiskCacheBackendTest, NewEvictionDoomAll) {
2846   SetNewEviction();
2847   BackendDoomAll();
2848 }
2849
2850 TEST_F(DiskCacheBackendTest, MemoryOnlyDoomAll) {
2851   SetMemoryOnlyMode();
2852   BackendDoomAll();
2853 }
2854
2855 TEST_F(DiskCacheBackendTest, AppCacheOnlyDoomAll) {
2856   SetCacheType(net::APP_CACHE);
2857   BackendDoomAll();
2858 }
2859
2860 TEST_F(DiskCacheBackendTest, ShaderCacheOnlyDoomAll) {
2861   SetCacheType(net::SHADER_CACHE);
2862   BackendDoomAll();
2863 }
2864
2865 // If the index size changes when we doom the cache, we should not crash.
2866 void DiskCacheBackendTest::BackendDoomAll2() {
2867   EXPECT_EQ(2, cache_->GetEntryCount());
2868   EXPECT_EQ(net::OK, DoomAllEntries());
2869
2870   disk_cache::Entry* entry;
2871   ASSERT_EQ(net::OK, CreateEntry("Something new", &entry));
2872   entry->Close();
2873
2874   EXPECT_EQ(1, cache_->GetEntryCount());
2875 }
2876
2877 TEST_F(DiskCacheBackendTest, DoomAll2) {
2878   ASSERT_TRUE(CopyTestCache("bad_rankings2"));
2879   DisableFirstCleanup();
2880   SetMaxSize(20 * 1024 * 1024);
2881   InitCache();
2882   BackendDoomAll2();
2883 }
2884
2885 TEST_F(DiskCacheBackendTest, NewEvictionDoomAll2) {
2886   ASSERT_TRUE(CopyTestCache("bad_rankings2"));
2887   DisableFirstCleanup();
2888   SetMaxSize(20 * 1024 * 1024);
2889   SetNewEviction();
2890   InitCache();
2891   BackendDoomAll2();
2892 }
2893
2894 // We should be able to create the same entry on multiple simultaneous instances
2895 // of the cache.
2896 TEST_F(DiskCacheTest, MultipleInstances) {
2897   base::ScopedTempDir store1, store2;
2898   ASSERT_TRUE(store1.CreateUniqueTempDir());
2899   ASSERT_TRUE(store2.CreateUniqueTempDir());
2900
2901   base::Thread cache_thread("CacheThread");
2902   ASSERT_TRUE(cache_thread.StartWithOptions(
2903       base::Thread::Options(base::MessageLoop::TYPE_IO, 0)));
2904   net::TestCompletionCallback cb;
2905
2906   const int kNumberOfCaches = 2;
2907   scoped_ptr<disk_cache::Backend> cache[kNumberOfCaches];
2908
2909   int rv = disk_cache::CreateCacheBackend(net::DISK_CACHE,
2910                                           net::CACHE_BACKEND_DEFAULT,
2911                                           store1.path(),
2912                                           0,
2913                                           false,
2914                                           cache_thread.task_runner(),
2915                                           NULL,
2916                                           &cache[0],
2917                                           cb.callback());
2918   ASSERT_EQ(net::OK, cb.GetResult(rv));
2919   rv = disk_cache::CreateCacheBackend(net::MEDIA_CACHE,
2920                                       net::CACHE_BACKEND_DEFAULT,
2921                                       store2.path(),
2922                                       0,
2923                                       false,
2924                                       cache_thread.task_runner(),
2925                                       NULL,
2926                                       &cache[1],
2927                                       cb.callback());
2928   ASSERT_EQ(net::OK, cb.GetResult(rv));
2929
2930   ASSERT_TRUE(cache[0].get() != NULL && cache[1].get() != NULL);
2931
2932   std::string key("the first key");
2933   disk_cache::Entry* entry;
2934   for (int i = 0; i < kNumberOfCaches; i++) {
2935     rv = cache[i]->CreateEntry(key, &entry, cb.callback());
2936     ASSERT_EQ(net::OK, cb.GetResult(rv));
2937     entry->Close();
2938   }
2939 }
2940
2941 // Test the six regions of the curve that determines the max cache size.
2942 TEST_F(DiskCacheTest, AutomaticMaxSize) {
2943   using disk_cache::kDefaultCacheSize;
2944   int64 large_size = kDefaultCacheSize;
2945
2946   // Region 1: expected = available * 0.8
2947   EXPECT_EQ((kDefaultCacheSize - 1) * 8 / 10,
2948             disk_cache::PreferredCacheSize(large_size - 1));
2949   EXPECT_EQ(kDefaultCacheSize * 8 / 10,
2950             disk_cache::PreferredCacheSize(large_size));
2951   EXPECT_EQ(kDefaultCacheSize - 1,
2952             disk_cache::PreferredCacheSize(large_size * 10 / 8 - 1));
2953
2954   // Region 2: expected = default_size
2955   EXPECT_EQ(kDefaultCacheSize,
2956             disk_cache::PreferredCacheSize(large_size * 10 / 8));
2957   EXPECT_EQ(kDefaultCacheSize,
2958             disk_cache::PreferredCacheSize(large_size * 10 - 1));
2959
2960   // Region 3: expected = available * 0.1
2961   EXPECT_EQ(kDefaultCacheSize,
2962             disk_cache::PreferredCacheSize(large_size * 10));
2963   EXPECT_EQ((kDefaultCacheSize * 25 - 1) / 10,
2964             disk_cache::PreferredCacheSize(large_size * 25 - 1));
2965
2966   // Region 4: expected = default_size * 2.5
2967   EXPECT_EQ(kDefaultCacheSize * 25 / 10,
2968             disk_cache::PreferredCacheSize(large_size * 25));
2969   EXPECT_EQ(kDefaultCacheSize * 25 / 10,
2970             disk_cache::PreferredCacheSize(large_size * 100 - 1));
2971   EXPECT_EQ(kDefaultCacheSize * 25 / 10,
2972             disk_cache::PreferredCacheSize(large_size * 100));
2973   EXPECT_EQ(kDefaultCacheSize * 25 / 10,
2974             disk_cache::PreferredCacheSize(large_size * 250 - 1));
2975
2976   // Region 5: expected = available * 0.1
2977   int64 largest_size = kDefaultCacheSize * 4;
2978   EXPECT_EQ(kDefaultCacheSize * 25 / 10,
2979             disk_cache::PreferredCacheSize(large_size * 250));
2980   EXPECT_EQ(largest_size - 1,
2981             disk_cache::PreferredCacheSize(largest_size * 100 - 1));
2982
2983   // Region 6: expected = largest possible size
2984   EXPECT_EQ(largest_size,
2985             disk_cache::PreferredCacheSize(largest_size * 100));
2986   EXPECT_EQ(largest_size,
2987             disk_cache::PreferredCacheSize(largest_size * 10000));
2988 }
2989
2990 // Tests that we can "migrate" a running instance from one experiment group to
2991 // another.
2992 TEST_F(DiskCacheBackendTest, Histograms) {
2993   InitCache();
2994   disk_cache::BackendImpl* backend_ = cache_impl_;  // Needed be the macro.
2995
2996   for (int i = 1; i < 3; i++) {
2997     CACHE_UMA(HOURS, "FillupTime", i, 28);
2998   }
2999 }
3000
3001 // Make sure that we keep the total memory used by the internal buffers under
3002 // control.
3003 TEST_F(DiskCacheBackendTest, TotalBuffersSize1) {
3004   InitCache();
3005   std::string key("the first key");
3006   disk_cache::Entry* entry;
3007   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
3008
3009   const int kSize = 200;
3010   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
3011   CacheTestFillBuffer(buffer->data(), kSize, true);
3012
3013   for (int i = 0; i < 10; i++) {
3014     SCOPED_TRACE(i);
3015     // Allocate 2MB for this entry.
3016     EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, true));
3017     EXPECT_EQ(kSize, WriteData(entry, 1, 0, buffer.get(), kSize, true));
3018     EXPECT_EQ(kSize,
3019               WriteData(entry, 0, 1024 * 1024, buffer.get(), kSize, false));
3020     EXPECT_EQ(kSize,
3021               WriteData(entry, 1, 1024 * 1024, buffer.get(), kSize, false));
3022
3023     // Delete one of the buffers and truncate the other.
3024     EXPECT_EQ(0, WriteData(entry, 0, 0, buffer.get(), 0, true));
3025     EXPECT_EQ(0, WriteData(entry, 1, 10, buffer.get(), 0, true));
3026
3027     // Delete the second buffer, writing 10 bytes to disk.
3028     entry->Close();
3029     ASSERT_EQ(net::OK, OpenEntry(key, &entry));
3030   }
3031
3032   entry->Close();
3033   EXPECT_EQ(0, cache_impl_->GetTotalBuffersSize());
3034 }
3035
3036 // This test assumes at least 150MB of system memory.
3037 TEST_F(DiskCacheBackendTest, TotalBuffersSize2) {
3038   InitCache();
3039
3040   const int kOneMB = 1024 * 1024;
3041   EXPECT_TRUE(cache_impl_->IsAllocAllowed(0, kOneMB));
3042   EXPECT_EQ(kOneMB, cache_impl_->GetTotalBuffersSize());
3043
3044   EXPECT_TRUE(cache_impl_->IsAllocAllowed(0, kOneMB));
3045   EXPECT_EQ(kOneMB * 2, cache_impl_->GetTotalBuffersSize());
3046
3047   EXPECT_TRUE(cache_impl_->IsAllocAllowed(0, kOneMB));
3048   EXPECT_EQ(kOneMB * 3, cache_impl_->GetTotalBuffersSize());
3049
3050   cache_impl_->BufferDeleted(kOneMB);
3051   EXPECT_EQ(kOneMB * 2, cache_impl_->GetTotalBuffersSize());
3052
3053   // Check the upper limit.
3054   EXPECT_FALSE(cache_impl_->IsAllocAllowed(0, 30 * kOneMB));
3055
3056   for (int i = 0; i < 30; i++)
3057     cache_impl_->IsAllocAllowed(0, kOneMB);  // Ignore the result.
3058
3059   EXPECT_FALSE(cache_impl_->IsAllocAllowed(0, kOneMB));
3060 }
3061
3062 // Tests that sharing of external files works and we are able to delete the
3063 // files when we need to.
3064 TEST_F(DiskCacheBackendTest, FileSharing) {
3065   InitCache();
3066
3067   disk_cache::Addr address(0x80000001);
3068   ASSERT_TRUE(cache_impl_->CreateExternalFile(&address));
3069   base::FilePath name = cache_impl_->GetFileName(address);
3070
3071   scoped_refptr<disk_cache::File> file(new disk_cache::File(false));
3072   file->Init(name);
3073
3074 #if defined(OS_WIN)
3075   DWORD sharing = FILE_SHARE_READ | FILE_SHARE_WRITE;
3076   DWORD access = GENERIC_READ | GENERIC_WRITE;
3077   base::win::ScopedHandle file2(CreateFile(
3078       name.value().c_str(), access, sharing, NULL, OPEN_EXISTING, 0, NULL));
3079   EXPECT_FALSE(file2.IsValid());
3080
3081   sharing |= FILE_SHARE_DELETE;
3082   file2.Set(CreateFile(name.value().c_str(), access, sharing, NULL,
3083                        OPEN_EXISTING, 0, NULL));
3084   EXPECT_TRUE(file2.IsValid());
3085 #endif
3086
3087   EXPECT_TRUE(base::DeleteFile(name, false));
3088
3089   // We should be able to use the file.
3090   const int kSize = 200;
3091   char buffer1[kSize];
3092   char buffer2[kSize];
3093   memset(buffer1, 't', kSize);
3094   memset(buffer2, 0, kSize);
3095   EXPECT_TRUE(file->Write(buffer1, kSize, 0));
3096   EXPECT_TRUE(file->Read(buffer2, kSize, 0));
3097   EXPECT_EQ(0, memcmp(buffer1, buffer2, kSize));
3098
3099   EXPECT_TRUE(disk_cache::DeleteCacheFile(name));
3100 }
3101
3102 TEST_F(DiskCacheBackendTest, UpdateRankForExternalCacheHit) {
3103   InitCache();
3104
3105   disk_cache::Entry* entry;
3106
3107   for (int i = 0; i < 2; ++i) {
3108     std::string key = base::StringPrintf("key%d", i);
3109     ASSERT_EQ(net::OK, CreateEntry(key, &entry));
3110     entry->Close();
3111   }
3112
3113   // Ping the oldest entry.
3114   cache_->OnExternalCacheHit("key0");
3115
3116   TrimForTest(false);
3117
3118   // Make sure the older key remains.
3119   EXPECT_EQ(1, cache_->GetEntryCount());
3120   ASSERT_EQ(net::OK, OpenEntry("key0", &entry));
3121   entry->Close();
3122 }
3123
3124 TEST_F(DiskCacheBackendTest, ShaderCacheUpdateRankForExternalCacheHit) {
3125   SetCacheType(net::SHADER_CACHE);
3126   InitCache();
3127
3128   disk_cache::Entry* entry;
3129
3130   for (int i = 0; i < 2; ++i) {
3131     std::string key = base::StringPrintf("key%d", i);
3132     ASSERT_EQ(net::OK, CreateEntry(key, &entry));
3133     entry->Close();
3134   }
3135
3136   // Ping the oldest entry.
3137   cache_->OnExternalCacheHit("key0");
3138
3139   TrimForTest(false);
3140
3141   // Make sure the older key remains.
3142   EXPECT_EQ(1, cache_->GetEntryCount());
3143   ASSERT_EQ(net::OK, OpenEntry("key0", &entry));
3144   entry->Close();
3145 }
3146
3147 // The Simple Cache backend requires a few guarantees from the filesystem like
3148 // atomic renaming of recently open files. Those guarantees are not provided in
3149 // general on Windows.
3150 #if defined(OS_POSIX)
3151
3152 TEST_F(DiskCacheBackendTest, SimpleCacheShutdownWithPendingCreate) {
3153   SetCacheType(net::APP_CACHE);
3154   SetSimpleCacheMode();
3155   BackendShutdownWithPendingCreate(false);
3156 }
3157
3158 TEST_F(DiskCacheBackendTest, SimpleCacheShutdownWithPendingFileIO) {
3159   SetCacheType(net::APP_CACHE);
3160   SetSimpleCacheMode();
3161   BackendShutdownWithPendingFileIO(false);
3162 }
3163
3164 TEST_F(DiskCacheBackendTest, SimpleCacheBasics) {
3165   SetSimpleCacheMode();
3166   BackendBasics();
3167 }
3168
3169 TEST_F(DiskCacheBackendTest, SimpleCacheAppCacheBasics) {
3170   SetCacheType(net::APP_CACHE);
3171   SetSimpleCacheMode();
3172   BackendBasics();
3173 }
3174
3175 TEST_F(DiskCacheBackendTest, SimpleCacheKeying) {
3176   SetSimpleCacheMode();
3177   BackendKeying();
3178 }
3179
3180 TEST_F(DiskCacheBackendTest, SimpleCacheAppCacheKeying) {
3181   SetSimpleCacheMode();
3182   SetCacheType(net::APP_CACHE);
3183   BackendKeying();
3184 }
3185
3186 TEST_F(DiskCacheBackendTest, DISABLED_SimpleCacheSetSize) {
3187   SetSimpleCacheMode();
3188   BackendSetSize();
3189 }
3190
3191 // MacOS has a default open file limit of 256 files, which is incompatible with
3192 // this simple cache test.
3193 #if defined(OS_MACOSX)
3194 #define SIMPLE_MAYBE_MACOS(TestName) DISABLED_ ## TestName
3195 #else
3196 #define SIMPLE_MAYBE_MACOS(TestName) TestName
3197 #endif
3198
3199 TEST_F(DiskCacheBackendTest, SIMPLE_MAYBE_MACOS(SimpleCacheLoad)) {
3200   SetMaxSize(0x100000);
3201   SetSimpleCacheMode();
3202   BackendLoad();
3203 }
3204
3205 TEST_F(DiskCacheBackendTest, SIMPLE_MAYBE_MACOS(SimpleCacheAppCacheLoad)) {
3206   SetCacheType(net::APP_CACHE);
3207   SetSimpleCacheMode();
3208   SetMaxSize(0x100000);
3209   BackendLoad();
3210 }
3211
3212 TEST_F(DiskCacheBackendTest, SimpleDoomRecent) {
3213   SetSimpleCacheMode();
3214   BackendDoomRecent();
3215 }
3216
3217 // crbug.com/330926, crbug.com/370677
3218 TEST_F(DiskCacheBackendTest, DISABLED_SimpleDoomBetween) {
3219   SetSimpleCacheMode();
3220   BackendDoomBetween();
3221 }
3222
3223 TEST_F(DiskCacheBackendTest, SimpleCacheDoomAll) {
3224   SetSimpleCacheMode();
3225   BackendDoomAll();
3226 }
3227
3228 TEST_F(DiskCacheBackendTest, SimpleCacheAppCacheOnlyDoomAll) {
3229   SetCacheType(net::APP_CACHE);
3230   SetSimpleCacheMode();
3231   BackendDoomAll();
3232 }
3233
3234 TEST_F(DiskCacheBackendTest, SimpleCacheOpenMissingFile) {
3235   SetSimpleCacheMode();
3236   InitCache();
3237
3238   const char* key = "the first key";
3239   disk_cache::Entry* entry = NULL;
3240
3241   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
3242   ASSERT_TRUE(entry != NULL);
3243   entry->Close();
3244   entry = NULL;
3245
3246   // To make sure the file creation completed we need to call open again so that
3247   // we block until it actually created the files.
3248   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
3249   ASSERT_TRUE(entry != NULL);
3250   entry->Close();
3251   entry = NULL;
3252
3253   // Delete one of the files in the entry.
3254   base::FilePath to_delete_file = cache_path_.AppendASCII(
3255       disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0));
3256   EXPECT_TRUE(base::PathExists(to_delete_file));
3257   EXPECT_TRUE(disk_cache::DeleteCacheFile(to_delete_file));
3258
3259   // Failing to open the entry should delete the rest of these files.
3260   ASSERT_EQ(net::ERR_FAILED, OpenEntry(key, &entry));
3261
3262   // Confirm the rest of the files are gone.
3263   for (int i = 1; i < disk_cache::kSimpleEntryFileCount; ++i) {
3264     base::FilePath should_be_gone_file(cache_path_.AppendASCII(
3265         disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, i)));
3266     EXPECT_FALSE(base::PathExists(should_be_gone_file));
3267   }
3268 }
3269
3270 TEST_F(DiskCacheBackendTest, SimpleCacheOpenBadFile) {
3271   SetSimpleCacheMode();
3272   InitCache();
3273
3274   const char* key = "the first key";
3275   disk_cache::Entry* entry = NULL;
3276
3277   ASSERT_EQ(net::OK, CreateEntry(key, &entry));
3278   disk_cache::Entry* null = NULL;
3279   ASSERT_NE(null, entry);
3280   entry->Close();
3281   entry = NULL;
3282
3283   // To make sure the file creation completed we need to call open again so that
3284   // we block until it actually created the files.
3285   ASSERT_EQ(net::OK, OpenEntry(key, &entry));
3286   ASSERT_NE(null, entry);
3287   entry->Close();
3288   entry = NULL;
3289
3290   // Write an invalid header for stream 0 and stream 1.
3291   base::FilePath entry_file1_path = cache_path_.AppendASCII(
3292       disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0));
3293
3294   disk_cache::SimpleFileHeader header;
3295   header.initial_magic_number = GG_UINT64_C(0xbadf00d);
3296   EXPECT_EQ(
3297       implicit_cast<int>(sizeof(header)),
3298       base::WriteFile(entry_file1_path, reinterpret_cast<char*>(&header),
3299                            sizeof(header)));
3300   ASSERT_EQ(net::ERR_FAILED, OpenEntry(key, &entry));
3301 }
3302
3303 // Tests that the Simple Cache Backend fails to initialize with non-matching
3304 // file structure on disk.
3305 TEST_F(DiskCacheBackendTest, SimpleCacheOverBlockfileCache) {
3306   // Create a cache structure with the |BackendImpl|.
3307   InitCache();
3308   disk_cache::Entry* entry;
3309   const int kSize = 50;
3310   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
3311   CacheTestFillBuffer(buffer->data(), kSize, false);
3312   ASSERT_EQ(net::OK, CreateEntry("key", &entry));
3313   ASSERT_EQ(0, WriteData(entry, 0, 0, buffer.get(), 0, false));
3314   entry->Close();
3315   cache_.reset();
3316
3317   // Check that the |SimpleBackendImpl| does not favor this structure.
3318   base::Thread cache_thread("CacheThread");
3319   ASSERT_TRUE(cache_thread.StartWithOptions(
3320       base::Thread::Options(base::MessageLoop::TYPE_IO, 0)));
3321   disk_cache::SimpleBackendImpl* simple_cache =
3322       new disk_cache::SimpleBackendImpl(
3323           cache_path_, 0, net::DISK_CACHE, cache_thread.task_runner(), NULL);
3324   net::TestCompletionCallback cb;
3325   int rv = simple_cache->Init(cb.callback());
3326   EXPECT_NE(net::OK, cb.GetResult(rv));
3327   delete simple_cache;
3328   DisableIntegrityCheck();
3329 }
3330
3331 // Tests that the |BackendImpl| refuses to initialize on top of the files
3332 // generated by the Simple Cache Backend.
3333 TEST_F(DiskCacheBackendTest, BlockfileCacheOverSimpleCache) {
3334   // Create a cache structure with the |SimpleBackendImpl|.
3335   SetSimpleCacheMode();
3336   InitCache();
3337   disk_cache::Entry* entry;
3338   const int kSize = 50;
3339   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
3340   CacheTestFillBuffer(buffer->data(), kSize, false);
3341   ASSERT_EQ(net::OK, CreateEntry("key", &entry));
3342   ASSERT_EQ(0, WriteData(entry, 0, 0, buffer.get(), 0, false));
3343   entry->Close();
3344   cache_.reset();
3345
3346   // Check that the |BackendImpl| does not favor this structure.
3347   base::Thread cache_thread("CacheThread");
3348   ASSERT_TRUE(cache_thread.StartWithOptions(
3349       base::Thread::Options(base::MessageLoop::TYPE_IO, 0)));
3350   disk_cache::BackendImpl* cache = new disk_cache::BackendImpl(
3351       cache_path_, base::ThreadTaskRunnerHandle::Get(), NULL);
3352   cache->SetUnitTestMode();
3353   net::TestCompletionCallback cb;
3354   int rv = cache->Init(cb.callback());
3355   EXPECT_NE(net::OK, cb.GetResult(rv));
3356   delete cache;
3357   DisableIntegrityCheck();
3358 }
3359
3360 TEST_F(DiskCacheBackendTest, SimpleCacheFixEnumerators) {
3361   SetSimpleCacheMode();
3362   BackendFixEnumerators();
3363 }
3364
3365 // Tests basic functionality of the SimpleBackend implementation of the
3366 // enumeration API.
3367 TEST_F(DiskCacheBackendTest, SimpleCacheEnumerationBasics) {
3368   SetSimpleCacheMode();
3369   InitCache();
3370   std::set<std::string> key_pool;
3371   ASSERT_TRUE(CreateSetOfRandomEntries(&key_pool));
3372
3373   // Check that enumeration returns all entries.
3374   std::set<std::string> keys_to_match(key_pool);
3375   scoped_ptr<TestIterator> iter = CreateIterator();
3376   size_t count = 0;
3377   ASSERT_TRUE(EnumerateAndMatchKeys(-1, iter.get(), &keys_to_match, &count));
3378   iter.reset();
3379   EXPECT_EQ(key_pool.size(), count);
3380   EXPECT_TRUE(keys_to_match.empty());
3381
3382   // Check that opening entries does not affect enumeration.
3383   keys_to_match = key_pool;
3384   iter = CreateIterator();
3385   count = 0;
3386   disk_cache::Entry* entry_opened_before;
3387   ASSERT_EQ(net::OK, OpenEntry(*(key_pool.begin()), &entry_opened_before));
3388   ASSERT_TRUE(EnumerateAndMatchKeys(key_pool.size()/2,
3389                                     iter.get(),
3390                                     &keys_to_match,
3391                                     &count));
3392
3393   disk_cache::Entry* entry_opened_middle;
3394   ASSERT_EQ(net::OK,
3395             OpenEntry(*(keys_to_match.begin()), &entry_opened_middle));
3396   ASSERT_TRUE(EnumerateAndMatchKeys(-1, iter.get(), &keys_to_match, &count));
3397   iter.reset();
3398   entry_opened_before->Close();
3399   entry_opened_middle->Close();
3400
3401   EXPECT_EQ(key_pool.size(), count);
3402   EXPECT_TRUE(keys_to_match.empty());
3403 }
3404
3405 // Tests that the enumerations are not affected by dooming an entry in the
3406 // middle.
3407 TEST_F(DiskCacheBackendTest, SimpleCacheEnumerationWhileDoomed) {
3408   SetSimpleCacheMode();
3409   InitCache();
3410   std::set<std::string> key_pool;
3411   ASSERT_TRUE(CreateSetOfRandomEntries(&key_pool));
3412
3413   // Check that enumeration returns all entries but the doomed one.
3414   std::set<std::string> keys_to_match(key_pool);
3415   scoped_ptr<TestIterator> iter = CreateIterator();
3416   size_t count = 0;
3417   ASSERT_TRUE(EnumerateAndMatchKeys(key_pool.size()/2,
3418                                     iter.get(),
3419                                     &keys_to_match,
3420                                     &count));
3421
3422   std::string key_to_delete = *(keys_to_match.begin());
3423   DoomEntry(key_to_delete);
3424   keys_to_match.erase(key_to_delete);
3425   key_pool.erase(key_to_delete);
3426   ASSERT_TRUE(EnumerateAndMatchKeys(-1, iter.get(), &keys_to_match, &count));
3427   iter.reset();
3428
3429   EXPECT_EQ(key_pool.size(), count);
3430   EXPECT_TRUE(keys_to_match.empty());
3431 }
3432
3433 // Tests that enumerations are not affected by corrupt files.
3434 TEST_F(DiskCacheBackendTest, SimpleCacheEnumerationCorruption) {
3435   SetSimpleCacheMode();
3436   InitCache();
3437   std::set<std::string> key_pool;
3438   ASSERT_TRUE(CreateSetOfRandomEntries(&key_pool));
3439
3440   // Create a corrupt entry. The write/read sequence ensures that the entry will
3441   // have been created before corrupting the platform files, in the case of
3442   // optimistic operations.
3443   const std::string key = "the key";
3444   disk_cache::Entry* corrupted_entry;
3445
3446   ASSERT_EQ(net::OK, CreateEntry(key, &corrupted_entry));
3447   ASSERT_TRUE(corrupted_entry);
3448   const int kSize = 50;
3449   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
3450   CacheTestFillBuffer(buffer->data(), kSize, false);
3451   ASSERT_EQ(kSize,
3452             WriteData(corrupted_entry, 0, 0, buffer.get(), kSize, false));
3453   ASSERT_EQ(kSize, ReadData(corrupted_entry, 0, 0, buffer.get(), kSize));
3454   corrupted_entry->Close();
3455
3456   EXPECT_TRUE(disk_cache::simple_util::CreateCorruptFileForTests(
3457       key, cache_path_));
3458   EXPECT_EQ(key_pool.size() + 1,
3459             implicit_cast<size_t>(cache_->GetEntryCount()));
3460
3461   // Check that enumeration returns all entries but the corrupt one.
3462   std::set<std::string> keys_to_match(key_pool);
3463   scoped_ptr<TestIterator> iter = CreateIterator();
3464   size_t count = 0;
3465   ASSERT_TRUE(EnumerateAndMatchKeys(-1, iter.get(), &keys_to_match, &count));
3466   iter.reset();
3467
3468   EXPECT_EQ(key_pool.size(), count);
3469   EXPECT_TRUE(keys_to_match.empty());
3470 }
3471
3472 // Tests that enumerations don't leak memory when the backend is destructed
3473 // mid-enumeration.
3474 TEST_F(DiskCacheBackendTest, SimpleCacheEnumerationDestruction) {
3475   SetSimpleCacheMode();
3476   InitCache();
3477   std::set<std::string> key_pool;
3478   ASSERT_TRUE(CreateSetOfRandomEntries(&key_pool));
3479
3480   scoped_ptr<TestIterator> iter = CreateIterator();
3481   disk_cache::Entry* entry = NULL;
3482   ASSERT_EQ(net::OK, iter->OpenNextEntry(&entry));
3483   EXPECT_TRUE(entry);
3484   disk_cache::ScopedEntryPtr entry_closer(entry);
3485
3486   cache_.reset();
3487   // This test passes if we don't leak memory.
3488 }
3489
3490 #endif  // defined(OS_POSIX)