[Cleanup] Used scoped pointers in KeyedServiceFactory's SetTestingFactory functions.
[chromium-blink-merge.git] / chrome / browser / extensions / api / storage / settings_sync_unittest.cc
blobc0f7656d50030883222d3a7a4467cfaab9f1d217
1 // Copyright (c) 2012 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.
5 #include "base/bind.h"
6 #include "base/files/scoped_temp_dir.h"
7 #include "base/json/json_reader.h"
8 #include "base/json/json_writer.h"
9 #include "base/memory/linked_ptr.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/strings/stringprintf.h"
13 #include "chrome/browser/extensions/api/storage/settings_sync_util.h"
14 #include "chrome/browser/extensions/api/storage/sync_value_store_cache.h"
15 #include "chrome/browser/extensions/api/storage/syncable_settings_storage.h"
16 #include "chrome/test/base/testing_profile.h"
17 #include "content/public/test/test_browser_thread.h"
18 #include "extensions/browser/api/storage/leveldb_settings_storage_factory.h"
19 #include "extensions/browser/api/storage/settings_storage_factory.h"
20 #include "extensions/browser/api/storage/settings_test_util.h"
21 #include "extensions/browser/api/storage/storage_frontend.h"
22 #include "extensions/browser/event_router.h"
23 #include "extensions/browser/event_router_factory.h"
24 #include "extensions/browser/extension_system.h"
25 #include "extensions/browser/mock_extension_system.h"
26 #include "extensions/browser/value_store/testing_value_store.h"
27 #include "extensions/common/manifest.h"
28 #include "sync/api/sync_change_processor.h"
29 #include "sync/api/sync_change_processor_wrapper_for_test.h"
30 #include "sync/api/sync_error_factory.h"
31 #include "sync/api/sync_error_factory_mock.h"
32 #include "testing/gtest/include/gtest/gtest.h"
34 using base::DictionaryValue;
35 using base::ListValue;
36 using base::Value;
37 using content::BrowserThread;
39 namespace extensions {
41 namespace util = settings_test_util;
43 namespace {
45 // To save typing ValueStore::DEFAULTS everywhere.
46 const ValueStore::WriteOptions DEFAULTS = ValueStore::DEFAULTS;
48 // More saving typing. Maps extension IDs to a list of sync changes for that
49 // extension.
50 using SettingSyncDataMultimap =
51 std::map<std::string, linked_ptr<SettingSyncDataList>>;
53 // Gets the pretty-printed JSON for a value.
54 static std::string GetJson(const base::Value& value) {
55 std::string json;
56 base::JSONWriter::WriteWithOptions(
57 value, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json);
58 return json;
61 // Returns whether two Values are equal.
62 testing::AssertionResult ValuesEq(
63 const char* _1, const char* _2,
64 const base::Value* expected,
65 const base::Value* actual) {
66 if (expected == actual) {
67 return testing::AssertionSuccess();
69 if (!expected && actual) {
70 return testing::AssertionFailure() <<
71 "Expected NULL, actual: " << GetJson(*actual);
73 if (expected && !actual) {
74 return testing::AssertionFailure() <<
75 "Expected: " << GetJson(*expected) << ", actual NULL";
77 if (!expected->Equals(actual)) {
78 return testing::AssertionFailure() <<
79 "Expected: " << GetJson(*expected) << ", actual: " << GetJson(*actual);
81 return testing::AssertionSuccess();
84 // Returns whether the result of a storage operation is an expected value.
85 // Logs when different.
86 testing::AssertionResult SettingsEq(
87 const char* _1, const char* _2,
88 const base::DictionaryValue& expected,
89 ValueStore::ReadResult actual) {
90 if (actual->HasError()) {
91 return testing::AssertionFailure() <<
92 "Expected: " << expected <<
93 ", actual has error: " << actual->error().message;
95 return ValuesEq(_1, _2, &expected, &actual->settings());
98 // SyncChangeProcessor which just records the changes made, accessed after
99 // being converted to the more useful SettingSyncData via changes().
100 class MockSyncChangeProcessor : public syncer::SyncChangeProcessor {
101 public:
102 MockSyncChangeProcessor() : fail_all_requests_(false) {}
104 // syncer::SyncChangeProcessor implementation.
105 syncer::SyncError ProcessSyncChanges(
106 const tracked_objects::Location& from_here,
107 const syncer::SyncChangeList& change_list) override {
108 if (fail_all_requests_) {
109 return syncer::SyncError(
110 FROM_HERE,
111 syncer::SyncError::DATATYPE_ERROR,
112 "MockSyncChangeProcessor: configured to fail",
113 change_list[0].sync_data().GetDataType());
115 for (syncer::SyncChangeList::const_iterator it = change_list.begin();
116 it != change_list.end(); ++it) {
117 changes_.push_back(new SettingSyncData(*it));
119 return syncer::SyncError();
122 syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override {
123 return syncer::SyncDataList();
126 // Mock methods.
128 const SettingSyncDataList& changes() { return changes_; }
130 void ClearChanges() {
131 changes_.clear();
134 void set_fail_all_requests(bool fail_all_requests) {
135 fail_all_requests_ = fail_all_requests;
138 // Returns the only change for a given extension setting. If there is not
139 // exactly 1 change for that key, a test assertion will fail.
140 SettingSyncData* GetOnlyChange(const std::string& extension_id,
141 const std::string& key) {
142 std::vector<SettingSyncData*> matching_changes;
143 for (SettingSyncDataList::iterator it = changes_.begin();
144 it != changes_.end(); ++it) {
145 if ((*it)->extension_id() == extension_id && (*it)->key() == key) {
146 matching_changes.push_back(*it);
149 if (matching_changes.empty()) {
150 ADD_FAILURE() << "No matching changes for " << extension_id << "/" <<
151 key << " (out of " << changes_.size() << ")";
152 return nullptr;
154 if (matching_changes.size() != 1u) {
155 ADD_FAILURE() << matching_changes.size() << " matching changes for " <<
156 extension_id << "/" << key << " (out of " << changes_.size() << ")";
158 return matching_changes[0];
161 private:
162 SettingSyncDataList changes_;
163 bool fail_all_requests_;
166 // SettingsStorageFactory which always returns TestingValueStore objects,
167 // and allows individually created objects to be returned.
168 class TestingValueStoreFactory : public SettingsStorageFactory {
169 public:
170 TestingValueStore* GetExisting(const std::string& extension_id) {
171 DCHECK(created_.count(extension_id));
172 return created_[extension_id];
175 // SettingsStorageFactory implementation.
176 ValueStore* Create(const base::FilePath& base_path,
177 const std::string& extension_id) override {
178 TestingValueStore* new_storage = new TestingValueStore();
179 DCHECK(!created_.count(extension_id));
180 created_[extension_id] = new_storage;
181 return new_storage;
184 // Testing value stores don't actually create a real database. Don't delete
185 // any files.
186 void DeleteDatabaseIfExists(const base::FilePath& base_path,
187 const std::string& extension_id) override {}
189 private:
190 // SettingsStorageFactory is refcounted.
191 ~TestingValueStoreFactory() override {}
193 // None of these storage areas are owned by this factory, so care must be
194 // taken when calling GetExisting.
195 std::map<std::string, TestingValueStore*> created_;
198 scoped_ptr<KeyedService> MockExtensionSystemFactoryFunction(
199 content::BrowserContext* context) {
200 return make_scoped_ptr(new MockExtensionSystem(context));
203 scoped_ptr<KeyedService> BuildEventRouter(content::BrowserContext* profile) {
204 return make_scoped_ptr(new extensions::EventRouter(profile, nullptr));
207 } // namespace
209 class ExtensionSettingsSyncTest : public testing::Test {
210 public:
211 ExtensionSettingsSyncTest()
212 : ui_thread_(BrowserThread::UI, base::MessageLoop::current()),
213 file_thread_(BrowserThread::FILE, base::MessageLoop::current()),
214 storage_factory_(new util::ScopedSettingsStorageFactory()),
215 sync_processor_(new MockSyncChangeProcessor),
216 sync_processor_wrapper_(new syncer::SyncChangeProcessorWrapperForTest(
217 sync_processor_.get())) {}
219 void SetUp() override {
220 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
221 profile_.reset(new TestingProfile(temp_dir_.path()));
222 storage_factory_->Reset(new LeveldbSettingsStorageFactory());
223 frontend_ = StorageFrontend::CreateForTesting(storage_factory_,
224 profile_.get()).Pass();
226 ExtensionsBrowserClient::Get()
227 ->GetExtensionSystemFactory()
228 ->SetTestingFactoryAndUse(profile_.get(),
229 &MockExtensionSystemFactoryFunction);
231 EventRouterFactory::GetInstance()->SetTestingFactory(profile_.get(),
232 &BuildEventRouter);
235 void TearDown() override {
236 frontend_.reset();
237 profile_.reset();
238 // Execute any pending deletion tasks.
239 message_loop_.RunUntilIdle();
242 protected:
243 // Adds a record of an extension or app to the extension service, then returns
244 // its storage area.
245 ValueStore* AddExtensionAndGetStorage(
246 const std::string& id, Manifest::Type type) {
247 scoped_refptr<const Extension> extension =
248 util::AddExtensionWithId(profile_.get(), id, type);
249 return util::GetStorage(extension, frontend_.get());
252 // Gets the syncer::SyncableService for the given sync type.
253 syncer::SyncableService* GetSyncableService(syncer::ModelType model_type) {
254 base::MessageLoop::current()->RunUntilIdle();
255 SyncValueStoreCache* sync_cache = static_cast<SyncValueStoreCache*>(
256 frontend_->GetValueStoreCache(settings_namespace::SYNC));
257 return sync_cache->GetSyncableService(model_type);
260 // Gets all the sync data from the SyncableService for a sync type as a map
261 // from extension id to its sync data.
262 SettingSyncDataMultimap GetAllSyncData(syncer::ModelType model_type) {
263 syncer::SyncDataList as_list =
264 GetSyncableService(model_type)->GetAllSyncData(model_type);
265 SettingSyncDataMultimap as_map;
266 for (syncer::SyncDataList::iterator it = as_list.begin();
267 it != as_list.end(); ++it) {
268 SettingSyncData* sync_data = new SettingSyncData(*it);
269 linked_ptr<SettingSyncDataList>& list_for_extension =
270 as_map[sync_data->extension_id()];
271 if (!list_for_extension.get())
272 list_for_extension.reset(new SettingSyncDataList());
273 list_for_extension->push_back(sync_data);
275 return as_map;
278 // Need these so that the DCHECKs for running on FILE or UI threads pass.
279 base::MessageLoop message_loop_;
280 content::TestBrowserThread ui_thread_;
281 content::TestBrowserThread file_thread_;
283 base::ScopedTempDir temp_dir_;
284 scoped_ptr<TestingProfile> profile_;
285 scoped_ptr<StorageFrontend> frontend_;
286 scoped_refptr<util::ScopedSettingsStorageFactory> storage_factory_;
287 scoped_ptr<MockSyncChangeProcessor> sync_processor_;
288 scoped_ptr<syncer::SyncChangeProcessorWrapperForTest> sync_processor_wrapper_;
291 // Get a semblance of coverage for both EXTENSION_SETTINGS and APP_SETTINGS
292 // sync by roughly alternative which one to test.
294 TEST_F(ExtensionSettingsSyncTest, NoDataDoesNotInvokeSync) {
295 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
296 Manifest::Type type = Manifest::TYPE_EXTENSION;
298 EXPECT_EQ(0u, GetAllSyncData(model_type).size());
300 // Have one extension created before sync is set up, the other created after.
301 AddExtensionAndGetStorage("s1", type);
302 EXPECT_EQ(0u, GetAllSyncData(model_type).size());
304 GetSyncableService(model_type)
305 ->MergeDataAndStartSyncing(
306 model_type,
307 syncer::SyncDataList(),
308 sync_processor_wrapper_.Pass(),
309 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
311 AddExtensionAndGetStorage("s2", type);
312 EXPECT_EQ(0u, GetAllSyncData(model_type).size());
314 GetSyncableService(model_type)->StopSyncing(model_type);
316 EXPECT_EQ(0u, sync_processor_->changes().size());
317 EXPECT_EQ(0u, GetAllSyncData(model_type).size());
320 TEST_F(ExtensionSettingsSyncTest, InSyncDataDoesNotInvokeSync) {
321 syncer::ModelType model_type = syncer::APP_SETTINGS;
322 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
324 base::StringValue value1("fooValue");
325 base::ListValue value2;
326 value2.Append(new base::StringValue("barValue"));
328 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
329 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
331 storage1->Set(DEFAULTS, "foo", value1);
332 storage2->Set(DEFAULTS, "bar", value2);
334 SettingSyncDataMultimap all_sync_data = GetAllSyncData(model_type);
335 EXPECT_EQ(2u, all_sync_data.size());
336 EXPECT_EQ(1u, all_sync_data["s1"]->size());
337 EXPECT_PRED_FORMAT2(ValuesEq, &value1, &(*all_sync_data["s1"])[0]->value());
338 EXPECT_EQ(1u, all_sync_data["s2"]->size());
339 EXPECT_PRED_FORMAT2(ValuesEq, &value2, &(*all_sync_data["s2"])[0]->value());
341 syncer::SyncDataList sync_data;
342 sync_data.push_back(settings_sync_util::CreateData(
343 "s1", "foo", value1, model_type));
344 sync_data.push_back(settings_sync_util::CreateData(
345 "s2", "bar", value2, model_type));
347 GetSyncableService(model_type)
348 ->MergeDataAndStartSyncing(
349 model_type,
350 sync_data,
351 sync_processor_wrapper_.Pass(),
352 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
354 // Already in sync, so no changes.
355 EXPECT_EQ(0u, sync_processor_->changes().size());
357 // Regression test: not-changing the synced value shouldn't result in a sync
358 // change, and changing the synced value should result in an update.
359 storage1->Set(DEFAULTS, "foo", value1);
360 EXPECT_EQ(0u, sync_processor_->changes().size());
362 storage1->Set(DEFAULTS, "foo", value2);
363 EXPECT_EQ(1u, sync_processor_->changes().size());
364 SettingSyncData* change = sync_processor_->GetOnlyChange("s1", "foo");
365 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change->change_type());
366 EXPECT_TRUE(value2.Equals(&change->value()));
368 GetSyncableService(model_type)->StopSyncing(model_type);
371 TEST_F(ExtensionSettingsSyncTest, LocalDataWithNoSyncDataIsPushedToSync) {
372 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
373 Manifest::Type type = Manifest::TYPE_EXTENSION;
375 base::StringValue value1("fooValue");
376 base::ListValue value2;
377 value2.Append(new base::StringValue("barValue"));
379 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
380 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
382 storage1->Set(DEFAULTS, "foo", value1);
383 storage2->Set(DEFAULTS, "bar", value2);
385 GetSyncableService(model_type)
386 ->MergeDataAndStartSyncing(
387 model_type,
388 syncer::SyncDataList(),
389 sync_processor_wrapper_.Pass(),
390 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
392 // All settings should have been pushed to sync.
393 EXPECT_EQ(2u, sync_processor_->changes().size());
394 SettingSyncData* change = sync_processor_->GetOnlyChange("s1", "foo");
395 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change->change_type());
396 EXPECT_TRUE(value1.Equals(&change->value()));
397 change = sync_processor_->GetOnlyChange("s2", "bar");
398 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change->change_type());
399 EXPECT_TRUE(value2.Equals(&change->value()));
401 GetSyncableService(model_type)->StopSyncing(model_type);
404 TEST_F(ExtensionSettingsSyncTest, AnySyncDataOverwritesLocalData) {
405 syncer::ModelType model_type = syncer::APP_SETTINGS;
406 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
408 base::StringValue value1("fooValue");
409 base::ListValue value2;
410 value2.Append(new base::StringValue("barValue"));
412 // Maintain dictionaries mirrored to the expected values of the settings in
413 // each storage area.
414 base::DictionaryValue expected1, expected2;
416 // Pre-populate one of the storage areas.
417 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
418 storage1->Set(DEFAULTS, "overwriteMe", value1);
420 syncer::SyncDataList sync_data;
421 sync_data.push_back(settings_sync_util::CreateData(
422 "s1", "foo", value1, model_type));
423 sync_data.push_back(settings_sync_util::CreateData(
424 "s2", "bar", value2, model_type));
425 GetSyncableService(model_type)
426 ->MergeDataAndStartSyncing(
427 model_type,
428 sync_data,
429 sync_processor_wrapper_.Pass(),
430 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
431 expected1.Set("foo", value1.DeepCopy());
432 expected2.Set("bar", value2.DeepCopy());
434 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
436 // All changes should be local, so no sync changes.
437 EXPECT_EQ(0u, sync_processor_->changes().size());
439 // Sync settings should have been pushed to local settings.
440 EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
441 EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
443 GetSyncableService(model_type)->StopSyncing(model_type);
446 TEST_F(ExtensionSettingsSyncTest, ProcessSyncChanges) {
447 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
448 Manifest::Type type = Manifest::TYPE_EXTENSION;
450 base::StringValue value1("fooValue");
451 base::ListValue value2;
452 value2.Append(new base::StringValue("barValue"));
454 // Maintain dictionaries mirrored to the expected values of the settings in
455 // each storage area.
456 base::DictionaryValue expected1, expected2;
458 // Make storage1 initialised from local data, storage2 initialised from sync.
459 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
460 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
462 storage1->Set(DEFAULTS, "foo", value1);
463 expected1.Set("foo", value1.DeepCopy());
465 syncer::SyncDataList sync_data;
466 sync_data.push_back(settings_sync_util::CreateData(
467 "s2", "bar", value2, model_type));
469 GetSyncableService(model_type)
470 ->MergeDataAndStartSyncing(
471 model_type,
472 sync_data,
473 sync_processor_wrapper_.Pass(),
474 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
475 expected2.Set("bar", value2.DeepCopy());
477 // Make sync add some settings.
478 syncer::SyncChangeList change_list;
479 change_list.push_back(settings_sync_util::CreateAdd(
480 "s1", "bar", value2, model_type));
481 change_list.push_back(settings_sync_util::CreateAdd(
482 "s2", "foo", value1, model_type));
483 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
484 expected1.Set("bar", value2.DeepCopy());
485 expected2.Set("foo", value1.DeepCopy());
487 EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
488 EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
490 // Make sync update some settings, storage1 the new setting, storage2 the
491 // initial setting.
492 change_list.clear();
493 change_list.push_back(settings_sync_util::CreateUpdate(
494 "s1", "bar", value2, model_type));
495 change_list.push_back(settings_sync_util::CreateUpdate(
496 "s2", "bar", value1, model_type));
497 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
498 expected1.Set("bar", value2.DeepCopy());
499 expected2.Set("bar", value1.DeepCopy());
501 EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
502 EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
504 // Make sync remove some settings, storage1 the initial setting, storage2 the
505 // new setting.
506 change_list.clear();
507 change_list.push_back(settings_sync_util::CreateDelete(
508 "s1", "foo", model_type));
509 change_list.push_back(settings_sync_util::CreateDelete(
510 "s2", "foo", model_type));
511 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
512 expected1.Remove("foo", NULL);
513 expected2.Remove("foo", NULL);
515 EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
516 EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
518 GetSyncableService(model_type)->StopSyncing(model_type);
521 TEST_F(ExtensionSettingsSyncTest, PushToSync) {
522 syncer::ModelType model_type = syncer::APP_SETTINGS;
523 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
525 base::StringValue value1("fooValue");
526 base::ListValue value2;
527 value2.Append(new base::StringValue("barValue"));
529 // Make storage1/2 initialised from local data, storage3/4 initialised from
530 // sync.
531 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
532 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
533 ValueStore* storage3 = AddExtensionAndGetStorage("s3", type);
534 ValueStore* storage4 = AddExtensionAndGetStorage("s4", type);
536 storage1->Set(DEFAULTS, "foo", value1);
537 storage2->Set(DEFAULTS, "foo", value1);
539 syncer::SyncDataList sync_data;
540 sync_data.push_back(settings_sync_util::CreateData(
541 "s3", "bar", value2, model_type));
542 sync_data.push_back(settings_sync_util::CreateData(
543 "s4", "bar", value2, model_type));
545 GetSyncableService(model_type)
546 ->MergeDataAndStartSyncing(
547 model_type,
548 sync_data,
549 sync_processor_wrapper_.Pass(),
550 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
552 // Add something locally.
553 storage1->Set(DEFAULTS, "bar", value2);
554 storage2->Set(DEFAULTS, "bar", value2);
555 storage3->Set(DEFAULTS, "foo", value1);
556 storage4->Set(DEFAULTS, "foo", value1);
558 SettingSyncData* change = sync_processor_->GetOnlyChange("s1", "bar");
559 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change->change_type());
560 EXPECT_TRUE(value2.Equals(&change->value()));
561 sync_processor_->GetOnlyChange("s2", "bar");
562 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change->change_type());
563 EXPECT_TRUE(value2.Equals(&change->value()));
564 change = sync_processor_->GetOnlyChange("s3", "foo");
565 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change->change_type());
566 EXPECT_TRUE(value1.Equals(&change->value()));
567 change = sync_processor_->GetOnlyChange("s4", "foo");
568 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change->change_type());
569 EXPECT_TRUE(value1.Equals(&change->value()));
571 // Change something locally, storage1/3 the new setting and storage2/4 the
572 // initial setting, for all combinations of local vs sync intialisation and
573 // new vs initial.
574 sync_processor_->ClearChanges();
575 storage1->Set(DEFAULTS, "bar", value1);
576 storage2->Set(DEFAULTS, "foo", value2);
577 storage3->Set(DEFAULTS, "bar", value1);
578 storage4->Set(DEFAULTS, "foo", value2);
580 change = sync_processor_->GetOnlyChange("s1", "bar");
581 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change->change_type());
582 EXPECT_TRUE(value1.Equals(&change->value()));
583 change = sync_processor_->GetOnlyChange("s2", "foo");
584 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change->change_type());
585 EXPECT_TRUE(value2.Equals(&change->value()));
586 change = sync_processor_->GetOnlyChange("s3", "bar");
587 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change->change_type());
588 EXPECT_TRUE(value1.Equals(&change->value()));
589 change = sync_processor_->GetOnlyChange("s4", "foo");
590 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change->change_type());
591 EXPECT_TRUE(value2.Equals(&change->value()));
593 // Remove something locally, storage1/3 the new setting and storage2/4 the
594 // initial setting, for all combinations of local vs sync intialisation and
595 // new vs initial.
596 sync_processor_->ClearChanges();
597 storage1->Remove("foo");
598 storage2->Remove("bar");
599 storage3->Remove("foo");
600 storage4->Remove("bar");
602 EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
603 sync_processor_->GetOnlyChange("s1", "foo")->change_type());
604 EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
605 sync_processor_->GetOnlyChange("s2", "bar")->change_type());
606 EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
607 sync_processor_->GetOnlyChange("s3", "foo")->change_type());
608 EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
609 sync_processor_->GetOnlyChange("s4", "bar")->change_type());
611 // Remove some nonexistent settings.
612 sync_processor_->ClearChanges();
613 storage1->Remove("foo");
614 storage2->Remove("bar");
615 storage3->Remove("foo");
616 storage4->Remove("bar");
618 EXPECT_EQ(0u, sync_processor_->changes().size());
620 // Clear the rest of the settings. Add the removed ones back first so that
621 // more than one setting is cleared.
622 storage1->Set(DEFAULTS, "foo", value1);
623 storage2->Set(DEFAULTS, "bar", value2);
624 storage3->Set(DEFAULTS, "foo", value1);
625 storage4->Set(DEFAULTS, "bar", value2);
627 sync_processor_->ClearChanges();
628 storage1->Clear();
629 storage2->Clear();
630 storage3->Clear();
631 storage4->Clear();
633 EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
634 sync_processor_->GetOnlyChange("s1", "foo")->change_type());
635 EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
636 sync_processor_->GetOnlyChange("s1", "bar")->change_type());
637 EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
638 sync_processor_->GetOnlyChange("s2", "foo")->change_type());
639 EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
640 sync_processor_->GetOnlyChange("s2", "bar")->change_type());
641 EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
642 sync_processor_->GetOnlyChange("s3", "foo")->change_type());
643 EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
644 sync_processor_->GetOnlyChange("s3", "bar")->change_type());
645 EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
646 sync_processor_->GetOnlyChange("s4", "foo")->change_type());
647 EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
648 sync_processor_->GetOnlyChange("s4", "bar")->change_type());
650 GetSyncableService(model_type)->StopSyncing(model_type);
653 TEST_F(ExtensionSettingsSyncTest, ExtensionAndAppSettingsSyncSeparately) {
654 base::StringValue value1("fooValue");
655 base::ListValue value2;
656 value2.Append(new base::StringValue("barValue"));
658 // storage1 is an extension, storage2 is an app.
659 ValueStore* storage1 = AddExtensionAndGetStorage(
660 "s1", Manifest::TYPE_EXTENSION);
661 ValueStore* storage2 = AddExtensionAndGetStorage(
662 "s2", Manifest::TYPE_LEGACY_PACKAGED_APP);
664 storage1->Set(DEFAULTS, "foo", value1);
665 storage2->Set(DEFAULTS, "bar", value2);
667 SettingSyncDataMultimap extension_sync_data =
668 GetAllSyncData(syncer::EXTENSION_SETTINGS);
669 EXPECT_EQ(1u, extension_sync_data.size());
670 EXPECT_EQ(1u, extension_sync_data["s1"]->size());
671 EXPECT_PRED_FORMAT2(ValuesEq, &value1,
672 &(*extension_sync_data["s1"])[0]->value());
674 SettingSyncDataMultimap app_sync_data = GetAllSyncData(syncer::APP_SETTINGS);
675 EXPECT_EQ(1u, app_sync_data.size());
676 EXPECT_EQ(1u, app_sync_data["s2"]->size());
677 EXPECT_PRED_FORMAT2(ValuesEq, &value2, &(*app_sync_data["s2"])[0]->value());
679 // Stop each separately, there should be no changes either time.
680 syncer::SyncDataList sync_data;
681 sync_data.push_back(settings_sync_util::CreateData(
682 "s1", "foo", value1, syncer::EXTENSION_SETTINGS));
684 GetSyncableService(syncer::EXTENSION_SETTINGS)
685 ->MergeDataAndStartSyncing(
686 syncer::EXTENSION_SETTINGS,
687 sync_data,
688 sync_processor_wrapper_.Pass(),
689 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
690 GetSyncableService(syncer::EXTENSION_SETTINGS)->
691 StopSyncing(syncer::EXTENSION_SETTINGS);
692 EXPECT_EQ(0u, sync_processor_->changes().size());
694 sync_data.clear();
695 sync_data.push_back(settings_sync_util::CreateData(
696 "s2", "bar", value2, syncer::APP_SETTINGS));
698 scoped_ptr<syncer::SyncChangeProcessorWrapperForTest> app_settings_delegate_(
699 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
700 GetSyncableService(syncer::APP_SETTINGS)
701 ->MergeDataAndStartSyncing(
702 syncer::APP_SETTINGS,
703 sync_data,
704 app_settings_delegate_.Pass(),
705 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
706 GetSyncableService(syncer::APP_SETTINGS)->
707 StopSyncing(syncer::APP_SETTINGS);
708 EXPECT_EQ(0u, sync_processor_->changes().size());
711 TEST_F(ExtensionSettingsSyncTest, FailingStartSyncingDisablesSync) {
712 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
713 Manifest::Type type = Manifest::TYPE_EXTENSION;
715 base::StringValue fooValue("fooValue");
716 base::StringValue barValue("barValue");
718 // There is a bit of a convoluted method to get storage areas that can fail;
719 // hand out TestingValueStore object then toggle them failing/succeeding
720 // as necessary.
721 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
722 storage_factory_->Reset(testing_factory);
724 ValueStore* good = AddExtensionAndGetStorage("good", type);
725 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
727 // Make bad fail for incoming sync changes.
728 testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
730 syncer::SyncDataList sync_data;
731 sync_data.push_back(settings_sync_util::CreateData(
732 "good", "foo", fooValue, model_type));
733 sync_data.push_back(settings_sync_util::CreateData(
734 "bad", "foo", fooValue, model_type));
735 GetSyncableService(model_type)
736 ->MergeDataAndStartSyncing(
737 model_type,
738 sync_data,
739 sync_processor_wrapper_.Pass(),
740 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
742 testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
745 base::DictionaryValue dict;
746 dict.Set("foo", fooValue.DeepCopy());
747 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
750 base::DictionaryValue dict;
751 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
754 // Changes made to good should be sent to sync, changes from bad shouldn't.
755 sync_processor_->ClearChanges();
756 good->Set(DEFAULTS, "bar", barValue);
757 bad->Set(DEFAULTS, "bar", barValue);
759 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
760 sync_processor_->GetOnlyChange("good", "bar")->change_type());
761 EXPECT_EQ(1u, sync_processor_->changes().size());
764 base::DictionaryValue dict;
765 dict.Set("foo", fooValue.DeepCopy());
766 dict.Set("bar", barValue.DeepCopy());
767 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
770 base::DictionaryValue dict;
771 dict.Set("bar", barValue.DeepCopy());
772 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
775 // Changes received from sync should go to good but not bad (even when it's
776 // not failing).
778 syncer::SyncChangeList change_list;
779 change_list.push_back(settings_sync_util::CreateUpdate(
780 "good", "foo", barValue, model_type));
781 // (Sending UPDATE here even though it's adding, since that's what the state
782 // of sync is. In any case, it won't work.)
783 change_list.push_back(settings_sync_util::CreateUpdate(
784 "bad", "foo", barValue, model_type));
785 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
789 base::DictionaryValue dict;
790 dict.Set("foo", barValue.DeepCopy());
791 dict.Set("bar", barValue.DeepCopy());
792 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
795 base::DictionaryValue dict;
796 dict.Set("bar", barValue.DeepCopy());
797 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
800 // Changes made to bad still shouldn't go to sync, even though it didn't fail
801 // last time.
802 sync_processor_->ClearChanges();
803 good->Set(DEFAULTS, "bar", fooValue);
804 bad->Set(DEFAULTS, "bar", fooValue);
806 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
807 sync_processor_->GetOnlyChange("good", "bar")->change_type());
808 EXPECT_EQ(1u, sync_processor_->changes().size());
811 base::DictionaryValue dict;
812 dict.Set("foo", barValue.DeepCopy());
813 dict.Set("bar", fooValue.DeepCopy());
814 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
817 base::DictionaryValue dict;
818 dict.Set("bar", fooValue.DeepCopy());
819 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
822 // Failing ProcessSyncChanges shouldn't go to the storage.
823 testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
825 syncer::SyncChangeList change_list;
826 change_list.push_back(settings_sync_util::CreateUpdate(
827 "good", "foo", fooValue, model_type));
828 // (Ditto.)
829 change_list.push_back(settings_sync_util::CreateUpdate(
830 "bad", "foo", fooValue, model_type));
831 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
833 testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
836 base::DictionaryValue dict;
837 dict.Set("foo", fooValue.DeepCopy());
838 dict.Set("bar", fooValue.DeepCopy());
839 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
842 base::DictionaryValue dict;
843 dict.Set("bar", fooValue.DeepCopy());
844 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
847 // Restarting sync should make bad start syncing again.
848 sync_processor_->ClearChanges();
849 GetSyncableService(model_type)->StopSyncing(model_type);
850 sync_processor_wrapper_.reset(
851 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
852 GetSyncableService(model_type)
853 ->MergeDataAndStartSyncing(
854 model_type,
855 syncer::SyncDataList(),
856 sync_processor_wrapper_.Pass(),
857 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
859 // Local settings will have been pushed to sync, since it's empty (in this
860 // test; presumably it wouldn't be live, since we've been getting changes).
861 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
862 sync_processor_->GetOnlyChange("good", "foo")->change_type());
863 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
864 sync_processor_->GetOnlyChange("good", "bar")->change_type());
865 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
866 sync_processor_->GetOnlyChange("bad", "bar")->change_type());
867 EXPECT_EQ(3u, sync_processor_->changes().size());
869 // Live local changes now get pushed, too.
870 sync_processor_->ClearChanges();
871 good->Set(DEFAULTS, "bar", barValue);
872 bad->Set(DEFAULTS, "bar", barValue);
874 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
875 sync_processor_->GetOnlyChange("good", "bar")->change_type());
876 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
877 sync_processor_->GetOnlyChange("bad", "bar")->change_type());
878 EXPECT_EQ(2u, sync_processor_->changes().size());
880 // And ProcessSyncChanges work, too.
882 syncer::SyncChangeList change_list;
883 change_list.push_back(settings_sync_util::CreateUpdate(
884 "good", "bar", fooValue, model_type));
885 change_list.push_back(settings_sync_util::CreateUpdate(
886 "bad", "bar", fooValue, model_type));
887 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
891 base::DictionaryValue dict;
892 dict.Set("foo", fooValue.DeepCopy());
893 dict.Set("bar", fooValue.DeepCopy());
894 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
897 base::DictionaryValue dict;
898 dict.Set("bar", fooValue.DeepCopy());
899 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
903 TEST_F(ExtensionSettingsSyncTest, FailingProcessChangesDisablesSync) {
904 // The test above tests a failing ProcessSyncChanges too, but here test with
905 // an initially passing MergeDataAndStartSyncing.
906 syncer::ModelType model_type = syncer::APP_SETTINGS;
907 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
909 base::StringValue fooValue("fooValue");
910 base::StringValue barValue("barValue");
912 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
913 storage_factory_->Reset(testing_factory);
915 ValueStore* good = AddExtensionAndGetStorage("good", type);
916 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
918 // Unlike before, initially succeeding MergeDataAndStartSyncing.
920 syncer::SyncDataList sync_data;
921 sync_data.push_back(settings_sync_util::CreateData(
922 "good", "foo", fooValue, model_type));
923 sync_data.push_back(settings_sync_util::CreateData(
924 "bad", "foo", fooValue, model_type));
925 GetSyncableService(model_type)
926 ->MergeDataAndStartSyncing(
927 model_type,
928 sync_data,
929 sync_processor_wrapper_.Pass(),
930 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
933 EXPECT_EQ(0u, sync_processor_->changes().size());
936 base::DictionaryValue dict;
937 dict.Set("foo", fooValue.DeepCopy());
938 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
941 base::DictionaryValue dict;
942 dict.Set("foo", fooValue.DeepCopy());
943 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
946 // Now fail ProcessSyncChanges for bad.
947 testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
949 syncer::SyncChangeList change_list;
950 change_list.push_back(settings_sync_util::CreateAdd(
951 "good", "bar", barValue, model_type));
952 change_list.push_back(settings_sync_util::CreateAdd(
953 "bad", "bar", barValue, model_type));
954 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
956 testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
959 base::DictionaryValue dict;
960 dict.Set("foo", fooValue.DeepCopy());
961 dict.Set("bar", barValue.DeepCopy());
962 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
965 base::DictionaryValue dict;
966 dict.Set("foo", fooValue.DeepCopy());
967 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
970 // No more changes sent to sync for bad.
971 sync_processor_->ClearChanges();
972 good->Set(DEFAULTS, "foo", barValue);
973 bad->Set(DEFAULTS, "foo", barValue);
975 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
976 sync_processor_->GetOnlyChange("good", "foo")->change_type());
977 EXPECT_EQ(1u, sync_processor_->changes().size());
979 // No more changes received from sync should go to bad.
981 syncer::SyncChangeList change_list;
982 change_list.push_back(settings_sync_util::CreateAdd(
983 "good", "foo", fooValue, model_type));
984 change_list.push_back(settings_sync_util::CreateAdd(
985 "bad", "foo", fooValue, model_type));
986 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
990 base::DictionaryValue dict;
991 dict.Set("foo", fooValue.DeepCopy());
992 dict.Set("bar", barValue.DeepCopy());
993 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
996 base::DictionaryValue dict;
997 dict.Set("foo", barValue.DeepCopy());
998 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
1002 TEST_F(ExtensionSettingsSyncTest, FailingGetAllSyncDataDoesntStopSync) {
1003 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
1004 Manifest::Type type = Manifest::TYPE_EXTENSION;
1006 base::StringValue fooValue("fooValue");
1007 base::StringValue barValue("barValue");
1009 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
1010 storage_factory_->Reset(testing_factory);
1012 ValueStore* good = AddExtensionAndGetStorage("good", type);
1013 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
1015 good->Set(DEFAULTS, "foo", fooValue);
1016 bad->Set(DEFAULTS, "foo", fooValue);
1018 // Even though bad will fail to get all sync data, sync data should still
1019 // include that from good.
1020 testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
1022 syncer::SyncDataList all_sync_data =
1023 GetSyncableService(model_type)->GetAllSyncData(model_type);
1024 EXPECT_EQ(1u, all_sync_data.size());
1025 EXPECT_EQ("good/foo", syncer::SyncDataLocal(all_sync_data[0]).GetTag());
1027 testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
1029 // Sync shouldn't be disabled for good (nor bad -- but this is unimportant).
1030 GetSyncableService(model_type)
1031 ->MergeDataAndStartSyncing(
1032 model_type,
1033 syncer::SyncDataList(),
1034 sync_processor_wrapper_.Pass(),
1035 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1037 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
1038 sync_processor_->GetOnlyChange("good", "foo")->change_type());
1039 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
1040 sync_processor_->GetOnlyChange("bad", "foo")->change_type());
1041 EXPECT_EQ(2u, sync_processor_->changes().size());
1043 sync_processor_->ClearChanges();
1044 good->Set(DEFAULTS, "bar", barValue);
1045 bad->Set(DEFAULTS, "bar", barValue);
1047 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
1048 sync_processor_->GetOnlyChange("good", "bar")->change_type());
1049 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
1050 sync_processor_->GetOnlyChange("bad", "bar")->change_type());
1051 EXPECT_EQ(2u, sync_processor_->changes().size());
1054 TEST_F(ExtensionSettingsSyncTest, FailureToReadChangesToPushDisablesSync) {
1055 syncer::ModelType model_type = syncer::APP_SETTINGS;
1056 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
1058 base::StringValue fooValue("fooValue");
1059 base::StringValue barValue("barValue");
1061 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
1062 storage_factory_->Reset(testing_factory);
1064 ValueStore* good = AddExtensionAndGetStorage("good", type);
1065 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
1067 good->Set(DEFAULTS, "foo", fooValue);
1068 bad->Set(DEFAULTS, "foo", fooValue);
1070 // good will successfully push foo:fooValue to sync, but bad will fail to
1071 // get them so won't.
1072 testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
1073 GetSyncableService(model_type)
1074 ->MergeDataAndStartSyncing(
1075 model_type,
1076 syncer::SyncDataList(),
1077 sync_processor_wrapper_.Pass(),
1078 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1079 testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
1081 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
1082 sync_processor_->GetOnlyChange("good", "foo")->change_type());
1083 EXPECT_EQ(1u, sync_processor_->changes().size());
1085 // bad should now be disabled for sync.
1086 sync_processor_->ClearChanges();
1087 good->Set(DEFAULTS, "bar", barValue);
1088 bad->Set(DEFAULTS, "bar", barValue);
1090 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
1091 sync_processor_->GetOnlyChange("good", "bar")->change_type());
1092 EXPECT_EQ(1u, sync_processor_->changes().size());
1095 syncer::SyncChangeList change_list;
1096 change_list.push_back(settings_sync_util::CreateUpdate(
1097 "good", "foo", barValue, model_type));
1098 // (Sending ADD here even though it's updating, since that's what the state
1099 // of sync is. In any case, it won't work.)
1100 change_list.push_back(settings_sync_util::CreateAdd(
1101 "bad", "foo", barValue, model_type));
1102 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1106 base::DictionaryValue dict;
1107 dict.Set("foo", barValue.DeepCopy());
1108 dict.Set("bar", barValue.DeepCopy());
1109 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
1112 base::DictionaryValue dict;
1113 dict.Set("foo", fooValue.DeepCopy());
1114 dict.Set("bar", barValue.DeepCopy());
1115 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
1118 // Re-enabling sync without failing should cause the local changes from bad
1119 // to be pushed to sync successfully, as should future changes to bad.
1120 sync_processor_->ClearChanges();
1121 GetSyncableService(model_type)->StopSyncing(model_type);
1122 sync_processor_wrapper_.reset(
1123 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
1124 GetSyncableService(model_type)
1125 ->MergeDataAndStartSyncing(
1126 model_type,
1127 syncer::SyncDataList(),
1128 sync_processor_wrapper_.Pass(),
1129 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1131 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
1132 sync_processor_->GetOnlyChange("good", "foo")->change_type());
1133 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
1134 sync_processor_->GetOnlyChange("good", "bar")->change_type());
1135 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
1136 sync_processor_->GetOnlyChange("bad", "foo")->change_type());
1137 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
1138 sync_processor_->GetOnlyChange("bad", "bar")->change_type());
1139 EXPECT_EQ(4u, sync_processor_->changes().size());
1141 sync_processor_->ClearChanges();
1142 good->Set(DEFAULTS, "bar", fooValue);
1143 bad->Set(DEFAULTS, "bar", fooValue);
1145 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
1146 sync_processor_->GetOnlyChange("good", "bar")->change_type());
1147 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
1148 sync_processor_->GetOnlyChange("good", "bar")->change_type());
1149 EXPECT_EQ(2u, sync_processor_->changes().size());
1152 TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalStateDisablesSync) {
1153 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
1154 Manifest::Type type = Manifest::TYPE_EXTENSION;
1156 base::StringValue fooValue("fooValue");
1157 base::StringValue barValue("barValue");
1159 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
1160 storage_factory_->Reset(testing_factory);
1162 ValueStore* good = AddExtensionAndGetStorage("good", type);
1163 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
1165 // Only set bad; setting good will cause it to fail below.
1166 bad->Set(DEFAULTS, "foo", fooValue);
1168 sync_processor_->set_fail_all_requests(true);
1169 GetSyncableService(model_type)
1170 ->MergeDataAndStartSyncing(
1171 model_type,
1172 syncer::SyncDataList(),
1173 sync_processor_wrapper_.Pass(),
1174 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1175 sync_processor_->set_fail_all_requests(false);
1177 // Changes from good will be send to sync, changes from bad won't.
1178 sync_processor_->ClearChanges();
1179 good->Set(DEFAULTS, "foo", barValue);
1180 bad->Set(DEFAULTS, "foo", barValue);
1182 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
1183 sync_processor_->GetOnlyChange("good", "foo")->change_type());
1184 EXPECT_EQ(1u, sync_processor_->changes().size());
1186 // Changes from sync will be sent to good, not to bad.
1188 syncer::SyncChangeList change_list;
1189 change_list.push_back(settings_sync_util::CreateAdd(
1190 "good", "bar", barValue, model_type));
1191 change_list.push_back(settings_sync_util::CreateAdd(
1192 "bad", "bar", barValue, model_type));
1193 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1197 base::DictionaryValue dict;
1198 dict.Set("foo", barValue.DeepCopy());
1199 dict.Set("bar", barValue.DeepCopy());
1200 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
1203 base::DictionaryValue dict;
1204 dict.Set("foo", barValue.DeepCopy());
1205 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
1208 // Restarting sync makes everything work again.
1209 sync_processor_->ClearChanges();
1210 GetSyncableService(model_type)->StopSyncing(model_type);
1211 sync_processor_wrapper_.reset(
1212 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
1213 GetSyncableService(model_type)
1214 ->MergeDataAndStartSyncing(
1215 model_type,
1216 syncer::SyncDataList(),
1217 sync_processor_wrapper_.Pass(),
1218 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1220 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
1221 sync_processor_->GetOnlyChange("good", "foo")->change_type());
1222 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
1223 sync_processor_->GetOnlyChange("good", "bar")->change_type());
1224 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
1225 sync_processor_->GetOnlyChange("bad", "foo")->change_type());
1226 EXPECT_EQ(3u, sync_processor_->changes().size());
1228 sync_processor_->ClearChanges();
1229 good->Set(DEFAULTS, "foo", fooValue);
1230 bad->Set(DEFAULTS, "foo", fooValue);
1232 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
1233 sync_processor_->GetOnlyChange("good", "foo")->change_type());
1234 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
1235 sync_processor_->GetOnlyChange("good", "foo")->change_type());
1236 EXPECT_EQ(2u, sync_processor_->changes().size());
1239 TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalChangeDisablesSync) {
1240 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
1241 Manifest::Type type = Manifest::TYPE_EXTENSION;
1243 base::StringValue fooValue("fooValue");
1244 base::StringValue barValue("barValue");
1246 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
1247 storage_factory_->Reset(testing_factory);
1249 ValueStore* good = AddExtensionAndGetStorage("good", type);
1250 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
1252 GetSyncableService(model_type)
1253 ->MergeDataAndStartSyncing(
1254 model_type,
1255 syncer::SyncDataList(),
1256 sync_processor_wrapper_.Pass(),
1257 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1259 // bad will fail to send changes.
1260 good->Set(DEFAULTS, "foo", fooValue);
1261 sync_processor_->set_fail_all_requests(true);
1262 bad->Set(DEFAULTS, "foo", fooValue);
1263 sync_processor_->set_fail_all_requests(false);
1265 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
1266 sync_processor_->GetOnlyChange("good", "foo")->change_type());
1267 EXPECT_EQ(1u, sync_processor_->changes().size());
1269 // No further changes should be sent from bad.
1270 sync_processor_->ClearChanges();
1271 good->Set(DEFAULTS, "foo", barValue);
1272 bad->Set(DEFAULTS, "foo", barValue);
1274 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
1275 sync_processor_->GetOnlyChange("good", "foo")->change_type());
1276 EXPECT_EQ(1u, sync_processor_->changes().size());
1278 // Changes from sync will be sent to good, not to bad.
1280 syncer::SyncChangeList change_list;
1281 change_list.push_back(settings_sync_util::CreateAdd(
1282 "good", "bar", barValue, model_type));
1283 change_list.push_back(settings_sync_util::CreateAdd(
1284 "bad", "bar", barValue, model_type));
1285 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1289 base::DictionaryValue dict;
1290 dict.Set("foo", barValue.DeepCopy());
1291 dict.Set("bar", barValue.DeepCopy());
1292 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
1295 base::DictionaryValue dict;
1296 dict.Set("foo", barValue.DeepCopy());
1297 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
1300 // Restarting sync makes everything work again.
1301 sync_processor_->ClearChanges();
1302 GetSyncableService(model_type)->StopSyncing(model_type);
1303 sync_processor_wrapper_.reset(
1304 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
1305 GetSyncableService(model_type)
1306 ->MergeDataAndStartSyncing(
1307 model_type,
1308 syncer::SyncDataList(),
1309 sync_processor_wrapper_.Pass(),
1310 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1312 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
1313 sync_processor_->GetOnlyChange("good", "foo")->change_type());
1314 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
1315 sync_processor_->GetOnlyChange("good", "bar")->change_type());
1316 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
1317 sync_processor_->GetOnlyChange("bad", "foo")->change_type());
1318 EXPECT_EQ(3u, sync_processor_->changes().size());
1320 sync_processor_->ClearChanges();
1321 good->Set(DEFAULTS, "foo", fooValue);
1322 bad->Set(DEFAULTS, "foo", fooValue);
1324 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
1325 sync_processor_->GetOnlyChange("good", "foo")->change_type());
1326 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
1327 sync_processor_->GetOnlyChange("good", "foo")->change_type());
1328 EXPECT_EQ(2u, sync_processor_->changes().size());
1331 TEST_F(ExtensionSettingsSyncTest,
1332 LargeOutgoingChangeRejectedButIncomingAccepted) {
1333 syncer::ModelType model_type = syncer::APP_SETTINGS;
1334 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
1336 // This value should be larger than the limit in sync_storage_backend.cc.
1337 std::string string_10k;
1338 for (size_t i = 0; i < 10000; ++i) {
1339 string_10k.append("a");
1341 base::StringValue large_value(string_10k);
1343 GetSyncableService(model_type)
1344 ->MergeDataAndStartSyncing(
1345 model_type,
1346 syncer::SyncDataList(),
1347 sync_processor_wrapper_.Pass(),
1348 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1350 // Large local change rejected and doesn't get sent out.
1351 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
1352 EXPECT_TRUE(storage1->Set(DEFAULTS, "large_value", large_value)->HasError());
1353 EXPECT_EQ(0u, sync_processor_->changes().size());
1355 // Large incoming change should still get accepted.
1356 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
1358 syncer::SyncChangeList change_list;
1359 change_list.push_back(settings_sync_util::CreateAdd(
1360 "s1", "large_value", large_value, model_type));
1361 change_list.push_back(settings_sync_util::CreateAdd(
1362 "s2", "large_value", large_value, model_type));
1363 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1366 base::DictionaryValue expected;
1367 expected.Set("large_value", large_value.DeepCopy());
1368 EXPECT_PRED_FORMAT2(SettingsEq, expected, storage1->Get());
1369 EXPECT_PRED_FORMAT2(SettingsEq, expected, storage2->Get());
1372 GetSyncableService(model_type)->StopSyncing(model_type);
1375 TEST_F(ExtensionSettingsSyncTest, Dots) {
1376 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
1377 Manifest::Type type = Manifest::TYPE_EXTENSION;
1379 ValueStore* storage = AddExtensionAndGetStorage("ext", type);
1382 syncer::SyncDataList sync_data_list;
1383 scoped_ptr<base::Value> string_value(new base::StringValue("value"));
1384 sync_data_list.push_back(settings_sync_util::CreateData(
1385 "ext", "key.with.dot", *string_value, model_type));
1387 GetSyncableService(model_type)
1388 ->MergeDataAndStartSyncing(
1389 model_type,
1390 sync_data_list,
1391 sync_processor_wrapper_.Pass(),
1392 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1395 // Test dots in keys that come from sync.
1397 ValueStore::ReadResult data = storage->Get();
1398 ASSERT_FALSE(data->HasError());
1400 base::DictionaryValue expected_data;
1401 expected_data.SetWithoutPathExpansion(
1402 "key.with.dot",
1403 new base::StringValue("value"));
1404 EXPECT_TRUE(base::Value::Equals(&expected_data, &data->settings()));
1407 // Test dots in keys going to sync.
1409 scoped_ptr<base::Value> string_value(new base::StringValue("spot"));
1410 storage->Set(DEFAULTS, "key.with.spot", *string_value);
1412 ASSERT_EQ(1u, sync_processor_->changes().size());
1413 SettingSyncData* sync_data = sync_processor_->changes()[0];
1414 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, sync_data->change_type());
1415 EXPECT_EQ("ext", sync_data->extension_id());
1416 EXPECT_EQ("key.with.spot", sync_data->key());
1417 EXPECT_TRUE(sync_data->value().Equals(string_value.get()));
1421 // In other (frontend) tests, we assume that the result of GetStorage
1422 // is a pointer to the a Storage owned by a Frontend object, but for
1423 // the unlimitedStorage case, this might not be true. So, write the
1424 // tests in a "callback" style. We should really rewrite all tests to
1425 // be asynchronous in this way.
1427 namespace {
1429 static void UnlimitedSyncStorageTestCallback(ValueStore* sync_storage) {
1430 // Sync storage should still run out after ~100K; the unlimitedStorage
1431 // permission can't apply to sync.
1432 scoped_ptr<base::Value> kilobyte = util::CreateKilobyte();
1433 for (int i = 0; i < 100; ++i) {
1434 sync_storage->Set(
1435 ValueStore::DEFAULTS, base::StringPrintf("%d", i), *kilobyte);
1438 EXPECT_TRUE(sync_storage->Set(ValueStore::DEFAULTS, "WillError", *kilobyte)
1439 ->HasError());
1442 static void UnlimitedLocalStorageTestCallback(ValueStore* local_storage) {
1443 // Local storage should never run out.
1444 scoped_ptr<base::Value> megabyte = util::CreateMegabyte();
1445 for (int i = 0; i < 7; ++i) {
1446 local_storage->Set(
1447 ValueStore::DEFAULTS, base::StringPrintf("%d", i), *megabyte);
1450 EXPECT_FALSE(local_storage->Set(ValueStore::DEFAULTS, "WontError", *megabyte)
1451 ->HasError());
1454 } // namespace
1456 #if defined(OS_WIN)
1457 // See: http://crbug.com/227296
1458 #define MAYBE_UnlimitedStorageForLocalButNotSync \
1459 DISABLED_UnlimitedStorageForLocalButNotSync
1460 #else
1461 #define MAYBE_UnlimitedStorageForLocalButNotSync \
1462 UnlimitedStorageForLocalButNotSync
1463 #endif
1464 TEST_F(ExtensionSettingsSyncTest, MAYBE_UnlimitedStorageForLocalButNotSync) {
1465 const std::string id = "ext";
1466 std::set<std::string> permissions;
1467 permissions.insert("unlimitedStorage");
1468 scoped_refptr<const Extension> extension =
1469 util::AddExtensionWithIdAndPermissions(
1470 profile_.get(), id, Manifest::TYPE_EXTENSION, permissions);
1472 frontend_->RunWithStorage(extension,
1473 settings_namespace::SYNC,
1474 base::Bind(&UnlimitedSyncStorageTestCallback));
1475 frontend_->RunWithStorage(extension,
1476 settings_namespace::LOCAL,
1477 base::Bind(&UnlimitedLocalStorageTestCallback));
1479 base::MessageLoop::current()->RunUntilIdle();
1482 } // namespace extensions