| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/disk_cache/simple/simple_index.h" | 5 #include "net/disk_cache/simple/simple_index.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <functional> | 8 #include <functional> |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <utility> | 10 #include <utility> |
| 11 | 11 |
| 12 #include "base/files/scoped_temp_dir.h" | 12 #include "base/files/scoped_temp_dir.h" |
| 13 #include "base/hash.h" | 13 #include "base/hash.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/metrics/field_trial.h" |
| 16 #include "base/metrics/field_trial_param_associator.h" |
| 15 #include "base/pickle.h" | 17 #include "base/pickle.h" |
| 16 #include "base/sha1.h" | 18 #include "base/sha1.h" |
| 17 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
| 18 #include "base/task_runner.h" | 20 #include "base/task_runner.h" |
| 21 #include "base/test/mock_entropy_provider.h" |
| 22 #include "base/test/scoped_feature_list.h" |
| 19 #include "base/threading/platform_thread.h" | 23 #include "base/threading/platform_thread.h" |
| 20 #include "base/time/time.h" | 24 #include "base/time/time.h" |
| 21 #include "net/base/cache_type.h" | 25 #include "net/base/cache_type.h" |
| 26 #include "net/disk_cache/simple/simple_experiment.h" |
| 22 #include "net/disk_cache/simple/simple_index_delegate.h" | 27 #include "net/disk_cache/simple/simple_index_delegate.h" |
| 23 #include "net/disk_cache/simple/simple_index_file.h" | 28 #include "net/disk_cache/simple/simple_index_file.h" |
| 24 #include "net/disk_cache/simple/simple_test_util.h" | 29 #include "net/disk_cache/simple/simple_test_util.h" |
| 25 #include "net/disk_cache/simple/simple_util.h" | 30 #include "net/disk_cache/simple/simple_util.h" |
| 26 #include "testing/gtest/include/gtest/gtest.h" | 31 #include "testing/gtest/include/gtest/gtest.h" |
| 27 | 32 |
| 28 namespace disk_cache { | 33 namespace disk_cache { |
| 29 namespace { | 34 namespace { |
| 30 | 35 |
| 31 const base::Time kTestLastUsedTime = | 36 const base::Time kTestLastUsedTime = |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 | 111 |
| 107 void SetUp() override { | 112 void SetUp() override { |
| 108 std::unique_ptr<MockSimpleIndexFile> index_file(new MockSimpleIndexFile()); | 113 std::unique_ptr<MockSimpleIndexFile> index_file(new MockSimpleIndexFile()); |
| 109 index_file_ = index_file->AsWeakPtr(); | 114 index_file_ = index_file->AsWeakPtr(); |
| 110 index_.reset( | 115 index_.reset( |
| 111 new SimpleIndex(NULL, this, net::DISK_CACHE, std::move(index_file))); | 116 new SimpleIndex(NULL, this, net::DISK_CACHE, std::move(index_file))); |
| 112 | 117 |
| 113 index_->Initialize(base::Time()); | 118 index_->Initialize(base::Time()); |
| 114 } | 119 } |
| 115 | 120 |
| 121 void EnableEvictBySize() { |
| 122 // Enable size-based eviction. |
| 123 const std::string kTrialName = "EvictWithSizeTrial"; |
| 124 const std::string kGroupName = "GroupFoo"; // Value not used |
| 125 |
| 126 field_trial_list_ = base::MakeUnique<base::FieldTrialList>( |
| 127 base::MakeUnique<base::MockEntropyProvider>()); |
| 128 |
| 129 scoped_refptr<base::FieldTrial> trial = |
| 130 base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName); |
| 131 |
| 132 std::map<std::string, std::string> params; |
| 133 params[kSizeEvictionParam] = "1"; |
| 134 base::FieldTrialParamAssociator::GetInstance()->AssociateFieldTrialParams( |
| 135 kTrialName, kGroupName, params); |
| 136 |
| 137 std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); |
| 138 feature_list->RegisterFieldTrialOverride( |
| 139 kSimpleCacheEvictionWithSizeExperiment.name, |
| 140 base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial.get()); |
| 141 scoped_feature_list_.InitWithFeatureList(std::move(feature_list)); |
| 142 } |
| 143 |
| 116 void WaitForTimeChange() { | 144 void WaitForTimeChange() { |
| 117 const base::Time initial_time = base::Time::Now(); | 145 const base::Time initial_time = base::Time::Now(); |
| 118 do { | 146 do { |
| 119 base::PlatformThread::YieldCurrentThread(); | 147 base::PlatformThread::YieldCurrentThread(); |
| 120 } while (base::Time::Now() - | 148 } while (base::Time::Now() - |
| 121 initial_time < base::TimeDelta::FromSeconds(1)); | 149 initial_time < base::TimeDelta::FromSeconds(1)); |
| 122 } | 150 } |
| 123 | 151 |
| 124 // From SimpleIndexDelegate: | 152 // From SimpleIndexDelegate: |
| 125 void DoomEntries(std::vector<uint64_t>* entry_hashes, | 153 void DoomEntries(std::vector<uint64_t>* entry_hashes, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 | 186 |
| 159 const std::vector<uint64_t>& last_doom_entry_hashes() const { | 187 const std::vector<uint64_t>& last_doom_entry_hashes() const { |
| 160 return last_doom_entry_hashes_; | 188 return last_doom_entry_hashes_; |
| 161 } | 189 } |
| 162 int doom_entries_calls() const { return doom_entries_calls_; } | 190 int doom_entries_calls() const { return doom_entries_calls_; } |
| 163 | 191 |
| 164 const simple_util::ImmutableArray<uint64_t, 16> hashes_; | 192 const simple_util::ImmutableArray<uint64_t, 16> hashes_; |
| 165 std::unique_ptr<SimpleIndex> index_; | 193 std::unique_ptr<SimpleIndex> index_; |
| 166 base::WeakPtr<MockSimpleIndexFile> index_file_; | 194 base::WeakPtr<MockSimpleIndexFile> index_file_; |
| 167 | 195 |
| 196 std::unique_ptr<base::FieldTrialList> field_trial_list_; |
| 197 base::test::ScopedFeatureList scoped_feature_list_; |
| 198 |
| 168 std::vector<uint64_t> last_doom_entry_hashes_; | 199 std::vector<uint64_t> last_doom_entry_hashes_; |
| 169 int doom_entries_calls_; | 200 int doom_entries_calls_; |
| 170 }; | 201 }; |
| 171 | 202 |
| 172 TEST_F(EntryMetadataTest, Basics) { | 203 TEST_F(EntryMetadataTest, Basics) { |
| 173 EntryMetadata entry_metadata; | 204 EntryMetadata entry_metadata; |
| 174 EXPECT_EQ(base::Time(), entry_metadata.GetLastUsedTime()); | 205 EXPECT_EQ(base::Time(), entry_metadata.GetLastUsedTime()); |
| 175 EXPECT_EQ(0U, entry_metadata.GetEntrySize()); | 206 EXPECT_EQ(0U, entry_metadata.GetEntrySize()); |
| 176 | 207 |
| 177 entry_metadata = NewEntryMetadataWithValues(); | 208 entry_metadata = NewEntryMetadataWithValues(); |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 // that. | 592 // that. |
| 562 index()->UpdateEntrySize(hashes_.at<3>(), 475u); | 593 index()->UpdateEntrySize(hashes_.at<3>(), 475u); |
| 563 EXPECT_EQ(1, doom_entries_calls()); | 594 EXPECT_EQ(1, doom_entries_calls()); |
| 564 EXPECT_EQ(1, index()->GetEntryCount()); | 595 EXPECT_EQ(1, index()->GetEntryCount()); |
| 565 EXPECT_FALSE(index()->Has(hashes_.at<1>())); | 596 EXPECT_FALSE(index()->Has(hashes_.at<1>())); |
| 566 EXPECT_FALSE(index()->Has(hashes_.at<2>())); | 597 EXPECT_FALSE(index()->Has(hashes_.at<2>())); |
| 567 EXPECT_TRUE(index()->Has(hashes_.at<3>())); | 598 EXPECT_TRUE(index()->Has(hashes_.at<3>())); |
| 568 ASSERT_EQ(2u, last_doom_entry_hashes().size()); | 599 ASSERT_EQ(2u, last_doom_entry_hashes().size()); |
| 569 } | 600 } |
| 570 | 601 |
| 602 TEST_F(SimpleIndexTest, EvictBySize) { |
| 603 EnableEvictBySize(); |
| 604 // Enabled, now we can run the actual test. |
| 605 base::Time now(base::Time::Now()); |
| 606 index()->SetMaxSize(50000); |
| 607 InsertIntoIndexFileReturn(hashes_.at<1>(), now - base::TimeDelta::FromDays(2), |
| 608 475u); |
| 609 InsertIntoIndexFileReturn(hashes_.at<2>(), now - base::TimeDelta::FromDays(1), |
| 610 40000u); |
| 611 ReturnIndexFile(); |
| 612 WaitForTimeChange(); |
| 613 |
| 614 index()->Insert(hashes_.at<3>()); |
| 615 // Confirm index is as expected: No eviction, everything there. |
| 616 EXPECT_EQ(3, index()->GetEntryCount()); |
| 617 EXPECT_EQ(0, doom_entries_calls()); |
| 618 EXPECT_TRUE(index()->Has(hashes_.at<1>())); |
| 619 EXPECT_TRUE(index()->Has(hashes_.at<2>())); |
| 620 EXPECT_TRUE(index()->Has(hashes_.at<3>())); |
| 621 |
| 622 // Trigger an eviction, and make sure the right things are tossed. |
| 623 // TODO(rdsmith): This is dependent on the innards of the implementation |
| 624 // as to at exactly what point we trigger eviction. Not sure how to fix |
| 625 // that. |
| 626 index()->UpdateEntrySize(hashes_.at<3>(), 40000u); |
| 627 EXPECT_EQ(1, doom_entries_calls()); |
| 628 EXPECT_EQ(2, index()->GetEntryCount()); |
| 629 EXPECT_TRUE(index()->Has(hashes_.at<1>())); |
| 630 EXPECT_FALSE(index()->Has(hashes_.at<2>())); |
| 631 EXPECT_TRUE(index()->Has(hashes_.at<3>())); |
| 632 ASSERT_EQ(1u, last_doom_entry_hashes().size()); |
| 633 } |
| 634 |
| 635 // Same as test above, but using much older entries to make sure that small |
| 636 // things eventually get evictied. |
| 637 TEST_F(SimpleIndexTest, EvictBySize2) { |
| 638 EnableEvictBySize(); |
| 639 // Enabled, now we can run the actual test. |
| 640 base::Time now(base::Time::Now()); |
| 641 index()->SetMaxSize(50000); |
| 642 InsertIntoIndexFileReturn(hashes_.at<1>(), |
| 643 now - base::TimeDelta::FromDays(200), 475u); |
| 644 InsertIntoIndexFileReturn(hashes_.at<2>(), now - base::TimeDelta::FromDays(1), |
| 645 40000u); |
| 646 ReturnIndexFile(); |
| 647 WaitForTimeChange(); |
| 648 |
| 649 index()->Insert(hashes_.at<3>()); |
| 650 // Confirm index is as expected: No eviction, everything there. |
| 651 EXPECT_EQ(3, index()->GetEntryCount()); |
| 652 EXPECT_EQ(0, doom_entries_calls()); |
| 653 EXPECT_TRUE(index()->Has(hashes_.at<1>())); |
| 654 EXPECT_TRUE(index()->Has(hashes_.at<2>())); |
| 655 EXPECT_TRUE(index()->Has(hashes_.at<3>())); |
| 656 |
| 657 // Trigger an eviction, and make sure the right things are tossed. |
| 658 // TODO(rdsmith): This is dependent on the innards of the implementation |
| 659 // as to at exactly what point we trigger eviction. Not sure how to fix |
| 660 // that. |
| 661 index()->UpdateEntrySize(hashes_.at<3>(), 40000u); |
| 662 EXPECT_EQ(1, doom_entries_calls()); |
| 663 EXPECT_EQ(1, index()->GetEntryCount()); |
| 664 EXPECT_FALSE(index()->Has(hashes_.at<1>())); |
| 665 EXPECT_FALSE(index()->Has(hashes_.at<2>())); |
| 666 EXPECT_TRUE(index()->Has(hashes_.at<3>())); |
| 667 ASSERT_EQ(2u, last_doom_entry_hashes().size()); |
| 668 } |
| 669 |
| 571 // Confirm all the operations queue a disk write at some point in the | 670 // Confirm all the operations queue a disk write at some point in the |
| 572 // future. | 671 // future. |
| 573 TEST_F(SimpleIndexTest, DiskWriteQueued) { | 672 TEST_F(SimpleIndexTest, DiskWriteQueued) { |
| 574 index()->SetMaxSize(1000); | 673 index()->SetMaxSize(1000); |
| 575 ReturnIndexFile(); | 674 ReturnIndexFile(); |
| 576 | 675 |
| 577 EXPECT_FALSE(index()->write_to_disk_timer_.IsRunning()); | 676 EXPECT_FALSE(index()->write_to_disk_timer_.IsRunning()); |
| 578 | 677 |
| 579 const uint64_t kHash1 = hashes_.at<1>(); | 678 const uint64_t kHash1 = hashes_.at<1>(); |
| 580 index()->Insert(kHash1); | 679 index()->Insert(kHash1); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 WaitForTimeChange(); | 738 WaitForTimeChange(); |
| 640 EXPECT_EQ(expected_trigger, index()->write_to_disk_timer_.desired_run_time()); | 739 EXPECT_EQ(expected_trigger, index()->write_to_disk_timer_.desired_run_time()); |
| 641 index()->Insert(hashes_.at<2>()); | 740 index()->Insert(hashes_.at<2>()); |
| 642 index()->UpdateEntrySize(hashes_.at<2>(), 40u); | 741 index()->UpdateEntrySize(hashes_.at<2>(), 40u); |
| 643 EXPECT_TRUE(index()->write_to_disk_timer_.IsRunning()); | 742 EXPECT_TRUE(index()->write_to_disk_timer_.IsRunning()); |
| 644 EXPECT_LT(expected_trigger, index()->write_to_disk_timer_.desired_run_time()); | 743 EXPECT_LT(expected_trigger, index()->write_to_disk_timer_.desired_run_time()); |
| 645 index()->write_to_disk_timer_.Stop(); | 744 index()->write_to_disk_timer_.Stop(); |
| 646 } | 745 } |
| 647 | 746 |
| 648 } // namespace disk_cache | 747 } // namespace disk_cache |
| OLD | NEW |