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