Add GCMChannelStatusSyncer to schedule requests and enable/disable GCM
[chromium-blink-merge.git] / chrome / browser / prefs / leveldb_pref_store_unittest.cc
blobfe9baeba721b67932edb444718c3b69750f918d7
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
3 // found in the LICENSE file.
5 #include "chrome/browser/prefs/leveldb_pref_store.h"
7 #include "base/files/file_util.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/path_service.h"
12 #include "base/run_loop.h"
13 #include "base/values.h"
14 #include "chrome/common/chrome_paths.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 namespace {
20 class MockPrefStoreObserver : public PrefStore::Observer {
21 public:
22 MOCK_METHOD1(OnPrefValueChanged, void(const std::string&));
23 MOCK_METHOD1(OnInitializationCompleted, void(bool));
26 class MockReadErrorDelegate : public PersistentPrefStore::ReadErrorDelegate {
27 public:
28 MOCK_METHOD1(OnError, void(PersistentPrefStore::PrefReadError));
31 } // namespace
33 class LevelDBPrefStoreTest : public testing::Test {
34 protected:
35 virtual void SetUp() OVERRIDE {
36 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
38 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_dir_));
39 data_dir_ = data_dir_.AppendASCII("prefs");
40 ASSERT_TRUE(PathExists(data_dir_));
43 virtual void TearDown() OVERRIDE {
44 Close();
47 void Open() {
48 pref_store_ = new LevelDBPrefStore(
49 temp_dir_.path(), message_loop_.message_loop_proxy().get());
50 EXPECT_EQ(LevelDBPrefStore::PREF_READ_ERROR_NONE, pref_store_->ReadPrefs());
53 void Close() {
54 pref_store_ = NULL;
55 base::RunLoop().RunUntilIdle();
58 void CloseAndReopen() {
59 Close();
60 Open();
63 // The path to temporary directory used to contain the test operations.
64 base::ScopedTempDir temp_dir_;
65 // The path to the directory where the test data is stored in the source tree.
66 base::FilePath data_dir_;
67 // A message loop that we can use as the file thread message loop.
68 base::MessageLoop message_loop_;
70 scoped_refptr<LevelDBPrefStore> pref_store_;
73 TEST_F(LevelDBPrefStoreTest, PutAndGet) {
74 Open();
75 const std::string key = "some.key";
76 pref_store_->SetValue(key, new base::FundamentalValue(5));
77 base::FundamentalValue orig_value(5);
78 const base::Value* actual_value;
79 EXPECT_TRUE(pref_store_->GetValue(key, &actual_value));
80 EXPECT_TRUE(orig_value.Equals(actual_value));
83 TEST_F(LevelDBPrefStoreTest, PutAndGetPersistent) {
84 Open();
85 const std::string key = "some.key";
86 pref_store_->SetValue(key, new base::FundamentalValue(5));
88 CloseAndReopen();
89 const base::Value* actual_value = NULL;
90 base::FundamentalValue orig_value(5);
91 EXPECT_TRUE(pref_store_->GetValue(key, &actual_value));
92 EXPECT_TRUE(orig_value.Equals(actual_value));
95 TEST_F(LevelDBPrefStoreTest, BasicObserver) {
96 scoped_refptr<LevelDBPrefStore> pref_store = new LevelDBPrefStore(
97 temp_dir_.path(), message_loop_.message_loop_proxy().get());
98 MockPrefStoreObserver mock_observer;
99 pref_store->AddObserver(&mock_observer);
100 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
101 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs());
102 testing::Mock::VerifyAndClearExpectations(&mock_observer);
104 const std::string key = "some.key";
105 EXPECT_CALL(mock_observer, OnPrefValueChanged(key)).Times(1);
106 pref_store->SetValue(key, new base::FundamentalValue(5));
108 pref_store->RemoveObserver(&mock_observer);
111 TEST_F(LevelDBPrefStoreTest, SetValueSilently) {
112 Open();
114 MockPrefStoreObserver mock_observer;
115 pref_store_->AddObserver(&mock_observer);
116 const std::string key = "some.key";
117 EXPECT_CALL(mock_observer, OnPrefValueChanged(key)).Times(0);
118 pref_store_->SetValueSilently(key, new base::FundamentalValue(30));
119 pref_store_->RemoveObserver(&mock_observer);
121 CloseAndReopen();
122 base::FundamentalValue value(30);
123 const base::Value* actual_value = NULL;
124 EXPECT_TRUE(pref_store_->GetValue(key, &actual_value));
125 EXPECT_TRUE(base::Value::Equals(&value, actual_value));
128 TEST_F(LevelDBPrefStoreTest, GetMutableValue) {
129 Open();
131 const std::string key = "some.key";
132 base::DictionaryValue* orig_value = new base::DictionaryValue;
133 orig_value->SetInteger("key2", 25);
134 pref_store_->SetValue(key, orig_value);
136 base::Value* actual_value;
137 EXPECT_TRUE(pref_store_->GetMutableValue(key, &actual_value));
138 EXPECT_TRUE(orig_value->Equals(actual_value));
139 base::DictionaryValue* dict_value;
140 ASSERT_TRUE(actual_value->GetAsDictionary(&dict_value));
141 dict_value->SetInteger("key2", 30);
142 pref_store_->ReportValueChanged(key);
144 // Ensure the new value is stored in memory.
145 const base::Value* retrieved_value;
146 EXPECT_TRUE(pref_store_->GetValue(key, &retrieved_value));
147 scoped_ptr<base::DictionaryValue> golden_value(new base::DictionaryValue);
148 golden_value->SetInteger("key2", 30);
149 EXPECT_TRUE(base::Value::Equals(golden_value.get(), retrieved_value));
151 // Ensure the new value is persisted to disk.
152 CloseAndReopen();
153 EXPECT_TRUE(pref_store_->GetValue(key, &retrieved_value));
154 EXPECT_TRUE(base::Value::Equals(golden_value.get(), retrieved_value));
157 TEST_F(LevelDBPrefStoreTest, RemoveFromMemory) {
158 Open();
159 const std::string key = "some.key";
160 pref_store_->SetValue(key, new base::FundamentalValue(5));
162 MockPrefStoreObserver mock_observer;
163 pref_store_->AddObserver(&mock_observer);
164 EXPECT_CALL(mock_observer, OnPrefValueChanged(key)).Times(1);
165 pref_store_->RemoveValue(key);
166 pref_store_->RemoveObserver(&mock_observer);
168 const base::Value* retrieved_value;
169 EXPECT_FALSE(pref_store_->GetValue(key, &retrieved_value));
172 TEST_F(LevelDBPrefStoreTest, RemoveFromDisk) {
173 Open();
174 const std::string key = "some.key";
175 pref_store_->SetValue(key, new base::FundamentalValue(5));
177 CloseAndReopen();
179 pref_store_->RemoveValue(key);
181 CloseAndReopen();
183 const base::Value* retrieved_value;
184 EXPECT_FALSE(pref_store_->GetValue(key, &retrieved_value));
187 TEST_F(LevelDBPrefStoreTest, OpenAsync) {
188 // First set a key/value with a synchronous connection.
189 Open();
190 const std::string key = "some.key";
191 pref_store_->SetValue(key, new base::FundamentalValue(5));
192 Close();
194 scoped_refptr<LevelDBPrefStore> pref_store(new LevelDBPrefStore(
195 temp_dir_.path(), message_loop_.message_loop_proxy().get()));
196 MockReadErrorDelegate* delegate = new MockReadErrorDelegate;
197 pref_store->ReadPrefsAsync(delegate);
199 MockPrefStoreObserver mock_observer;
200 pref_store->AddObserver(&mock_observer);
201 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
202 base::RunLoop().RunUntilIdle();
203 pref_store->RemoveObserver(&mock_observer);
205 const base::Value* result;
206 EXPECT_TRUE(pref_store->GetValue("some.key", &result));
207 int int_value;
208 EXPECT_TRUE(result->GetAsInteger(&int_value));
209 EXPECT_EQ(5, int_value);
211 pref_store = NULL;
214 TEST_F(LevelDBPrefStoreTest, OpenAsyncError) {
215 // Open a connection that will lock the database.
216 Open();
218 // Try to open an async connection to the same database.
219 scoped_refptr<LevelDBPrefStore> pref_store(new LevelDBPrefStore(
220 temp_dir_.path(), message_loop_.message_loop_proxy().get()));
221 MockReadErrorDelegate* delegate = new MockReadErrorDelegate;
222 pref_store->ReadPrefsAsync(delegate);
224 MockPrefStoreObserver mock_observer;
225 pref_store->AddObserver(&mock_observer);
226 EXPECT_CALL(*delegate,
227 OnError(PersistentPrefStore::PREF_READ_ERROR_LEVELDB_IO))
228 .Times(1);
229 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
230 base::RunLoop().RunUntilIdle();
231 pref_store->RemoveObserver(&mock_observer);
233 EXPECT_TRUE(pref_store->ReadOnly());
234 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_LEVELDB_IO,
235 pref_store->GetReadError());
237 // Sync connection to the database will be closed by the destructor.
240 TEST_F(LevelDBPrefStoreTest, RepairCorrupt) {
241 // Open a database where CURRENT has no newline. Ensure that repair is called
242 // and there is no error reading the database.
243 base::FilePath corrupted_dir = data_dir_.AppendASCII("corrupted_leveldb");
244 base::FilePath dest = temp_dir_.path().AppendASCII("corrupted_leveldb");
245 const bool kRecursive = true;
246 ASSERT_TRUE(CopyDirectory(corrupted_dir, dest, kRecursive));
247 pref_store_ =
248 new LevelDBPrefStore(dest, message_loop_.message_loop_proxy().get());
249 EXPECT_EQ(LevelDBPrefStore::PREF_READ_ERROR_LEVELDB_CORRUPTION,
250 pref_store_->ReadPrefs());
253 TEST_F(LevelDBPrefStoreTest, Values) {
254 Open();
255 pref_store_->SetValue("boolean", new base::FundamentalValue(false));
256 pref_store_->SetValue("integer", new base::FundamentalValue(10));
257 pref_store_->SetValue("double", new base::FundamentalValue(10.3));
258 pref_store_->SetValue("string", new base::StringValue("some string"));
260 base::DictionaryValue* dict_value = new base::DictionaryValue;
261 dict_value->Set("boolean", new base::FundamentalValue(true));
262 scoped_ptr<base::DictionaryValue> golden_dict_value(dict_value->DeepCopy());
263 pref_store_->SetValue("dictionary", dict_value);
265 base::ListValue* list_value = new base::ListValue;
266 list_value->Set(2, new base::StringValue("string in list"));
267 scoped_ptr<base::ListValue> golden_list_value(list_value->DeepCopy());
268 pref_store_->SetValue("list", list_value);
270 // Do something nontrivial as well.
271 base::DictionaryValue* compound_value = new base::DictionaryValue;
272 base::ListValue* outer_list = new base::ListValue;
273 base::ListValue* inner_list = new base::ListValue;
274 inner_list->Set(0, new base::FundamentalValue(5));
275 outer_list->Set(1, inner_list);
276 compound_value->Set("compound_lists", outer_list);
277 scoped_ptr<base::DictionaryValue> golden_compound_value(
278 compound_value->DeepCopy());
279 pref_store_->SetValue("compound_value", compound_value);
281 CloseAndReopen();
283 const base::Value* value;
284 EXPECT_TRUE(pref_store_->GetValue("boolean", &value));
285 EXPECT_TRUE(base::FundamentalValue(false).Equals(value));
287 EXPECT_TRUE(pref_store_->GetValue("integer", &value));
288 EXPECT_TRUE(base::FundamentalValue(10).Equals(value));
290 EXPECT_TRUE(pref_store_->GetValue("double", &value));
291 EXPECT_TRUE(base::FundamentalValue(10.3).Equals(value));
293 EXPECT_TRUE(pref_store_->GetValue("string", &value));
294 EXPECT_TRUE(base::StringValue("some string").Equals(value));
296 EXPECT_TRUE(pref_store_->GetValue("dictionary", &value));
297 EXPECT_TRUE(base::Value::Equals(golden_dict_value.get(), value));
299 EXPECT_TRUE(pref_store_->GetValue("list", &value));
300 EXPECT_TRUE(base::Value::Equals(golden_list_value.get(), value));
302 EXPECT_TRUE(pref_store_->GetValue("compound_value", &value));
303 EXPECT_TRUE(base::Value::Equals(golden_compound_value.get(), value));