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.
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/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "chrome/browser/extensions/api/storage/leveldb_settings_storage_factory.h"
12 #include "chrome/browser/extensions/api/storage/settings_frontend.h"
13 #include "chrome/browser/extensions/api/storage/settings_storage_factory.h"
14 #include "chrome/browser/extensions/api/storage/settings_sync_util.h"
15 #include "chrome/browser/extensions/api/storage/settings_test_util.h"
16 #include "chrome/browser/extensions/api/storage/syncable_settings_storage.h"
17 #include "chrome/browser/extensions/extension_system.h"
18 #include "chrome/browser/extensions/test_extension_service.h"
19 #include "chrome/browser/value_store/testing_value_store.h"
20 #include "content/public/test/test_browser_thread.h"
21 #include "extensions/common/manifest.h"
22 #include "sync/api/sync_change_processor.h"
23 #include "sync/api/sync_error_factory.h"
24 #include "sync/api/sync_error_factory_mock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
27 using base::DictionaryValue;
28 using base::ListValue;
30 using content::BrowserThread;
32 namespace extensions {
34 namespace util = settings_test_util;
38 // To save typing ValueStore::DEFAULTS everywhere.
39 const ValueStore::WriteOptions DEFAULTS = ValueStore::DEFAULTS;
41 // Gets the pretty-printed JSON for a value.
42 static std::string GetJson(const Value& value) {
44 base::JSONWriter::WriteWithOptions(&value,
45 base::JSONWriter::OPTIONS_PRETTY_PRINT,
50 // Returns whether two Values are equal.
51 testing::AssertionResult ValuesEq(
52 const char* _1, const char* _2,
53 const Value* expected,
54 const Value* actual) {
55 if (expected == actual) {
56 return testing::AssertionSuccess();
58 if (!expected && actual) {
59 return testing::AssertionFailure() <<
60 "Expected NULL, actual: " << GetJson(*actual);
62 if (expected && !actual) {
63 return testing::AssertionFailure() <<
64 "Expected: " << GetJson(*expected) << ", actual NULL";
66 if (!expected->Equals(actual)) {
67 return testing::AssertionFailure() <<
68 "Expected: " << GetJson(*expected) << ", actual: " << GetJson(*actual);
70 return testing::AssertionSuccess();
73 // Returns whether the result of a storage operation is an expected value.
74 // Logs when different.
75 testing::AssertionResult SettingsEq(
76 const char* _1, const char* _2,
77 const DictionaryValue& expected,
78 ValueStore::ReadResult actual) {
79 if (actual->HasError()) {
80 return testing::AssertionFailure() <<
81 "Expected: " << expected <<
82 ", actual has error: " << actual->error().message;
84 return ValuesEq(_1, _2, &expected, &actual->settings());
87 // SyncChangeProcessor which just records the changes made, accessed after
88 // being converted to the more useful SettingSyncData via changes().
89 class MockSyncChangeProcessor : public syncer::SyncChangeProcessor {
91 MockSyncChangeProcessor() : fail_all_requests_(false) {}
93 // syncer::SyncChangeProcessor implementation.
94 virtual syncer::SyncError ProcessSyncChanges(
95 const tracked_objects::Location& from_here,
96 const syncer::SyncChangeList& change_list) OVERRIDE {
97 if (fail_all_requests_) {
98 return syncer::SyncError(
100 syncer::SyncError::DATATYPE_ERROR,
101 "MockSyncChangeProcessor: configured to fail",
102 change_list[0].sync_data().GetDataType());
104 for (syncer::SyncChangeList::const_iterator it = change_list.begin();
105 it != change_list.end(); ++it) {
106 changes_.push_back(SettingSyncData(*it));
108 return syncer::SyncError();
111 virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const
113 return syncer::SyncDataList();
118 const SettingSyncDataList& changes() { return changes_; }
120 void ClearChanges() {
124 void set_fail_all_requests(bool fail_all_requests) {
125 fail_all_requests_ = fail_all_requests;
128 // Returns the only change for a given extension setting. If there is not
129 // exactly 1 change for that key, a test assertion will fail.
130 SettingSyncData GetOnlyChange(
131 const std::string& extension_id, const std::string& key) {
132 SettingSyncDataList matching_changes;
133 for (SettingSyncDataList::iterator it = changes_.begin();
134 it != changes_.end(); ++it) {
135 if (it->extension_id() == extension_id && it->key() == key) {
136 matching_changes.push_back(*it);
139 if (matching_changes.empty()) {
140 ADD_FAILURE() << "No matching changes for " << extension_id << "/" <<
141 key << " (out of " << changes_.size() << ")";
142 return SettingSyncData(syncer::SyncChange::ACTION_INVALID,
145 scoped_ptr<Value>(new DictionaryValue()));
147 if (matching_changes.size() != 1u) {
148 ADD_FAILURE() << matching_changes.size() << " matching changes for " <<
149 extension_id << "/" << key << " (out of " << changes_.size() << ")";
151 return matching_changes[0];
155 SettingSyncDataList changes_;
156 bool fail_all_requests_;
159 class SyncChangeProcessorDelegate : public syncer::SyncChangeProcessor {
161 explicit SyncChangeProcessorDelegate(syncer::SyncChangeProcessor* recipient)
162 : recipient_(recipient) {
165 virtual ~SyncChangeProcessorDelegate() {}
167 // syncer::SyncChangeProcessor implementation.
168 virtual syncer::SyncError ProcessSyncChanges(
169 const tracked_objects::Location& from_here,
170 const syncer::SyncChangeList& change_list) OVERRIDE {
171 return recipient_->ProcessSyncChanges(from_here, change_list);
174 virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const
176 return recipient_->GetAllSyncData(type);
180 // The recipient of all sync changes.
181 syncer::SyncChangeProcessor* recipient_;
183 DISALLOW_COPY_AND_ASSIGN(SyncChangeProcessorDelegate);
186 // SettingsStorageFactory which always returns TestingValueStore objects,
187 // and allows individually created objects to be returned.
188 class TestingValueStoreFactory : public SettingsStorageFactory {
190 TestingValueStore* GetExisting(const std::string& extension_id) {
191 DCHECK(created_.count(extension_id));
192 return created_[extension_id];
195 // SettingsStorageFactory implementation.
196 virtual ValueStore* Create(const base::FilePath& base_path,
197 const std::string& extension_id) OVERRIDE {
198 TestingValueStore* new_storage = new TestingValueStore();
199 DCHECK(!created_.count(extension_id));
200 created_[extension_id] = new_storage;
205 // SettingsStorageFactory is refcounted.
206 virtual ~TestingValueStoreFactory() {}
208 // None of these storage areas are owned by this factory, so care must be
209 // taken when calling GetExisting.
210 std::map<std::string, TestingValueStore*> created_;
215 class ExtensionSettingsSyncTest : public testing::Test {
217 ExtensionSettingsSyncTest()
218 : ui_thread_(BrowserThread::UI, base::MessageLoop::current()),
219 file_thread_(BrowserThread::FILE, base::MessageLoop::current()),
220 storage_factory_(new util::ScopedSettingsStorageFactory()),
221 sync_processor_(new MockSyncChangeProcessor),
222 sync_processor_delegate_(new SyncChangeProcessorDelegate(
223 sync_processor_.get())) {}
225 virtual void SetUp() OVERRIDE {
226 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
227 profile_.reset(new util::MockProfile(temp_dir_.path()));
228 storage_factory_->Reset(new LeveldbSettingsStorageFactory());
230 SettingsFrontend::Create(storage_factory_.get(), profile_.get()));
233 virtual void TearDown() OVERRIDE {
236 // Execute any pending deletion tasks.
237 message_loop_.RunUntilIdle();
241 // Adds a record of an extension or app to the extension service, then returns
243 ValueStore* AddExtensionAndGetStorage(
244 const std::string& id, Manifest::Type type) {
245 ExtensionServiceInterface* esi =
246 extensions::ExtensionSystem::Get(profile_.get())->extension_service();
247 static_cast<extensions::settings_test_util::MockExtensionService*>(esi)->
248 AddExtensionWithId(id, type);
249 return util::GetStorage(id, 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 return frontend_->GetBackendForSync(model_type);
258 // Gets all the sync data from the SyncableService for a sync type as a map
259 // from extension id to its sync data.
260 std::map<std::string, SettingSyncDataList> GetAllSyncData(
261 syncer::ModelType model_type) {
262 syncer::SyncDataList as_list =
263 GetSyncableService(model_type)->GetAllSyncData(model_type);
264 std::map<std::string, SettingSyncDataList> as_map;
265 for (syncer::SyncDataList::iterator it = as_list.begin();
266 it != as_list.end(); ++it) {
267 SettingSyncData sync_data(*it);
268 as_map[sync_data.extension_id()].push_back(sync_data);
273 // Need these so that the DCHECKs for running on FILE or UI threads pass.
274 base::MessageLoop message_loop_;
275 content::TestBrowserThread ui_thread_;
276 content::TestBrowserThread file_thread_;
278 base::ScopedTempDir temp_dir_;
279 scoped_ptr<util::MockProfile> profile_;
280 scoped_ptr<SettingsFrontend> frontend_;
281 scoped_refptr<util::ScopedSettingsStorageFactory> storage_factory_;
282 scoped_ptr<MockSyncChangeProcessor> sync_processor_;
283 scoped_ptr<SyncChangeProcessorDelegate> sync_processor_delegate_;
286 // Get a semblance of coverage for both EXTENSION_SETTINGS and APP_SETTINGS
287 // sync by roughly alternative which one to test.
289 TEST_F(ExtensionSettingsSyncTest, NoDataDoesNotInvokeSync) {
290 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
291 Manifest::Type type = Manifest::TYPE_EXTENSION;
293 EXPECT_EQ(0u, GetAllSyncData(model_type).size());
295 // Have one extension created before sync is set up, the other created after.
296 AddExtensionAndGetStorage("s1", type);
297 EXPECT_EQ(0u, GetAllSyncData(model_type).size());
299 GetSyncableService(model_type)->MergeDataAndStartSyncing(
301 syncer::SyncDataList(),
302 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
303 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
305 AddExtensionAndGetStorage("s2", type);
306 EXPECT_EQ(0u, GetAllSyncData(model_type).size());
308 GetSyncableService(model_type)->StopSyncing(model_type);
310 EXPECT_EQ(0u, sync_processor_->changes().size());
311 EXPECT_EQ(0u, GetAllSyncData(model_type).size());
314 TEST_F(ExtensionSettingsSyncTest, InSyncDataDoesNotInvokeSync) {
315 syncer::ModelType model_type = syncer::APP_SETTINGS;
316 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
318 StringValue value1("fooValue");
320 value2.Append(new base::StringValue("barValue"));
322 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
323 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
325 storage1->Set(DEFAULTS, "foo", value1);
326 storage2->Set(DEFAULTS, "bar", value2);
328 std::map<std::string, SettingSyncDataList> all_sync_data =
329 GetAllSyncData(model_type);
330 EXPECT_EQ(2u, all_sync_data.size());
331 EXPECT_EQ(1u, all_sync_data["s1"].size());
332 EXPECT_PRED_FORMAT2(ValuesEq, &value1, &all_sync_data["s1"][0].value());
333 EXPECT_EQ(1u, all_sync_data["s2"].size());
334 EXPECT_PRED_FORMAT2(ValuesEq, &value2, &all_sync_data["s2"][0].value());
336 syncer::SyncDataList sync_data;
337 sync_data.push_back(settings_sync_util::CreateData(
338 "s1", "foo", value1, model_type));
339 sync_data.push_back(settings_sync_util::CreateData(
340 "s2", "bar", value2, model_type));
342 GetSyncableService(model_type)->MergeDataAndStartSyncing(
343 model_type, sync_data,
344 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
345 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
347 // Already in sync, so no changes.
348 EXPECT_EQ(0u, sync_processor_->changes().size());
350 // Regression test: not-changing the synced value shouldn't result in a sync
351 // change, and changing the synced value should result in an update.
352 storage1->Set(DEFAULTS, "foo", value1);
353 EXPECT_EQ(0u, sync_processor_->changes().size());
355 storage1->Set(DEFAULTS, "foo", value2);
356 EXPECT_EQ(1u, sync_processor_->changes().size());
357 SettingSyncData change = sync_processor_->GetOnlyChange("s1", "foo");
358 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
359 EXPECT_TRUE(value2.Equals(&change.value()));
361 GetSyncableService(model_type)->StopSyncing(model_type);
364 TEST_F(ExtensionSettingsSyncTest, LocalDataWithNoSyncDataIsPushedToSync) {
365 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
366 Manifest::Type type = Manifest::TYPE_EXTENSION;
368 StringValue value1("fooValue");
370 value2.Append(new base::StringValue("barValue"));
372 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
373 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
375 storage1->Set(DEFAULTS, "foo", value1);
376 storage2->Set(DEFAULTS, "bar", value2);
378 GetSyncableService(model_type)->MergeDataAndStartSyncing(
380 syncer::SyncDataList(),
381 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
382 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
384 // All settings should have been pushed to sync.
385 EXPECT_EQ(2u, sync_processor_->changes().size());
386 SettingSyncData change = sync_processor_->GetOnlyChange("s1", "foo");
387 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
388 EXPECT_TRUE(value1.Equals(&change.value()));
389 change = sync_processor_->GetOnlyChange("s2", "bar");
390 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
391 EXPECT_TRUE(value2.Equals(&change.value()));
393 GetSyncableService(model_type)->StopSyncing(model_type);
396 TEST_F(ExtensionSettingsSyncTest, AnySyncDataOverwritesLocalData) {
397 syncer::ModelType model_type = syncer::APP_SETTINGS;
398 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
400 StringValue value1("fooValue");
402 value2.Append(new base::StringValue("barValue"));
404 // Maintain dictionaries mirrored to the expected values of the settings in
405 // each storage area.
406 DictionaryValue expected1, expected2;
408 // Pre-populate one of the storage areas.
409 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
410 storage1->Set(DEFAULTS, "overwriteMe", value1);
412 syncer::SyncDataList sync_data;
413 sync_data.push_back(settings_sync_util::CreateData(
414 "s1", "foo", value1, model_type));
415 sync_data.push_back(settings_sync_util::CreateData(
416 "s2", "bar", value2, model_type));
417 GetSyncableService(model_type)->MergeDataAndStartSyncing(
418 model_type, sync_data,
419 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
420 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
421 expected1.Set("foo", value1.DeepCopy());
422 expected2.Set("bar", value2.DeepCopy());
424 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
426 // All changes should be local, so no sync changes.
427 EXPECT_EQ(0u, sync_processor_->changes().size());
429 // Sync settings should have been pushed to local settings.
430 EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
431 EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
433 GetSyncableService(model_type)->StopSyncing(model_type);
436 TEST_F(ExtensionSettingsSyncTest, ProcessSyncChanges) {
437 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
438 Manifest::Type type = Manifest::TYPE_EXTENSION;
440 StringValue value1("fooValue");
442 value2.Append(new base::StringValue("barValue"));
444 // Maintain dictionaries mirrored to the expected values of the settings in
445 // each storage area.
446 DictionaryValue expected1, expected2;
448 // Make storage1 initialised from local data, storage2 initialised from sync.
449 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
450 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
452 storage1->Set(DEFAULTS, "foo", value1);
453 expected1.Set("foo", value1.DeepCopy());
455 syncer::SyncDataList sync_data;
456 sync_data.push_back(settings_sync_util::CreateData(
457 "s2", "bar", value2, model_type));
459 GetSyncableService(model_type)->MergeDataAndStartSyncing(
460 model_type, sync_data,
461 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
462 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
463 expected2.Set("bar", value2.DeepCopy());
465 // Make sync add some settings.
466 syncer::SyncChangeList change_list;
467 change_list.push_back(settings_sync_util::CreateAdd(
468 "s1", "bar", value2, model_type));
469 change_list.push_back(settings_sync_util::CreateAdd(
470 "s2", "foo", value1, model_type));
471 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
472 expected1.Set("bar", value2.DeepCopy());
473 expected2.Set("foo", value1.DeepCopy());
475 EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
476 EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
478 // Make sync update some settings, storage1 the new setting, storage2 the
481 change_list.push_back(settings_sync_util::CreateUpdate(
482 "s1", "bar", value2, model_type));
483 change_list.push_back(settings_sync_util::CreateUpdate(
484 "s2", "bar", value1, model_type));
485 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
486 expected1.Set("bar", value2.DeepCopy());
487 expected2.Set("bar", value1.DeepCopy());
489 EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
490 EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
492 // Make sync remove some settings, storage1 the initial setting, storage2 the
495 change_list.push_back(settings_sync_util::CreateDelete(
496 "s1", "foo", model_type));
497 change_list.push_back(settings_sync_util::CreateDelete(
498 "s2", "foo", model_type));
499 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
500 expected1.Remove("foo", NULL);
501 expected2.Remove("foo", NULL);
503 EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
504 EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
506 GetSyncableService(model_type)->StopSyncing(model_type);
509 TEST_F(ExtensionSettingsSyncTest, PushToSync) {
510 syncer::ModelType model_type = syncer::APP_SETTINGS;
511 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
513 StringValue value1("fooValue");
515 value2.Append(new base::StringValue("barValue"));
517 // Make storage1/2 initialised from local data, storage3/4 initialised from
519 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
520 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
521 ValueStore* storage3 = AddExtensionAndGetStorage("s3", type);
522 ValueStore* storage4 = AddExtensionAndGetStorage("s4", type);
524 storage1->Set(DEFAULTS, "foo", value1);
525 storage2->Set(DEFAULTS, "foo", value1);
527 syncer::SyncDataList sync_data;
528 sync_data.push_back(settings_sync_util::CreateData(
529 "s3", "bar", value2, model_type));
530 sync_data.push_back(settings_sync_util::CreateData(
531 "s4", "bar", value2, model_type));
533 GetSyncableService(model_type)->MergeDataAndStartSyncing(
534 model_type, sync_data,
535 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
536 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
538 // Add something locally.
539 storage1->Set(DEFAULTS, "bar", value2);
540 storage2->Set(DEFAULTS, "bar", value2);
541 storage3->Set(DEFAULTS, "foo", value1);
542 storage4->Set(DEFAULTS, "foo", value1);
544 SettingSyncData change = sync_processor_->GetOnlyChange("s1", "bar");
545 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
546 EXPECT_TRUE(value2.Equals(&change.value()));
547 sync_processor_->GetOnlyChange("s2", "bar");
548 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
549 EXPECT_TRUE(value2.Equals(&change.value()));
550 change = sync_processor_->GetOnlyChange("s3", "foo");
551 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
552 EXPECT_TRUE(value1.Equals(&change.value()));
553 change = sync_processor_->GetOnlyChange("s4", "foo");
554 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
555 EXPECT_TRUE(value1.Equals(&change.value()));
557 // Change something locally, storage1/3 the new setting and storage2/4 the
558 // initial setting, for all combinations of local vs sync intialisation and
560 sync_processor_->ClearChanges();
561 storage1->Set(DEFAULTS, "bar", value1);
562 storage2->Set(DEFAULTS, "foo", value2);
563 storage3->Set(DEFAULTS, "bar", value1);
564 storage4->Set(DEFAULTS, "foo", value2);
566 change = sync_processor_->GetOnlyChange("s1", "bar");
567 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
568 EXPECT_TRUE(value1.Equals(&change.value()));
569 change = sync_processor_->GetOnlyChange("s2", "foo");
570 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
571 EXPECT_TRUE(value2.Equals(&change.value()));
572 change = sync_processor_->GetOnlyChange("s3", "bar");
573 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
574 EXPECT_TRUE(value1.Equals(&change.value()));
575 change = sync_processor_->GetOnlyChange("s4", "foo");
576 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
577 EXPECT_TRUE(value2.Equals(&change.value()));
579 // Remove something locally, storage1/3 the new setting and storage2/4 the
580 // initial setting, for all combinations of local vs sync intialisation and
582 sync_processor_->ClearChanges();
583 storage1->Remove("foo");
584 storage2->Remove("bar");
585 storage3->Remove("foo");
586 storage4->Remove("bar");
589 syncer::SyncChange::ACTION_DELETE,
590 sync_processor_->GetOnlyChange("s1", "foo").change_type());
592 syncer::SyncChange::ACTION_DELETE,
593 sync_processor_->GetOnlyChange("s2", "bar").change_type());
595 syncer::SyncChange::ACTION_DELETE,
596 sync_processor_->GetOnlyChange("s3", "foo").change_type());
598 syncer::SyncChange::ACTION_DELETE,
599 sync_processor_->GetOnlyChange("s4", "bar").change_type());
601 // Remove some nonexistent settings.
602 sync_processor_->ClearChanges();
603 storage1->Remove("foo");
604 storage2->Remove("bar");
605 storage3->Remove("foo");
606 storage4->Remove("bar");
608 EXPECT_EQ(0u, sync_processor_->changes().size());
610 // Clear the rest of the settings. Add the removed ones back first so that
611 // more than one setting is cleared.
612 storage1->Set(DEFAULTS, "foo", value1);
613 storage2->Set(DEFAULTS, "bar", value2);
614 storage3->Set(DEFAULTS, "foo", value1);
615 storage4->Set(DEFAULTS, "bar", value2);
617 sync_processor_->ClearChanges();
624 syncer::SyncChange::ACTION_DELETE,
625 sync_processor_->GetOnlyChange("s1", "foo").change_type());
627 syncer::SyncChange::ACTION_DELETE,
628 sync_processor_->GetOnlyChange("s1", "bar").change_type());
630 syncer::SyncChange::ACTION_DELETE,
631 sync_processor_->GetOnlyChange("s2", "foo").change_type());
633 syncer::SyncChange::ACTION_DELETE,
634 sync_processor_->GetOnlyChange("s2", "bar").change_type());
636 syncer::SyncChange::ACTION_DELETE,
637 sync_processor_->GetOnlyChange("s3", "foo").change_type());
639 syncer::SyncChange::ACTION_DELETE,
640 sync_processor_->GetOnlyChange("s3", "bar").change_type());
642 syncer::SyncChange::ACTION_DELETE,
643 sync_processor_->GetOnlyChange("s4", "foo").change_type());
645 syncer::SyncChange::ACTION_DELETE,
646 sync_processor_->GetOnlyChange("s4", "bar").change_type());
648 GetSyncableService(model_type)->StopSyncing(model_type);
651 TEST_F(ExtensionSettingsSyncTest, ExtensionAndAppSettingsSyncSeparately) {
652 StringValue value1("fooValue");
654 value2.Append(new base::StringValue("barValue"));
656 // storage1 is an extension, storage2 is an app.
657 ValueStore* storage1 = AddExtensionAndGetStorage(
658 "s1", Manifest::TYPE_EXTENSION);
659 ValueStore* storage2 = AddExtensionAndGetStorage(
660 "s2", Manifest::TYPE_LEGACY_PACKAGED_APP);
662 storage1->Set(DEFAULTS, "foo", value1);
663 storage2->Set(DEFAULTS, "bar", value2);
665 std::map<std::string, SettingSyncDataList> extension_sync_data =
666 GetAllSyncData(syncer::EXTENSION_SETTINGS);
667 EXPECT_EQ(1u, extension_sync_data.size());
668 EXPECT_EQ(1u, extension_sync_data["s1"].size());
669 EXPECT_PRED_FORMAT2(ValuesEq, &value1, &extension_sync_data["s1"][0].value());
671 std::map<std::string, SettingSyncDataList> app_sync_data =
672 GetAllSyncData(syncer::APP_SETTINGS);
673 EXPECT_EQ(1u, app_sync_data.size());
674 EXPECT_EQ(1u, app_sync_data["s2"].size());
675 EXPECT_PRED_FORMAT2(ValuesEq, &value2, &app_sync_data["s2"][0].value());
677 // Stop each separately, there should be no changes either time.
678 syncer::SyncDataList sync_data;
679 sync_data.push_back(settings_sync_util::CreateData(
680 "s1", "foo", value1, syncer::EXTENSION_SETTINGS));
682 GetSyncableService(syncer::EXTENSION_SETTINGS)->MergeDataAndStartSyncing(
683 syncer::EXTENSION_SETTINGS,
685 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
686 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
687 GetSyncableService(syncer::EXTENSION_SETTINGS)->
688 StopSyncing(syncer::EXTENSION_SETTINGS);
689 EXPECT_EQ(0u, sync_processor_->changes().size());
692 sync_data.push_back(settings_sync_util::CreateData(
693 "s2", "bar", value2, syncer::APP_SETTINGS));
695 scoped_ptr<SyncChangeProcessorDelegate> app_settings_delegate_(
696 new SyncChangeProcessorDelegate(sync_processor_.get()));
697 GetSyncableService(syncer::APP_SETTINGS)->MergeDataAndStartSyncing(
698 syncer::APP_SETTINGS,
700 app_settings_delegate_.PassAs<syncer::SyncChangeProcessor>(),
701 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
702 GetSyncableService(syncer::APP_SETTINGS)->
703 StopSyncing(syncer::APP_SETTINGS);
704 EXPECT_EQ(0u, sync_processor_->changes().size());
707 TEST_F(ExtensionSettingsSyncTest, FailingStartSyncingDisablesSync) {
708 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
709 Manifest::Type type = Manifest::TYPE_EXTENSION;
711 StringValue fooValue("fooValue");
712 StringValue barValue("barValue");
714 // There is a bit of a convoluted method to get storage areas that can fail;
715 // hand out TestingValueStore object then toggle them failing/succeeding
717 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
718 storage_factory_->Reset(testing_factory);
720 ValueStore* good = AddExtensionAndGetStorage("good", type);
721 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
723 // Make bad fail for incoming sync changes.
724 testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
726 syncer::SyncDataList sync_data;
727 sync_data.push_back(settings_sync_util::CreateData(
728 "good", "foo", fooValue, model_type));
729 sync_data.push_back(settings_sync_util::CreateData(
730 "bad", "foo", fooValue, model_type));
731 GetSyncableService(model_type)->MergeDataAndStartSyncing(
734 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
735 scoped_ptr<syncer::SyncErrorFactory>(
736 new syncer::SyncErrorFactoryMock()));
738 testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
741 DictionaryValue dict;
742 dict.Set("foo", fooValue.DeepCopy());
743 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
746 DictionaryValue dict;
747 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
750 // Changes made to good should be sent to sync, changes from bad shouldn't.
751 sync_processor_->ClearChanges();
752 good->Set(DEFAULTS, "bar", barValue);
753 bad->Set(DEFAULTS, "bar", barValue);
756 syncer::SyncChange::ACTION_ADD,
757 sync_processor_->GetOnlyChange("good", "bar").change_type());
758 EXPECT_EQ(1u, sync_processor_->changes().size());
761 DictionaryValue dict;
762 dict.Set("foo", fooValue.DeepCopy());
763 dict.Set("bar", barValue.DeepCopy());
764 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
767 DictionaryValue dict;
768 dict.Set("bar", barValue.DeepCopy());
769 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
772 // Changes received from sync should go to good but not bad (even when it's
775 syncer::SyncChangeList change_list;
776 change_list.push_back(settings_sync_util::CreateUpdate(
777 "good", "foo", barValue, model_type));
778 // (Sending UPDATE here even though it's adding, since that's what the state
779 // of sync is. In any case, it won't work.)
780 change_list.push_back(settings_sync_util::CreateUpdate(
781 "bad", "foo", barValue, model_type));
782 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
786 DictionaryValue dict;
787 dict.Set("foo", barValue.DeepCopy());
788 dict.Set("bar", barValue.DeepCopy());
789 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
792 DictionaryValue dict;
793 dict.Set("bar", barValue.DeepCopy());
794 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
797 // Changes made to bad still shouldn't go to sync, even though it didn't fail
799 sync_processor_->ClearChanges();
800 good->Set(DEFAULTS, "bar", fooValue);
801 bad->Set(DEFAULTS, "bar", fooValue);
804 syncer::SyncChange::ACTION_UPDATE,
805 sync_processor_->GetOnlyChange("good", "bar").change_type());
806 EXPECT_EQ(1u, sync_processor_->changes().size());
809 DictionaryValue dict;
810 dict.Set("foo", barValue.DeepCopy());
811 dict.Set("bar", fooValue.DeepCopy());
812 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
815 DictionaryValue dict;
816 dict.Set("bar", fooValue.DeepCopy());
817 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
820 // Failing ProcessSyncChanges shouldn't go to the storage.
821 testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
823 syncer::SyncChangeList change_list;
824 change_list.push_back(settings_sync_util::CreateUpdate(
825 "good", "foo", fooValue, model_type));
827 change_list.push_back(settings_sync_util::CreateUpdate(
828 "bad", "foo", fooValue, model_type));
829 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
831 testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
834 DictionaryValue dict;
835 dict.Set("foo", fooValue.DeepCopy());
836 dict.Set("bar", fooValue.DeepCopy());
837 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
840 DictionaryValue dict;
841 dict.Set("bar", fooValue.DeepCopy());
842 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
845 // Restarting sync should make bad start syncing again.
846 sync_processor_->ClearChanges();
847 GetSyncableService(model_type)->StopSyncing(model_type);
848 sync_processor_delegate_.reset(new SyncChangeProcessorDelegate(
849 sync_processor_.get()));
850 GetSyncableService(model_type)->MergeDataAndStartSyncing(
852 syncer::SyncDataList(),
853 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
854 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
856 // Local settings will have been pushed to sync, since it's empty (in this
857 // test; presumably it wouldn't be live, since we've been getting changes).
859 syncer::SyncChange::ACTION_ADD,
860 sync_processor_->GetOnlyChange("good", "foo").change_type());
862 syncer::SyncChange::ACTION_ADD,
863 sync_processor_->GetOnlyChange("good", "bar").change_type());
865 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);
875 syncer::SyncChange::ACTION_UPDATE,
876 sync_processor_->GetOnlyChange("good", "bar").change_type());
878 syncer::SyncChange::ACTION_UPDATE,
879 sync_processor_->GetOnlyChange("bad", "bar").change_type());
880 EXPECT_EQ(2u, sync_processor_->changes().size());
882 // And ProcessSyncChanges work, too.
884 syncer::SyncChangeList change_list;
885 change_list.push_back(settings_sync_util::CreateUpdate(
886 "good", "bar", fooValue, model_type));
887 change_list.push_back(settings_sync_util::CreateUpdate(
888 "bad", "bar", fooValue, model_type));
889 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
893 DictionaryValue dict;
894 dict.Set("foo", fooValue.DeepCopy());
895 dict.Set("bar", fooValue.DeepCopy());
896 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
899 DictionaryValue dict;
900 dict.Set("bar", fooValue.DeepCopy());
901 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
905 TEST_F(ExtensionSettingsSyncTest, FailingProcessChangesDisablesSync) {
906 // The test above tests a failing ProcessSyncChanges too, but here test with
907 // an initially passing MergeDataAndStartSyncing.
908 syncer::ModelType model_type = syncer::APP_SETTINGS;
909 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
911 StringValue fooValue("fooValue");
912 StringValue barValue("barValue");
914 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
915 storage_factory_->Reset(testing_factory);
917 ValueStore* good = AddExtensionAndGetStorage("good", type);
918 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
920 // Unlike before, initially succeeding MergeDataAndStartSyncing.
922 syncer::SyncDataList sync_data;
923 sync_data.push_back(settings_sync_util::CreateData(
924 "good", "foo", fooValue, model_type));
925 sync_data.push_back(settings_sync_util::CreateData(
926 "bad", "foo", fooValue, model_type));
927 GetSyncableService(model_type)->MergeDataAndStartSyncing(
930 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
931 scoped_ptr<syncer::SyncErrorFactory>(
932 new syncer::SyncErrorFactoryMock()));
935 EXPECT_EQ(0u, sync_processor_->changes().size());
938 DictionaryValue dict;
939 dict.Set("foo", fooValue.DeepCopy());
940 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
943 DictionaryValue dict;
944 dict.Set("foo", fooValue.DeepCopy());
945 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
948 // Now fail ProcessSyncChanges for bad.
949 testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
951 syncer::SyncChangeList change_list;
952 change_list.push_back(settings_sync_util::CreateAdd(
953 "good", "bar", barValue, model_type));
954 change_list.push_back(settings_sync_util::CreateAdd(
955 "bad", "bar", barValue, model_type));
956 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
958 testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
961 DictionaryValue dict;
962 dict.Set("foo", fooValue.DeepCopy());
963 dict.Set("bar", barValue.DeepCopy());
964 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
967 DictionaryValue dict;
968 dict.Set("foo", fooValue.DeepCopy());
969 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
972 // No more changes sent to sync for bad.
973 sync_processor_->ClearChanges();
974 good->Set(DEFAULTS, "foo", barValue);
975 bad->Set(DEFAULTS, "foo", barValue);
978 syncer::SyncChange::ACTION_UPDATE,
979 sync_processor_->GetOnlyChange("good", "foo").change_type());
980 EXPECT_EQ(1u, sync_processor_->changes().size());
982 // No more changes received from sync should go to bad.
984 syncer::SyncChangeList change_list;
985 change_list.push_back(settings_sync_util::CreateAdd(
986 "good", "foo", fooValue, model_type));
987 change_list.push_back(settings_sync_util::CreateAdd(
988 "bad", "foo", fooValue, model_type));
989 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
993 DictionaryValue dict;
994 dict.Set("foo", fooValue.DeepCopy());
995 dict.Set("bar", barValue.DeepCopy());
996 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
999 DictionaryValue dict;
1000 dict.Set("foo", barValue.DeepCopy());
1001 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
1005 TEST_F(ExtensionSettingsSyncTest, FailingGetAllSyncDataDoesntStopSync) {
1006 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
1007 Manifest::Type type = Manifest::TYPE_EXTENSION;
1009 StringValue fooValue("fooValue");
1010 StringValue barValue("barValue");
1012 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
1013 storage_factory_->Reset(testing_factory);
1015 ValueStore* good = AddExtensionAndGetStorage("good", type);
1016 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
1018 good->Set(DEFAULTS, "foo", fooValue);
1019 bad->Set(DEFAULTS, "foo", fooValue);
1021 // Even though bad will fail to get all sync data, sync data should still
1022 // include that from good.
1023 testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
1025 syncer::SyncDataList all_sync_data =
1026 GetSyncableService(model_type)->GetAllSyncData(model_type);
1027 EXPECT_EQ(1u, all_sync_data.size());
1028 EXPECT_EQ("good/foo", all_sync_data[0].GetTag());
1030 testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
1032 // Sync shouldn't be disabled for good (nor bad -- but this is unimportant).
1033 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1035 syncer::SyncDataList(),
1036 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
1037 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1040 syncer::SyncChange::ACTION_ADD,
1041 sync_processor_->GetOnlyChange("good", "foo").change_type());
1043 syncer::SyncChange::ACTION_ADD,
1044 sync_processor_->GetOnlyChange("bad", "foo").change_type());
1045 EXPECT_EQ(2u, sync_processor_->changes().size());
1047 sync_processor_->ClearChanges();
1048 good->Set(DEFAULTS, "bar", barValue);
1049 bad->Set(DEFAULTS, "bar", barValue);
1052 syncer::SyncChange::ACTION_ADD,
1053 sync_processor_->GetOnlyChange("good", "bar").change_type());
1055 syncer::SyncChange::ACTION_ADD,
1056 sync_processor_->GetOnlyChange("bad", "bar").change_type());
1057 EXPECT_EQ(2u, sync_processor_->changes().size());
1060 TEST_F(ExtensionSettingsSyncTest, FailureToReadChangesToPushDisablesSync) {
1061 syncer::ModelType model_type = syncer::APP_SETTINGS;
1062 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
1064 StringValue fooValue("fooValue");
1065 StringValue barValue("barValue");
1067 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
1068 storage_factory_->Reset(testing_factory);
1070 ValueStore* good = AddExtensionAndGetStorage("good", type);
1071 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
1073 good->Set(DEFAULTS, "foo", fooValue);
1074 bad->Set(DEFAULTS, "foo", fooValue);
1076 // good will successfully push foo:fooValue to sync, but bad will fail to
1077 // get them so won't.
1078 testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
1079 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1081 syncer::SyncDataList(),
1082 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
1083 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1084 testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
1087 syncer::SyncChange::ACTION_ADD,
1088 sync_processor_->GetOnlyChange("good", "foo").change_type());
1089 EXPECT_EQ(1u, sync_processor_->changes().size());
1091 // bad should now be disabled for sync.
1092 sync_processor_->ClearChanges();
1093 good->Set(DEFAULTS, "bar", barValue);
1094 bad->Set(DEFAULTS, "bar", barValue);
1097 syncer::SyncChange::ACTION_ADD,
1098 sync_processor_->GetOnlyChange("good", "bar").change_type());
1099 EXPECT_EQ(1u, sync_processor_->changes().size());
1102 syncer::SyncChangeList change_list;
1103 change_list.push_back(settings_sync_util::CreateUpdate(
1104 "good", "foo", barValue, model_type));
1105 // (Sending ADD here even though it's updating, since that's what the state
1106 // of sync is. In any case, it won't work.)
1107 change_list.push_back(settings_sync_util::CreateAdd(
1108 "bad", "foo", barValue, model_type));
1109 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1113 DictionaryValue dict;
1114 dict.Set("foo", barValue.DeepCopy());
1115 dict.Set("bar", barValue.DeepCopy());
1116 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
1119 DictionaryValue dict;
1120 dict.Set("foo", fooValue.DeepCopy());
1121 dict.Set("bar", barValue.DeepCopy());
1122 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
1125 // Re-enabling sync without failing should cause the local changes from bad
1126 // to be pushed to sync successfully, as should future changes to bad.
1127 sync_processor_->ClearChanges();
1128 GetSyncableService(model_type)->StopSyncing(model_type);
1129 sync_processor_delegate_.reset(new SyncChangeProcessorDelegate(
1130 sync_processor_.get()));
1131 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1133 syncer::SyncDataList(),
1134 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
1135 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1138 syncer::SyncChange::ACTION_ADD,
1139 sync_processor_->GetOnlyChange("good", "foo").change_type());
1141 syncer::SyncChange::ACTION_ADD,
1142 sync_processor_->GetOnlyChange("good", "bar").change_type());
1144 syncer::SyncChange::ACTION_ADD,
1145 sync_processor_->GetOnlyChange("bad", "foo").change_type());
1147 syncer::SyncChange::ACTION_ADD,
1148 sync_processor_->GetOnlyChange("bad", "bar").change_type());
1149 EXPECT_EQ(4u, sync_processor_->changes().size());
1151 sync_processor_->ClearChanges();
1152 good->Set(DEFAULTS, "bar", fooValue);
1153 bad->Set(DEFAULTS, "bar", fooValue);
1156 syncer::SyncChange::ACTION_UPDATE,
1157 sync_processor_->GetOnlyChange("good", "bar").change_type());
1159 syncer::SyncChange::ACTION_UPDATE,
1160 sync_processor_->GetOnlyChange("good", "bar").change_type());
1161 EXPECT_EQ(2u, sync_processor_->changes().size());
1164 TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalStateDisablesSync) {
1165 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
1166 Manifest::Type type = Manifest::TYPE_EXTENSION;
1168 StringValue fooValue("fooValue");
1169 StringValue barValue("barValue");
1171 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
1172 storage_factory_->Reset(testing_factory);
1174 ValueStore* good = AddExtensionAndGetStorage("good", type);
1175 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
1177 // Only set bad; setting good will cause it to fail below.
1178 bad->Set(DEFAULTS, "foo", fooValue);
1180 sync_processor_->set_fail_all_requests(true);
1181 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1183 syncer::SyncDataList(),
1184 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
1185 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1186 sync_processor_->set_fail_all_requests(false);
1188 // Changes from good will be send to sync, changes from bad won't.
1189 sync_processor_->ClearChanges();
1190 good->Set(DEFAULTS, "foo", barValue);
1191 bad->Set(DEFAULTS, "foo", barValue);
1194 syncer::SyncChange::ACTION_ADD,
1195 sync_processor_->GetOnlyChange("good", "foo").change_type());
1196 EXPECT_EQ(1u, sync_processor_->changes().size());
1198 // Changes from sync will be sent to good, not to bad.
1200 syncer::SyncChangeList change_list;
1201 change_list.push_back(settings_sync_util::CreateAdd(
1202 "good", "bar", barValue, model_type));
1203 change_list.push_back(settings_sync_util::CreateAdd(
1204 "bad", "bar", barValue, model_type));
1205 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1209 DictionaryValue dict;
1210 dict.Set("foo", barValue.DeepCopy());
1211 dict.Set("bar", barValue.DeepCopy());
1212 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
1215 DictionaryValue dict;
1216 dict.Set("foo", barValue.DeepCopy());
1217 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
1220 // Restarting sync makes everything work again.
1221 sync_processor_->ClearChanges();
1222 GetSyncableService(model_type)->StopSyncing(model_type);
1223 sync_processor_delegate_.reset(new SyncChangeProcessorDelegate(
1224 sync_processor_.get()));
1225 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1227 syncer::SyncDataList(),
1228 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
1229 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1232 syncer::SyncChange::ACTION_ADD,
1233 sync_processor_->GetOnlyChange("good", "foo").change_type());
1235 syncer::SyncChange::ACTION_ADD,
1236 sync_processor_->GetOnlyChange("good", "bar").change_type());
1238 syncer::SyncChange::ACTION_ADD,
1239 sync_processor_->GetOnlyChange("bad", "foo").change_type());
1240 EXPECT_EQ(3u, sync_processor_->changes().size());
1242 sync_processor_->ClearChanges();
1243 good->Set(DEFAULTS, "foo", fooValue);
1244 bad->Set(DEFAULTS, "foo", fooValue);
1247 syncer::SyncChange::ACTION_UPDATE,
1248 sync_processor_->GetOnlyChange("good", "foo").change_type());
1250 syncer::SyncChange::ACTION_UPDATE,
1251 sync_processor_->GetOnlyChange("good", "foo").change_type());
1252 EXPECT_EQ(2u, sync_processor_->changes().size());
1255 TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalChangeDisablesSync) {
1256 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
1257 Manifest::Type type = Manifest::TYPE_EXTENSION;
1259 StringValue fooValue("fooValue");
1260 StringValue barValue("barValue");
1262 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
1263 storage_factory_->Reset(testing_factory);
1265 ValueStore* good = AddExtensionAndGetStorage("good", type);
1266 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
1268 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1270 syncer::SyncDataList(),
1271 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
1272 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1274 // bad will fail to send changes.
1275 good->Set(DEFAULTS, "foo", fooValue);
1276 sync_processor_->set_fail_all_requests(true);
1277 bad->Set(DEFAULTS, "foo", fooValue);
1278 sync_processor_->set_fail_all_requests(false);
1281 syncer::SyncChange::ACTION_ADD,
1282 sync_processor_->GetOnlyChange("good", "foo").change_type());
1283 EXPECT_EQ(1u, sync_processor_->changes().size());
1285 // No further changes should be sent from bad.
1286 sync_processor_->ClearChanges();
1287 good->Set(DEFAULTS, "foo", barValue);
1288 bad->Set(DEFAULTS, "foo", barValue);
1291 syncer::SyncChange::ACTION_UPDATE,
1292 sync_processor_->GetOnlyChange("good", "foo").change_type());
1293 EXPECT_EQ(1u, sync_processor_->changes().size());
1295 // Changes from sync will be sent to good, not to bad.
1297 syncer::SyncChangeList change_list;
1298 change_list.push_back(settings_sync_util::CreateAdd(
1299 "good", "bar", barValue, model_type));
1300 change_list.push_back(settings_sync_util::CreateAdd(
1301 "bad", "bar", barValue, model_type));
1302 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1306 DictionaryValue dict;
1307 dict.Set("foo", barValue.DeepCopy());
1308 dict.Set("bar", barValue.DeepCopy());
1309 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
1312 DictionaryValue dict;
1313 dict.Set("foo", barValue.DeepCopy());
1314 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
1317 // Restarting sync makes everything work again.
1318 sync_processor_->ClearChanges();
1319 GetSyncableService(model_type)->StopSyncing(model_type);
1320 sync_processor_delegate_.reset(new SyncChangeProcessorDelegate(
1321 sync_processor_.get()));
1322 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1324 syncer::SyncDataList(),
1325 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
1326 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1329 syncer::SyncChange::ACTION_ADD,
1330 sync_processor_->GetOnlyChange("good", "foo").change_type());
1332 syncer::SyncChange::ACTION_ADD,
1333 sync_processor_->GetOnlyChange("good", "bar").change_type());
1335 syncer::SyncChange::ACTION_ADD,
1336 sync_processor_->GetOnlyChange("bad", "foo").change_type());
1337 EXPECT_EQ(3u, sync_processor_->changes().size());
1339 sync_processor_->ClearChanges();
1340 good->Set(DEFAULTS, "foo", fooValue);
1341 bad->Set(DEFAULTS, "foo", fooValue);
1344 syncer::SyncChange::ACTION_UPDATE,
1345 sync_processor_->GetOnlyChange("good", "foo").change_type());
1347 syncer::SyncChange::ACTION_UPDATE,
1348 sync_processor_->GetOnlyChange("good", "foo").change_type());
1349 EXPECT_EQ(2u, sync_processor_->changes().size());
1352 TEST_F(ExtensionSettingsSyncTest,
1353 LargeOutgoingChangeRejectedButIncomingAccepted) {
1354 syncer::ModelType model_type = syncer::APP_SETTINGS;
1355 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
1357 // This value should be larger than the limit in settings_backend.cc.
1358 std::string string_5k;
1359 for (size_t i = 0; i < 5000; ++i) {
1360 string_5k.append("a");
1362 StringValue large_value(string_5k);
1364 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1366 syncer::SyncDataList(),
1367 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
1368 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1370 // Large local change rejected and doesn't get sent out.
1371 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
1372 EXPECT_TRUE(storage1->Set(DEFAULTS, "large_value", large_value)->HasError());
1373 EXPECT_EQ(0u, sync_processor_->changes().size());
1375 // Large incoming change should still get accepted.
1376 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
1378 syncer::SyncChangeList change_list;
1379 change_list.push_back(settings_sync_util::CreateAdd(
1380 "s1", "large_value", large_value, model_type));
1381 change_list.push_back(settings_sync_util::CreateAdd(
1382 "s2", "large_value", large_value, model_type));
1383 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1386 DictionaryValue expected;
1387 expected.Set("large_value", large_value.DeepCopy());
1388 EXPECT_PRED_FORMAT2(SettingsEq, expected, storage1->Get());
1389 EXPECT_PRED_FORMAT2(SettingsEq, expected, storage2->Get());
1392 GetSyncableService(model_type)->StopSyncing(model_type);
1395 TEST_F(ExtensionSettingsSyncTest, Dots) {
1396 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
1397 Manifest::Type type = Manifest::TYPE_EXTENSION;
1399 ValueStore* storage = AddExtensionAndGetStorage("ext", type);
1402 syncer::SyncDataList sync_data_list;
1403 scoped_ptr<Value> string_value(new base::StringValue("value"));
1404 sync_data_list.push_back(settings_sync_util::CreateData(
1405 "ext", "key.with.dot", *string_value, model_type));
1407 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1410 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
1411 scoped_ptr<syncer::SyncErrorFactory>(
1412 new syncer::SyncErrorFactoryMock()));
1415 // Test dots in keys that come from sync.
1417 ValueStore::ReadResult data = storage->Get();
1418 ASSERT_FALSE(data->HasError());
1420 DictionaryValue expected_data;
1421 expected_data.SetWithoutPathExpansion(
1423 new base::StringValue("value"));
1424 EXPECT_TRUE(Value::Equals(&expected_data, &data->settings()));
1427 // Test dots in keys going to sync.
1429 scoped_ptr<Value> string_value(new base::StringValue("spot"));
1430 storage->Set(DEFAULTS, "key.with.spot", *string_value);
1432 ASSERT_EQ(1u, sync_processor_->changes().size());
1433 SettingSyncData sync_data = sync_processor_->changes()[0];
1434 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, sync_data.change_type());
1435 EXPECT_EQ("ext", sync_data.extension_id());
1436 EXPECT_EQ("key.with.spot", sync_data.key());
1437 EXPECT_TRUE(sync_data.value().Equals(string_value.get()));
1441 } // namespace extensions