| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "services/preferences/persistent_pref_store_impl.h" | 5 #include "services/preferences/persistent_pref_store_impl.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/macros.h" | 9 #include "base/macros.h" |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 class PersistentPrefStoreMock : public InMemoryPrefStore { | 33 class PersistentPrefStoreMock : public InMemoryPrefStore { |
| 34 public: | 34 public: |
| 35 MOCK_METHOD0(CommitPendingWrite, void()); | 35 MOCK_METHOD0(CommitPendingWrite, void()); |
| 36 MOCK_METHOD0(SchedulePendingLossyWrites, void()); | 36 MOCK_METHOD0(SchedulePendingLossyWrites, void()); |
| 37 MOCK_METHOD0(ClearMutableValues, void()); | 37 MOCK_METHOD0(ClearMutableValues, void()); |
| 38 | 38 |
| 39 private: | 39 private: |
| 40 ~PersistentPrefStoreMock() override = default; | 40 ~PersistentPrefStoreMock() override = default; |
| 41 }; | 41 }; |
| 42 | 42 |
| 43 class PrefStoreConnectorMock : public mojom::PrefStoreConnector { | |
| 44 public: | |
| 45 MOCK_METHOD1(Connect, void(const ConnectCallback&)); | |
| 46 }; | |
| 47 | |
| 48 class InitializationMockPersistentPrefStore : public InMemoryPrefStore { | 43 class InitializationMockPersistentPrefStore : public InMemoryPrefStore { |
| 49 public: | 44 public: |
| 50 bool IsInitializationComplete() const override { return initialized_; } | 45 InitializationMockPersistentPrefStore( |
| 46 bool success, |
| 47 PersistentPrefStore::PrefReadError error, |
| 48 bool read_only) |
| 49 : success_(success), read_error_(error), read_only_(read_only) {} |
| 50 |
| 51 bool IsInitializationComplete() const override { |
| 52 return initialized_ && success_; |
| 53 } |
| 51 | 54 |
| 52 void AddObserver(PrefStore::Observer* observer) override { | 55 void AddObserver(PrefStore::Observer* observer) override { |
| 53 observers_.AddObserver(observer); | 56 observers_.AddObserver(observer); |
| 54 } | 57 } |
| 55 | 58 |
| 56 void RemoveObserver(PrefStore::Observer* observer) override { | 59 void RemoveObserver(PrefStore::Observer* observer) override { |
| 57 observers_.RemoveObserver(observer); | 60 observers_.RemoveObserver(observer); |
| 58 } | 61 } |
| 59 | 62 |
| 60 void ReadPrefsAsync(ReadErrorDelegate* error_delegate) override { | 63 void ReadPrefsAsync(ReadErrorDelegate* error_delegate) override { |
| 61 DCHECK(!error_delegate); | 64 DCHECK(!error_delegate); |
| 65 DCHECK(!initialized_); |
| 66 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 67 FROM_HERE, |
| 68 base::Bind(&InitializationMockPersistentPrefStore::CompleteRead, this)); |
| 69 } |
| 70 |
| 71 void CompleteRead() { |
| 72 initialized_ = true; |
| 73 for (auto& observer : observers_) { |
| 74 observer.OnInitializationCompleted(success_); |
| 75 } |
| 62 } | 76 } |
| 63 | 77 |
| 64 PersistentPrefStore::PrefReadError GetReadError() const override { | 78 PersistentPrefStore::PrefReadError GetReadError() const override { |
| 65 return read_error_; | 79 return read_error_; |
| 66 } | 80 } |
| 67 bool ReadOnly() const override { return read_only_; } | 81 bool ReadOnly() const override { return read_only_; } |
| 68 | 82 |
| 69 void Initialize(bool success, | |
| 70 PersistentPrefStore::PrefReadError error, | |
| 71 bool read_only) { | |
| 72 initialized_ = success; | |
| 73 read_error_ = error; | |
| 74 read_only_ = read_only; | |
| 75 for (auto& observer : observers_) { | |
| 76 observer.OnInitializationCompleted(initialized_); | |
| 77 } | |
| 78 } | |
| 79 | |
| 80 private: | 83 private: |
| 81 ~InitializationMockPersistentPrefStore() override = default; | 84 ~InitializationMockPersistentPrefStore() override = default; |
| 82 | 85 |
| 86 bool initialized_ = false; |
| 87 bool success_; |
| 83 PersistentPrefStore::PrefReadError read_error_; | 88 PersistentPrefStore::PrefReadError read_error_; |
| 84 bool read_only_ = false; | 89 bool read_only_; |
| 85 bool initialized_ = false; | |
| 86 base::ObserverList<PrefStore::Observer, true> observers_; | 90 base::ObserverList<PrefStore::Observer, true> observers_; |
| 87 }; | 91 }; |
| 88 | 92 |
| 93 constexpr char kKey[] = "path.to.key"; |
| 94 |
| 89 class PersistentPrefStoreImplTest : public testing::Test { | 95 class PersistentPrefStoreImplTest : public testing::Test { |
| 90 public: | 96 public: |
| 91 PersistentPrefStoreImplTest() = default; | 97 PersistentPrefStoreImplTest() = default; |
| 92 | 98 |
| 93 // testing::Test: | 99 // testing::Test: |
| 94 void TearDown() override { | 100 void TearDown() override { |
| 95 pref_store_ = nullptr; | 101 pref_store_ = nullptr; |
| 96 base::RunLoop().RunUntilIdle(); | 102 base::RunLoop().RunUntilIdle(); |
| 97 bindings_.CloseAllBindings(); | 103 impl_.reset(); |
| 98 backing_pref_store_.reset(); | |
| 99 base::RunLoop().RunUntilIdle(); | 104 base::RunLoop().RunUntilIdle(); |
| 100 } | 105 } |
| 101 | 106 |
| 102 void CreateImpl(scoped_refptr<PersistentPrefStore> backing_pref_store) { | 107 void CreateImpl(scoped_refptr<PersistentPrefStore> backing_pref_store) { |
| 103 backing_pref_store_ = base::MakeUnique<PersistentPrefStoreImpl>( | 108 base::RunLoop run_loop; |
| 104 std::move(backing_pref_store), nullptr); | 109 bool initialized = backing_pref_store->IsInitializationComplete(); |
| 105 mojo::Binding<mojom::PersistentPrefStoreConnector> binding( | 110 impl_ = base::MakeUnique<PersistentPrefStoreImpl>( |
| 106 backing_pref_store_.get()); | 111 std::move(backing_pref_store), nullptr, run_loop.QuitClosure()); |
| 112 if (!initialized) |
| 113 run_loop.Run(); |
| 107 pref_store_ = CreateConnection(); | 114 pref_store_ = CreateConnection(); |
| 108 } | 115 } |
| 109 | 116 |
| 110 mojom::PersistentPrefStoreConnectorPtr CreateConnector() { | |
| 111 return bindings_.CreateInterfacePtrAndBind(backing_pref_store_.get()); | |
| 112 } | |
| 113 | |
| 114 scoped_refptr<PersistentPrefStore> CreateConnection() { | 117 scoped_refptr<PersistentPrefStore> CreateConnection() { |
| 115 return make_scoped_refptr(new PersistentPrefStoreClient( | 118 return make_scoped_refptr( |
| 116 bindings_.CreateInterfacePtrAndBind(backing_pref_store_.get()))); | 119 new PersistentPrefStoreClient(impl_->CreateConnection())); |
| 117 } | 120 } |
| 118 | 121 |
| 119 PersistentPrefStore* pref_store() { return pref_store_.get(); } | 122 PersistentPrefStore* pref_store() { return pref_store_.get(); } |
| 120 | 123 |
| 121 private: | 124 private: |
| 122 base::MessageLoop message_loop_; | 125 base::MessageLoop message_loop_; |
| 123 | 126 |
| 124 std::unique_ptr<PersistentPrefStoreImpl> backing_pref_store_; | 127 std::unique_ptr<PersistentPrefStoreImpl> impl_; |
| 125 mojo::BindingSet<mojom::PersistentPrefStoreConnector> bindings_; | |
| 126 | 128 |
| 127 scoped_refptr<PersistentPrefStore> pref_store_; | 129 scoped_refptr<PersistentPrefStore> pref_store_; |
| 128 | 130 |
| 129 DISALLOW_COPY_AND_ASSIGN(PersistentPrefStoreImplTest); | 131 DISALLOW_COPY_AND_ASSIGN(PersistentPrefStoreImplTest); |
| 130 }; | 132 }; |
| 131 | 133 |
| 132 TEST_F(PersistentPrefStoreImplTest, InitializationSuccess) { | 134 TEST_F(PersistentPrefStoreImplTest, InitializationSuccess) { |
| 133 auto backing_pref_store = | 135 auto backing_pref_store = |
| 134 make_scoped_refptr(new InitializationMockPersistentPrefStore); | 136 make_scoped_refptr(new InitializationMockPersistentPrefStore( |
| 137 true, PersistentPrefStore::PREF_READ_ERROR_NONE, false)); |
| 135 CreateImpl(backing_pref_store); | 138 CreateImpl(backing_pref_store); |
| 136 backing_pref_store->Initialize( | |
| 137 true, PersistentPrefStore::PREF_READ_ERROR_NONE, false); | |
| 138 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, | |
| 139 pref_store()->ReadPrefs()); | |
| 140 EXPECT_TRUE(pref_store()->IsInitializationComplete()); | 139 EXPECT_TRUE(pref_store()->IsInitializationComplete()); |
| 141 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, | 140 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, |
| 142 pref_store()->GetReadError()); | 141 pref_store()->GetReadError()); |
| 143 EXPECT_FALSE(pref_store()->ReadOnly()); | 142 EXPECT_FALSE(pref_store()->ReadOnly()); |
| 144 } | 143 } |
| 145 | 144 |
| 146 TEST_F(PersistentPrefStoreImplTest, InitializationFailure) { | 145 TEST_F(PersistentPrefStoreImplTest, InitializationFailure) { |
| 147 auto backing_pref_store = | 146 auto backing_pref_store = |
| 148 make_scoped_refptr(new InitializationMockPersistentPrefStore); | 147 make_scoped_refptr(new InitializationMockPersistentPrefStore( |
| 148 false, PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE, true)); |
| 149 CreateImpl(backing_pref_store); | 149 CreateImpl(backing_pref_store); |
| 150 backing_pref_store->Initialize( | |
| 151 false, PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE, true); | |
| 152 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE, | |
| 153 pref_store()->ReadPrefs()); | |
| 154 EXPECT_FALSE(pref_store()->IsInitializationComplete()); | 150 EXPECT_FALSE(pref_store()->IsInitializationComplete()); |
| 155 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE, | 151 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE, |
| 156 pref_store()->GetReadError()); | 152 pref_store()->GetReadError()); |
| 157 EXPECT_TRUE(pref_store()->ReadOnly()); | 153 EXPECT_TRUE(pref_store()->ReadOnly()); |
| 158 } | 154 } |
| 159 | 155 |
| 160 class TestReadErrorDelegate : public PersistentPrefStore::ReadErrorDelegate { | 156 class TestReadErrorDelegate : public PersistentPrefStore::ReadErrorDelegate { |
| 161 public: | 157 public: |
| 162 TestReadErrorDelegate(PersistentPrefStore::PrefReadError* storage, | 158 TestReadErrorDelegate(PersistentPrefStore::PrefReadError* storage, |
| 163 const base::Closure& quit) | 159 const base::Closure& quit) |
| 164 : storage_(storage), quit_(quit) { | 160 : storage_(storage), quit_(quit) { |
| 165 DCHECK(storage_); | 161 DCHECK(storage_); |
| 166 DCHECK(quit_); | 162 DCHECK(quit_); |
| 167 } | 163 } |
| 168 | 164 |
| 169 void OnError(PersistentPrefStore::PrefReadError error) override { | 165 void OnError(PersistentPrefStore::PrefReadError error) override { |
| 170 *storage_ = error; | 166 *storage_ = error; |
| 171 quit_.Run(); | 167 quit_.Run(); |
| 172 } | 168 } |
| 173 | 169 |
| 174 private: | 170 private: |
| 175 PersistentPrefStore::PrefReadError* const storage_; | 171 PersistentPrefStore::PrefReadError* const storage_; |
| 176 const base::Closure quit_; | 172 const base::Closure quit_; |
| 177 }; | 173 }; |
| 178 | 174 |
| 179 TEST_F(PersistentPrefStoreImplTest, InitializationFailure_AsyncRead) { | |
| 180 auto backing_pref_store = | |
| 181 make_scoped_refptr(new InitializationMockPersistentPrefStore); | |
| 182 CreateImpl(backing_pref_store); | |
| 183 backing_pref_store->Initialize( | |
| 184 false, PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE, true); | |
| 185 PersistentPrefStore::PrefReadError read_error = | |
| 186 PersistentPrefStore::PREF_READ_ERROR_NONE; | |
| 187 base::RunLoop run_loop; | |
| 188 pref_store()->ReadPrefsAsync( | |
| 189 new TestReadErrorDelegate(&read_error, run_loop.QuitClosure())); | |
| 190 run_loop.Run(); | |
| 191 EXPECT_FALSE(pref_store()->IsInitializationComplete()); | |
| 192 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE, read_error); | |
| 193 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE, | |
| 194 pref_store()->GetReadError()); | |
| 195 EXPECT_TRUE(pref_store()->ReadOnly()); | |
| 196 } | |
| 197 | |
| 198 TEST_F(PersistentPrefStoreImplTest, DelayedInitializationSuccess) { | |
| 199 auto backing_pref_store = | |
| 200 make_scoped_refptr(new InitializationMockPersistentPrefStore); | |
| 201 | |
| 202 CreateImpl(backing_pref_store); | |
| 203 auto connector = CreateConnector(); | |
| 204 base::RunLoop run_loop; | |
| 205 connector->Connect(base::Bind( | |
| 206 [](const base::Closure& quit, | |
| 207 PersistentPrefStore::PrefReadError read_error, bool read_only, | |
| 208 std::unique_ptr<base::DictionaryValue> local_prefs, | |
| 209 mojom::PersistentPrefStorePtr pref_store, | |
| 210 mojom::PrefStoreObserverRequest observer_request) { | |
| 211 quit.Run(); | |
| 212 EXPECT_FALSE(read_only); | |
| 213 EXPECT_TRUE(local_prefs); | |
| 214 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, read_error); | |
| 215 }, | |
| 216 run_loop.QuitClosure())); | |
| 217 connector.FlushForTesting(); | |
| 218 backing_pref_store->Initialize( | |
| 219 true, PersistentPrefStore::PREF_READ_ERROR_NONE, false); | |
| 220 run_loop.Run(); | |
| 221 } | |
| 222 | |
| 223 TEST_F(PersistentPrefStoreImplTest, DelayedInitializationFailure) { | |
| 224 auto backing_pref_store = | |
| 225 make_scoped_refptr(new InitializationMockPersistentPrefStore); | |
| 226 | |
| 227 CreateImpl(backing_pref_store); | |
| 228 auto connector = CreateConnector(); | |
| 229 base::RunLoop run_loop; | |
| 230 connector->Connect(base::Bind( | |
| 231 [](const base::Closure& quit, | |
| 232 PersistentPrefStore::PrefReadError read_error, bool read_only, | |
| 233 std::unique_ptr<base::DictionaryValue> local_prefs, | |
| 234 mojom::PersistentPrefStorePtr pref_store, | |
| 235 mojom::PrefStoreObserverRequest observer_request) { | |
| 236 quit.Run(); | |
| 237 EXPECT_TRUE(read_only); | |
| 238 EXPECT_FALSE(local_prefs); | |
| 239 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED, | |
| 240 read_error); | |
| 241 }, | |
| 242 run_loop.QuitClosure())); | |
| 243 connector.FlushForTesting(); | |
| 244 backing_pref_store->Initialize( | |
| 245 false, PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED, true); | |
| 246 run_loop.Run(); | |
| 247 } | |
| 248 | |
| 249 constexpr char kKey[] = "path.to.key"; | |
| 250 | |
| 251 TEST_F(PersistentPrefStoreImplTest, InitialValue) { | 175 TEST_F(PersistentPrefStoreImplTest, InitialValue) { |
| 252 auto backing_pref_store = make_scoped_refptr(new InMemoryPrefStore()); | 176 auto backing_pref_store = make_scoped_refptr(new InMemoryPrefStore()); |
| 253 const base::Value value("value"); | 177 const base::Value value("value"); |
| 254 backing_pref_store->SetValue(kKey, value.CreateDeepCopy(), 0); | 178 backing_pref_store->SetValue(kKey, value.CreateDeepCopy(), 0); |
| 255 CreateImpl(backing_pref_store); | 179 CreateImpl(backing_pref_store); |
| 256 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, | |
| 257 pref_store()->ReadPrefs()); | |
| 258 EXPECT_TRUE(pref_store()->IsInitializationComplete()); | 180 EXPECT_TRUE(pref_store()->IsInitializationComplete()); |
| 259 const base::Value* output = nullptr; | 181 const base::Value* output = nullptr; |
| 260 ASSERT_TRUE(pref_store()->GetValue(kKey, &output)); | 182 ASSERT_TRUE(pref_store()->GetValue(kKey, &output)); |
| 261 EXPECT_TRUE(value.Equals(output)); | 183 EXPECT_TRUE(value.Equals(output)); |
| 262 } | 184 } |
| 263 | 185 |
| 264 TEST_F(PersistentPrefStoreImplTest, InitialValueWithoutPathExpansion) { | 186 TEST_F(PersistentPrefStoreImplTest, InitialValueWithoutPathExpansion) { |
| 265 auto backing_pref_store = make_scoped_refptr(new InMemoryPrefStore()); | 187 auto backing_pref_store = make_scoped_refptr(new InMemoryPrefStore()); |
| 266 base::DictionaryValue dict; | 188 base::DictionaryValue dict; |
| 267 dict.SetStringWithoutPathExpansion(kKey, "value"); | 189 dict.SetStringWithoutPathExpansion(kKey, "value"); |
| 268 backing_pref_store->SetValue(kKey, dict.CreateDeepCopy(), 0); | 190 backing_pref_store->SetValue(kKey, dict.CreateDeepCopy(), 0); |
| 269 CreateImpl(backing_pref_store); | 191 CreateImpl(backing_pref_store); |
| 270 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, | |
| 271 pref_store()->ReadPrefs()); | |
| 272 EXPECT_TRUE(pref_store()->IsInitializationComplete()); | 192 EXPECT_TRUE(pref_store()->IsInitializationComplete()); |
| 273 const base::Value* output = nullptr; | 193 const base::Value* output = nullptr; |
| 274 ASSERT_TRUE(pref_store()->GetValue(kKey, &output)); | 194 ASSERT_TRUE(pref_store()->GetValue(kKey, &output)); |
| 275 EXPECT_TRUE(dict.Equals(output)); | 195 EXPECT_TRUE(dict.Equals(output)); |
| 276 } | 196 } |
| 277 | 197 |
| 278 TEST_F(PersistentPrefStoreImplTest, WriteObservedByOtherClient) { | 198 TEST_F(PersistentPrefStoreImplTest, WriteObservedByOtherClient) { |
| 279 auto backing_pref_store = make_scoped_refptr(new InMemoryPrefStore()); | 199 auto backing_pref_store = make_scoped_refptr(new InMemoryPrefStore()); |
| 280 CreateImpl(backing_pref_store); | 200 CreateImpl(backing_pref_store); |
| 281 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, | |
| 282 pref_store()->ReadPrefs()); | |
| 283 EXPECT_TRUE(pref_store()->IsInitializationComplete()); | 201 EXPECT_TRUE(pref_store()->IsInitializationComplete()); |
| 284 | 202 |
| 285 auto other_pref_store = CreateConnection(); | 203 auto other_pref_store = CreateConnection(); |
| 286 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, | |
| 287 other_pref_store->ReadPrefs()); | |
| 288 EXPECT_TRUE(other_pref_store->IsInitializationComplete()); | 204 EXPECT_TRUE(other_pref_store->IsInitializationComplete()); |
| 289 | 205 |
| 290 const base::Value value("value"); | 206 const base::Value value("value"); |
| 291 pref_store()->SetValueSilently(kKey, value.CreateDeepCopy(), 0); | 207 pref_store()->SetValueSilently(kKey, value.CreateDeepCopy(), 0); |
| 292 | 208 |
| 293 PrefStoreObserverMock observer; | 209 PrefStoreObserverMock observer; |
| 294 other_pref_store->AddObserver(&observer); | 210 other_pref_store->AddObserver(&observer); |
| 295 base::RunLoop run_loop; | 211 base::RunLoop run_loop; |
| 296 EXPECT_CALL(observer, OnPrefValueChanged(kKey)) | 212 EXPECT_CALL(observer, OnPrefValueChanged(kKey)) |
| 297 .Times(1) | 213 .Times(1) |
| 298 .WillOnce(WithoutArgs(Invoke([&run_loop]() { run_loop.Quit(); }))); | 214 .WillOnce(WithoutArgs(Invoke([&run_loop]() { run_loop.Quit(); }))); |
| 299 run_loop.Run(); | 215 run_loop.Run(); |
| 300 other_pref_store->RemoveObserver(&observer); | 216 other_pref_store->RemoveObserver(&observer); |
| 301 | 217 |
| 302 const base::Value* output = nullptr; | 218 const base::Value* output = nullptr; |
| 303 ASSERT_TRUE(other_pref_store->GetValue(kKey, &output)); | 219 ASSERT_TRUE(other_pref_store->GetValue(kKey, &output)); |
| 304 EXPECT_TRUE(value.Equals(output)); | 220 EXPECT_TRUE(value.Equals(output)); |
| 305 } | 221 } |
| 306 | 222 |
| 307 TEST_F(PersistentPrefStoreImplTest, | 223 TEST_F(PersistentPrefStoreImplTest, |
| 308 WriteWithoutPathExpansionObservedByOtherClient) { | 224 WriteWithoutPathExpansionObservedByOtherClient) { |
| 309 auto backing_pref_store = make_scoped_refptr(new InMemoryPrefStore()); | 225 auto backing_pref_store = make_scoped_refptr(new InMemoryPrefStore()); |
| 310 CreateImpl(backing_pref_store); | 226 CreateImpl(backing_pref_store); |
| 311 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, | |
| 312 pref_store()->ReadPrefs()); | |
| 313 EXPECT_TRUE(pref_store()->IsInitializationComplete()); | 227 EXPECT_TRUE(pref_store()->IsInitializationComplete()); |
| 314 | 228 |
| 315 auto other_pref_store = CreateConnection(); | 229 auto other_pref_store = CreateConnection(); |
| 316 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, | |
| 317 other_pref_store->ReadPrefs()); | |
| 318 EXPECT_TRUE(other_pref_store->IsInitializationComplete()); | 230 EXPECT_TRUE(other_pref_store->IsInitializationComplete()); |
| 319 | 231 |
| 320 base::DictionaryValue dict; | 232 base::DictionaryValue dict; |
| 321 dict.SetStringWithoutPathExpansion(kKey, "value"); | 233 dict.SetStringWithoutPathExpansion(kKey, "value"); |
| 322 pref_store()->SetValue(kKey, dict.CreateDeepCopy(), 0); | 234 pref_store()->SetValue(kKey, dict.CreateDeepCopy(), 0); |
| 323 | 235 |
| 324 PrefStoreObserverMock observer; | 236 PrefStoreObserverMock observer; |
| 325 other_pref_store->AddObserver(&observer); | 237 other_pref_store->AddObserver(&observer); |
| 326 base::RunLoop run_loop; | 238 base::RunLoop run_loop; |
| 327 EXPECT_CALL(observer, OnPrefValueChanged(kKey)) | 239 EXPECT_CALL(observer, OnPrefValueChanged(kKey)) |
| 328 .Times(1) | 240 .Times(1) |
| 329 .WillOnce(WithoutArgs(Invoke([&run_loop]() { run_loop.Quit(); }))); | 241 .WillOnce(WithoutArgs(Invoke([&run_loop]() { run_loop.Quit(); }))); |
| 330 run_loop.Run(); | 242 run_loop.Run(); |
| 331 other_pref_store->RemoveObserver(&observer); | 243 other_pref_store->RemoveObserver(&observer); |
| 332 | 244 |
| 333 const base::Value* output = nullptr; | 245 const base::Value* output = nullptr; |
| 334 ASSERT_TRUE(other_pref_store->GetValue(kKey, &output)); | 246 ASSERT_TRUE(other_pref_store->GetValue(kKey, &output)); |
| 335 EXPECT_TRUE(dict.Equals(output)); | 247 EXPECT_TRUE(dict.Equals(output)); |
| 336 } | 248 } |
| 337 | 249 |
| 338 TEST_F(PersistentPrefStoreImplTest, RemoveObservedByOtherClient) { | 250 TEST_F(PersistentPrefStoreImplTest, RemoveObservedByOtherClient) { |
| 339 auto backing_pref_store = make_scoped_refptr(new InMemoryPrefStore()); | 251 auto backing_pref_store = make_scoped_refptr(new InMemoryPrefStore()); |
| 340 const base::Value value("value"); | 252 const base::Value value("value"); |
| 341 backing_pref_store->SetValue(kKey, value.CreateDeepCopy(), 0); | 253 backing_pref_store->SetValue(kKey, value.CreateDeepCopy(), 0); |
| 342 CreateImpl(backing_pref_store); | 254 CreateImpl(backing_pref_store); |
| 343 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, | |
| 344 pref_store()->ReadPrefs()); | |
| 345 EXPECT_TRUE(pref_store()->IsInitializationComplete()); | 255 EXPECT_TRUE(pref_store()->IsInitializationComplete()); |
| 346 | 256 |
| 347 auto other_pref_store = CreateConnection(); | 257 auto other_pref_store = CreateConnection(); |
| 348 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, | |
| 349 other_pref_store->ReadPrefs()); | |
| 350 EXPECT_TRUE(other_pref_store->IsInitializationComplete()); | 258 EXPECT_TRUE(other_pref_store->IsInitializationComplete()); |
| 351 | 259 |
| 352 const base::Value* output = nullptr; | 260 const base::Value* output = nullptr; |
| 353 ASSERT_TRUE(other_pref_store->GetValue(kKey, &output)); | 261 ASSERT_TRUE(other_pref_store->GetValue(kKey, &output)); |
| 354 EXPECT_TRUE(value.Equals(output)); | 262 EXPECT_TRUE(value.Equals(output)); |
| 355 pref_store()->RemoveValue(kKey, 0); | 263 pref_store()->RemoveValue(kKey, 0); |
| 356 | 264 |
| 357 // This should be a no-op and shouldn't trigger a notification for the other | 265 // This should be a no-op and shouldn't trigger a notification for the other |
| 358 // client. | 266 // client. |
| 359 pref_store()->RemoveValue(kKey, 0); | 267 pref_store()->RemoveValue(kKey, 0); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 371 EXPECT_FALSE(other_pref_store->GetValue(kKey, &output)); | 279 EXPECT_FALSE(other_pref_store->GetValue(kKey, &output)); |
| 372 } | 280 } |
| 373 | 281 |
| 374 TEST_F(PersistentPrefStoreImplTest, | 282 TEST_F(PersistentPrefStoreImplTest, |
| 375 RemoveWithoutPathExpansionObservedByOtherClient) { | 283 RemoveWithoutPathExpansionObservedByOtherClient) { |
| 376 auto backing_pref_store = make_scoped_refptr(new InMemoryPrefStore()); | 284 auto backing_pref_store = make_scoped_refptr(new InMemoryPrefStore()); |
| 377 base::DictionaryValue dict; | 285 base::DictionaryValue dict; |
| 378 dict.SetStringWithoutPathExpansion(kKey, "value"); | 286 dict.SetStringWithoutPathExpansion(kKey, "value"); |
| 379 backing_pref_store->SetValue(kKey, dict.CreateDeepCopy(), 0); | 287 backing_pref_store->SetValue(kKey, dict.CreateDeepCopy(), 0); |
| 380 CreateImpl(backing_pref_store); | 288 CreateImpl(backing_pref_store); |
| 381 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, | |
| 382 pref_store()->ReadPrefs()); | |
| 383 EXPECT_TRUE(pref_store()->IsInitializationComplete()); | 289 EXPECT_TRUE(pref_store()->IsInitializationComplete()); |
| 384 | 290 |
| 385 auto other_pref_store = CreateConnection(); | 291 auto other_pref_store = CreateConnection(); |
| 386 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, | |
| 387 other_pref_store->ReadPrefs()); | |
| 388 EXPECT_TRUE(other_pref_store->IsInitializationComplete()); | 292 EXPECT_TRUE(other_pref_store->IsInitializationComplete()); |
| 389 | 293 |
| 390 const base::Value* output = nullptr; | 294 const base::Value* output = nullptr; |
| 391 ASSERT_TRUE(other_pref_store->GetValue(kKey, &output)); | 295 ASSERT_TRUE(other_pref_store->GetValue(kKey, &output)); |
| 392 EXPECT_TRUE(dict.Equals(output)); | 296 EXPECT_TRUE(dict.Equals(output)); |
| 393 | 297 |
| 394 base::Value* mutable_value = nullptr; | 298 base::Value* mutable_value = nullptr; |
| 395 dict.SetStringWithoutPathExpansion(kKey, "value"); | 299 dict.SetStringWithoutPathExpansion(kKey, "value"); |
| 396 ASSERT_TRUE(pref_store()->GetMutableValue(kKey, &mutable_value)); | 300 ASSERT_TRUE(pref_store()->GetMutableValue(kKey, &mutable_value)); |
| 397 base::DictionaryValue* mutable_dict = nullptr; | 301 base::DictionaryValue* mutable_dict = nullptr; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 410 | 314 |
| 411 ASSERT_TRUE(other_pref_store->GetValue(kKey, &output)); | 315 ASSERT_TRUE(other_pref_store->GetValue(kKey, &output)); |
| 412 const base::DictionaryValue* dict_value = nullptr; | 316 const base::DictionaryValue* dict_value = nullptr; |
| 413 ASSERT_TRUE(output->GetAsDictionary(&dict_value)); | 317 ASSERT_TRUE(output->GetAsDictionary(&dict_value)); |
| 414 EXPECT_TRUE(dict_value->empty()); | 318 EXPECT_TRUE(dict_value->empty()); |
| 415 } | 319 } |
| 416 | 320 |
| 417 TEST_F(PersistentPrefStoreImplTest, CommitPendingWrite) { | 321 TEST_F(PersistentPrefStoreImplTest, CommitPendingWrite) { |
| 418 auto backing_store = make_scoped_refptr(new PersistentPrefStoreMock); | 322 auto backing_store = make_scoped_refptr(new PersistentPrefStoreMock); |
| 419 CreateImpl(backing_store); | 323 CreateImpl(backing_store); |
| 420 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, | |
| 421 pref_store()->ReadPrefs()); | |
| 422 base::RunLoop run_loop; | 324 base::RunLoop run_loop; |
| 423 EXPECT_CALL(*backing_store, CommitPendingWrite()) | 325 EXPECT_CALL(*backing_store, CommitPendingWrite()) |
| 424 .Times(2) | 326 .Times(2) |
| 425 .WillOnce(WithoutArgs(Invoke([&run_loop]() { run_loop.Quit(); }))); | 327 .WillOnce(WithoutArgs(Invoke([&run_loop]() { run_loop.Quit(); }))); |
| 426 pref_store()->CommitPendingWrite(); | 328 pref_store()->CommitPendingWrite(); |
| 427 run_loop.Run(); | 329 run_loop.Run(); |
| 428 } | 330 } |
| 429 | 331 |
| 430 TEST_F(PersistentPrefStoreImplTest, SchedulePendingLossyWrites) { | 332 TEST_F(PersistentPrefStoreImplTest, SchedulePendingLossyWrites) { |
| 431 auto backing_store = make_scoped_refptr(new PersistentPrefStoreMock); | 333 auto backing_store = make_scoped_refptr(new PersistentPrefStoreMock); |
| 432 CreateImpl(backing_store); | 334 CreateImpl(backing_store); |
| 433 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, | |
| 434 pref_store()->ReadPrefs()); | |
| 435 base::RunLoop run_loop; | 335 base::RunLoop run_loop; |
| 436 EXPECT_CALL(*backing_store, SchedulePendingLossyWrites()) | 336 EXPECT_CALL(*backing_store, SchedulePendingLossyWrites()) |
| 437 .Times(1) | 337 .Times(1) |
| 438 .WillOnce(WithoutArgs(Invoke([&run_loop]() { run_loop.Quit(); }))); | 338 .WillOnce(WithoutArgs(Invoke([&run_loop]() { run_loop.Quit(); }))); |
| 439 EXPECT_CALL(*backing_store, CommitPendingWrite()).Times(1); | 339 EXPECT_CALL(*backing_store, CommitPendingWrite()).Times(1); |
| 440 pref_store()->SchedulePendingLossyWrites(); | 340 pref_store()->SchedulePendingLossyWrites(); |
| 441 run_loop.Run(); | 341 run_loop.Run(); |
| 442 } | 342 } |
| 443 | 343 |
| 444 TEST_F(PersistentPrefStoreImplTest, ClearMutableValues) { | 344 TEST_F(PersistentPrefStoreImplTest, ClearMutableValues) { |
| 445 auto backing_store = make_scoped_refptr(new PersistentPrefStoreMock); | 345 auto backing_store = make_scoped_refptr(new PersistentPrefStoreMock); |
| 446 CreateImpl(backing_store); | 346 CreateImpl(backing_store); |
| 447 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, | |
| 448 pref_store()->ReadPrefs()); | |
| 449 base::RunLoop run_loop; | 347 base::RunLoop run_loop; |
| 450 EXPECT_CALL(*backing_store, ClearMutableValues()) | 348 EXPECT_CALL(*backing_store, ClearMutableValues()) |
| 451 .Times(1) | 349 .Times(1) |
| 452 .WillOnce(WithoutArgs(Invoke([&run_loop]() { run_loop.Quit(); }))); | 350 .WillOnce(WithoutArgs(Invoke([&run_loop]() { run_loop.Quit(); }))); |
| 453 EXPECT_CALL(*backing_store, CommitPendingWrite()).Times(1); | 351 EXPECT_CALL(*backing_store, CommitPendingWrite()).Times(1); |
| 454 pref_store()->ClearMutableValues(); | 352 pref_store()->ClearMutableValues(); |
| 455 run_loop.Run(); | 353 run_loop.Run(); |
| 456 } | 354 } |
| 457 | 355 |
| 458 } // namespace | 356 } // namespace |
| 459 } // namespace prefs | 357 } // namespace prefs |
| OLD | NEW |