| Index: net/sdch/sdch_owner_unittest.cc
|
| diff --git a/net/sdch/sdch_owner_unittest.cc b/net/sdch/sdch_owner_unittest.cc
|
| index 9ce957928f2f6f2ea8e30a6eaa2f991a3870c9d4..91d1e6d51f365201889b447c6fc64a66fc72b34f 100644
|
| --- a/net/sdch/sdch_owner_unittest.cc
|
| +++ b/net/sdch/sdch_owner_unittest.cc
|
| @@ -9,7 +9,6 @@
|
| #include "base/location.h"
|
| #include "base/macros.h"
|
| #include "base/memory/memory_pressure_listener.h"
|
| -#include "base/prefs/testing_pref_store.h"
|
| #include "base/run_loop.h"
|
| #include "base/single_thread_task_runner.h"
|
| #include "base/strings/stringprintf.h"
|
| @@ -27,17 +26,16 @@
|
| #include "net/url_request/url_request_test_util.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| +namespace net {
|
| +
|
| namespace {
|
|
|
| -bool GetDictionaryForURL(TestingPrefStore* store,
|
| +bool GetDictionaryForURL(SdchOwner::PrefStorage* store,
|
| const GURL& url,
|
| std::string* hash,
|
| base::DictionaryValue** dict) {
|
| - base::Value* sdch_val = nullptr;
|
| base::DictionaryValue* sdch_dict = nullptr;
|
| - if (!store->GetMutableValue("SDCH", &sdch_val))
|
| - return false;
|
| - if (!sdch_val->GetAsDictionary(&sdch_dict))
|
| + if (!store->GetMutableValue(&sdch_dict))
|
| return false;
|
|
|
| base::DictionaryValue* dicts_dict = nullptr;
|
| @@ -63,9 +61,59 @@ bool GetDictionaryForURL(TestingPrefStore* store,
|
| return false;
|
| }
|
|
|
| -} // namespace
|
| +// This class supports copying so we can emulate persistent storage.
|
| +class TestPrefStorage : public SdchOwner::PrefStorage {
|
| + public:
|
| + explicit TestPrefStorage(bool initialized)
|
| + : initialized_(initialized), initialization_observer_(nullptr) {}
|
| + explicit TestPrefStorage(const TestPrefStorage& other)
|
| + : initialized_(other.initialized_),
|
| + initialization_observer_(nullptr) { // Don't copy observer.
|
| + storage_.MergeDictionary(&other.storage_);
|
| + }
|
|
|
| -namespace net {
|
| + ~TestPrefStorage() override {}
|
| +
|
| + void SetInitialized() {
|
| + DCHECK(!initialized_);
|
| + initialized_ = true;
|
| + if (initialization_observer_)
|
| + initialization_observer_->OnPrefStorageInitializationComplete(true);
|
| + }
|
| +
|
| + ReadError GetReadError() const override { return PERSISTENCE_FAILURE_NONE; }
|
| +
|
| + bool GetValue(const base::DictionaryValue** result) const override {
|
| + *result = &storage_;
|
| + return true;
|
| + }
|
| + bool GetMutableValue(base::DictionaryValue** result) override {
|
| + *result = &storage_;
|
| + return true;
|
| + }
|
| + void SetValue(scoped_ptr<base::DictionaryValue> value) override {
|
| + storage_.Clear();
|
| + storage_.MergeDictionary(value.get());
|
| + }
|
| +
|
| + void ReportValueChanged() override {}
|
| +
|
| + // This storage class requires no special initialization.
|
| + bool IsInitializationComplete() override { return initialized_; }
|
| + void StartObservingInit(SdchOwner* observer) override {
|
| + DCHECK(!initialization_observer_);
|
| + initialization_observer_ = observer;
|
| + }
|
| + void StopObservingInit() override { initialization_observer_ = nullptr; }
|
| +
|
| + private:
|
| + bool initialized_;
|
| + SdchOwner* initialization_observer_;
|
| +
|
| + base::DictionaryValue storage_;
|
| +};
|
| +
|
| +} // namespace
|
|
|
| static const char generic_url[] = "http://www.example.com";
|
| static const char generic_domain[] = "www.example.com";
|
| @@ -263,7 +311,6 @@ class SdchOwnerTest : public testing::Test {
|
| SdchOwnerTest()
|
| : last_jobs_created_(error_jobs_created),
|
| dictionary_creation_index_(0),
|
| - pref_store_(new TestingPrefStore),
|
| sdch_owner_(new SdchOwner(&sdch_manager_, &url_request_context_)) {
|
| // Any jobs created on this context will immediately error,
|
| // which leaves the test in control of signals to SdchOwner.
|
| @@ -277,7 +324,6 @@ class SdchOwnerTest : public testing::Test {
|
| SdchManager& sdch_manager() { return sdch_manager_; }
|
| SdchOwner& sdch_owner() { return *(sdch_owner_.get()); }
|
| BoundNetLog& bound_net_log() { return net_log_; }
|
| - TestingPrefStore& pref_store() { return *(pref_store_.get()); }
|
|
|
| int JobsRecentlyCreated() {
|
| int result = error_jobs_created - last_jobs_created_;
|
| @@ -359,7 +405,6 @@ class SdchOwnerTest : public testing::Test {
|
| MockURLRequestJobFactory job_factory_;
|
| URLRequestContext url_request_context_;
|
| SdchManager sdch_manager_;
|
| - scoped_refptr<TestingPrefStore> pref_store_;
|
| scoped_ptr<SdchOwner> sdch_owner_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(SdchOwnerTest);
|
| @@ -686,8 +731,10 @@ TEST_F(SdchOwnerTest, MemoryPressureReturnsSpace) {
|
|
|
| // Confirm that use of a pinned dictionary after its removal works properly.
|
| TEST_F(SdchOwnerTest, PinRemoveUse) {
|
| - pref_store().SetInitializationCompleted();
|
| - sdch_owner().EnablePersistentStorage(&pref_store());
|
| + // Pass ownership of the storage to the SdchOwner, but keep a pointer.
|
| + TestPrefStorage* pref_store = new TestPrefStorage(true);
|
| + sdch_owner().EnablePersistentStorage(
|
| + scoped_ptr<SdchOwner::PrefStorage>(pref_store));
|
|
|
| std::string server_hash_d1;
|
| EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 2, base::Time::Now(),
|
| @@ -701,15 +748,13 @@ TEST_F(SdchOwnerTest, PinRemoveUse) {
|
|
|
| const base::Value* result = nullptr;
|
| const base::DictionaryValue* dict_result = nullptr;
|
| - ASSERT_TRUE(pref_store().GetValue("SDCH", &result));
|
| - ASSERT_TRUE(result->GetAsDictionary(&dict_result));
|
| + ASSERT_TRUE(pref_store->GetValue(&dict_result));
|
| EXPECT_TRUE(dict_result->Get("dictionaries", &result));
|
| EXPECT_TRUE(dict_result->Get("dictionaries." + server_hash_d1, &result));
|
|
|
| sdch_manager().ClearData();
|
|
|
| - ASSERT_TRUE(pref_store().GetValue("SDCH", &result));
|
| - ASSERT_TRUE(result->GetAsDictionary(&dict_result));
|
| + ASSERT_TRUE(pref_store->GetValue(&dict_result));
|
| EXPECT_TRUE(dict_result->Get("dictionaries", &result));
|
| EXPECT_FALSE(dict_result->Get("dictionaries." + server_hash_d1, &result));
|
|
|
| @@ -720,8 +765,7 @@ TEST_F(SdchOwnerTest, PinRemoveUse) {
|
|
|
| sdch_manager().OnDictionaryUsed(server_hash_d1);
|
|
|
| - ASSERT_TRUE(pref_store().GetValue("SDCH", &result));
|
| - ASSERT_TRUE(result->GetAsDictionary(&dict_result));
|
| + ASSERT_TRUE(pref_store->GetValue(&dict_result));
|
| EXPECT_TRUE(dict_result->Get("dictionaries", &result));
|
| EXPECT_FALSE(dict_result->Get("dictionaries." + server_hash_d1, &result));
|
| }
|
| @@ -749,16 +793,16 @@ TEST_F(SdchOwnerTest, UsageIntervalMetrics) {
|
|
|
| class SdchOwnerPersistenceTest : public ::testing::Test {
|
| public:
|
| - SdchOwnerPersistenceTest() : pref_store_(new TestingPrefStore()) {
|
| - pref_store_->SetInitializationCompleted();
|
| - }
|
| + SdchOwnerPersistenceTest() {}
|
| virtual ~SdchOwnerPersistenceTest() {}
|
|
|
| void ClearOwner() {
|
| owner_.reset(NULL);
|
| }
|
|
|
| - void ResetOwner(bool delay) {
|
| + // If the storage points is non-null it will be saved as the persistent
|
| + // storage for the SdchOwner.
|
| + void ResetOwner(scoped_ptr<SdchOwner::PrefStorage> storage) {
|
| // This has to be done first, since SdchOwner may be observing SdchManager,
|
| // and SdchManager can't be destroyed with a live observer.
|
| owner_.reset(NULL);
|
| @@ -770,8 +814,8 @@ class SdchOwnerPersistenceTest : public ::testing::Test {
|
| owner_->SetMinSpaceForDictionaryFetch(
|
| SdchOwnerTest::kMinFetchSpaceForTesting);
|
| owner_->SetFetcherForTesting(make_scoped_ptr(fetcher_));
|
| - if (!delay)
|
| - owner_->EnablePersistentStorage(pref_store_.get());
|
| + if (storage)
|
| + owner_->EnablePersistentStorage(std::move(storage));
|
| }
|
|
|
| void InsertDictionaryForURL(const GURL& url, const std::string& nonce) {
|
| @@ -798,7 +842,6 @@ class SdchOwnerPersistenceTest : public ::testing::Test {
|
|
|
| protected:
|
| BoundNetLog net_log_;
|
| - scoped_refptr<TestingPrefStore> pref_store_;
|
| scoped_ptr<SdchManager> manager_;
|
| MockSdchDictionaryFetcher* fetcher_;
|
| scoped_ptr<SdchOwner> owner_;
|
| @@ -807,15 +850,7 @@ class SdchOwnerPersistenceTest : public ::testing::Test {
|
|
|
| // Test an empty persistence store.
|
| TEST_F(SdchOwnerPersistenceTest, Empty) {
|
| - ResetOwner(false);
|
| - EXPECT_EQ(0, owner_->GetDictionaryCountForTesting());
|
| -}
|
| -
|
| -// Test a persistence store with an empty dictionary.
|
| -TEST_F(SdchOwnerPersistenceTest, Persistent_EmptyDict) {
|
| - pref_store_->SetValue("SDCH", make_scoped_ptr(new base::DictionaryValue()),
|
| - WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
|
| - ResetOwner(false);
|
| + ResetOwner(make_scoped_ptr(new TestPrefStorage(true)));
|
| EXPECT_EQ(0, owner_->GetDictionaryCountForTesting());
|
| }
|
|
|
| @@ -823,10 +858,15 @@ TEST_F(SdchOwnerPersistenceTest, Persistent_EmptyDict) {
|
| TEST_F(SdchOwnerPersistenceTest, Persistent_BadVersion) {
|
| scoped_ptr<base::DictionaryValue> sdch_dict(new base::DictionaryValue());
|
| sdch_dict->SetInteger("version", 2);
|
| - pref_store_->SetValue("SDCH", std::move(sdch_dict),
|
| - WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
|
|
|
| - ResetOwner(false);
|
| + scoped_ptr<TestPrefStorage> storage(new TestPrefStorage(true));
|
| + storage->SetValue(std::move(sdch_dict));
|
| +
|
| + TestPrefStorage* old_storage = storage.get(); // Save storage pointer.
|
| + ResetOwner(std::move(storage)); // Takes ownership of storage pointer.
|
| +
|
| + storage.reset(new TestPrefStorage(*old_storage));
|
| + ResetOwner(std::move(storage));
|
| EXPECT_EQ(0, owner_->GetDictionaryCountForTesting());
|
| }
|
|
|
| @@ -836,21 +876,25 @@ TEST_F(SdchOwnerPersistenceTest, Persistent_EmptyDictList) {
|
| scoped_ptr<base::DictionaryValue> dicts(new base::DictionaryValue());
|
| sdch_dict->SetInteger("version", 1);
|
| sdch_dict->Set("dictionaries", std::move(dicts));
|
| - pref_store_->SetValue("SDCH", std::move(sdch_dict),
|
| - WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
|
|
|
| - ResetOwner(false);
|
| + scoped_ptr<TestPrefStorage> storage(new TestPrefStorage(true));
|
| + storage->SetValue(std::move(sdch_dict));
|
| + ResetOwner(std::move(storage));
|
| EXPECT_EQ(0, owner_->GetDictionaryCountForTesting());
|
| }
|
|
|
| TEST_F(SdchOwnerPersistenceTest, OneDict) {
|
| const GURL url("http://www.example.com/dict");
|
| - ResetOwner(false);
|
| +
|
| + scoped_ptr<TestPrefStorage> storage(new TestPrefStorage(true));
|
| + TestPrefStorage* old_storage = storage.get(); // Save storage pointer.
|
| + ResetOwner(std::move(storage)); // Takes ownership of storage pointer.
|
| EXPECT_EQ(0, owner_->GetDictionaryCountForTesting());
|
| InsertDictionaryForURL(url, "0");
|
| EXPECT_EQ(1, owner_->GetDictionaryCountForTesting());
|
|
|
| - ResetOwner(false);
|
| + storage.reset(new TestPrefStorage(*old_storage));
|
| + ResetOwner(std::move(storage));
|
| EXPECT_EQ(0, owner_->GetDictionaryCountForTesting());
|
| EXPECT_TRUE(CompleteLoadFromURL(url, "0", true));
|
| EXPECT_EQ(1, owner_->GetDictionaryCountForTesting());
|
| @@ -859,11 +903,15 @@ TEST_F(SdchOwnerPersistenceTest, OneDict) {
|
| TEST_F(SdchOwnerPersistenceTest, TwoDicts) {
|
| const GURL url0("http://www.example.com/dict0");
|
| const GURL url1("http://www.example.com/dict1");
|
| - ResetOwner(false);
|
| +
|
| + scoped_ptr<TestPrefStorage> storage(new TestPrefStorage(true));
|
| + TestPrefStorage* old_storage = storage.get(); // Save storage pointer.
|
| + ResetOwner(std::move(storage)); // Takes ownership of storage pointer.
|
| InsertDictionaryForURL(url0, "0");
|
| InsertDictionaryForURL(url1, "1");
|
|
|
| - ResetOwner(false);
|
| + storage.reset(new TestPrefStorage(*old_storage));
|
| + ResetOwner(std::move(storage));
|
| EXPECT_TRUE(CompleteLoadFromURL(url0, "0", true));
|
| EXPECT_TRUE(CompleteLoadFromURL(url1, "1", true));
|
| EXPECT_EQ(2, owner_->GetDictionaryCountForTesting());
|
| @@ -874,19 +922,20 @@ TEST_F(SdchOwnerPersistenceTest, TwoDicts) {
|
| TEST_F(SdchOwnerPersistenceTest, OneGoodDictOneBadDict) {
|
| const GURL url0("http://www.example.com/dict0");
|
| const GURL url1("http://www.example.com/dict1");
|
| - ResetOwner(false);
|
| +
|
| + scoped_ptr<TestPrefStorage> storage(new TestPrefStorage(true));
|
| + TestPrefStorage* old_storage = storage.get(); // Save storage pointer.
|
| + ResetOwner(std::move(storage)); // Takes ownership of storage.
|
| InsertDictionaryForURL(url0, "0");
|
| InsertDictionaryForURL(url1, "1");
|
|
|
| - // Mutate the pref store a bit now. Clear the owner first, to ensure that the
|
| - // SdchOwner doesn't observe these changes and object. The manual dictionary
|
| - // manipulation is a bit icky.
|
| - ClearOwner();
|
| + // Make a new storage based on the current contents of the old one.
|
| + storage.reset(new TestPrefStorage(*old_storage));
|
| base::DictionaryValue* dict = nullptr;
|
| - ASSERT_TRUE(GetDictionaryForURL(pref_store_.get(), url1, nullptr, &dict));
|
| + ASSERT_TRUE(GetDictionaryForURL(storage.get(), url1, nullptr, &dict));
|
| dict->Remove("use_count", nullptr);
|
|
|
| - ResetOwner(false);
|
| + ResetOwner(std::move(storage));
|
| EXPECT_TRUE(CompleteLoadFromURL(url0, "0", true));
|
| EXPECT_FALSE(CompleteLoadFromURL(url1, "1", true));
|
| EXPECT_EQ(1, owner_->GetDictionaryCountForTesting());
|
| @@ -896,27 +945,31 @@ TEST_F(SdchOwnerPersistenceTest, OneGoodDictOneBadDict) {
|
|
|
| TEST_F(SdchOwnerPersistenceTest, UsingDictionaryUpdatesUseCount) {
|
| const GURL url("http://www.example.com/dict");
|
| - ResetOwner(false);
|
| +
|
| + scoped_ptr<TestPrefStorage> storage(new TestPrefStorage(true));
|
| + TestPrefStorage* old_storage = storage.get(); // Save storage pointer.
|
| + ResetOwner(std::move(storage)); // Takes ownership of storage pointer.
|
| InsertDictionaryForURL(url, "0");
|
|
|
| std::string hash;
|
| int old_count;
|
| + storage.reset(new TestPrefStorage(*old_storage));
|
| {
|
| ClearOwner();
|
| base::DictionaryValue* dict = nullptr;
|
| - ASSERT_TRUE(GetDictionaryForURL(pref_store_.get(), url, &hash, &dict));
|
| + ASSERT_TRUE(GetDictionaryForURL(storage.get(), url, &hash, &dict));
|
| ASSERT_TRUE(dict->GetInteger("use_count", &old_count));
|
| }
|
|
|
| - ResetOwner(false);
|
| + old_storage = storage.get(); // Save storage pointer.
|
| + ResetOwner(std::move(storage)); // Takes ownership of storage pointer.
|
| ASSERT_TRUE(CompleteLoadFromURL(url, "0", true));
|
| owner_->OnDictionaryUsed(hash);
|
|
|
| int new_count;
|
| {
|
| - ClearOwner();
|
| base::DictionaryValue* dict = nullptr;
|
| - ASSERT_TRUE(GetDictionaryForURL(pref_store_.get(), url, nullptr, &dict));
|
| + ASSERT_TRUE(GetDictionaryForURL(old_storage, url, nullptr, &dict));
|
| ASSERT_TRUE(dict->GetInteger("use_count", &new_count));
|
| }
|
|
|
| @@ -927,13 +980,16 @@ TEST_F(SdchOwnerPersistenceTest, LoadingDictionaryMerges) {
|
| const GURL url0("http://www.example.com/dict0");
|
| const GURL url1("http://www.example.com/dict1");
|
|
|
| - ResetOwner(false);
|
| + scoped_ptr<TestPrefStorage> storage(new TestPrefStorage(true));
|
| + TestPrefStorage* old_storage = storage.get(); // Save storage pointer.
|
| + ResetOwner(std::move(storage)); // Takes ownership of storage pointer.
|
| InsertDictionaryForURL(url1, "1");
|
|
|
| - ResetOwner(true);
|
| + storage.reset(new TestPrefStorage(*old_storage));
|
| + ResetOwner(scoped_ptr<SdchOwner::PrefStorage>());
|
| InsertDictionaryForURL(url0, "0");
|
| EXPECT_EQ(1, owner_->GetDictionaryCountForTesting());
|
| - owner_->EnablePersistentStorage(pref_store_.get());
|
| + owner_->EnablePersistentStorage(std::move(storage));
|
| ASSERT_TRUE(CompleteLoadFromURL(url1, "1", true));
|
| EXPECT_EQ(2, owner_->GetDictionaryCountForTesting());
|
| }
|
| @@ -941,12 +997,16 @@ TEST_F(SdchOwnerPersistenceTest, LoadingDictionaryMerges) {
|
| TEST_F(SdchOwnerPersistenceTest, PersistenceMetrics) {
|
| const GURL url0("http://www.example.com/dict0");
|
| const GURL url1("http://www.example.com/dict1");
|
| - ResetOwner(false);
|
| +
|
| + scoped_ptr<TestPrefStorage> storage(new TestPrefStorage(true));
|
| + TestPrefStorage* old_storage = storage.get(); // Save storage pointer.
|
| + ResetOwner(std::move(storage)); // Takes ownership of storage pointer.
|
|
|
| InsertDictionaryForURL(url0, "0");
|
| InsertDictionaryForURL(url1, "1");
|
|
|
| - ResetOwner(false);
|
| + storage.reset(new TestPrefStorage(*old_storage));
|
| + ResetOwner(std::move(storage));
|
|
|
| base::HistogramTester tester;
|
|
|
|
|