OLD | NEW |
(Empty) | |
| 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/prefs/leveldb_pref_store.h" |
| 6 |
| 7 #include "base/file_util.h" |
| 8 #include "base/files/scoped_temp_dir.h" |
| 9 #include "base/memory/ref_counted.h" |
| 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/message_loop/message_loop.h" |
| 12 #include "base/path_service.h" |
| 13 #include "base/prefs/pref_filter.h" |
| 14 #include "base/run_loop.h" |
| 15 #include "base/strings/utf_string_conversions.h" |
| 16 #include "base/values.h" |
| 17 #include "testing/gmock/include/gmock/gmock.h" |
| 18 #include "testing/gtest/include/gtest/gtest.h" |
| 19 |
| 20 namespace base { |
| 21 namespace { |
| 22 |
| 23 class MockPrefStoreObserver : public PrefStore::Observer { |
| 24 public: |
| 25 MOCK_METHOD1(OnPrefValueChanged, void(const std::string&)); |
| 26 MOCK_METHOD1(OnInitializationCompleted, void(bool)); |
| 27 }; |
| 28 |
| 29 class MockReadErrorDelegate : public PersistentPrefStore::ReadErrorDelegate { |
| 30 public: |
| 31 MOCK_METHOD1(OnError, void(PersistentPrefStore::PrefReadError)); |
| 32 }; |
| 33 |
| 34 } // namespace |
| 35 |
| 36 class LevelDBPrefStoreTest : public testing::Test { |
| 37 protected: |
| 38 virtual void SetUp() OVERRIDE { |
| 39 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| 40 |
| 41 ASSERT_TRUE(PathService::Get(base::DIR_TEST_DATA, &data_dir_)); |
| 42 data_dir_ = data_dir_.AppendASCII("prefs"); |
| 43 ASSERT_TRUE(PathExists(data_dir_)); |
| 44 } |
| 45 |
| 46 void Open() { |
| 47 pref_store_ = new LevelDBPrefStore( |
| 48 temp_dir_.path(), message_loop_.message_loop_proxy().get()); |
| 49 EXPECT_EQ(LevelDBPrefStore::PREF_READ_ERROR_NONE, pref_store_->ReadPrefs()); |
| 50 } |
| 51 |
| 52 void CloseAndReopen() { |
| 53 pref_store_ = NULL; |
| 54 RunLoop().RunUntilIdle(); |
| 55 Open(); |
| 56 } |
| 57 |
| 58 // The path to temporary directory used to contain the test operations. |
| 59 base::ScopedTempDir temp_dir_; |
| 60 // The path to the directory where the test data is stored in the source tree. |
| 61 base::FilePath data_dir_; |
| 62 // A message loop that we can use as the file thread message loop. |
| 63 MessageLoop message_loop_; |
| 64 |
| 65 scoped_refptr<LevelDBPrefStore> pref_store_; |
| 66 }; |
| 67 |
| 68 TEST_F(LevelDBPrefStoreTest, PutAndGet) { |
| 69 Open(); |
| 70 const std::string key = "some.key"; |
| 71 pref_store_->SetValue(key, new FundamentalValue(5)); |
| 72 RunLoop().RunUntilIdle(); |
| 73 FundamentalValue orig_value(5); |
| 74 const base::Value* actual_value; |
| 75 EXPECT_TRUE(pref_store_->GetValue(key, &actual_value)); |
| 76 EXPECT_TRUE(orig_value.Equals(actual_value)); |
| 77 } |
| 78 |
| 79 TEST_F(LevelDBPrefStoreTest, PutAndGetPersistent) { |
| 80 Open(); |
| 81 const std::string key = "some.key"; |
| 82 base::Value* value = new FundamentalValue(5); |
| 83 pref_store_->SetValue(key, value); |
| 84 RunLoop().RunUntilIdle(); |
| 85 |
| 86 CloseAndReopen(); |
| 87 const base::Value* actual_value = NULL; |
| 88 FundamentalValue orig_value(5); |
| 89 EXPECT_TRUE(pref_store_->GetValue(key, &actual_value)); |
| 90 EXPECT_TRUE(orig_value.Equals(actual_value)); |
| 91 } |
| 92 |
| 93 TEST_F(LevelDBPrefStoreTest, BasicObserver) { |
| 94 scoped_refptr<LevelDBPrefStore> pref_store = new LevelDBPrefStore( |
| 95 temp_dir_.path(), message_loop_.message_loop_proxy().get()); |
| 96 MockPrefStoreObserver mock_observer; |
| 97 pref_store->AddObserver(&mock_observer); |
| 98 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1); |
| 99 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs()); |
| 100 ::testing::Mock::VerifyAndClearExpectations(&mock_observer); |
| 101 |
| 102 const std::string key = "some.key"; |
| 103 base::Value* value = new FundamentalValue(5); |
| 104 EXPECT_CALL(mock_observer, OnPrefValueChanged(key)).Times(1); |
| 105 pref_store->SetValue(key, value); |
| 106 |
| 107 pref_store->RemoveObserver(&mock_observer); |
| 108 } |
| 109 |
| 110 TEST_F(LevelDBPrefStoreTest, SetValueSilently) { |
| 111 Open(); |
| 112 |
| 113 MockPrefStoreObserver mock_observer; |
| 114 pref_store_->AddObserver(&mock_observer); |
| 115 const std::string key = "some.key"; |
| 116 base::Value* value = new FundamentalValue(30); |
| 117 EXPECT_CALL(mock_observer, OnPrefValueChanged(key)).Times(0); |
| 118 pref_store_->SetValueSilently(key, value); |
| 119 RunLoop().RunUntilIdle(); |
| 120 pref_store_->RemoveObserver(&mock_observer); |
| 121 |
| 122 CloseAndReopen(); |
| 123 value = new FundamentalValue(30); |
| 124 const base::Value* actual_value = NULL; |
| 125 EXPECT_TRUE(pref_store_->GetValue(key, &actual_value)); |
| 126 EXPECT_TRUE(base::Value::Equals(value, actual_value)); |
| 127 } |
| 128 |
| 129 TEST_F(LevelDBPrefStoreTest, GetMutableValue) { |
| 130 Open(); |
| 131 |
| 132 const std::string key = "some.key"; |
| 133 base::DictionaryValue* orig_value = new DictionaryValue; |
| 134 orig_value->SetInteger("key2", 25); |
| 135 pref_store_->SetValue(key, orig_value); |
| 136 base::Value* actual_value; |
| 137 |
| 138 EXPECT_TRUE(pref_store_->GetMutableValue(key, &actual_value)); |
| 139 EXPECT_TRUE(orig_value->Equals(actual_value)); |
| 140 base::DictionaryValue* dict_value = |
| 141 static_cast<base::DictionaryValue*>(actual_value); |
| 142 dict_value->SetInteger("key2", 30); |
| 143 pref_store_->ReportValueChanged(key); |
| 144 RunLoop().RunUntilIdle(); |
| 145 |
| 146 // Ensure the new value is stored in memory. |
| 147 const base::Value* retrieved_value; |
| 148 EXPECT_TRUE(pref_store_->GetValue(key, &retrieved_value)); |
| 149 const base::DictionaryValue* dictionary; |
| 150 EXPECT_TRUE(retrieved_value->GetAsDictionary(&dictionary)); |
| 151 const base::Value* inner_value; |
| 152 EXPECT_TRUE(dictionary->Get("key2", &inner_value)); |
| 153 int inner_integer; |
| 154 EXPECT_TRUE(inner_value->GetAsInteger(&inner_integer)); |
| 155 EXPECT_EQ(30, inner_integer); |
| 156 |
| 157 // Ensure the new value is persisted to disk. |
| 158 CloseAndReopen(); |
| 159 EXPECT_TRUE(pref_store_->GetValue(key, &retrieved_value)); |
| 160 EXPECT_TRUE(retrieved_value->GetAsDictionary(&dictionary)); |
| 161 EXPECT_TRUE(dictionary->Get("key2", &inner_value)); |
| 162 EXPECT_TRUE(inner_value->GetAsInteger(&inner_integer)); |
| 163 EXPECT_EQ(30, inner_integer); |
| 164 } |
| 165 |
| 166 TEST_F(LevelDBPrefStoreTest, Remove) { |
| 167 Open(); |
| 168 const std::string key = "some.key"; |
| 169 base::Value* orig_value = new FundamentalValue(5); |
| 170 pref_store_->SetValue(key, orig_value); |
| 171 MockPrefStoreObserver mock_observer; |
| 172 pref_store_->AddObserver(&mock_observer); |
| 173 EXPECT_CALL(mock_observer, OnPrefValueChanged(key)).Times(1); |
| 174 pref_store_->RemoveValue(key); |
| 175 pref_store_->RemoveObserver(&mock_observer); |
| 176 RunLoop().RunUntilIdle(); |
| 177 |
| 178 CloseAndReopen(); |
| 179 const base::Value* retrieved_value; |
| 180 EXPECT_FALSE(pref_store_->GetValue(key, &retrieved_value)); |
| 181 } |
| 182 |
| 183 TEST_F(LevelDBPrefStoreTest, OpenAsync) { |
| 184 pref_store_ = new LevelDBPrefStore( |
| 185 temp_dir_.path(), message_loop_.message_loop_proxy().get()); |
| 186 MockReadErrorDelegate* delegate = new MockReadErrorDelegate; |
| 187 pref_store_->ReadPrefsAsync(delegate); |
| 188 EXPECT_CALL(*delegate, |
| 189 OnError(PersistentPrefStore::PREF_READ_ERROR_NO_FILE)).Times(0); |
| 190 MockPrefStoreObserver mock_observer; |
| 191 pref_store_->AddObserver(&mock_observer); |
| 192 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1); |
| 193 RunLoop().RunUntilIdle(); |
| 194 pref_store_->RemoveObserver(&mock_observer); |
| 195 } |
| 196 |
| 197 } // namespace base |
OLD | NEW |