Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(433)

Side by Side Diff: services/preferences/pref_service_factory_unittest.cc

Issue 2812863002: Pref service: Add a ScopedDictionaryPrefUpdate to track value changes. (Closed)
Patch Set: rebase Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2017 The Chromium Authors. All rights reserved. 1 // Copyright (c) 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/public/cpp/pref_service_factory.h" 5 #include "services/preferences/public/cpp/pref_service_factory.h"
6 6
7 #include "base/files/scoped_temp_dir.h" 7 #include "base/files/scoped_temp_dir.h"
8 #include "base/memory/ptr_util.h" 8 #include "base/memory/ptr_util.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/utf_string_conversions.h"
10 #include "base/test/sequenced_worker_pool_owner.h" 11 #include "base/test/sequenced_worker_pool_owner.h"
11 #include "components/prefs/pref_change_registrar.h" 12 #include "components/prefs/pref_change_registrar.h"
12 #include "components/prefs/pref_registry_simple.h" 13 #include "components/prefs/pref_registry_simple.h"
13 #include "components/prefs/pref_service.h" 14 #include "components/prefs/pref_service.h"
14 #include "components/prefs/value_map_pref_store.h" 15 #include "components/prefs/value_map_pref_store.h"
15 #include "components/prefs/writeable_pref_store.h" 16 #include "components/prefs/writeable_pref_store.h"
16 #include "mojo/public/cpp/bindings/binding_set.h" 17 #include "mojo/public/cpp/bindings/binding_set.h"
17 #include "services/preferences/public/cpp/pref_service_main.h" 18 #include "services/preferences/public/cpp/pref_service_main.h"
18 #include "services/preferences/public/cpp/pref_store_impl.h" 19 #include "services/preferences/public/cpp/pref_store_impl.h"
20 #include "services/preferences/public/cpp/scoped_pref_update.h"
19 #include "services/preferences/public/interfaces/preferences.mojom.h" 21 #include "services/preferences/public/interfaces/preferences.mojom.h"
20 #include "services/service_manager/public/cpp/binder_registry.h" 22 #include "services/service_manager/public/cpp/binder_registry.h"
21 #include "services/service_manager/public/cpp/interface_factory.h" 23 #include "services/service_manager/public/cpp/interface_factory.h"
22 #include "services/service_manager/public/cpp/service_context.h" 24 #include "services/service_manager/public/cpp/service_context.h"
23 #include "services/service_manager/public/cpp/service_test.h" 25 #include "services/service_manager/public/cpp/service_test.h"
24 #include "services/service_manager/public/interfaces/service_factory.mojom.h" 26 #include "services/service_manager/public/interfaces/service_factory.mojom.h"
25 27
26 namespace prefs { 28 namespace prefs {
27 namespace { 29 namespace {
28 30
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 service_manager::BinderRegistry registry_; 71 service_manager::BinderRegistry registry_;
70 mojo::BindingSet<service_manager::mojom::ServiceFactory> 72 mojo::BindingSet<service_manager::mojom::ServiceFactory>
71 service_factory_bindings_; 73 service_factory_bindings_;
72 std::unique_ptr<service_manager::ServiceContext> pref_service_context_; 74 std::unique_ptr<service_manager::ServiceContext> pref_service_context_;
73 }; 75 };
74 76
75 constexpr int kInitialValue = 1; 77 constexpr int kInitialValue = 1;
76 constexpr int kUpdatedValue = 2; 78 constexpr int kUpdatedValue = 2;
77 constexpr char kKey[] = "some_key"; 79 constexpr char kKey[] = "some_key";
78 constexpr char kOtherKey[] = "some_other_key"; 80 constexpr char kOtherKey[] = "some_other_key";
81 constexpr char kDictionaryKey[] = "a.dictionary.pref";
79 82
80 class PrefServiceFactoryTest : public base::MessageLoop::DestructionObserver, 83 class PrefServiceFactoryTest : public base::MessageLoop::DestructionObserver,
81 public service_manager::test::ServiceTest { 84 public service_manager::test::ServiceTest {
82 public: 85 public:
83 PrefServiceFactoryTest() : ServiceTest("prefs_unittests", false) {} 86 PrefServiceFactoryTest() : ServiceTest("prefs_unittests", false) {}
84 87
85 protected: 88 protected:
86 void SetUp() override { 89 void SetUp() override {
87 ServiceTest::SetUp(); 90 ServiceTest::SetUp();
88 ASSERT_TRUE(profile_dir_.CreateUniqueTempDir()); 91 ASSERT_TRUE(profile_dir_.CreateUniqueTempDir());
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 // base::MessageLoop::DestructionObserver 127 // base::MessageLoop::DestructionObserver
125 void WillDestroyCurrentMessageLoop() override { worker_pool_owner_.reset(); } 128 void WillDestroyCurrentMessageLoop() override { worker_pool_owner_.reset(); }
126 129
127 // Create a fully initialized PrefService synchronously. 130 // Create a fully initialized PrefService synchronously.
128 std::unique_ptr<PrefService> Create() { 131 std::unique_ptr<PrefService> Create() {
129 std::unique_ptr<PrefService> pref_service; 132 std::unique_ptr<PrefService> pref_service;
130 base::RunLoop run_loop; 133 base::RunLoop run_loop;
131 auto pref_registry = make_scoped_refptr(new PrefRegistrySimple()); 134 auto pref_registry = make_scoped_refptr(new PrefRegistrySimple());
132 pref_registry->RegisterIntegerPref(kKey, kInitialValue); 135 pref_registry->RegisterIntegerPref(kKey, kInitialValue);
133 pref_registry->RegisterIntegerPref(kOtherKey, kInitialValue); 136 pref_registry->RegisterIntegerPref(kOtherKey, kInitialValue);
137 pref_registry->RegisterDictionaryPref(kDictionaryKey);
134 ConnectToPrefService(connector(), pref_registry, 138 ConnectToPrefService(connector(), pref_registry,
135 std::vector<PrefValueStore::PrefStoreType>(), 139 std::vector<PrefValueStore::PrefStoreType>(),
136 base::Bind(&PrefServiceFactoryTest::OnCreate, 140 base::Bind(&PrefServiceFactoryTest::OnCreate,
137 run_loop.QuitClosure(), &pref_service)); 141 run_loop.QuitClosure(), &pref_service));
138 run_loop.Run(); 142 run_loop.Run();
139 return pref_service; 143 return pref_service;
140 } 144 }
141 145
142 // Wait until first update of the pref |key| in |pref_service| synchronously. 146 // Wait until first update of the pref |key| in |pref_service| synchronously.
143 void WaitForPrefChange(PrefService* pref_service, const std::string& key) { 147 void WaitForPrefChange(PrefService* pref_service, const std::string& key) {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 262
259 above_user_prefs_pref_store()->SetValue(kKey, 263 above_user_prefs_pref_store()->SetValue(kKey,
260 base::MakeUnique<base::Value>(2), 0); 264 base::MakeUnique<base::Value>(2), 0);
261 WaitForPrefChange(pref_service.get(), kKey); 265 WaitForPrefChange(pref_service.get(), kKey);
262 EXPECT_EQ(2, pref_service->GetInteger(kKey)); 266 EXPECT_EQ(2, pref_service->GetInteger(kKey));
263 267
264 pref_service->SetInteger(kKey, 3); 268 pref_service->SetInteger(kKey, 3);
265 EXPECT_EQ(2, pref_service->GetInteger(kKey)); 269 EXPECT_EQ(2, pref_service->GetInteger(kKey));
266 } 270 }
267 271
272 void Fail(PrefService* pref_service) {
273 FAIL() << "Unexpected change notification: "
274 << *pref_service->GetDictionary(kDictionaryKey);
275 }
276
277 TEST_F(PrefServiceFactoryTest, MultipleClients_SubPrefUpdates_Basic) {
278 auto pref_service = Create();
279 auto pref_service2 = Create();
280
281 void (*updates[])(ScopedDictionaryPrefUpdate*) = {
282 [](ScopedDictionaryPrefUpdate* update) {
283 (*update)->SetInteger("path.to.integer", 1);
284 int out = 0;
285 ASSERT_TRUE((*update)->GetInteger("path.to.integer", &out));
286 EXPECT_EQ(1, out);
287 },
288 [](ScopedDictionaryPrefUpdate* update) {
289 (*update)->SetIntegerWithoutPathExpansion("key.for.integer", 2);
290 int out = 0;
291 ASSERT_TRUE(
292 (*update)->GetIntegerWithoutPathExpansion("key.for.integer", &out));
293 EXPECT_EQ(2, out);
294 },
295 [](ScopedDictionaryPrefUpdate* update) {
296 (*update)->SetDouble("path.to.double", 3);
297 double out = 0;
298 ASSERT_TRUE((*update)->GetDouble("path.to.double", &out));
299 EXPECT_EQ(3, out);
300 },
301 [](ScopedDictionaryPrefUpdate* update) {
302 (*update)->SetDoubleWithoutPathExpansion("key.for.double", 4);
303 double out = 0;
304 ASSERT_TRUE(
305 (*update)->GetDoubleWithoutPathExpansion("key.for.double", &out));
306 EXPECT_EQ(4, out);
307 },
308 [](ScopedDictionaryPrefUpdate* update) {
309 (*update)->SetBoolean("path.to.boolean", true);
310 bool out = 0;
311 ASSERT_TRUE((*update)->GetBoolean("path.to.boolean", &out));
312 EXPECT_TRUE(out);
313 },
314 [](ScopedDictionaryPrefUpdate* update) {
315 (*update)->SetBooleanWithoutPathExpansion("key.for.boolean", false);
316 bool out = 0;
317 ASSERT_TRUE(
318 (*update)->GetBooleanWithoutPathExpansion("key.for.boolean", &out));
319 EXPECT_FALSE(out);
320 },
321 [](ScopedDictionaryPrefUpdate* update) {
322 (*update)->SetString("path.to.string", "hello");
323 std::string out;
324 ASSERT_TRUE((*update)->GetString("path.to.string", &out));
325 EXPECT_EQ("hello", out);
326 },
327 [](ScopedDictionaryPrefUpdate* update) {
328 (*update)->SetStringWithoutPathExpansion("key.for.string", "prefs!");
329 std::string out;
330 ASSERT_TRUE(
331 (*update)->GetStringWithoutPathExpansion("key.for.string", &out));
332 EXPECT_EQ("prefs!", out);
333 },
334 [](ScopedDictionaryPrefUpdate* update) {
335 (*update)->SetString("path.to.string", base::ASCIIToUTF16("hello"));
336 base::string16 out;
337 ASSERT_TRUE((*update)->GetString("path.to.string", &out));
338 EXPECT_EQ(base::ASCIIToUTF16("hello"), out);
339 },
340 [](ScopedDictionaryPrefUpdate* update) {
341 (*update)->SetStringWithoutPathExpansion("key.for.string16",
342 base::ASCIIToUTF16("prefs!"));
343 base::string16 out;
344 ASSERT_TRUE(
345 (*update)->GetStringWithoutPathExpansion("key.for.string16", &out));
346 EXPECT_EQ(base::ASCIIToUTF16("prefs!"), out);
347 },
348 [](ScopedDictionaryPrefUpdate* update) {
349 base::Value buffer(std::vector<char>{1, 2, 3, 4, 5});
350 (*update)->Set("path.to.binary", base::MakeUnique<base::Value>(buffer));
351 const base::Value* out;
352 ASSERT_TRUE((*update)->GetBinary("path.to.binary", &out));
353 EXPECT_EQ(buffer, *out);
354 },
355 [](ScopedDictionaryPrefUpdate* update) {
356 base::ListValue list;
357 list.AppendInteger(1);
358 list.AppendDouble(2);
359 list.AppendBoolean(true);
360 list.AppendString("four");
361 (*update)->Set("path.to.list", list.CreateDeepCopy());
362 const base::ListValue* out = nullptr;
363 ASSERT_TRUE((*update)->GetList("path.to.list", &out));
364 EXPECT_EQ(list, *out);
365 },
366 [](ScopedDictionaryPrefUpdate* update) {
367 base::ListValue list;
368 list.AppendInteger(1);
369 list.AppendDouble(2);
370 list.AppendBoolean(true);
371 list.AppendString("four");
372 (*update)->SetWithoutPathExpansion("key.for.list",
373 list.CreateDeepCopy());
374 const base::ListValue* out = nullptr;
375 ASSERT_TRUE(
376 (*update)->GetListWithoutPathExpansion("key.for.list", &out));
377 EXPECT_EQ(list, *out);
378 },
379 [](ScopedDictionaryPrefUpdate* update) {
380 base::DictionaryValue dict;
381 dict.SetInteger("int", 1);
382 dict.SetDouble("double", 2);
383 dict.SetBoolean("bool", true);
384 dict.SetString("string", "four");
385 (*update)->Set("path.to.dict", dict.CreateDeepCopy());
386 const base::DictionaryValue* out = nullptr;
387 ASSERT_TRUE((*update)->GetDictionary("path.to.dict", &out));
388 EXPECT_EQ(dict, *out);
389 },
390 [](ScopedDictionaryPrefUpdate* update) {
391 base::DictionaryValue dict;
392 dict.SetInteger("int", 1);
393 dict.SetDouble("double", 2);
394 dict.SetBoolean("bool", true);
395 dict.SetString("string", "four");
396 (*update)->SetWithoutPathExpansion("key.for.dict",
397 dict.CreateDeepCopy());
398 const base::DictionaryValue* out = nullptr;
399 ASSERT_TRUE(
400 (*update)->GetDictionaryWithoutPathExpansion("key.for.dict", &out));
401 EXPECT_EQ(dict, *out);
402 },
403 };
404 int current_value = kInitialValue + 1;
405 for (auto& mutation : updates) {
406 base::DictionaryValue expected_value;
407 {
408 ScopedDictionaryPrefUpdate update(pref_service.get(), kDictionaryKey);
409 EXPECT_EQ(update->AsConstDictionary()->empty(), update->empty());
410 EXPECT_EQ(update->AsConstDictionary()->size(), update->size());
411 mutation(&update);
412 EXPECT_EQ(update->AsConstDictionary()->empty(), update->empty());
413 EXPECT_EQ(update->AsConstDictionary()->size(), update->size());
414 expected_value = *update->AsConstDictionary();
415 }
416
417 EXPECT_EQ(expected_value, *pref_service->GetDictionary(kDictionaryKey));
418 WaitForPrefChange(pref_service2.get(), kDictionaryKey);
419 EXPECT_EQ(expected_value, *pref_service2->GetDictionary(kDictionaryKey));
420
421 {
422 ScopedDictionaryPrefUpdate update(pref_service.get(), kDictionaryKey);
423 mutation(&update);
424 EXPECT_EQ(expected_value, *update->AsConstDictionary());
425 }
426 {
427 PrefChangeRegistrar registrar;
428 registrar.Init(pref_service2.get());
429 registrar.Add(kDictionaryKey, base::Bind(&Fail, pref_service2.get()));
430 pref_service->SetInteger(kKey, ++current_value);
431 WaitForPrefChange(pref_service2.get(), kKey);
432 }
433 if (!pref_service->GetDictionary(kDictionaryKey)->empty()) {
434 {
435 ScopedDictionaryPrefUpdate update(pref_service.get(), kDictionaryKey);
436 update->Clear();
437 }
438 WaitForPrefChange(pref_service2.get(), kDictionaryKey);
439 }
440 }
441 }
442
443 TEST_F(PrefServiceFactoryTest, MultipleClients_SubPrefUpdates_Erase) {
444 auto pref_service = Create();
445 auto pref_service2 = Create();
446 {
447 ScopedDictionaryPrefUpdate update(pref_service.get(), kDictionaryKey);
448 update->SetInteger("path.to.integer", 1);
449 }
450 WaitForPrefChange(pref_service2.get(), kDictionaryKey);
451
452 {
453 ScopedDictionaryPrefUpdate update(pref_service.get(), kDictionaryKey);
454 ASSERT_TRUE(update->RemovePath("path.to.integer", nullptr));
455 }
456 WaitForPrefChange(pref_service2.get(), kDictionaryKey);
457 EXPECT_TRUE(pref_service2->GetDictionary(kDictionaryKey)->empty());
458 }
459
460 TEST_F(PrefServiceFactoryTest, MultipleClients_SubPrefUpdates_ClearDictionary) {
461 auto pref_service = Create();
462 auto pref_service2 = Create();
463
464 { ScopedDictionaryPrefUpdate update(pref_service.get(), kDictionaryKey); }
465 WaitForPrefChange(pref_service2.get(), kDictionaryKey);
466
467 {
468 ScopedDictionaryPrefUpdate update(pref_service.get(), kDictionaryKey);
469 update->Clear();
470 }
471 PrefChangeRegistrar registrar;
472 registrar.Init(pref_service2.get());
473 registrar.Add(kDictionaryKey, base::Bind(&Fail, pref_service2.get()));
474 pref_service->SetInteger(kKey, kUpdatedValue);
475 WaitForPrefChange(pref_service2.get(), kKey);
476 }
477
268 } // namespace 478 } // namespace
269 } // namespace prefs 479 } // namespace prefs
OLDNEW
« no previous file with comments | « services/preferences/persistent_pref_store_impl.cc ('k') | services/preferences/public/cpp/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698