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