OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/sdch/sdch_owner.h" | 5 #include "net/sdch/sdch_owner.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/location.h" | 9 #include "base/location.h" |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
11 #include "base/memory/memory_pressure_listener.h" | 11 #include "base/memory/memory_pressure_listener.h" |
12 #include "base/prefs/testing_pref_store.h" | |
13 #include "base/run_loop.h" | 12 #include "base/run_loop.h" |
14 #include "base/single_thread_task_runner.h" | 13 #include "base/single_thread_task_runner.h" |
15 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
16 #include "base/test/histogram_tester.h" | 15 #include "base/test/histogram_tester.h" |
17 #include "base/test/simple_test_clock.h" | 16 #include "base/test/simple_test_clock.h" |
18 #include "base/thread_task_runner_handle.h" | 17 #include "base/thread_task_runner_handle.h" |
19 #include "base/values.h" | 18 #include "base/values.h" |
20 #include "net/base/sdch_manager.h" | 19 #include "net/base/sdch_manager.h" |
21 #include "net/log/net_log.h" | 20 #include "net/log/net_log.h" |
22 #include "net/url_request/url_request.h" | 21 #include "net/url_request/url_request.h" |
23 #include "net/url_request/url_request_context.h" | 22 #include "net/url_request/url_request_context.h" |
24 #include "net/url_request/url_request_error_job.h" | 23 #include "net/url_request/url_request_error_job.h" |
25 #include "net/url_request/url_request_job.h" | 24 #include "net/url_request/url_request_job.h" |
26 #include "net/url_request/url_request_job_factory.h" | 25 #include "net/url_request/url_request_job_factory.h" |
27 #include "net/url_request/url_request_test_util.h" | 26 #include "net/url_request/url_request_test_util.h" |
28 #include "testing/gtest/include/gtest/gtest.h" | 27 #include "testing/gtest/include/gtest/gtest.h" |
29 | 28 |
| 29 namespace net { |
| 30 |
30 namespace { | 31 namespace { |
31 | 32 |
32 bool GetDictionaryForURL(TestingPrefStore* store, | 33 bool GetDictionaryForURL(SdchOwner::PrefStorage* store, |
33 const GURL& url, | 34 const GURL& url, |
34 std::string* hash, | 35 std::string* hash, |
35 base::DictionaryValue** dict) { | 36 base::DictionaryValue** dict) { |
36 base::Value* sdch_val = nullptr; | |
37 base::DictionaryValue* sdch_dict = nullptr; | 37 base::DictionaryValue* sdch_dict = nullptr; |
38 if (!store->GetMutableValue("SDCH", &sdch_val)) | 38 if (!store->GetMutableValue(&sdch_dict)) |
39 return false; | |
40 if (!sdch_val->GetAsDictionary(&sdch_dict)) | |
41 return false; | 39 return false; |
42 | 40 |
43 base::DictionaryValue* dicts_dict = nullptr; | 41 base::DictionaryValue* dicts_dict = nullptr; |
44 if (!sdch_dict->GetDictionary("dictionaries", &dicts_dict)) | 42 if (!sdch_dict->GetDictionary("dictionaries", &dicts_dict)) |
45 return false; | 43 return false; |
46 | 44 |
47 base::DictionaryValue::Iterator it(*dicts_dict); | 45 base::DictionaryValue::Iterator it(*dicts_dict); |
48 while (!it.IsAtEnd()) { | 46 while (!it.IsAtEnd()) { |
49 const base::DictionaryValue* d = nullptr; | 47 const base::DictionaryValue* d = nullptr; |
50 if (!it.value().GetAsDictionary(&d)) | 48 if (!it.value().GetAsDictionary(&d)) |
51 continue; | 49 continue; |
52 std::string dict_url; | 50 std::string dict_url; |
53 if (d->GetString("url", &dict_url) && dict_url == url.spec()) { | 51 if (d->GetString("url", &dict_url) && dict_url == url.spec()) { |
54 if (hash) | 52 if (hash) |
55 *hash = it.key(); | 53 *hash = it.key(); |
56 if (dict) | 54 if (dict) |
57 dicts_dict->GetDictionary(it.key(), dict); | 55 dicts_dict->GetDictionary(it.key(), dict); |
58 return true; | 56 return true; |
59 } | 57 } |
60 it.Advance(); | 58 it.Advance(); |
61 } | 59 } |
62 | 60 |
63 return false; | 61 return false; |
64 } | 62 } |
65 | 63 |
| 64 // This class supports copying so we can emulate persistent storage. |
| 65 class TestPrefStorage : public SdchOwner::PrefStorage { |
| 66 public: |
| 67 explicit TestPrefStorage(bool initialized) |
| 68 : initialized_(initialized), initialization_observer_(nullptr) {} |
| 69 explicit TestPrefStorage(const TestPrefStorage& other) |
| 70 : initialized_(other.initialized_), |
| 71 initialization_observer_(nullptr) { // Don't copy observer. |
| 72 storage_.MergeDictionary(&other.storage_); |
| 73 } |
| 74 |
| 75 ~TestPrefStorage() override {} |
| 76 |
| 77 void SetInitialized() { |
| 78 DCHECK(!initialized_); |
| 79 initialized_ = true; |
| 80 if (initialization_observer_) |
| 81 initialization_observer_->OnPrefStorageInitializationComplete(true); |
| 82 } |
| 83 |
| 84 ReadError GetReadError() const override { return PERSISTENCE_FAILURE_NONE; } |
| 85 |
| 86 bool GetValue(const base::DictionaryValue** result) const override { |
| 87 *result = &storage_; |
| 88 return true; |
| 89 } |
| 90 bool GetMutableValue(base::DictionaryValue** result) override { |
| 91 *result = &storage_; |
| 92 return true; |
| 93 } |
| 94 void SetValue(scoped_ptr<base::DictionaryValue> value) override { |
| 95 storage_.Clear(); |
| 96 storage_.MergeDictionary(value.get()); |
| 97 } |
| 98 |
| 99 void ReportValueChanged() override {} |
| 100 |
| 101 // This storage class requires no special initialization. |
| 102 bool IsInitializationComplete() override { return initialized_; } |
| 103 void StartObservingInit(SdchOwner* observer) override { |
| 104 DCHECK(!initialization_observer_); |
| 105 initialization_observer_ = observer; |
| 106 } |
| 107 void StopObservingInit() override { initialization_observer_ = nullptr; } |
| 108 |
| 109 private: |
| 110 bool initialized_; |
| 111 SdchOwner* initialization_observer_; |
| 112 |
| 113 base::DictionaryValue storage_; |
| 114 }; |
| 115 |
66 } // namespace | 116 } // namespace |
67 | 117 |
68 namespace net { | |
69 | |
70 static const char generic_url[] = "http://www.example.com"; | 118 static const char generic_url[] = "http://www.example.com"; |
71 static const char generic_domain[] = "www.example.com"; | 119 static const char generic_domain[] = "www.example.com"; |
72 | 120 |
73 static std::string NewSdchDictionary(size_t dictionary_size) { | 121 static std::string NewSdchDictionary(size_t dictionary_size) { |
74 std::string dictionary; | 122 std::string dictionary; |
75 dictionary.append("Domain: "); | 123 dictionary.append("Domain: "); |
76 dictionary.append(generic_domain); | 124 dictionary.append(generic_domain); |
77 dictionary.append("\n"); | 125 dictionary.append("\n"); |
78 dictionary.append("\n"); | 126 dictionary.append("\n"); |
79 | 127 |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 // * Either of the above, having previously added dictionaries to create | 304 // * Either of the above, having previously added dictionaries to create |
257 // a particular initial state. | 305 // a particular initial state. |
258 class SdchOwnerTest : public testing::Test { | 306 class SdchOwnerTest : public testing::Test { |
259 public: | 307 public: |
260 static const size_t kMaxSizeForTesting = 1000 * 50; | 308 static const size_t kMaxSizeForTesting = 1000 * 50; |
261 static const size_t kMinFetchSpaceForTesting = 500; | 309 static const size_t kMinFetchSpaceForTesting = 500; |
262 | 310 |
263 SdchOwnerTest() | 311 SdchOwnerTest() |
264 : last_jobs_created_(error_jobs_created), | 312 : last_jobs_created_(error_jobs_created), |
265 dictionary_creation_index_(0), | 313 dictionary_creation_index_(0), |
266 pref_store_(new TestingPrefStore), | |
267 sdch_owner_(new SdchOwner(&sdch_manager_, &url_request_context_)) { | 314 sdch_owner_(new SdchOwner(&sdch_manager_, &url_request_context_)) { |
268 // Any jobs created on this context will immediately error, | 315 // Any jobs created on this context will immediately error, |
269 // which leaves the test in control of signals to SdchOwner. | 316 // which leaves the test in control of signals to SdchOwner. |
270 url_request_context_.set_job_factory(&job_factory_); | 317 url_request_context_.set_job_factory(&job_factory_); |
271 | 318 |
272 // Reduce sizes to reduce time for string operations. | 319 // Reduce sizes to reduce time for string operations. |
273 sdch_owner_->SetMaxTotalDictionarySize(kMaxSizeForTesting); | 320 sdch_owner_->SetMaxTotalDictionarySize(kMaxSizeForTesting); |
274 sdch_owner_->SetMinSpaceForDictionaryFetch(kMinFetchSpaceForTesting); | 321 sdch_owner_->SetMinSpaceForDictionaryFetch(kMinFetchSpaceForTesting); |
275 } | 322 } |
276 | 323 |
277 SdchManager& sdch_manager() { return sdch_manager_; } | 324 SdchManager& sdch_manager() { return sdch_manager_; } |
278 SdchOwner& sdch_owner() { return *(sdch_owner_.get()); } | 325 SdchOwner& sdch_owner() { return *(sdch_owner_.get()); } |
279 BoundNetLog& bound_net_log() { return net_log_; } | 326 BoundNetLog& bound_net_log() { return net_log_; } |
280 TestingPrefStore& pref_store() { return *(pref_store_.get()); } | |
281 | 327 |
282 int JobsRecentlyCreated() { | 328 int JobsRecentlyCreated() { |
283 int result = error_jobs_created - last_jobs_created_; | 329 int result = error_jobs_created - last_jobs_created_; |
284 last_jobs_created_ = error_jobs_created; | 330 last_jobs_created_ = error_jobs_created; |
285 return result; | 331 return result; |
286 } | 332 } |
287 | 333 |
288 bool DictionaryPresentInManager(const std::string& server_hash) { | 334 bool DictionaryPresentInManager(const std::string& server_hash) { |
289 // Presumes all tests use generic url. | 335 // Presumes all tests use generic url. |
290 SdchProblemCode tmp; | 336 SdchProblemCode tmp; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 int last_jobs_created_; | 398 int last_jobs_created_; |
353 BoundNetLog net_log_; | 399 BoundNetLog net_log_; |
354 int dictionary_creation_index_; | 400 int dictionary_creation_index_; |
355 | 401 |
356 // The dependencies of these objects (sdch_owner_ -> {sdch_manager_, | 402 // The dependencies of these objects (sdch_owner_ -> {sdch_manager_, |
357 // url_request_context_}, url_request_context_->job_factory_) require | 403 // url_request_context_}, url_request_context_->job_factory_) require |
358 // this order for correct destruction semantics. | 404 // this order for correct destruction semantics. |
359 MockURLRequestJobFactory job_factory_; | 405 MockURLRequestJobFactory job_factory_; |
360 URLRequestContext url_request_context_; | 406 URLRequestContext url_request_context_; |
361 SdchManager sdch_manager_; | 407 SdchManager sdch_manager_; |
362 scoped_refptr<TestingPrefStore> pref_store_; | |
363 scoped_ptr<SdchOwner> sdch_owner_; | 408 scoped_ptr<SdchOwner> sdch_owner_; |
364 | 409 |
365 DISALLOW_COPY_AND_ASSIGN(SdchOwnerTest); | 410 DISALLOW_COPY_AND_ASSIGN(SdchOwnerTest); |
366 }; | 411 }; |
367 | 412 |
368 // Does OnGetDictionary result in a fetch when there's enough space, and not | 413 // Does OnGetDictionary result in a fetch when there's enough space, and not |
369 // when there's not? | 414 // when there's not? |
370 TEST_F(SdchOwnerTest, OnGetDictionary_Fetching) { | 415 TEST_F(SdchOwnerTest, OnGetDictionary_Fetching) { |
371 GURL request_url(std::string(generic_url) + "/r1"); | 416 GURL request_url(std::string(generic_url) + "/r1"); |
372 | 417 |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 EXPECT_FALSE(DictionaryPresentInManager(server_hash_d1)); | 724 EXPECT_FALSE(DictionaryPresentInManager(server_hash_d1)); |
680 EXPECT_FALSE(DictionaryPresentInManager(server_hash_d2)); | 725 EXPECT_FALSE(DictionaryPresentInManager(server_hash_d2)); |
681 | 726 |
682 // Addition should now succeed. | 727 // Addition should now succeed. |
683 EXPECT_TRUE( | 728 EXPECT_TRUE( |
684 CreateAndAddDictionary(kMaxSizeForTesting, base::Time::Now(), nullptr)); | 729 CreateAndAddDictionary(kMaxSizeForTesting, base::Time::Now(), nullptr)); |
685 } | 730 } |
686 | 731 |
687 // Confirm that use of a pinned dictionary after its removal works properly. | 732 // Confirm that use of a pinned dictionary after its removal works properly. |
688 TEST_F(SdchOwnerTest, PinRemoveUse) { | 733 TEST_F(SdchOwnerTest, PinRemoveUse) { |
689 pref_store().SetInitializationCompleted(); | 734 // Pass ownership of the storage to the SdchOwner, but keep a pointer. |
690 sdch_owner().EnablePersistentStorage(&pref_store()); | 735 TestPrefStorage* pref_store = new TestPrefStorage(true); |
| 736 sdch_owner().EnablePersistentStorage( |
| 737 scoped_ptr<SdchOwner::PrefStorage>(pref_store)); |
691 | 738 |
692 std::string server_hash_d1; | 739 std::string server_hash_d1; |
693 EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 2, base::Time::Now(), | 740 EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 2, base::Time::Now(), |
694 &server_hash_d1)); | 741 &server_hash_d1)); |
695 | 742 |
696 scoped_ptr<SdchManager::DictionarySet> return_set( | 743 scoped_ptr<SdchManager::DictionarySet> return_set( |
697 sdch_manager().GetDictionarySet( | 744 sdch_manager().GetDictionarySet( |
698 GURL(std::string(generic_url) + "/x.html"))); | 745 GURL(std::string(generic_url) + "/x.html"))); |
699 ASSERT_TRUE(return_set.get()); | 746 ASSERT_TRUE(return_set.get()); |
700 EXPECT_TRUE(return_set->GetDictionaryText(server_hash_d1)); | 747 EXPECT_TRUE(return_set->GetDictionaryText(server_hash_d1)); |
701 | 748 |
702 const base::Value* result = nullptr; | 749 const base::Value* result = nullptr; |
703 const base::DictionaryValue* dict_result = nullptr; | 750 const base::DictionaryValue* dict_result = nullptr; |
704 ASSERT_TRUE(pref_store().GetValue("SDCH", &result)); | 751 ASSERT_TRUE(pref_store->GetValue(&dict_result)); |
705 ASSERT_TRUE(result->GetAsDictionary(&dict_result)); | |
706 EXPECT_TRUE(dict_result->Get("dictionaries", &result)); | 752 EXPECT_TRUE(dict_result->Get("dictionaries", &result)); |
707 EXPECT_TRUE(dict_result->Get("dictionaries." + server_hash_d1, &result)); | 753 EXPECT_TRUE(dict_result->Get("dictionaries." + server_hash_d1, &result)); |
708 | 754 |
709 sdch_manager().ClearData(); | 755 sdch_manager().ClearData(); |
710 | 756 |
711 ASSERT_TRUE(pref_store().GetValue("SDCH", &result)); | 757 ASSERT_TRUE(pref_store->GetValue(&dict_result)); |
712 ASSERT_TRUE(result->GetAsDictionary(&dict_result)); | |
713 EXPECT_TRUE(dict_result->Get("dictionaries", &result)); | 758 EXPECT_TRUE(dict_result->Get("dictionaries", &result)); |
714 EXPECT_FALSE(dict_result->Get("dictionaries." + server_hash_d1, &result)); | 759 EXPECT_FALSE(dict_result->Get("dictionaries." + server_hash_d1, &result)); |
715 | 760 |
716 scoped_ptr<SdchManager::DictionarySet> return_set2( | 761 scoped_ptr<SdchManager::DictionarySet> return_set2( |
717 sdch_manager().GetDictionarySet( | 762 sdch_manager().GetDictionarySet( |
718 GURL(std::string(generic_url) + "/x.html"))); | 763 GURL(std::string(generic_url) + "/x.html"))); |
719 EXPECT_FALSE(return_set2.get()); | 764 EXPECT_FALSE(return_set2.get()); |
720 | 765 |
721 sdch_manager().OnDictionaryUsed(server_hash_d1); | 766 sdch_manager().OnDictionaryUsed(server_hash_d1); |
722 | 767 |
723 ASSERT_TRUE(pref_store().GetValue("SDCH", &result)); | 768 ASSERT_TRUE(pref_store->GetValue(&dict_result)); |
724 ASSERT_TRUE(result->GetAsDictionary(&dict_result)); | |
725 EXPECT_TRUE(dict_result->Get("dictionaries", &result)); | 769 EXPECT_TRUE(dict_result->Get("dictionaries", &result)); |
726 EXPECT_FALSE(dict_result->Get("dictionaries." + server_hash_d1, &result)); | 770 EXPECT_FALSE(dict_result->Get("dictionaries." + server_hash_d1, &result)); |
727 } | 771 } |
728 | 772 |
729 TEST_F(SdchOwnerTest, UsageIntervalMetrics) { | 773 TEST_F(SdchOwnerTest, UsageIntervalMetrics) { |
730 const GURL url("http://www.example.com/dict0"); | 774 const GURL url("http://www.example.com/dict0"); |
731 | 775 |
732 std::string server_hash; | 776 std::string server_hash; |
733 base::Time last_used_time(base::Time::Now() - base::TimeDelta::FromHours(23)); | 777 base::Time last_used_time(base::Time::Now() - base::TimeDelta::FromHours(23)); |
734 base::Time created_time(base::Time::Now() - base::TimeDelta::FromHours(47)); | 778 base::Time created_time(base::Time::Now() - base::TimeDelta::FromHours(47)); |
735 | 779 |
736 EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 3, last_used_time, | 780 EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 3, last_used_time, |
737 created_time, &server_hash)); | 781 created_time, &server_hash)); |
738 | 782 |
739 base::HistogramTester tester; | 783 base::HistogramTester tester; |
740 | 784 |
741 sdch_owner().OnDictionaryUsed(server_hash); | 785 sdch_owner().OnDictionaryUsed(server_hash); |
742 tester.ExpectTotalCount("Sdch3.FirstUseInterval", 1); | 786 tester.ExpectTotalCount("Sdch3.FirstUseInterval", 1); |
743 tester.ExpectTotalCount("Sdch3.UsageInterval2", 0); | 787 tester.ExpectTotalCount("Sdch3.UsageInterval2", 0); |
744 | 788 |
745 sdch_owner().OnDictionaryUsed(server_hash); | 789 sdch_owner().OnDictionaryUsed(server_hash); |
746 tester.ExpectTotalCount("Sdch3.FirstUseInterval", 1); // count didn't change | 790 tester.ExpectTotalCount("Sdch3.FirstUseInterval", 1); // count didn't change |
747 tester.ExpectTotalCount("Sdch3.UsageInterval2", 1); | 791 tester.ExpectTotalCount("Sdch3.UsageInterval2", 1); |
748 } | 792 } |
749 | 793 |
750 class SdchOwnerPersistenceTest : public ::testing::Test { | 794 class SdchOwnerPersistenceTest : public ::testing::Test { |
751 public: | 795 public: |
752 SdchOwnerPersistenceTest() : pref_store_(new TestingPrefStore()) { | 796 SdchOwnerPersistenceTest() {} |
753 pref_store_->SetInitializationCompleted(); | |
754 } | |
755 virtual ~SdchOwnerPersistenceTest() {} | 797 virtual ~SdchOwnerPersistenceTest() {} |
756 | 798 |
757 void ClearOwner() { | 799 void ClearOwner() { |
758 owner_.reset(NULL); | 800 owner_.reset(NULL); |
759 } | 801 } |
760 | 802 |
761 void ResetOwner(bool delay) { | 803 // If the storage points is non-null it will be saved as the persistent |
| 804 // storage for the SdchOwner. |
| 805 void ResetOwner(scoped_ptr<SdchOwner::PrefStorage> storage) { |
762 // This has to be done first, since SdchOwner may be observing SdchManager, | 806 // This has to be done first, since SdchOwner may be observing SdchManager, |
763 // and SdchManager can't be destroyed with a live observer. | 807 // and SdchManager can't be destroyed with a live observer. |
764 owner_.reset(NULL); | 808 owner_.reset(NULL); |
765 manager_.reset(new SdchManager()); | 809 manager_.reset(new SdchManager()); |
766 fetcher_ = new MockSdchDictionaryFetcher(); | 810 fetcher_ = new MockSdchDictionaryFetcher(); |
767 owner_.reset(new SdchOwner(manager_.get(), | 811 owner_.reset(new SdchOwner(manager_.get(), |
768 &url_request_context_)); | 812 &url_request_context_)); |
769 owner_->SetMaxTotalDictionarySize(SdchOwnerTest::kMaxSizeForTesting); | 813 owner_->SetMaxTotalDictionarySize(SdchOwnerTest::kMaxSizeForTesting); |
770 owner_->SetMinSpaceForDictionaryFetch( | 814 owner_->SetMinSpaceForDictionaryFetch( |
771 SdchOwnerTest::kMinFetchSpaceForTesting); | 815 SdchOwnerTest::kMinFetchSpaceForTesting); |
772 owner_->SetFetcherForTesting(make_scoped_ptr(fetcher_)); | 816 owner_->SetFetcherForTesting(make_scoped_ptr(fetcher_)); |
773 if (!delay) | 817 if (storage) |
774 owner_->EnablePersistentStorage(pref_store_.get()); | 818 owner_->EnablePersistentStorage(std::move(storage)); |
775 } | 819 } |
776 | 820 |
777 void InsertDictionaryForURL(const GURL& url, const std::string& nonce) { | 821 void InsertDictionaryForURL(const GURL& url, const std::string& nonce) { |
778 owner_->OnDictionaryFetched(base::Time::Now(), base::Time::Now(), 1, | 822 owner_->OnDictionaryFetched(base::Time::Now(), base::Time::Now(), 1, |
779 CreateDictionary(url, nonce), url, net_log_, | 823 CreateDictionary(url, nonce), url, net_log_, |
780 false); | 824 false); |
781 } | 825 } |
782 | 826 |
783 bool CompleteLoadFromURL(const GURL& url, const std::string& nonce, | 827 bool CompleteLoadFromURL(const GURL& url, const std::string& nonce, |
784 bool was_from_cache) { | 828 bool was_from_cache) { |
785 return fetcher_->CompletePendingRequest(url, CreateDictionary(url, nonce), | 829 return fetcher_->CompletePendingRequest(url, CreateDictionary(url, nonce), |
786 net_log_, was_from_cache); | 830 net_log_, was_from_cache); |
787 } | 831 } |
788 | 832 |
789 std::string CreateDictionary(const GURL& url, const std::string& nonce) { | 833 std::string CreateDictionary(const GURL& url, const std::string& nonce) { |
790 std::string dict; | 834 std::string dict; |
791 dict.append("Domain: "); | 835 dict.append("Domain: "); |
792 dict.append(url.host()); | 836 dict.append(url.host()); |
793 dict.append("\n\n"); | 837 dict.append("\n\n"); |
794 dict.append(url.spec()); | 838 dict.append(url.spec()); |
795 dict.append(nonce); | 839 dict.append(nonce); |
796 return dict; | 840 return dict; |
797 } | 841 } |
798 | 842 |
799 protected: | 843 protected: |
800 BoundNetLog net_log_; | 844 BoundNetLog net_log_; |
801 scoped_refptr<TestingPrefStore> pref_store_; | |
802 scoped_ptr<SdchManager> manager_; | 845 scoped_ptr<SdchManager> manager_; |
803 MockSdchDictionaryFetcher* fetcher_; | 846 MockSdchDictionaryFetcher* fetcher_; |
804 scoped_ptr<SdchOwner> owner_; | 847 scoped_ptr<SdchOwner> owner_; |
805 TestURLRequestContext url_request_context_; | 848 TestURLRequestContext url_request_context_; |
806 }; | 849 }; |
807 | 850 |
808 // Test an empty persistence store. | 851 // Test an empty persistence store. |
809 TEST_F(SdchOwnerPersistenceTest, Empty) { | 852 TEST_F(SdchOwnerPersistenceTest, Empty) { |
810 ResetOwner(false); | 853 ResetOwner(make_scoped_ptr(new TestPrefStorage(true))); |
811 EXPECT_EQ(0, owner_->GetDictionaryCountForTesting()); | 854 EXPECT_EQ(0, owner_->GetDictionaryCountForTesting()); |
812 } | 855 } |
813 | 856 |
814 // Test a persistence store with an empty dictionary. | |
815 TEST_F(SdchOwnerPersistenceTest, Persistent_EmptyDict) { | |
816 pref_store_->SetValue("SDCH", make_scoped_ptr(new base::DictionaryValue()), | |
817 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); | |
818 ResetOwner(false); | |
819 EXPECT_EQ(0, owner_->GetDictionaryCountForTesting()); | |
820 } | |
821 | |
822 // Test a persistence store with a bad version number. | 857 // Test a persistence store with a bad version number. |
823 TEST_F(SdchOwnerPersistenceTest, Persistent_BadVersion) { | 858 TEST_F(SdchOwnerPersistenceTest, Persistent_BadVersion) { |
824 scoped_ptr<base::DictionaryValue> sdch_dict(new base::DictionaryValue()); | 859 scoped_ptr<base::DictionaryValue> sdch_dict(new base::DictionaryValue()); |
825 sdch_dict->SetInteger("version", 2); | 860 sdch_dict->SetInteger("version", 2); |
826 pref_store_->SetValue("SDCH", std::move(sdch_dict), | |
827 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); | |
828 | 861 |
829 ResetOwner(false); | 862 scoped_ptr<TestPrefStorage> storage(new TestPrefStorage(true)); |
| 863 storage->SetValue(std::move(sdch_dict)); |
| 864 |
| 865 TestPrefStorage* old_storage = storage.get(); // Save storage pointer. |
| 866 ResetOwner(std::move(storage)); // Takes ownership of storage pointer. |
| 867 |
| 868 storage.reset(new TestPrefStorage(*old_storage)); |
| 869 ResetOwner(std::move(storage)); |
830 EXPECT_EQ(0, owner_->GetDictionaryCountForTesting()); | 870 EXPECT_EQ(0, owner_->GetDictionaryCountForTesting()); |
831 } | 871 } |
832 | 872 |
833 // Test a persistence store with an empty dictionaries map. | 873 // Test a persistence store with an empty dictionaries map. |
834 TEST_F(SdchOwnerPersistenceTest, Persistent_EmptyDictList) { | 874 TEST_F(SdchOwnerPersistenceTest, Persistent_EmptyDictList) { |
835 scoped_ptr<base::DictionaryValue> sdch_dict(new base::DictionaryValue()); | 875 scoped_ptr<base::DictionaryValue> sdch_dict(new base::DictionaryValue()); |
836 scoped_ptr<base::DictionaryValue> dicts(new base::DictionaryValue()); | 876 scoped_ptr<base::DictionaryValue> dicts(new base::DictionaryValue()); |
837 sdch_dict->SetInteger("version", 1); | 877 sdch_dict->SetInteger("version", 1); |
838 sdch_dict->Set("dictionaries", std::move(dicts)); | 878 sdch_dict->Set("dictionaries", std::move(dicts)); |
839 pref_store_->SetValue("SDCH", std::move(sdch_dict), | |
840 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); | |
841 | 879 |
842 ResetOwner(false); | 880 scoped_ptr<TestPrefStorage> storage(new TestPrefStorage(true)); |
| 881 storage->SetValue(std::move(sdch_dict)); |
| 882 ResetOwner(std::move(storage)); |
843 EXPECT_EQ(0, owner_->GetDictionaryCountForTesting()); | 883 EXPECT_EQ(0, owner_->GetDictionaryCountForTesting()); |
844 } | 884 } |
845 | 885 |
846 TEST_F(SdchOwnerPersistenceTest, OneDict) { | 886 TEST_F(SdchOwnerPersistenceTest, OneDict) { |
847 const GURL url("http://www.example.com/dict"); | 887 const GURL url("http://www.example.com/dict"); |
848 ResetOwner(false); | 888 |
| 889 scoped_ptr<TestPrefStorage> storage(new TestPrefStorage(true)); |
| 890 TestPrefStorage* old_storage = storage.get(); // Save storage pointer. |
| 891 ResetOwner(std::move(storage)); // Takes ownership of storage pointer. |
849 EXPECT_EQ(0, owner_->GetDictionaryCountForTesting()); | 892 EXPECT_EQ(0, owner_->GetDictionaryCountForTesting()); |
850 InsertDictionaryForURL(url, "0"); | 893 InsertDictionaryForURL(url, "0"); |
851 EXPECT_EQ(1, owner_->GetDictionaryCountForTesting()); | 894 EXPECT_EQ(1, owner_->GetDictionaryCountForTesting()); |
852 | 895 |
853 ResetOwner(false); | 896 storage.reset(new TestPrefStorage(*old_storage)); |
| 897 ResetOwner(std::move(storage)); |
854 EXPECT_EQ(0, owner_->GetDictionaryCountForTesting()); | 898 EXPECT_EQ(0, owner_->GetDictionaryCountForTesting()); |
855 EXPECT_TRUE(CompleteLoadFromURL(url, "0", true)); | 899 EXPECT_TRUE(CompleteLoadFromURL(url, "0", true)); |
856 EXPECT_EQ(1, owner_->GetDictionaryCountForTesting()); | 900 EXPECT_EQ(1, owner_->GetDictionaryCountForTesting()); |
857 } | 901 } |
858 | 902 |
859 TEST_F(SdchOwnerPersistenceTest, TwoDicts) { | 903 TEST_F(SdchOwnerPersistenceTest, TwoDicts) { |
860 const GURL url0("http://www.example.com/dict0"); | 904 const GURL url0("http://www.example.com/dict0"); |
861 const GURL url1("http://www.example.com/dict1"); | 905 const GURL url1("http://www.example.com/dict1"); |
862 ResetOwner(false); | 906 |
| 907 scoped_ptr<TestPrefStorage> storage(new TestPrefStorage(true)); |
| 908 TestPrefStorage* old_storage = storage.get(); // Save storage pointer. |
| 909 ResetOwner(std::move(storage)); // Takes ownership of storage pointer. |
863 InsertDictionaryForURL(url0, "0"); | 910 InsertDictionaryForURL(url0, "0"); |
864 InsertDictionaryForURL(url1, "1"); | 911 InsertDictionaryForURL(url1, "1"); |
865 | 912 |
866 ResetOwner(false); | 913 storage.reset(new TestPrefStorage(*old_storage)); |
| 914 ResetOwner(std::move(storage)); |
867 EXPECT_TRUE(CompleteLoadFromURL(url0, "0", true)); | 915 EXPECT_TRUE(CompleteLoadFromURL(url0, "0", true)); |
868 EXPECT_TRUE(CompleteLoadFromURL(url1, "1", true)); | 916 EXPECT_TRUE(CompleteLoadFromURL(url1, "1", true)); |
869 EXPECT_EQ(2, owner_->GetDictionaryCountForTesting()); | 917 EXPECT_EQ(2, owner_->GetDictionaryCountForTesting()); |
870 EXPECT_TRUE(owner_->HasDictionaryFromURLForTesting(url0)); | 918 EXPECT_TRUE(owner_->HasDictionaryFromURLForTesting(url0)); |
871 EXPECT_TRUE(owner_->HasDictionaryFromURLForTesting(url1)); | 919 EXPECT_TRUE(owner_->HasDictionaryFromURLForTesting(url1)); |
872 } | 920 } |
873 | 921 |
874 TEST_F(SdchOwnerPersistenceTest, OneGoodDictOneBadDict) { | 922 TEST_F(SdchOwnerPersistenceTest, OneGoodDictOneBadDict) { |
875 const GURL url0("http://www.example.com/dict0"); | 923 const GURL url0("http://www.example.com/dict0"); |
876 const GURL url1("http://www.example.com/dict1"); | 924 const GURL url1("http://www.example.com/dict1"); |
877 ResetOwner(false); | 925 |
| 926 scoped_ptr<TestPrefStorage> storage(new TestPrefStorage(true)); |
| 927 TestPrefStorage* old_storage = storage.get(); // Save storage pointer. |
| 928 ResetOwner(std::move(storage)); // Takes ownership of storage. |
878 InsertDictionaryForURL(url0, "0"); | 929 InsertDictionaryForURL(url0, "0"); |
879 InsertDictionaryForURL(url1, "1"); | 930 InsertDictionaryForURL(url1, "1"); |
880 | 931 |
881 // Mutate the pref store a bit now. Clear the owner first, to ensure that the | 932 // Make a new storage based on the current contents of the old one. |
882 // SdchOwner doesn't observe these changes and object. The manual dictionary | 933 storage.reset(new TestPrefStorage(*old_storage)); |
883 // manipulation is a bit icky. | |
884 ClearOwner(); | |
885 base::DictionaryValue* dict = nullptr; | 934 base::DictionaryValue* dict = nullptr; |
886 ASSERT_TRUE(GetDictionaryForURL(pref_store_.get(), url1, nullptr, &dict)); | 935 ASSERT_TRUE(GetDictionaryForURL(storage.get(), url1, nullptr, &dict)); |
887 dict->Remove("use_count", nullptr); | 936 dict->Remove("use_count", nullptr); |
888 | 937 |
889 ResetOwner(false); | 938 ResetOwner(std::move(storage)); |
890 EXPECT_TRUE(CompleteLoadFromURL(url0, "0", true)); | 939 EXPECT_TRUE(CompleteLoadFromURL(url0, "0", true)); |
891 EXPECT_FALSE(CompleteLoadFromURL(url1, "1", true)); | 940 EXPECT_FALSE(CompleteLoadFromURL(url1, "1", true)); |
892 EXPECT_EQ(1, owner_->GetDictionaryCountForTesting()); | 941 EXPECT_EQ(1, owner_->GetDictionaryCountForTesting()); |
893 EXPECT_TRUE(owner_->HasDictionaryFromURLForTesting(url0)); | 942 EXPECT_TRUE(owner_->HasDictionaryFromURLForTesting(url0)); |
894 EXPECT_FALSE(owner_->HasDictionaryFromURLForTesting(url1)); | 943 EXPECT_FALSE(owner_->HasDictionaryFromURLForTesting(url1)); |
895 } | 944 } |
896 | 945 |
897 TEST_F(SdchOwnerPersistenceTest, UsingDictionaryUpdatesUseCount) { | 946 TEST_F(SdchOwnerPersistenceTest, UsingDictionaryUpdatesUseCount) { |
898 const GURL url("http://www.example.com/dict"); | 947 const GURL url("http://www.example.com/dict"); |
899 ResetOwner(false); | 948 |
| 949 scoped_ptr<TestPrefStorage> storage(new TestPrefStorage(true)); |
| 950 TestPrefStorage* old_storage = storage.get(); // Save storage pointer. |
| 951 ResetOwner(std::move(storage)); // Takes ownership of storage pointer. |
900 InsertDictionaryForURL(url, "0"); | 952 InsertDictionaryForURL(url, "0"); |
901 | 953 |
902 std::string hash; | 954 std::string hash; |
903 int old_count; | 955 int old_count; |
| 956 storage.reset(new TestPrefStorage(*old_storage)); |
904 { | 957 { |
905 ClearOwner(); | 958 ClearOwner(); |
906 base::DictionaryValue* dict = nullptr; | 959 base::DictionaryValue* dict = nullptr; |
907 ASSERT_TRUE(GetDictionaryForURL(pref_store_.get(), url, &hash, &dict)); | 960 ASSERT_TRUE(GetDictionaryForURL(storage.get(), url, &hash, &dict)); |
908 ASSERT_TRUE(dict->GetInteger("use_count", &old_count)); | 961 ASSERT_TRUE(dict->GetInteger("use_count", &old_count)); |
909 } | 962 } |
910 | 963 |
911 ResetOwner(false); | 964 old_storage = storage.get(); // Save storage pointer. |
| 965 ResetOwner(std::move(storage)); // Takes ownership of storage pointer. |
912 ASSERT_TRUE(CompleteLoadFromURL(url, "0", true)); | 966 ASSERT_TRUE(CompleteLoadFromURL(url, "0", true)); |
913 owner_->OnDictionaryUsed(hash); | 967 owner_->OnDictionaryUsed(hash); |
914 | 968 |
915 int new_count; | 969 int new_count; |
916 { | 970 { |
917 ClearOwner(); | |
918 base::DictionaryValue* dict = nullptr; | 971 base::DictionaryValue* dict = nullptr; |
919 ASSERT_TRUE(GetDictionaryForURL(pref_store_.get(), url, nullptr, &dict)); | 972 ASSERT_TRUE(GetDictionaryForURL(old_storage, url, nullptr, &dict)); |
920 ASSERT_TRUE(dict->GetInteger("use_count", &new_count)); | 973 ASSERT_TRUE(dict->GetInteger("use_count", &new_count)); |
921 } | 974 } |
922 | 975 |
923 EXPECT_EQ(old_count + 1, new_count); | 976 EXPECT_EQ(old_count + 1, new_count); |
924 } | 977 } |
925 | 978 |
926 TEST_F(SdchOwnerPersistenceTest, LoadingDictionaryMerges) { | 979 TEST_F(SdchOwnerPersistenceTest, LoadingDictionaryMerges) { |
927 const GURL url0("http://www.example.com/dict0"); | 980 const GURL url0("http://www.example.com/dict0"); |
928 const GURL url1("http://www.example.com/dict1"); | 981 const GURL url1("http://www.example.com/dict1"); |
929 | 982 |
930 ResetOwner(false); | 983 scoped_ptr<TestPrefStorage> storage(new TestPrefStorage(true)); |
| 984 TestPrefStorage* old_storage = storage.get(); // Save storage pointer. |
| 985 ResetOwner(std::move(storage)); // Takes ownership of storage pointer. |
931 InsertDictionaryForURL(url1, "1"); | 986 InsertDictionaryForURL(url1, "1"); |
932 | 987 |
933 ResetOwner(true); | 988 storage.reset(new TestPrefStorage(*old_storage)); |
| 989 ResetOwner(scoped_ptr<SdchOwner::PrefStorage>()); |
934 InsertDictionaryForURL(url0, "0"); | 990 InsertDictionaryForURL(url0, "0"); |
935 EXPECT_EQ(1, owner_->GetDictionaryCountForTesting()); | 991 EXPECT_EQ(1, owner_->GetDictionaryCountForTesting()); |
936 owner_->EnablePersistentStorage(pref_store_.get()); | 992 owner_->EnablePersistentStorage(std::move(storage)); |
937 ASSERT_TRUE(CompleteLoadFromURL(url1, "1", true)); | 993 ASSERT_TRUE(CompleteLoadFromURL(url1, "1", true)); |
938 EXPECT_EQ(2, owner_->GetDictionaryCountForTesting()); | 994 EXPECT_EQ(2, owner_->GetDictionaryCountForTesting()); |
939 } | 995 } |
940 | 996 |
941 TEST_F(SdchOwnerPersistenceTest, PersistenceMetrics) { | 997 TEST_F(SdchOwnerPersistenceTest, PersistenceMetrics) { |
942 const GURL url0("http://www.example.com/dict0"); | 998 const GURL url0("http://www.example.com/dict0"); |
943 const GURL url1("http://www.example.com/dict1"); | 999 const GURL url1("http://www.example.com/dict1"); |
944 ResetOwner(false); | 1000 |
| 1001 scoped_ptr<TestPrefStorage> storage(new TestPrefStorage(true)); |
| 1002 TestPrefStorage* old_storage = storage.get(); // Save storage pointer. |
| 1003 ResetOwner(std::move(storage)); // Takes ownership of storage pointer. |
945 | 1004 |
946 InsertDictionaryForURL(url0, "0"); | 1005 InsertDictionaryForURL(url0, "0"); |
947 InsertDictionaryForURL(url1, "1"); | 1006 InsertDictionaryForURL(url1, "1"); |
948 | 1007 |
949 ResetOwner(false); | 1008 storage.reset(new TestPrefStorage(*old_storage)); |
| 1009 ResetOwner(std::move(storage)); |
950 | 1010 |
951 base::HistogramTester tester; | 1011 base::HistogramTester tester; |
952 | 1012 |
953 EXPECT_TRUE(CompleteLoadFromURL(url0, "0", true)); | 1013 EXPECT_TRUE(CompleteLoadFromURL(url0, "0", true)); |
954 EXPECT_TRUE(CompleteLoadFromURL(url1, "1", false)); | 1014 EXPECT_TRUE(CompleteLoadFromURL(url1, "1", false)); |
955 | 1015 |
956 tester.ExpectTotalCount("Sdch3.NetworkBytesSpent", 1); | 1016 tester.ExpectTotalCount("Sdch3.NetworkBytesSpent", 1); |
957 tester.ExpectUniqueSample("Sdch3.NetworkBytesSpent", | 1017 tester.ExpectUniqueSample("Sdch3.NetworkBytesSpent", |
958 CreateDictionary(url1, "1").size(), 1); | 1018 CreateDictionary(url1, "1").size(), 1); |
959 } | 1019 } |
960 | 1020 |
961 } // namespace net | 1021 } // namespace net |
OLD | NEW |