Add ENABLE_MEDIA_ROUTER define to builds other than Android and iOS.
[chromium-blink-merge.git] / chrome / browser / extensions / api / storage / settings_sync_unittest.cc
blob9ed1922f73d5998860d109f644206814caf2fd30
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/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/strings/stringprintf.h"
12 #include "chrome/browser/extensions/api/storage/settings_sync_util.h"
13 #include "chrome/browser/extensions/api/storage/sync_value_store_cache.h"
14 #include "chrome/browser/extensions/api/storage/syncable_settings_storage.h"
15 #include "chrome/test/base/testing_profile.h"
16 #include "content/public/test/test_browser_thread.h"
17 #include "extensions/browser/api/storage/leveldb_settings_storage_factory.h"
18 #include "extensions/browser/api/storage/settings_storage_factory.h"
19 #include "extensions/browser/api/storage/settings_test_util.h"
20 #include "extensions/browser/api/storage/storage_frontend.h"
21 #include "extensions/browser/extension_system.h"
22 #include "extensions/browser/mock_extension_system.h"
23 #include "extensions/browser/value_store/testing_value_store.h"
24 #include "extensions/common/manifest.h"
25 #include "sync/api/sync_change_processor.h"
26 #include "sync/api/sync_change_processor_wrapper_for_test.h"
27 #include "sync/api/sync_error_factory.h"
28 #include "sync/api/sync_error_factory_mock.h"
29 #include "testing/gtest/include/gtest/gtest.h"
31 using base::DictionaryValue;
32 using base::ListValue;
33 using base::Value;
34 using content::BrowserThread;
36 namespace extensions {
38 namespace util = settings_test_util;
40 namespace {
42 // To save typing ValueStore::DEFAULTS everywhere.
43 const ValueStore::WriteOptions DEFAULTS = ValueStore::DEFAULTS;
45 // Gets the pretty-printed JSON for a value.
46 static std::string GetJson(const base::Value& value) {
47 std::string json;
48 base::JSONWriter::WriteWithOptions(&value,
49 base::JSONWriter::OPTIONS_PRETTY_PRINT,
50 &json);
51 return json;
54 // Returns whether two Values are equal.
55 testing::AssertionResult ValuesEq(
56 const char* _1, const char* _2,
57 const base::Value* expected,
58 const base::Value* actual) {
59 if (expected == actual) {
60 return testing::AssertionSuccess();
62 if (!expected && actual) {
63 return testing::AssertionFailure() <<
64 "Expected NULL, actual: " << GetJson(*actual);
66 if (expected && !actual) {
67 return testing::AssertionFailure() <<
68 "Expected: " << GetJson(*expected) << ", actual NULL";
70 if (!expected->Equals(actual)) {
71 return testing::AssertionFailure() <<
72 "Expected: " << GetJson(*expected) << ", actual: " << GetJson(*actual);
74 return testing::AssertionSuccess();
77 // Returns whether the result of a storage operation is an expected value.
78 // Logs when different.
79 testing::AssertionResult SettingsEq(
80 const char* _1, const char* _2,
81 const base::DictionaryValue& expected,
82 ValueStore::ReadResult actual) {
83 if (actual->HasError()) {
84 return testing::AssertionFailure() <<
85 "Expected: " << expected <<
86 ", actual has error: " << actual->error().message;
88 return ValuesEq(_1, _2, &expected, &actual->settings());
91 // SyncChangeProcessor which just records the changes made, accessed after
92 // being converted to the more useful SettingSyncData via changes().
93 class MockSyncChangeProcessor : public syncer::SyncChangeProcessor {
94 public:
95 MockSyncChangeProcessor() : fail_all_requests_(false) {}
97 // syncer::SyncChangeProcessor implementation.
98 syncer::SyncError ProcessSyncChanges(
99 const tracked_objects::Location& from_here,
100 const syncer::SyncChangeList& change_list) override {
101 if (fail_all_requests_) {
102 return syncer::SyncError(
103 FROM_HERE,
104 syncer::SyncError::DATATYPE_ERROR,
105 "MockSyncChangeProcessor: configured to fail",
106 change_list[0].sync_data().GetDataType());
108 for (syncer::SyncChangeList::const_iterator it = change_list.begin();
109 it != change_list.end(); ++it) {
110 changes_.push_back(SettingSyncData(*it));
112 return syncer::SyncError();
115 syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override {
116 return syncer::SyncDataList();
119 // Mock methods.
121 const SettingSyncDataList& changes() { return changes_; }
123 void ClearChanges() {
124 changes_.clear();
127 void set_fail_all_requests(bool fail_all_requests) {
128 fail_all_requests_ = fail_all_requests;
131 // Returns the only change for a given extension setting. If there is not
132 // exactly 1 change for that key, a test assertion will fail.
133 SettingSyncData GetOnlyChange(
134 const std::string& extension_id, const std::string& key) {
135 SettingSyncDataList matching_changes;
136 for (SettingSyncDataList::iterator it = changes_.begin();
137 it != changes_.end(); ++it) {
138 if (it->extension_id() == extension_id && it->key() == key) {
139 matching_changes.push_back(*it);
142 if (matching_changes.empty()) {
143 ADD_FAILURE() << "No matching changes for " << extension_id << "/" <<
144 key << " (out of " << changes_.size() << ")";
145 return SettingSyncData(syncer::SyncChange::ACTION_INVALID,
146 std::string(),
147 std::string(),
148 scoped_ptr<base::Value>(
149 new base::DictionaryValue()));
151 if (matching_changes.size() != 1u) {
152 ADD_FAILURE() << matching_changes.size() << " matching changes for " <<
153 extension_id << "/" << key << " (out of " << changes_.size() << ")";
155 return matching_changes[0];
158 private:
159 SettingSyncDataList changes_;
160 bool fail_all_requests_;
163 // SettingsStorageFactory which always returns TestingValueStore objects,
164 // and allows individually created objects to be returned.
165 class TestingValueStoreFactory : public SettingsStorageFactory {
166 public:
167 TestingValueStore* GetExisting(const std::string& extension_id) {
168 DCHECK(created_.count(extension_id));
169 return created_[extension_id];
172 // SettingsStorageFactory implementation.
173 ValueStore* Create(const base::FilePath& base_path,
174 const std::string& extension_id) override {
175 TestingValueStore* new_storage = new TestingValueStore();
176 DCHECK(!created_.count(extension_id));
177 created_[extension_id] = new_storage;
178 return new_storage;
181 // Testing value stores don't actually create a real database. Don't delete
182 // any files.
183 void DeleteDatabaseIfExists(const base::FilePath& base_path,
184 const std::string& extension_id) override {}
186 private:
187 // SettingsStorageFactory is refcounted.
188 ~TestingValueStoreFactory() override {}
190 // None of these storage areas are owned by this factory, so care must be
191 // taken when calling GetExisting.
192 std::map<std::string, TestingValueStore*> created_;
195 } // namespace
197 class ExtensionSettingsSyncTest : public testing::Test {
198 public:
199 ExtensionSettingsSyncTest()
200 : ui_thread_(BrowserThread::UI, base::MessageLoop::current()),
201 file_thread_(BrowserThread::FILE, base::MessageLoop::current()),
202 storage_factory_(new util::ScopedSettingsStorageFactory()),
203 sync_processor_(new MockSyncChangeProcessor),
204 sync_processor_wrapper_(new syncer::SyncChangeProcessorWrapperForTest(
205 sync_processor_.get())) {}
207 void SetUp() override {
208 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
209 profile_.reset(new TestingProfile(temp_dir_.path()));
210 storage_factory_->Reset(new LeveldbSettingsStorageFactory());
211 frontend_.reset(
212 StorageFrontend::CreateForTesting(storage_factory_, profile_.get()));
214 ExtensionsBrowserClient::Get()
215 ->GetExtensionSystemFactory()
216 ->SetTestingFactoryAndUse(
217 profile_.get(), &util::MockExtensionSystemWithEventRouter::Build);
220 void TearDown() override {
221 frontend_.reset();
222 profile_.reset();
223 // Execute any pending deletion tasks.
224 message_loop_.RunUntilIdle();
227 protected:
228 // Adds a record of an extension or app to the extension service, then returns
229 // its storage area.
230 ValueStore* AddExtensionAndGetStorage(
231 const std::string& id, Manifest::Type type) {
232 scoped_refptr<const Extension> extension =
233 util::AddExtensionWithId(profile_.get(), id, type);
234 return util::GetStorage(extension, frontend_.get());
237 // Gets the syncer::SyncableService for the given sync type.
238 syncer::SyncableService* GetSyncableService(syncer::ModelType model_type) {
239 base::MessageLoop::current()->RunUntilIdle();
240 SyncValueStoreCache* sync_cache = static_cast<SyncValueStoreCache*>(
241 frontend_->GetValueStoreCache(settings_namespace::SYNC));
242 return sync_cache->GetSyncableService(model_type);
245 // Gets all the sync data from the SyncableService for a sync type as a map
246 // from extension id to its sync data.
247 std::map<std::string, SettingSyncDataList> GetAllSyncData(
248 syncer::ModelType model_type) {
249 syncer::SyncDataList as_list =
250 GetSyncableService(model_type)->GetAllSyncData(model_type);
251 std::map<std::string, SettingSyncDataList> as_map;
252 for (syncer::SyncDataList::iterator it = as_list.begin();
253 it != as_list.end(); ++it) {
254 SettingSyncData sync_data(*it);
255 as_map[sync_data.extension_id()].push_back(sync_data);
257 return as_map;
260 // Need these so that the DCHECKs for running on FILE or UI threads pass.
261 base::MessageLoop message_loop_;
262 content::TestBrowserThread ui_thread_;
263 content::TestBrowserThread file_thread_;
265 base::ScopedTempDir temp_dir_;
266 scoped_ptr<TestingProfile> profile_;
267 scoped_ptr<StorageFrontend> frontend_;
268 scoped_refptr<util::ScopedSettingsStorageFactory> storage_factory_;
269 scoped_ptr<MockSyncChangeProcessor> sync_processor_;
270 scoped_ptr<syncer::SyncChangeProcessorWrapperForTest> sync_processor_wrapper_;
273 // Get a semblance of coverage for both EXTENSION_SETTINGS and APP_SETTINGS
274 // sync by roughly alternative which one to test.
276 TEST_F(ExtensionSettingsSyncTest, NoDataDoesNotInvokeSync) {
277 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
278 Manifest::Type type = Manifest::TYPE_EXTENSION;
280 EXPECT_EQ(0u, GetAllSyncData(model_type).size());
282 // Have one extension created before sync is set up, the other created after.
283 AddExtensionAndGetStorage("s1", type);
284 EXPECT_EQ(0u, GetAllSyncData(model_type).size());
286 GetSyncableService(model_type)
287 ->MergeDataAndStartSyncing(
288 model_type,
289 syncer::SyncDataList(),
290 sync_processor_wrapper_.Pass(),
291 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
293 AddExtensionAndGetStorage("s2", type);
294 EXPECT_EQ(0u, GetAllSyncData(model_type).size());
296 GetSyncableService(model_type)->StopSyncing(model_type);
298 EXPECT_EQ(0u, sync_processor_->changes().size());
299 EXPECT_EQ(0u, GetAllSyncData(model_type).size());
302 TEST_F(ExtensionSettingsSyncTest, InSyncDataDoesNotInvokeSync) {
303 syncer::ModelType model_type = syncer::APP_SETTINGS;
304 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
306 base::StringValue value1("fooValue");
307 base::ListValue value2;
308 value2.Append(new base::StringValue("barValue"));
310 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
311 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
313 storage1->Set(DEFAULTS, "foo", value1);
314 storage2->Set(DEFAULTS, "bar", value2);
316 std::map<std::string, SettingSyncDataList> all_sync_data =
317 GetAllSyncData(model_type);
318 EXPECT_EQ(2u, all_sync_data.size());
319 EXPECT_EQ(1u, all_sync_data["s1"].size());
320 EXPECT_PRED_FORMAT2(ValuesEq, &value1, &all_sync_data["s1"][0].value());
321 EXPECT_EQ(1u, all_sync_data["s2"].size());
322 EXPECT_PRED_FORMAT2(ValuesEq, &value2, &all_sync_data["s2"][0].value());
324 syncer::SyncDataList sync_data;
325 sync_data.push_back(settings_sync_util::CreateData(
326 "s1", "foo", value1, model_type));
327 sync_data.push_back(settings_sync_util::CreateData(
328 "s2", "bar", value2, model_type));
330 GetSyncableService(model_type)
331 ->MergeDataAndStartSyncing(
332 model_type,
333 sync_data,
334 sync_processor_wrapper_.Pass(),
335 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
337 // Already in sync, so no changes.
338 EXPECT_EQ(0u, sync_processor_->changes().size());
340 // Regression test: not-changing the synced value shouldn't result in a sync
341 // change, and changing the synced value should result in an update.
342 storage1->Set(DEFAULTS, "foo", value1);
343 EXPECT_EQ(0u, sync_processor_->changes().size());
345 storage1->Set(DEFAULTS, "foo", value2);
346 EXPECT_EQ(1u, sync_processor_->changes().size());
347 SettingSyncData change = sync_processor_->GetOnlyChange("s1", "foo");
348 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
349 EXPECT_TRUE(value2.Equals(&change.value()));
351 GetSyncableService(model_type)->StopSyncing(model_type);
354 TEST_F(ExtensionSettingsSyncTest, LocalDataWithNoSyncDataIsPushedToSync) {
355 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
356 Manifest::Type type = Manifest::TYPE_EXTENSION;
358 base::StringValue value1("fooValue");
359 base::ListValue value2;
360 value2.Append(new base::StringValue("barValue"));
362 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
363 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
365 storage1->Set(DEFAULTS, "foo", value1);
366 storage2->Set(DEFAULTS, "bar", value2);
368 GetSyncableService(model_type)
369 ->MergeDataAndStartSyncing(
370 model_type,
371 syncer::SyncDataList(),
372 sync_processor_wrapper_.Pass(),
373 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
375 // All settings should have been pushed to sync.
376 EXPECT_EQ(2u, sync_processor_->changes().size());
377 SettingSyncData change = sync_processor_->GetOnlyChange("s1", "foo");
378 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
379 EXPECT_TRUE(value1.Equals(&change.value()));
380 change = sync_processor_->GetOnlyChange("s2", "bar");
381 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
382 EXPECT_TRUE(value2.Equals(&change.value()));
384 GetSyncableService(model_type)->StopSyncing(model_type);
387 TEST_F(ExtensionSettingsSyncTest, AnySyncDataOverwritesLocalData) {
388 syncer::ModelType model_type = syncer::APP_SETTINGS;
389 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
391 base::StringValue value1("fooValue");
392 base::ListValue value2;
393 value2.Append(new base::StringValue("barValue"));
395 // Maintain dictionaries mirrored to the expected values of the settings in
396 // each storage area.
397 base::DictionaryValue expected1, expected2;
399 // Pre-populate one of the storage areas.
400 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
401 storage1->Set(DEFAULTS, "overwriteMe", value1);
403 syncer::SyncDataList sync_data;
404 sync_data.push_back(settings_sync_util::CreateData(
405 "s1", "foo", value1, model_type));
406 sync_data.push_back(settings_sync_util::CreateData(
407 "s2", "bar", value2, model_type));
408 GetSyncableService(model_type)
409 ->MergeDataAndStartSyncing(
410 model_type,
411 sync_data,
412 sync_processor_wrapper_.Pass(),
413 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
414 expected1.Set("foo", value1.DeepCopy());
415 expected2.Set("bar", value2.DeepCopy());
417 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
419 // All changes should be local, so no sync changes.
420 EXPECT_EQ(0u, sync_processor_->changes().size());
422 // Sync settings should have been pushed to local settings.
423 EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
424 EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
426 GetSyncableService(model_type)->StopSyncing(model_type);
429 TEST_F(ExtensionSettingsSyncTest, ProcessSyncChanges) {
430 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
431 Manifest::Type type = Manifest::TYPE_EXTENSION;
433 base::StringValue value1("fooValue");
434 base::ListValue value2;
435 value2.Append(new base::StringValue("barValue"));
437 // Maintain dictionaries mirrored to the expected values of the settings in
438 // each storage area.
439 base::DictionaryValue expected1, expected2;
441 // Make storage1 initialised from local data, storage2 initialised from sync.
442 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
443 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
445 storage1->Set(DEFAULTS, "foo", value1);
446 expected1.Set("foo", value1.DeepCopy());
448 syncer::SyncDataList sync_data;
449 sync_data.push_back(settings_sync_util::CreateData(
450 "s2", "bar", value2, model_type));
452 GetSyncableService(model_type)
453 ->MergeDataAndStartSyncing(
454 model_type,
455 sync_data,
456 sync_processor_wrapper_.Pass(),
457 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
458 expected2.Set("bar", value2.DeepCopy());
460 // Make sync add some settings.
461 syncer::SyncChangeList change_list;
462 change_list.push_back(settings_sync_util::CreateAdd(
463 "s1", "bar", value2, model_type));
464 change_list.push_back(settings_sync_util::CreateAdd(
465 "s2", "foo", value1, model_type));
466 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
467 expected1.Set("bar", value2.DeepCopy());
468 expected2.Set("foo", value1.DeepCopy());
470 EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
471 EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
473 // Make sync update some settings, storage1 the new setting, storage2 the
474 // initial setting.
475 change_list.clear();
476 change_list.push_back(settings_sync_util::CreateUpdate(
477 "s1", "bar", value2, model_type));
478 change_list.push_back(settings_sync_util::CreateUpdate(
479 "s2", "bar", value1, model_type));
480 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
481 expected1.Set("bar", value2.DeepCopy());
482 expected2.Set("bar", value1.DeepCopy());
484 EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
485 EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
487 // Make sync remove some settings, storage1 the initial setting, storage2 the
488 // new setting.
489 change_list.clear();
490 change_list.push_back(settings_sync_util::CreateDelete(
491 "s1", "foo", model_type));
492 change_list.push_back(settings_sync_util::CreateDelete(
493 "s2", "foo", model_type));
494 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
495 expected1.Remove("foo", NULL);
496 expected2.Remove("foo", NULL);
498 EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
499 EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
501 GetSyncableService(model_type)->StopSyncing(model_type);
504 TEST_F(ExtensionSettingsSyncTest, PushToSync) {
505 syncer::ModelType model_type = syncer::APP_SETTINGS;
506 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
508 base::StringValue value1("fooValue");
509 base::ListValue value2;
510 value2.Append(new base::StringValue("barValue"));
512 // Make storage1/2 initialised from local data, storage3/4 initialised from
513 // sync.
514 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
515 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
516 ValueStore* storage3 = AddExtensionAndGetStorage("s3", type);
517 ValueStore* storage4 = AddExtensionAndGetStorage("s4", type);
519 storage1->Set(DEFAULTS, "foo", value1);
520 storage2->Set(DEFAULTS, "foo", value1);
522 syncer::SyncDataList sync_data;
523 sync_data.push_back(settings_sync_util::CreateData(
524 "s3", "bar", value2, model_type));
525 sync_data.push_back(settings_sync_util::CreateData(
526 "s4", "bar", value2, model_type));
528 GetSyncableService(model_type)
529 ->MergeDataAndStartSyncing(
530 model_type,
531 sync_data,
532 sync_processor_wrapper_.Pass(),
533 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
535 // Add something locally.
536 storage1->Set(DEFAULTS, "bar", value2);
537 storage2->Set(DEFAULTS, "bar", value2);
538 storage3->Set(DEFAULTS, "foo", value1);
539 storage4->Set(DEFAULTS, "foo", value1);
541 SettingSyncData change = sync_processor_->GetOnlyChange("s1", "bar");
542 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
543 EXPECT_TRUE(value2.Equals(&change.value()));
544 sync_processor_->GetOnlyChange("s2", "bar");
545 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
546 EXPECT_TRUE(value2.Equals(&change.value()));
547 change = sync_processor_->GetOnlyChange("s3", "foo");
548 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
549 EXPECT_TRUE(value1.Equals(&change.value()));
550 change = sync_processor_->GetOnlyChange("s4", "foo");
551 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
552 EXPECT_TRUE(value1.Equals(&change.value()));
554 // Change something locally, storage1/3 the new setting and storage2/4 the
555 // initial setting, for all combinations of local vs sync intialisation and
556 // new vs initial.
557 sync_processor_->ClearChanges();
558 storage1->Set(DEFAULTS, "bar", value1);
559 storage2->Set(DEFAULTS, "foo", value2);
560 storage3->Set(DEFAULTS, "bar", value1);
561 storage4->Set(DEFAULTS, "foo", value2);
563 change = sync_processor_->GetOnlyChange("s1", "bar");
564 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
565 EXPECT_TRUE(value1.Equals(&change.value()));
566 change = sync_processor_->GetOnlyChange("s2", "foo");
567 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
568 EXPECT_TRUE(value2.Equals(&change.value()));
569 change = sync_processor_->GetOnlyChange("s3", "bar");
570 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
571 EXPECT_TRUE(value1.Equals(&change.value()));
572 change = sync_processor_->GetOnlyChange("s4", "foo");
573 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
574 EXPECT_TRUE(value2.Equals(&change.value()));
576 // Remove something locally, storage1/3 the new setting and storage2/4 the
577 // initial setting, for all combinations of local vs sync intialisation and
578 // new vs initial.
579 sync_processor_->ClearChanges();
580 storage1->Remove("foo");
581 storage2->Remove("bar");
582 storage3->Remove("foo");
583 storage4->Remove("bar");
585 EXPECT_EQ(
586 syncer::SyncChange::ACTION_DELETE,
587 sync_processor_->GetOnlyChange("s1", "foo").change_type());
588 EXPECT_EQ(
589 syncer::SyncChange::ACTION_DELETE,
590 sync_processor_->GetOnlyChange("s2", "bar").change_type());
591 EXPECT_EQ(
592 syncer::SyncChange::ACTION_DELETE,
593 sync_processor_->GetOnlyChange("s3", "foo").change_type());
594 EXPECT_EQ(
595 syncer::SyncChange::ACTION_DELETE,
596 sync_processor_->GetOnlyChange("s4", "bar").change_type());
598 // Remove some nonexistent settings.
599 sync_processor_->ClearChanges();
600 storage1->Remove("foo");
601 storage2->Remove("bar");
602 storage3->Remove("foo");
603 storage4->Remove("bar");
605 EXPECT_EQ(0u, sync_processor_->changes().size());
607 // Clear the rest of the settings. Add the removed ones back first so that
608 // more than one setting is cleared.
609 storage1->Set(DEFAULTS, "foo", value1);
610 storage2->Set(DEFAULTS, "bar", value2);
611 storage3->Set(DEFAULTS, "foo", value1);
612 storage4->Set(DEFAULTS, "bar", value2);
614 sync_processor_->ClearChanges();
615 storage1->Clear();
616 storage2->Clear();
617 storage3->Clear();
618 storage4->Clear();
620 EXPECT_EQ(
621 syncer::SyncChange::ACTION_DELETE,
622 sync_processor_->GetOnlyChange("s1", "foo").change_type());
623 EXPECT_EQ(
624 syncer::SyncChange::ACTION_DELETE,
625 sync_processor_->GetOnlyChange("s1", "bar").change_type());
626 EXPECT_EQ(
627 syncer::SyncChange::ACTION_DELETE,
628 sync_processor_->GetOnlyChange("s2", "foo").change_type());
629 EXPECT_EQ(
630 syncer::SyncChange::ACTION_DELETE,
631 sync_processor_->GetOnlyChange("s2", "bar").change_type());
632 EXPECT_EQ(
633 syncer::SyncChange::ACTION_DELETE,
634 sync_processor_->GetOnlyChange("s3", "foo").change_type());
635 EXPECT_EQ(
636 syncer::SyncChange::ACTION_DELETE,
637 sync_processor_->GetOnlyChange("s3", "bar").change_type());
638 EXPECT_EQ(
639 syncer::SyncChange::ACTION_DELETE,
640 sync_processor_->GetOnlyChange("s4", "foo").change_type());
641 EXPECT_EQ(
642 syncer::SyncChange::ACTION_DELETE,
643 sync_processor_->GetOnlyChange("s4", "bar").change_type());
645 GetSyncableService(model_type)->StopSyncing(model_type);
648 TEST_F(ExtensionSettingsSyncTest, ExtensionAndAppSettingsSyncSeparately) {
649 base::StringValue value1("fooValue");
650 base::ListValue value2;
651 value2.Append(new base::StringValue("barValue"));
653 // storage1 is an extension, storage2 is an app.
654 ValueStore* storage1 = AddExtensionAndGetStorage(
655 "s1", Manifest::TYPE_EXTENSION);
656 ValueStore* storage2 = AddExtensionAndGetStorage(
657 "s2", Manifest::TYPE_LEGACY_PACKAGED_APP);
659 storage1->Set(DEFAULTS, "foo", value1);
660 storage2->Set(DEFAULTS, "bar", value2);
662 std::map<std::string, SettingSyncDataList> extension_sync_data =
663 GetAllSyncData(syncer::EXTENSION_SETTINGS);
664 EXPECT_EQ(1u, extension_sync_data.size());
665 EXPECT_EQ(1u, extension_sync_data["s1"].size());
666 EXPECT_PRED_FORMAT2(ValuesEq, &value1, &extension_sync_data["s1"][0].value());
668 std::map<std::string, SettingSyncDataList> app_sync_data =
669 GetAllSyncData(syncer::APP_SETTINGS);
670 EXPECT_EQ(1u, app_sync_data.size());
671 EXPECT_EQ(1u, app_sync_data["s2"].size());
672 EXPECT_PRED_FORMAT2(ValuesEq, &value2, &app_sync_data["s2"][0].value());
674 // Stop each separately, there should be no changes either time.
675 syncer::SyncDataList sync_data;
676 sync_data.push_back(settings_sync_util::CreateData(
677 "s1", "foo", value1, syncer::EXTENSION_SETTINGS));
679 GetSyncableService(syncer::EXTENSION_SETTINGS)
680 ->MergeDataAndStartSyncing(
681 syncer::EXTENSION_SETTINGS,
682 sync_data,
683 sync_processor_wrapper_.Pass(),
684 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
685 GetSyncableService(syncer::EXTENSION_SETTINGS)->
686 StopSyncing(syncer::EXTENSION_SETTINGS);
687 EXPECT_EQ(0u, sync_processor_->changes().size());
689 sync_data.clear();
690 sync_data.push_back(settings_sync_util::CreateData(
691 "s2", "bar", value2, syncer::APP_SETTINGS));
693 scoped_ptr<syncer::SyncChangeProcessorWrapperForTest> app_settings_delegate_(
694 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
695 GetSyncableService(syncer::APP_SETTINGS)
696 ->MergeDataAndStartSyncing(
697 syncer::APP_SETTINGS,
698 sync_data,
699 app_settings_delegate_.Pass(),
700 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
701 GetSyncableService(syncer::APP_SETTINGS)->
702 StopSyncing(syncer::APP_SETTINGS);
703 EXPECT_EQ(0u, sync_processor_->changes().size());
706 TEST_F(ExtensionSettingsSyncTest, FailingStartSyncingDisablesSync) {
707 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
708 Manifest::Type type = Manifest::TYPE_EXTENSION;
710 base::StringValue fooValue("fooValue");
711 base::StringValue barValue("barValue");
713 // There is a bit of a convoluted method to get storage areas that can fail;
714 // hand out TestingValueStore object then toggle them failing/succeeding
715 // as necessary.
716 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
717 storage_factory_->Reset(testing_factory);
719 ValueStore* good = AddExtensionAndGetStorage("good", type);
720 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
722 // Make bad fail for incoming sync changes.
723 testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
725 syncer::SyncDataList sync_data;
726 sync_data.push_back(settings_sync_util::CreateData(
727 "good", "foo", fooValue, model_type));
728 sync_data.push_back(settings_sync_util::CreateData(
729 "bad", "foo", fooValue, model_type));
730 GetSyncableService(model_type)
731 ->MergeDataAndStartSyncing(
732 model_type,
733 sync_data,
734 sync_processor_wrapper_.Pass(),
735 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
737 testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
740 base::DictionaryValue dict;
741 dict.Set("foo", fooValue.DeepCopy());
742 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
745 base::DictionaryValue dict;
746 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
749 // Changes made to good should be sent to sync, changes from bad shouldn't.
750 sync_processor_->ClearChanges();
751 good->Set(DEFAULTS, "bar", barValue);
752 bad->Set(DEFAULTS, "bar", barValue);
754 EXPECT_EQ(
755 syncer::SyncChange::ACTION_ADD,
756 sync_processor_->GetOnlyChange("good", "bar").change_type());
757 EXPECT_EQ(1u, sync_processor_->changes().size());
760 base::DictionaryValue dict;
761 dict.Set("foo", fooValue.DeepCopy());
762 dict.Set("bar", barValue.DeepCopy());
763 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
766 base::DictionaryValue dict;
767 dict.Set("bar", barValue.DeepCopy());
768 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
771 // Changes received from sync should go to good but not bad (even when it's
772 // not failing).
774 syncer::SyncChangeList change_list;
775 change_list.push_back(settings_sync_util::CreateUpdate(
776 "good", "foo", barValue, model_type));
777 // (Sending UPDATE here even though it's adding, since that's what the state
778 // of sync is. In any case, it won't work.)
779 change_list.push_back(settings_sync_util::CreateUpdate(
780 "bad", "foo", barValue, model_type));
781 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
785 base::DictionaryValue dict;
786 dict.Set("foo", barValue.DeepCopy());
787 dict.Set("bar", barValue.DeepCopy());
788 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
791 base::DictionaryValue dict;
792 dict.Set("bar", barValue.DeepCopy());
793 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
796 // Changes made to bad still shouldn't go to sync, even though it didn't fail
797 // last time.
798 sync_processor_->ClearChanges();
799 good->Set(DEFAULTS, "bar", fooValue);
800 bad->Set(DEFAULTS, "bar", fooValue);
802 EXPECT_EQ(
803 syncer::SyncChange::ACTION_UPDATE,
804 sync_processor_->GetOnlyChange("good", "bar").change_type());
805 EXPECT_EQ(1u, sync_processor_->changes().size());
808 base::DictionaryValue dict;
809 dict.Set("foo", barValue.DeepCopy());
810 dict.Set("bar", fooValue.DeepCopy());
811 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
814 base::DictionaryValue dict;
815 dict.Set("bar", fooValue.DeepCopy());
816 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
819 // Failing ProcessSyncChanges shouldn't go to the storage.
820 testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
822 syncer::SyncChangeList change_list;
823 change_list.push_back(settings_sync_util::CreateUpdate(
824 "good", "foo", fooValue, model_type));
825 // (Ditto.)
826 change_list.push_back(settings_sync_util::CreateUpdate(
827 "bad", "foo", fooValue, model_type));
828 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
830 testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
833 base::DictionaryValue dict;
834 dict.Set("foo", fooValue.DeepCopy());
835 dict.Set("bar", fooValue.DeepCopy());
836 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
839 base::DictionaryValue dict;
840 dict.Set("bar", fooValue.DeepCopy());
841 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
844 // Restarting sync should make bad start syncing again.
845 sync_processor_->ClearChanges();
846 GetSyncableService(model_type)->StopSyncing(model_type);
847 sync_processor_wrapper_.reset(
848 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
849 GetSyncableService(model_type)
850 ->MergeDataAndStartSyncing(
851 model_type,
852 syncer::SyncDataList(),
853 sync_processor_wrapper_.Pass(),
854 make_scoped_ptr(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).
858 EXPECT_EQ(
859 syncer::SyncChange::ACTION_ADD,
860 sync_processor_->GetOnlyChange("good", "foo").change_type());
861 EXPECT_EQ(
862 syncer::SyncChange::ACTION_ADD,
863 sync_processor_->GetOnlyChange("good", "bar").change_type());
864 EXPECT_EQ(
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);
874 EXPECT_EQ(
875 syncer::SyncChange::ACTION_UPDATE,
876 sync_processor_->GetOnlyChange("good", "bar").change_type());
877 EXPECT_EQ(
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 base::DictionaryValue dict;
894 dict.Set("foo", fooValue.DeepCopy());
895 dict.Set("bar", fooValue.DeepCopy());
896 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
899 base::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 base::StringValue fooValue("fooValue");
912 base::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)
928 ->MergeDataAndStartSyncing(
929 model_type,
930 sync_data,
931 sync_processor_wrapper_.Pass(),
932 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
935 EXPECT_EQ(0u, sync_processor_->changes().size());
938 base::DictionaryValue dict;
939 dict.Set("foo", fooValue.DeepCopy());
940 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
943 base::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 base::DictionaryValue dict;
962 dict.Set("foo", fooValue.DeepCopy());
963 dict.Set("bar", barValue.DeepCopy());
964 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
967 base::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);
977 EXPECT_EQ(
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 base::DictionaryValue dict;
994 dict.Set("foo", fooValue.DeepCopy());
995 dict.Set("bar", barValue.DeepCopy());
996 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
999 base::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 base::StringValue fooValue("fooValue");
1010 base::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", syncer::SyncDataLocal(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)
1034 ->MergeDataAndStartSyncing(
1035 model_type,
1036 syncer::SyncDataList(),
1037 sync_processor_wrapper_.Pass(),
1038 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1040 EXPECT_EQ(
1041 syncer::SyncChange::ACTION_ADD,
1042 sync_processor_->GetOnlyChange("good", "foo").change_type());
1043 EXPECT_EQ(
1044 syncer::SyncChange::ACTION_ADD,
1045 sync_processor_->GetOnlyChange("bad", "foo").change_type());
1046 EXPECT_EQ(2u, sync_processor_->changes().size());
1048 sync_processor_->ClearChanges();
1049 good->Set(DEFAULTS, "bar", barValue);
1050 bad->Set(DEFAULTS, "bar", barValue);
1052 EXPECT_EQ(
1053 syncer::SyncChange::ACTION_ADD,
1054 sync_processor_->GetOnlyChange("good", "bar").change_type());
1055 EXPECT_EQ(
1056 syncer::SyncChange::ACTION_ADD,
1057 sync_processor_->GetOnlyChange("bad", "bar").change_type());
1058 EXPECT_EQ(2u, sync_processor_->changes().size());
1061 TEST_F(ExtensionSettingsSyncTest, FailureToReadChangesToPushDisablesSync) {
1062 syncer::ModelType model_type = syncer::APP_SETTINGS;
1063 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
1065 base::StringValue fooValue("fooValue");
1066 base::StringValue barValue("barValue");
1068 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
1069 storage_factory_->Reset(testing_factory);
1071 ValueStore* good = AddExtensionAndGetStorage("good", type);
1072 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
1074 good->Set(DEFAULTS, "foo", fooValue);
1075 bad->Set(DEFAULTS, "foo", fooValue);
1077 // good will successfully push foo:fooValue to sync, but bad will fail to
1078 // get them so won't.
1079 testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
1080 GetSyncableService(model_type)
1081 ->MergeDataAndStartSyncing(
1082 model_type,
1083 syncer::SyncDataList(),
1084 sync_processor_wrapper_.Pass(),
1085 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1086 testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
1088 EXPECT_EQ(
1089 syncer::SyncChange::ACTION_ADD,
1090 sync_processor_->GetOnlyChange("good", "foo").change_type());
1091 EXPECT_EQ(1u, sync_processor_->changes().size());
1093 // bad should now be disabled for sync.
1094 sync_processor_->ClearChanges();
1095 good->Set(DEFAULTS, "bar", barValue);
1096 bad->Set(DEFAULTS, "bar", barValue);
1098 EXPECT_EQ(
1099 syncer::SyncChange::ACTION_ADD,
1100 sync_processor_->GetOnlyChange("good", "bar").change_type());
1101 EXPECT_EQ(1u, sync_processor_->changes().size());
1104 syncer::SyncChangeList change_list;
1105 change_list.push_back(settings_sync_util::CreateUpdate(
1106 "good", "foo", barValue, model_type));
1107 // (Sending ADD here even though it's updating, since that's what the state
1108 // of sync is. In any case, it won't work.)
1109 change_list.push_back(settings_sync_util::CreateAdd(
1110 "bad", "foo", barValue, model_type));
1111 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1115 base::DictionaryValue dict;
1116 dict.Set("foo", barValue.DeepCopy());
1117 dict.Set("bar", barValue.DeepCopy());
1118 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
1121 base::DictionaryValue dict;
1122 dict.Set("foo", fooValue.DeepCopy());
1123 dict.Set("bar", barValue.DeepCopy());
1124 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
1127 // Re-enabling sync without failing should cause the local changes from bad
1128 // to be pushed to sync successfully, as should future changes to bad.
1129 sync_processor_->ClearChanges();
1130 GetSyncableService(model_type)->StopSyncing(model_type);
1131 sync_processor_wrapper_.reset(
1132 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
1133 GetSyncableService(model_type)
1134 ->MergeDataAndStartSyncing(
1135 model_type,
1136 syncer::SyncDataList(),
1137 sync_processor_wrapper_.Pass(),
1138 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1140 EXPECT_EQ(
1141 syncer::SyncChange::ACTION_ADD,
1142 sync_processor_->GetOnlyChange("good", "foo").change_type());
1143 EXPECT_EQ(
1144 syncer::SyncChange::ACTION_ADD,
1145 sync_processor_->GetOnlyChange("good", "bar").change_type());
1146 EXPECT_EQ(
1147 syncer::SyncChange::ACTION_ADD,
1148 sync_processor_->GetOnlyChange("bad", "foo").change_type());
1149 EXPECT_EQ(
1150 syncer::SyncChange::ACTION_ADD,
1151 sync_processor_->GetOnlyChange("bad", "bar").change_type());
1152 EXPECT_EQ(4u, sync_processor_->changes().size());
1154 sync_processor_->ClearChanges();
1155 good->Set(DEFAULTS, "bar", fooValue);
1156 bad->Set(DEFAULTS, "bar", fooValue);
1158 EXPECT_EQ(
1159 syncer::SyncChange::ACTION_UPDATE,
1160 sync_processor_->GetOnlyChange("good", "bar").change_type());
1161 EXPECT_EQ(
1162 syncer::SyncChange::ACTION_UPDATE,
1163 sync_processor_->GetOnlyChange("good", "bar").change_type());
1164 EXPECT_EQ(2u, sync_processor_->changes().size());
1167 TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalStateDisablesSync) {
1168 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
1169 Manifest::Type type = Manifest::TYPE_EXTENSION;
1171 base::StringValue fooValue("fooValue");
1172 base::StringValue barValue("barValue");
1174 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
1175 storage_factory_->Reset(testing_factory);
1177 ValueStore* good = AddExtensionAndGetStorage("good", type);
1178 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
1180 // Only set bad; setting good will cause it to fail below.
1181 bad->Set(DEFAULTS, "foo", fooValue);
1183 sync_processor_->set_fail_all_requests(true);
1184 GetSyncableService(model_type)
1185 ->MergeDataAndStartSyncing(
1186 model_type,
1187 syncer::SyncDataList(),
1188 sync_processor_wrapper_.Pass(),
1189 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1190 sync_processor_->set_fail_all_requests(false);
1192 // Changes from good will be send to sync, changes from bad won't.
1193 sync_processor_->ClearChanges();
1194 good->Set(DEFAULTS, "foo", barValue);
1195 bad->Set(DEFAULTS, "foo", barValue);
1197 EXPECT_EQ(
1198 syncer::SyncChange::ACTION_ADD,
1199 sync_processor_->GetOnlyChange("good", "foo").change_type());
1200 EXPECT_EQ(1u, sync_processor_->changes().size());
1202 // Changes from sync will be sent to good, not to bad.
1204 syncer::SyncChangeList change_list;
1205 change_list.push_back(settings_sync_util::CreateAdd(
1206 "good", "bar", barValue, model_type));
1207 change_list.push_back(settings_sync_util::CreateAdd(
1208 "bad", "bar", barValue, model_type));
1209 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1213 base::DictionaryValue dict;
1214 dict.Set("foo", barValue.DeepCopy());
1215 dict.Set("bar", barValue.DeepCopy());
1216 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
1219 base::DictionaryValue dict;
1220 dict.Set("foo", barValue.DeepCopy());
1221 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
1224 // Restarting sync makes everything work again.
1225 sync_processor_->ClearChanges();
1226 GetSyncableService(model_type)->StopSyncing(model_type);
1227 sync_processor_wrapper_.reset(
1228 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
1229 GetSyncableService(model_type)
1230 ->MergeDataAndStartSyncing(
1231 model_type,
1232 syncer::SyncDataList(),
1233 sync_processor_wrapper_.Pass(),
1234 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1236 EXPECT_EQ(
1237 syncer::SyncChange::ACTION_ADD,
1238 sync_processor_->GetOnlyChange("good", "foo").change_type());
1239 EXPECT_EQ(
1240 syncer::SyncChange::ACTION_ADD,
1241 sync_processor_->GetOnlyChange("good", "bar").change_type());
1242 EXPECT_EQ(
1243 syncer::SyncChange::ACTION_ADD,
1244 sync_processor_->GetOnlyChange("bad", "foo").change_type());
1245 EXPECT_EQ(3u, sync_processor_->changes().size());
1247 sync_processor_->ClearChanges();
1248 good->Set(DEFAULTS, "foo", fooValue);
1249 bad->Set(DEFAULTS, "foo", fooValue);
1251 EXPECT_EQ(
1252 syncer::SyncChange::ACTION_UPDATE,
1253 sync_processor_->GetOnlyChange("good", "foo").change_type());
1254 EXPECT_EQ(
1255 syncer::SyncChange::ACTION_UPDATE,
1256 sync_processor_->GetOnlyChange("good", "foo").change_type());
1257 EXPECT_EQ(2u, sync_processor_->changes().size());
1260 TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalChangeDisablesSync) {
1261 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
1262 Manifest::Type type = Manifest::TYPE_EXTENSION;
1264 base::StringValue fooValue("fooValue");
1265 base::StringValue barValue("barValue");
1267 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
1268 storage_factory_->Reset(testing_factory);
1270 ValueStore* good = AddExtensionAndGetStorage("good", type);
1271 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
1273 GetSyncableService(model_type)
1274 ->MergeDataAndStartSyncing(
1275 model_type,
1276 syncer::SyncDataList(),
1277 sync_processor_wrapper_.Pass(),
1278 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1280 // bad will fail to send changes.
1281 good->Set(DEFAULTS, "foo", fooValue);
1282 sync_processor_->set_fail_all_requests(true);
1283 bad->Set(DEFAULTS, "foo", fooValue);
1284 sync_processor_->set_fail_all_requests(false);
1286 EXPECT_EQ(
1287 syncer::SyncChange::ACTION_ADD,
1288 sync_processor_->GetOnlyChange("good", "foo").change_type());
1289 EXPECT_EQ(1u, sync_processor_->changes().size());
1291 // No further changes should be sent from bad.
1292 sync_processor_->ClearChanges();
1293 good->Set(DEFAULTS, "foo", barValue);
1294 bad->Set(DEFAULTS, "foo", barValue);
1296 EXPECT_EQ(
1297 syncer::SyncChange::ACTION_UPDATE,
1298 sync_processor_->GetOnlyChange("good", "foo").change_type());
1299 EXPECT_EQ(1u, sync_processor_->changes().size());
1301 // Changes from sync will be sent to good, not to bad.
1303 syncer::SyncChangeList change_list;
1304 change_list.push_back(settings_sync_util::CreateAdd(
1305 "good", "bar", barValue, model_type));
1306 change_list.push_back(settings_sync_util::CreateAdd(
1307 "bad", "bar", barValue, model_type));
1308 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1312 base::DictionaryValue dict;
1313 dict.Set("foo", barValue.DeepCopy());
1314 dict.Set("bar", barValue.DeepCopy());
1315 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
1318 base::DictionaryValue dict;
1319 dict.Set("foo", barValue.DeepCopy());
1320 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
1323 // Restarting sync makes everything work again.
1324 sync_processor_->ClearChanges();
1325 GetSyncableService(model_type)->StopSyncing(model_type);
1326 sync_processor_wrapper_.reset(
1327 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
1328 GetSyncableService(model_type)
1329 ->MergeDataAndStartSyncing(
1330 model_type,
1331 syncer::SyncDataList(),
1332 sync_processor_wrapper_.Pass(),
1333 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1335 EXPECT_EQ(
1336 syncer::SyncChange::ACTION_ADD,
1337 sync_processor_->GetOnlyChange("good", "foo").change_type());
1338 EXPECT_EQ(
1339 syncer::SyncChange::ACTION_ADD,
1340 sync_processor_->GetOnlyChange("good", "bar").change_type());
1341 EXPECT_EQ(
1342 syncer::SyncChange::ACTION_ADD,
1343 sync_processor_->GetOnlyChange("bad", "foo").change_type());
1344 EXPECT_EQ(3u, sync_processor_->changes().size());
1346 sync_processor_->ClearChanges();
1347 good->Set(DEFAULTS, "foo", fooValue);
1348 bad->Set(DEFAULTS, "foo", fooValue);
1350 EXPECT_EQ(
1351 syncer::SyncChange::ACTION_UPDATE,
1352 sync_processor_->GetOnlyChange("good", "foo").change_type());
1353 EXPECT_EQ(
1354 syncer::SyncChange::ACTION_UPDATE,
1355 sync_processor_->GetOnlyChange("good", "foo").change_type());
1356 EXPECT_EQ(2u, sync_processor_->changes().size());
1359 TEST_F(ExtensionSettingsSyncTest,
1360 LargeOutgoingChangeRejectedButIncomingAccepted) {
1361 syncer::ModelType model_type = syncer::APP_SETTINGS;
1362 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
1364 // This value should be larger than the limit in sync_storage_backend.cc.
1365 std::string string_10k;
1366 for (size_t i = 0; i < 10000; ++i) {
1367 string_10k.append("a");
1369 base::StringValue large_value(string_10k);
1371 GetSyncableService(model_type)
1372 ->MergeDataAndStartSyncing(
1373 model_type,
1374 syncer::SyncDataList(),
1375 sync_processor_wrapper_.Pass(),
1376 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1378 // Large local change rejected and doesn't get sent out.
1379 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
1380 EXPECT_TRUE(storage1->Set(DEFAULTS, "large_value", large_value)->HasError());
1381 EXPECT_EQ(0u, sync_processor_->changes().size());
1383 // Large incoming change should still get accepted.
1384 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
1386 syncer::SyncChangeList change_list;
1387 change_list.push_back(settings_sync_util::CreateAdd(
1388 "s1", "large_value", large_value, model_type));
1389 change_list.push_back(settings_sync_util::CreateAdd(
1390 "s2", "large_value", large_value, model_type));
1391 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1394 base::DictionaryValue expected;
1395 expected.Set("large_value", large_value.DeepCopy());
1396 EXPECT_PRED_FORMAT2(SettingsEq, expected, storage1->Get());
1397 EXPECT_PRED_FORMAT2(SettingsEq, expected, storage2->Get());
1400 GetSyncableService(model_type)->StopSyncing(model_type);
1403 TEST_F(ExtensionSettingsSyncTest, Dots) {
1404 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
1405 Manifest::Type type = Manifest::TYPE_EXTENSION;
1407 ValueStore* storage = AddExtensionAndGetStorage("ext", type);
1410 syncer::SyncDataList sync_data_list;
1411 scoped_ptr<base::Value> string_value(new base::StringValue("value"));
1412 sync_data_list.push_back(settings_sync_util::CreateData(
1413 "ext", "key.with.dot", *string_value, model_type));
1415 GetSyncableService(model_type)
1416 ->MergeDataAndStartSyncing(
1417 model_type,
1418 sync_data_list,
1419 sync_processor_wrapper_.Pass(),
1420 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1423 // Test dots in keys that come from sync.
1425 ValueStore::ReadResult data = storage->Get();
1426 ASSERT_FALSE(data->HasError());
1428 base::DictionaryValue expected_data;
1429 expected_data.SetWithoutPathExpansion(
1430 "key.with.dot",
1431 new base::StringValue("value"));
1432 EXPECT_TRUE(base::Value::Equals(&expected_data, &data->settings()));
1435 // Test dots in keys going to sync.
1437 scoped_ptr<base::Value> string_value(new base::StringValue("spot"));
1438 storage->Set(DEFAULTS, "key.with.spot", *string_value);
1440 ASSERT_EQ(1u, sync_processor_->changes().size());
1441 SettingSyncData sync_data = sync_processor_->changes()[0];
1442 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, sync_data.change_type());
1443 EXPECT_EQ("ext", sync_data.extension_id());
1444 EXPECT_EQ("key.with.spot", sync_data.key());
1445 EXPECT_TRUE(sync_data.value().Equals(string_value.get()));
1449 // In other (frontend) tests, we assume that the result of GetStorage
1450 // is a pointer to the a Storage owned by a Frontend object, but for
1451 // the unlimitedStorage case, this might not be true. So, write the
1452 // tests in a "callback" style. We should really rewrite all tests to
1453 // be asynchronous in this way.
1455 namespace {
1457 static void UnlimitedSyncStorageTestCallback(ValueStore* sync_storage) {
1458 // Sync storage should still run out after ~100K; the unlimitedStorage
1459 // permission can't apply to sync.
1460 scoped_ptr<base::Value> kilobyte = util::CreateKilobyte();
1461 for (int i = 0; i < 100; ++i) {
1462 sync_storage->Set(
1463 ValueStore::DEFAULTS, base::StringPrintf("%d", i), *kilobyte);
1466 EXPECT_TRUE(sync_storage->Set(ValueStore::DEFAULTS, "WillError", *kilobyte)
1467 ->HasError());
1470 static void UnlimitedLocalStorageTestCallback(ValueStore* local_storage) {
1471 // Local storage should never run out.
1472 scoped_ptr<base::Value> megabyte = util::CreateMegabyte();
1473 for (int i = 0; i < 7; ++i) {
1474 local_storage->Set(
1475 ValueStore::DEFAULTS, base::StringPrintf("%d", i), *megabyte);
1478 EXPECT_FALSE(local_storage->Set(ValueStore::DEFAULTS, "WontError", *megabyte)
1479 ->HasError());
1482 } // namespace
1484 #if defined(OS_WIN)
1485 // See: http://crbug.com/227296
1486 #define MAYBE_UnlimitedStorageForLocalButNotSync \
1487 DISABLED_UnlimitedStorageForLocalButNotSync
1488 #else
1489 #define MAYBE_UnlimitedStorageForLocalButNotSync \
1490 UnlimitedStorageForLocalButNotSync
1491 #endif
1492 TEST_F(ExtensionSettingsSyncTest, MAYBE_UnlimitedStorageForLocalButNotSync) {
1493 const std::string id = "ext";
1494 std::set<std::string> permissions;
1495 permissions.insert("unlimitedStorage");
1496 scoped_refptr<const Extension> extension =
1497 util::AddExtensionWithIdAndPermissions(
1498 profile_.get(), id, Manifest::TYPE_EXTENSION, permissions);
1500 frontend_->RunWithStorage(extension,
1501 settings_namespace::SYNC,
1502 base::Bind(&UnlimitedSyncStorageTestCallback));
1503 frontend_->RunWithStorage(extension,
1504 settings_namespace::LOCAL,
1505 base::Bind(&UnlimitedLocalStorageTestCallback));
1507 base::MessageLoop::current()->RunUntilIdle();
1510 } // namespace extensions