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. 4 5 #include "chrome/browser/prefs/tracked/segregated_pref_store.h" 6 7 #include <set> 8 #include <string> 9 10 #include "base/bind.h" 11 #include "base/callback.h" 12 #include "base/memory/ref_counted.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/prefs/persistent_pref_store.h" 15 #include "base/prefs/pref_store_observer_mock.h" 16 #include "base/prefs/testing_pref_store.h" 17 #include "base/values.h" 18 #include "chrome/browser/prefs/tracked/segregated_pref_store.h" 19 #include "testing/gtest/include/gtest/gtest.h" 20 21 namespace { 22 23 const char kSelectedPref[] = "selected_pref"; 24 const char kUnselectedPref[] = "unselected_pref"; 25 26 const char kValue1[] = "value1"; 27 const char kValue2[] = "value2"; 28 29 class MockReadErrorDelegate : public PersistentPrefStore::ReadErrorDelegate { 30 public: 31 struct Data { 32 Data(bool invoked_in, PersistentPrefStore::PrefReadError read_error_in) 33 : invoked(invoked_in), read_error(read_error_in) {} 34 35 bool invoked; 36 PersistentPrefStore::PrefReadError read_error; 37 }; 38 39 explicit MockReadErrorDelegate(Data* data) : data_(data) { 40 DCHECK(data_); 41 EXPECT_FALSE(data_->invoked); 42 } 43 44 // PersistentPrefStore::ReadErrorDelegate implementation 45 virtual void OnError(PersistentPrefStore::PrefReadError read_error) OVERRIDE { 46 EXPECT_FALSE(data_->invoked); 47 data_->invoked = true; 48 data_->read_error = read_error; 49 } 50 51 private: 52 Data* data_; 53 }; 54 55 } // namespace 56 57 class SegregatedPrefStoreTest : public testing::Test { 58 public: 59 SegregatedPrefStoreTest() 60 : read_error_delegate_data_(false, 61 PersistentPrefStore::PREF_READ_ERROR_NONE), 62 read_error_delegate_( 63 new MockReadErrorDelegate(&read_error_delegate_data_)) {} 64 65 virtual void SetUp() OVERRIDE { 66 selected_store_ = new TestingPrefStore; 67 default_store_ = new TestingPrefStore; 68 69 std::set<std::string> selected_pref_names; 70 selected_pref_names.insert(kSelectedPref); 71 72 segregated_store_ = new SegregatedPrefStore( 73 default_store_, 74 selected_store_, 75 selected_pref_names); 76 77 segregated_store_->AddObserver(&observer_); 78 } 79 80 virtual void TearDown() OVERRIDE { 81 segregated_store_->RemoveObserver(&observer_); 82 } 83 84 protected: 85 scoped_ptr<PersistentPrefStore::ReadErrorDelegate> GetReadErrorDelegate() { 86 EXPECT_TRUE(read_error_delegate_); 87 return read_error_delegate_ 88 .PassAs<PersistentPrefStore::ReadErrorDelegate>(); 89 } 90 91 PrefStoreObserverMock observer_; 92 93 scoped_refptr<TestingPrefStore> default_store_; 94 scoped_refptr<TestingPrefStore> selected_store_; 95 scoped_refptr<SegregatedPrefStore> segregated_store_; 96 97 MockReadErrorDelegate::Data read_error_delegate_data_; 98 99 private: 100 scoped_ptr<MockReadErrorDelegate> read_error_delegate_; 101 }; 102 103 TEST_F(SegregatedPrefStoreTest, StoreValues) { 104 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, 105 segregated_store_->ReadPrefs()); 106 107 // Properly stores new values. 108 segregated_store_->SetValue(kSelectedPref, new base::StringValue(kValue1)); 109 segregated_store_->SetValue(kUnselectedPref, new base::StringValue(kValue2)); 110 111 ASSERT_TRUE(selected_store_->GetValue(kSelectedPref, NULL)); 112 ASSERT_FALSE(selected_store_->GetValue(kUnselectedPref, NULL)); 113 ASSERT_FALSE(default_store_->GetValue(kSelectedPref, NULL)); 114 ASSERT_TRUE(default_store_->GetValue(kUnselectedPref, NULL)); 115 116 ASSERT_TRUE(segregated_store_->GetValue(kSelectedPref, NULL)); 117 ASSERT_TRUE(segregated_store_->GetValue(kUnselectedPref, NULL)); 118 119 ASSERT_FALSE(selected_store_->committed()); 120 ASSERT_FALSE(default_store_->committed()); 121 122 segregated_store_->CommitPendingWrite(); 123 124 ASSERT_TRUE(selected_store_->committed()); 125 ASSERT_TRUE(default_store_->committed()); 126 } 127 128 TEST_F(SegregatedPrefStoreTest, ReadValues) { 129 selected_store_->SetValue(kSelectedPref, new base::StringValue(kValue1)); 130 default_store_->SetValue(kUnselectedPref, 131 new base::StringValue(kValue2)); 132 133 // Works properly with values that are already there. 134 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, 135 segregated_store_->ReadPrefs()); 136 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, 137 segregated_store_->GetReadError()); 138 139 ASSERT_TRUE(selected_store_->GetValue(kSelectedPref, NULL)); 140 ASSERT_FALSE(selected_store_->GetValue(kUnselectedPref, NULL)); 141 ASSERT_FALSE(default_store_->GetValue(kSelectedPref, NULL)); 142 ASSERT_TRUE(default_store_->GetValue(kUnselectedPref, NULL)); 143 144 ASSERT_TRUE(segregated_store_->GetValue(kSelectedPref, NULL)); 145 ASSERT_TRUE(segregated_store_->GetValue(kUnselectedPref, NULL)); 146 } 147 148 TEST_F(SegregatedPrefStoreTest, Observer) { 149 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, 150 segregated_store_->ReadPrefs()); 151 EXPECT_TRUE(observer_.initialized); 152 EXPECT_TRUE(observer_.initialization_success); 153 EXPECT_TRUE(observer_.changed_keys.empty()); 154 segregated_store_->SetValue(kSelectedPref, new base::StringValue(kValue1)); 155 observer_.VerifyAndResetChangedKey(kSelectedPref); 156 segregated_store_->SetValue(kUnselectedPref, new base::StringValue(kValue2)); 157 observer_.VerifyAndResetChangedKey(kUnselectedPref); 158 } 159 160 TEST_F(SegregatedPrefStoreTest, SelectedPrefReadNoFileError) { 161 // PREF_READ_ERROR_NO_FILE for the selected prefs file is silently converted 162 // to PREF_READ_ERROR_NONE. 163 selected_store_->set_read_error( 164 PersistentPrefStore::PREF_READ_ERROR_NO_FILE); 165 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, 166 segregated_store_->ReadPrefs()); 167 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, 168 segregated_store_->GetReadError()); 169 } 170 171 TEST_F(SegregatedPrefStoreTest, SelectedPrefReadError) { 172 selected_store_->set_read_error( 173 PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED); 174 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED, 175 segregated_store_->ReadPrefs()); 176 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED, 177 segregated_store_->GetReadError()); 178 } 179 180 TEST_F(SegregatedPrefStoreTest, SelectedPrefReadNoFileErrorAsync) { 181 // PREF_READ_ERROR_NO_FILE for the selected prefs file is silently converted 182 // to PREF_READ_ERROR_NONE. 183 selected_store_->set_read_error( 184 PersistentPrefStore::PREF_READ_ERROR_NO_FILE); 185 186 default_store_->SetBlockAsyncRead(true); 187 188 EXPECT_FALSE(read_error_delegate_data_.invoked); 189 190 segregated_store_->ReadPrefsAsync(GetReadErrorDelegate().release()); 191 192 EXPECT_FALSE(read_error_delegate_data_.invoked); 193 194 default_store_->SetBlockAsyncRead(false); 195 196 // ReadErrorDelegate is not invoked for ERROR_NONE. 197 EXPECT_FALSE(read_error_delegate_data_.invoked); 198 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, 199 segregated_store_->GetReadError()); 200 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, 201 segregated_store_->GetReadError()); 202 } 203 204 TEST_F(SegregatedPrefStoreTest, UnselectedPrefReadNoFileError) { 205 default_store_->set_read_error( 206 PersistentPrefStore::PREF_READ_ERROR_NO_FILE); 207 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, 208 segregated_store_->ReadPrefs()); 209 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, 210 segregated_store_->GetReadError()); 211 } 212 213 TEST_F(SegregatedPrefStoreTest, UnselectedPrefReadError) { 214 default_store_->set_read_error( 215 PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED); 216 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED, 217 segregated_store_->ReadPrefs()); 218 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED, 219 segregated_store_->GetReadError()); 220 } 221 222 TEST_F(SegregatedPrefStoreTest, BothPrefReadError) { 223 default_store_->set_read_error( 224 PersistentPrefStore::PREF_READ_ERROR_NO_FILE); 225 selected_store_->set_read_error( 226 PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED); 227 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, 228 segregated_store_->ReadPrefs()); 229 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, 230 segregated_store_->GetReadError()); 231 } 232 233 TEST_F(SegregatedPrefStoreTest, BothPrefReadErrorAsync) { 234 default_store_->set_read_error( 235 PersistentPrefStore::PREF_READ_ERROR_NO_FILE); 236 selected_store_->set_read_error( 237 PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED); 238 239 selected_store_->SetBlockAsyncRead(true); 240 241 EXPECT_FALSE(read_error_delegate_data_.invoked); 242 243 segregated_store_->ReadPrefsAsync(GetReadErrorDelegate().release()); 244 245 EXPECT_FALSE(read_error_delegate_data_.invoked); 246 247 selected_store_->SetBlockAsyncRead(false); 248 249 EXPECT_TRUE(read_error_delegate_data_.invoked); 250 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, 251 segregated_store_->GetReadError()); 252 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, 253 segregated_store_->GetReadError()); 254 } 255 256 TEST_F(SegregatedPrefStoreTest, IsInitializationComplete) { 257 EXPECT_FALSE(segregated_store_->IsInitializationComplete()); 258 segregated_store_->ReadPrefs(); 259 EXPECT_TRUE(segregated_store_->IsInitializationComplete()); 260 } 261 262 TEST_F(SegregatedPrefStoreTest, IsInitializationCompleteAsync) { 263 selected_store_->SetBlockAsyncRead(true); 264 default_store_->SetBlockAsyncRead(true); 265 EXPECT_FALSE(segregated_store_->IsInitializationComplete()); 266 segregated_store_->ReadPrefsAsync(NULL); 267 EXPECT_FALSE(segregated_store_->IsInitializationComplete()); 268 selected_store_->SetBlockAsyncRead(false); 269 EXPECT_FALSE(segregated_store_->IsInitializationComplete()); 270 default_store_->SetBlockAsyncRead(false); 271 EXPECT_TRUE(segregated_store_->IsInitializationComplete()); 272 } 273