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

Side by Side Diff: chrome/browser/extensions/settings/settings_sync_unittest.cc

Issue 11747025: Run the JSON Schema Compiler's bundle compilation on JSON files. Previously it (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix ms release build Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include "testing/gtest/include/gtest/gtest.h"
6
7 #include "base/bind.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/json/json_reader.h"
10 #include "base/json/json_writer.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop.h"
13 #include "chrome/browser/extensions/extension_system.h"
14 #include "chrome/browser/extensions/settings/leveldb_settings_storage_factory.h"
15 #include "chrome/browser/extensions/settings/settings_frontend.h"
16 #include "chrome/browser/extensions/settings/settings_storage_factory.h"
17 #include "chrome/browser/extensions/settings/settings_sync_util.h"
18 #include "chrome/browser/extensions/settings/settings_test_util.h"
19 #include "chrome/browser/extensions/settings/syncable_settings_storage.h"
20 #include "chrome/browser/extensions/test_extension_service.h"
21 #include "chrome/browser/value_store/testing_value_store.h"
22 #include "content/public/test/test_browser_thread.h"
23 #include "sync/api/sync_change_processor.h"
24 #include "sync/api/sync_error_factory.h"
25 #include "sync/api/sync_error_factory_mock.h"
26
27 using content::BrowserThread;
28
29 namespace extensions {
30
31 namespace util = settings_test_util;
32
33 namespace {
34
35 // To save typing ValueStore::DEFAULTS everywhere.
36 const ValueStore::WriteOptions DEFAULTS = ValueStore::DEFAULTS;
37
38 // Gets the pretty-printed JSON for a value.
39 static std::string GetJson(const Value& value) {
40 std::string json;
41 base::JSONWriter::WriteWithOptions(&value,
42 base::JSONWriter::OPTIONS_PRETTY_PRINT,
43 &json);
44 return json;
45 }
46
47 // Returns whether two Values are equal.
48 testing::AssertionResult ValuesEq(
49 const char* _1, const char* _2,
50 const Value* expected,
51 const Value* actual) {
52 if (expected == actual) {
53 return testing::AssertionSuccess();
54 }
55 if (!expected && actual) {
56 return testing::AssertionFailure() <<
57 "Expected NULL, actual: " << GetJson(*actual);
58 }
59 if (expected && !actual) {
60 return testing::AssertionFailure() <<
61 "Expected: " << GetJson(*expected) << ", actual NULL";
62 }
63 if (!expected->Equals(actual)) {
64 return testing::AssertionFailure() <<
65 "Expected: " << GetJson(*expected) << ", actual: " << GetJson(*actual);
66 }
67 return testing::AssertionSuccess();
68 }
69
70 // Returns whether the result of a storage operation is an expected value.
71 // Logs when different.
72 testing::AssertionResult SettingsEq(
73 const char* _1, const char* _2,
74 const DictionaryValue& expected,
75 ValueStore::ReadResult actual) {
76 if (actual->HasError()) {
77 return testing::AssertionFailure() <<
78 "Expected: " << GetJson(expected) <<
79 ", actual has error: " << actual->error();
80 }
81 return ValuesEq(_1, _2, &expected, actual->settings().get());
82 }
83
84 // SyncChangeProcessor which just records the changes made, accessed after
85 // being converted to the more useful SettingSyncData via changes().
86 class MockSyncChangeProcessor : public syncer::SyncChangeProcessor {
87 public:
88 MockSyncChangeProcessor() : fail_all_requests_(false) {}
89
90 // syncer::SyncChangeProcessor implementation.
91 virtual syncer::SyncError ProcessSyncChanges(
92 const tracked_objects::Location& from_here,
93 const syncer::SyncChangeList& change_list) OVERRIDE {
94 if (fail_all_requests_) {
95 return syncer::SyncError(
96 FROM_HERE,
97 "MockSyncChangeProcessor: configured to fail",
98 change_list[0].sync_data().GetDataType());
99 }
100 for (syncer::SyncChangeList::const_iterator it = change_list.begin();
101 it != change_list.end(); ++it) {
102 changes_.push_back(SettingSyncData(*it));
103 }
104 return syncer::SyncError();
105 }
106
107 // Mock methods.
108
109 const SettingSyncDataList& changes() { return changes_; }
110
111 void ClearChanges() {
112 changes_.clear();
113 }
114
115 void SetFailAllRequests(bool fail_all_requests) {
116 fail_all_requests_ = fail_all_requests;
117 }
118
119 // Returns the only change for a given extension setting. If there is not
120 // exactly 1 change for that key, a test assertion will fail.
121 SettingSyncData GetOnlyChange(
122 const std::string& extension_id, const std::string& key) {
123 SettingSyncDataList matching_changes;
124 for (SettingSyncDataList::iterator it = changes_.begin();
125 it != changes_.end(); ++it) {
126 if (it->extension_id() == extension_id && it->key() == key) {
127 matching_changes.push_back(*it);
128 }
129 }
130 if (matching_changes.empty()) {
131 ADD_FAILURE() << "No matching changes for " << extension_id << "/" <<
132 key << " (out of " << changes_.size() << ")";
133 return SettingSyncData(
134 syncer::SyncChange::ACTION_INVALID, "", "",
135 scoped_ptr<Value>(new DictionaryValue()));
136 }
137 if (matching_changes.size() != 1u) {
138 ADD_FAILURE() << matching_changes.size() << " matching changes for " <<
139 extension_id << "/" << key << " (out of " << changes_.size() << ")";
140 }
141 return matching_changes[0];
142 }
143
144 private:
145 SettingSyncDataList changes_;
146 bool fail_all_requests_;
147 };
148
149 class SyncChangeProcessorDelegate : public syncer::SyncChangeProcessor {
150 public:
151 explicit SyncChangeProcessorDelegate(syncer::SyncChangeProcessor* recipient)
152 : recipient_(recipient) {
153 DCHECK(recipient_);
154 }
155 virtual ~SyncChangeProcessorDelegate() {}
156
157 // syncer::SyncChangeProcessor implementation.
158 virtual syncer::SyncError ProcessSyncChanges(
159 const tracked_objects::Location& from_here,
160 const syncer::SyncChangeList& change_list) OVERRIDE {
161 return recipient_->ProcessSyncChanges(from_here, change_list);
162 }
163
164 private:
165 // The recipient of all sync changes.
166 syncer::SyncChangeProcessor* recipient_;
167
168 DISALLOW_COPY_AND_ASSIGN(SyncChangeProcessorDelegate);
169 };
170
171 // SettingsStorageFactory which always returns TestingValueStore objects,
172 // and allows individually created objects to be returned.
173 class TestingValueStoreFactory : public SettingsStorageFactory {
174 public:
175 TestingValueStore* GetExisting(const std::string& extension_id) {
176 DCHECK(created_.count(extension_id));
177 return created_[extension_id];
178 }
179
180 // SettingsStorageFactory implementation.
181 virtual ValueStore* Create(const FilePath& base_path,
182 const std::string& extension_id) OVERRIDE {
183 TestingValueStore* new_storage = new TestingValueStore();
184 DCHECK(!created_.count(extension_id));
185 created_[extension_id] = new_storage;
186 return new_storage;
187 }
188
189 private:
190 // SettingsStorageFactory is refcounted.
191 virtual ~TestingValueStoreFactory() {}
192
193 // None of these storage areas are owned by this factory, so care must be
194 // taken when calling GetExisting.
195 std::map<std::string, TestingValueStore*> created_;
196 };
197
198 } // namespace
199
200 class ExtensionSettingsSyncTest : public testing::Test {
201 public:
202 ExtensionSettingsSyncTest()
203 : ui_thread_(BrowserThread::UI, MessageLoop::current()),
204 file_thread_(BrowserThread::FILE, MessageLoop::current()),
205 storage_factory_(new util::ScopedSettingsStorageFactory()),
206 sync_processor_(new MockSyncChangeProcessor),
207 sync_processor_delegate_(new SyncChangeProcessorDelegate(
208 sync_processor_.get())) {}
209
210 virtual void SetUp() OVERRIDE {
211 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
212 profile_.reset(new util::MockProfile(temp_dir_.path()));
213 storage_factory_->Reset(new LeveldbSettingsStorageFactory());
214 frontend_.reset(
215 SettingsFrontend::Create(storage_factory_.get(), profile_.get()));
216 }
217
218 virtual void TearDown() OVERRIDE {
219 frontend_.reset();
220 profile_.reset();
221 // Execute any pending deletion tasks.
222 message_loop_.RunUntilIdle();
223 }
224
225 protected:
226 // Adds a record of an extension or app to the extension service, then returns
227 // its storage area.
228 ValueStore* AddExtensionAndGetStorage(
229 const std::string& id, Extension::Type type) {
230 ExtensionServiceInterface* esi =
231 extensions::ExtensionSystem::Get(profile_.get())->extension_service();
232 static_cast<extensions::settings_test_util::MockExtensionService*>(esi)->
233 AddExtensionWithId(id, type);
234 return util::GetStorage(id, frontend_.get());
235 }
236
237 // Gets the syncer::SyncableService for the given sync type.
238 syncer::SyncableService* GetSyncableService(syncer::ModelType model_type) {
239 MessageLoop::current()->RunUntilIdle();
240 return frontend_->GetBackendForSync(model_type);
241 }
242
243 // Gets all the sync data from the SyncableService for a sync type as a map
244 // from extension id to its sync data.
245 std::map<std::string, SettingSyncDataList> GetAllSyncData(
246 syncer::ModelType model_type) {
247 syncer::SyncDataList as_list =
248 GetSyncableService(model_type)->GetAllSyncData(model_type);
249 std::map<std::string, SettingSyncDataList> as_map;
250 for (syncer::SyncDataList::iterator it = as_list.begin();
251 it != as_list.end(); ++it) {
252 SettingSyncData sync_data(*it);
253 as_map[sync_data.extension_id()].push_back(sync_data);
254 }
255 return as_map;
256 }
257
258 // Need these so that the DCHECKs for running on FILE or UI threads pass.
259 MessageLoop message_loop_;
260 content::TestBrowserThread ui_thread_;
261 content::TestBrowserThread file_thread_;
262
263 base::ScopedTempDir temp_dir_;
264 scoped_ptr<util::MockProfile> profile_;
265 scoped_ptr<SettingsFrontend> frontend_;
266 scoped_refptr<util::ScopedSettingsStorageFactory> storage_factory_;
267 scoped_ptr<MockSyncChangeProcessor> sync_processor_;
268 scoped_ptr<SyncChangeProcessorDelegate> sync_processor_delegate_;
269 };
270
271 // Get a semblance of coverage for both EXTENSION_SETTINGS and APP_SETTINGS
272 // sync by roughly alternative which one to test.
273
274 TEST_F(ExtensionSettingsSyncTest, NoDataDoesNotInvokeSync) {
275 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
276 Extension::Type type = Extension::TYPE_EXTENSION;
277
278 EXPECT_EQ(0u, GetAllSyncData(model_type).size());
279
280 // Have one extension created before sync is set up, the other created after.
281 AddExtensionAndGetStorage("s1", type);
282 EXPECT_EQ(0u, GetAllSyncData(model_type).size());
283
284 GetSyncableService(model_type)->MergeDataAndStartSyncing(
285 model_type,
286 syncer::SyncDataList(),
287 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
288 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
289
290 AddExtensionAndGetStorage("s2", type);
291 EXPECT_EQ(0u, GetAllSyncData(model_type).size());
292
293 GetSyncableService(model_type)->StopSyncing(model_type);
294
295 EXPECT_EQ(0u, sync_processor_->changes().size());
296 EXPECT_EQ(0u, GetAllSyncData(model_type).size());
297 }
298
299 TEST_F(ExtensionSettingsSyncTest, InSyncDataDoesNotInvokeSync) {
300 syncer::ModelType model_type = syncer::APP_SETTINGS;
301 Extension::Type type = Extension::TYPE_LEGACY_PACKAGED_APP;
302
303 StringValue value1("fooValue");
304 ListValue value2;
305 value2.Append(StringValue::CreateStringValue("barValue"));
306
307 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
308 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
309
310 storage1->Set(DEFAULTS, "foo", value1);
311 storage2->Set(DEFAULTS, "bar", value2);
312
313 std::map<std::string, SettingSyncDataList> all_sync_data =
314 GetAllSyncData(model_type);
315 EXPECT_EQ(2u, all_sync_data.size());
316 EXPECT_EQ(1u, all_sync_data["s1"].size());
317 EXPECT_PRED_FORMAT2(ValuesEq, &value1, &all_sync_data["s1"][0].value());
318 EXPECT_EQ(1u, all_sync_data["s2"].size());
319 EXPECT_PRED_FORMAT2(ValuesEq, &value2, &all_sync_data["s2"][0].value());
320
321 syncer::SyncDataList sync_data;
322 sync_data.push_back(settings_sync_util::CreateData(
323 "s1", "foo", value1, model_type));
324 sync_data.push_back(settings_sync_util::CreateData(
325 "s2", "bar", value2, model_type));
326
327 GetSyncableService(model_type)->MergeDataAndStartSyncing(
328 model_type, sync_data,
329 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
330 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
331
332 // Already in sync, so no changes.
333 EXPECT_EQ(0u, sync_processor_->changes().size());
334
335 // Regression test: not-changing the synced value shouldn't result in a sync
336 // change, and changing the synced value should result in an update.
337 storage1->Set(DEFAULTS, "foo", value1);
338 EXPECT_EQ(0u, sync_processor_->changes().size());
339
340 storage1->Set(DEFAULTS, "foo", value2);
341 EXPECT_EQ(1u, sync_processor_->changes().size());
342 SettingSyncData change = sync_processor_->GetOnlyChange("s1", "foo");
343 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
344 EXPECT_TRUE(value2.Equals(&change.value()));
345
346 GetSyncableService(model_type)->StopSyncing(model_type);
347 }
348
349 TEST_F(ExtensionSettingsSyncTest, LocalDataWithNoSyncDataIsPushedToSync) {
350 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
351 Extension::Type type = Extension::TYPE_EXTENSION;
352
353 StringValue value1("fooValue");
354 ListValue value2;
355 value2.Append(StringValue::CreateStringValue("barValue"));
356
357 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
358 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
359
360 storage1->Set(DEFAULTS, "foo", value1);
361 storage2->Set(DEFAULTS, "bar", value2);
362
363 GetSyncableService(model_type)->MergeDataAndStartSyncing(
364 model_type,
365 syncer::SyncDataList(),
366 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
367 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
368
369 // All settings should have been pushed to sync.
370 EXPECT_EQ(2u, sync_processor_->changes().size());
371 SettingSyncData change = sync_processor_->GetOnlyChange("s1", "foo");
372 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
373 EXPECT_TRUE(value1.Equals(&change.value()));
374 change = sync_processor_->GetOnlyChange("s2", "bar");
375 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
376 EXPECT_TRUE(value2.Equals(&change.value()));
377
378 GetSyncableService(model_type)->StopSyncing(model_type);
379 }
380
381 TEST_F(ExtensionSettingsSyncTest, AnySyncDataOverwritesLocalData) {
382 syncer::ModelType model_type = syncer::APP_SETTINGS;
383 Extension::Type type = Extension::TYPE_LEGACY_PACKAGED_APP;
384
385 StringValue value1("fooValue");
386 ListValue value2;
387 value2.Append(StringValue::CreateStringValue("barValue"));
388
389 // Maintain dictionaries mirrored to the expected values of the settings in
390 // each storage area.
391 DictionaryValue expected1, expected2;
392
393 // Pre-populate one of the storage areas.
394 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
395 storage1->Set(DEFAULTS, "overwriteMe", value1);
396
397 syncer::SyncDataList sync_data;
398 sync_data.push_back(settings_sync_util::CreateData(
399 "s1", "foo", value1, model_type));
400 sync_data.push_back(settings_sync_util::CreateData(
401 "s2", "bar", value2, model_type));
402 GetSyncableService(model_type)->MergeDataAndStartSyncing(
403 model_type, sync_data,
404 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
405 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
406 expected1.Set("foo", value1.DeepCopy());
407 expected2.Set("bar", value2.DeepCopy());
408
409 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
410
411 // All changes should be local, so no sync changes.
412 EXPECT_EQ(0u, sync_processor_->changes().size());
413
414 // Sync settings should have been pushed to local settings.
415 EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
416 EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
417
418 GetSyncableService(model_type)->StopSyncing(model_type);
419 }
420
421 TEST_F(ExtensionSettingsSyncTest, ProcessSyncChanges) {
422 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
423 Extension::Type type = Extension::TYPE_EXTENSION;
424
425 StringValue value1("fooValue");
426 ListValue value2;
427 value2.Append(StringValue::CreateStringValue("barValue"));
428
429 // Maintain dictionaries mirrored to the expected values of the settings in
430 // each storage area.
431 DictionaryValue expected1, expected2;
432
433 // Make storage1 initialised from local data, storage2 initialised from sync.
434 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
435 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
436
437 storage1->Set(DEFAULTS, "foo", value1);
438 expected1.Set("foo", value1.DeepCopy());
439
440 syncer::SyncDataList sync_data;
441 sync_data.push_back(settings_sync_util::CreateData(
442 "s2", "bar", value2, model_type));
443
444 GetSyncableService(model_type)->MergeDataAndStartSyncing(
445 model_type, sync_data,
446 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
447 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
448 expected2.Set("bar", value2.DeepCopy());
449
450 // Make sync add some settings.
451 syncer::SyncChangeList change_list;
452 change_list.push_back(settings_sync_util::CreateAdd(
453 "s1", "bar", value2, model_type));
454 change_list.push_back(settings_sync_util::CreateAdd(
455 "s2", "foo", value1, model_type));
456 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
457 expected1.Set("bar", value2.DeepCopy());
458 expected2.Set("foo", value1.DeepCopy());
459
460 EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
461 EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
462
463 // Make sync update some settings, storage1 the new setting, storage2 the
464 // initial setting.
465 change_list.clear();
466 change_list.push_back(settings_sync_util::CreateUpdate(
467 "s1", "bar", value2, model_type));
468 change_list.push_back(settings_sync_util::CreateUpdate(
469 "s2", "bar", value1, model_type));
470 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
471 expected1.Set("bar", value2.DeepCopy());
472 expected2.Set("bar", value1.DeepCopy());
473
474 EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
475 EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
476
477 // Make sync remove some settings, storage1 the initial setting, storage2 the
478 // new setting.
479 change_list.clear();
480 change_list.push_back(settings_sync_util::CreateDelete(
481 "s1", "foo", model_type));
482 change_list.push_back(settings_sync_util::CreateDelete(
483 "s2", "foo", model_type));
484 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
485 expected1.Remove("foo", NULL);
486 expected2.Remove("foo", NULL);
487
488 EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
489 EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
490
491 GetSyncableService(model_type)->StopSyncing(model_type);
492 }
493
494 TEST_F(ExtensionSettingsSyncTest, PushToSync) {
495 syncer::ModelType model_type = syncer::APP_SETTINGS;
496 Extension::Type type = Extension::TYPE_LEGACY_PACKAGED_APP;
497
498 StringValue value1("fooValue");
499 ListValue value2;
500 value2.Append(StringValue::CreateStringValue("barValue"));
501
502 // Make storage1/2 initialised from local data, storage3/4 initialised from
503 // sync.
504 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
505 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
506 ValueStore* storage3 = AddExtensionAndGetStorage("s3", type);
507 ValueStore* storage4 = AddExtensionAndGetStorage("s4", type);
508
509 storage1->Set(DEFAULTS, "foo", value1);
510 storage2->Set(DEFAULTS, "foo", value1);
511
512 syncer::SyncDataList sync_data;
513 sync_data.push_back(settings_sync_util::CreateData(
514 "s3", "bar", value2, model_type));
515 sync_data.push_back(settings_sync_util::CreateData(
516 "s4", "bar", value2, model_type));
517
518 GetSyncableService(model_type)->MergeDataAndStartSyncing(
519 model_type, sync_data,
520 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
521 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
522
523 // Add something locally.
524 storage1->Set(DEFAULTS, "bar", value2);
525 storage2->Set(DEFAULTS, "bar", value2);
526 storage3->Set(DEFAULTS, "foo", value1);
527 storage4->Set(DEFAULTS, "foo", value1);
528
529 SettingSyncData change = sync_processor_->GetOnlyChange("s1", "bar");
530 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
531 EXPECT_TRUE(value2.Equals(&change.value()));
532 sync_processor_->GetOnlyChange("s2", "bar");
533 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
534 EXPECT_TRUE(value2.Equals(&change.value()));
535 change = sync_processor_->GetOnlyChange("s3", "foo");
536 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
537 EXPECT_TRUE(value1.Equals(&change.value()));
538 change = sync_processor_->GetOnlyChange("s4", "foo");
539 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
540 EXPECT_TRUE(value1.Equals(&change.value()));
541
542 // Change something locally, storage1/3 the new setting and storage2/4 the
543 // initial setting, for all combinations of local vs sync intialisation and
544 // new vs initial.
545 sync_processor_->ClearChanges();
546 storage1->Set(DEFAULTS, "bar", value1);
547 storage2->Set(DEFAULTS, "foo", value2);
548 storage3->Set(DEFAULTS, "bar", value1);
549 storage4->Set(DEFAULTS, "foo", value2);
550
551 change = sync_processor_->GetOnlyChange("s1", "bar");
552 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
553 EXPECT_TRUE(value1.Equals(&change.value()));
554 change = sync_processor_->GetOnlyChange("s2", "foo");
555 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
556 EXPECT_TRUE(value2.Equals(&change.value()));
557 change = sync_processor_->GetOnlyChange("s3", "bar");
558 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
559 EXPECT_TRUE(value1.Equals(&change.value()));
560 change = sync_processor_->GetOnlyChange("s4", "foo");
561 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
562 EXPECT_TRUE(value2.Equals(&change.value()));
563
564 // Remove something locally, storage1/3 the new setting and storage2/4 the
565 // initial setting, for all combinations of local vs sync intialisation and
566 // new vs initial.
567 sync_processor_->ClearChanges();
568 storage1->Remove("foo");
569 storage2->Remove("bar");
570 storage3->Remove("foo");
571 storage4->Remove("bar");
572
573 EXPECT_EQ(
574 syncer::SyncChange::ACTION_DELETE,
575 sync_processor_->GetOnlyChange("s1", "foo").change_type());
576 EXPECT_EQ(
577 syncer::SyncChange::ACTION_DELETE,
578 sync_processor_->GetOnlyChange("s2", "bar").change_type());
579 EXPECT_EQ(
580 syncer::SyncChange::ACTION_DELETE,
581 sync_processor_->GetOnlyChange("s3", "foo").change_type());
582 EXPECT_EQ(
583 syncer::SyncChange::ACTION_DELETE,
584 sync_processor_->GetOnlyChange("s4", "bar").change_type());
585
586 // Remove some nonexistent settings.
587 sync_processor_->ClearChanges();
588 storage1->Remove("foo");
589 storage2->Remove("bar");
590 storage3->Remove("foo");
591 storage4->Remove("bar");
592
593 EXPECT_EQ(0u, sync_processor_->changes().size());
594
595 // Clear the rest of the settings. Add the removed ones back first so that
596 // more than one setting is cleared.
597 storage1->Set(DEFAULTS, "foo", value1);
598 storage2->Set(DEFAULTS, "bar", value2);
599 storage3->Set(DEFAULTS, "foo", value1);
600 storage4->Set(DEFAULTS, "bar", value2);
601
602 sync_processor_->ClearChanges();
603 storage1->Clear();
604 storage2->Clear();
605 storage3->Clear();
606 storage4->Clear();
607
608 EXPECT_EQ(
609 syncer::SyncChange::ACTION_DELETE,
610 sync_processor_->GetOnlyChange("s1", "foo").change_type());
611 EXPECT_EQ(
612 syncer::SyncChange::ACTION_DELETE,
613 sync_processor_->GetOnlyChange("s1", "bar").change_type());
614 EXPECT_EQ(
615 syncer::SyncChange::ACTION_DELETE,
616 sync_processor_->GetOnlyChange("s2", "foo").change_type());
617 EXPECT_EQ(
618 syncer::SyncChange::ACTION_DELETE,
619 sync_processor_->GetOnlyChange("s2", "bar").change_type());
620 EXPECT_EQ(
621 syncer::SyncChange::ACTION_DELETE,
622 sync_processor_->GetOnlyChange("s3", "foo").change_type());
623 EXPECT_EQ(
624 syncer::SyncChange::ACTION_DELETE,
625 sync_processor_->GetOnlyChange("s3", "bar").change_type());
626 EXPECT_EQ(
627 syncer::SyncChange::ACTION_DELETE,
628 sync_processor_->GetOnlyChange("s4", "foo").change_type());
629 EXPECT_EQ(
630 syncer::SyncChange::ACTION_DELETE,
631 sync_processor_->GetOnlyChange("s4", "bar").change_type());
632
633 GetSyncableService(model_type)->StopSyncing(model_type);
634 }
635
636 TEST_F(ExtensionSettingsSyncTest, ExtensionAndAppSettingsSyncSeparately) {
637 StringValue value1("fooValue");
638 ListValue value2;
639 value2.Append(StringValue::CreateStringValue("barValue"));
640
641 // storage1 is an extension, storage2 is an app.
642 ValueStore* storage1 = AddExtensionAndGetStorage(
643 "s1", Extension::TYPE_EXTENSION);
644 ValueStore* storage2 = AddExtensionAndGetStorage(
645 "s2", Extension::TYPE_LEGACY_PACKAGED_APP);
646
647 storage1->Set(DEFAULTS, "foo", value1);
648 storage2->Set(DEFAULTS, "bar", value2);
649
650 std::map<std::string, SettingSyncDataList> extension_sync_data =
651 GetAllSyncData(syncer::EXTENSION_SETTINGS);
652 EXPECT_EQ(1u, extension_sync_data.size());
653 EXPECT_EQ(1u, extension_sync_data["s1"].size());
654 EXPECT_PRED_FORMAT2(ValuesEq, &value1, &extension_sync_data["s1"][0].value());
655
656 std::map<std::string, SettingSyncDataList> app_sync_data =
657 GetAllSyncData(syncer::APP_SETTINGS);
658 EXPECT_EQ(1u, app_sync_data.size());
659 EXPECT_EQ(1u, app_sync_data["s2"].size());
660 EXPECT_PRED_FORMAT2(ValuesEq, &value2, &app_sync_data["s2"][0].value());
661
662 // Stop each separately, there should be no changes either time.
663 syncer::SyncDataList sync_data;
664 sync_data.push_back(settings_sync_util::CreateData(
665 "s1", "foo", value1, syncer::EXTENSION_SETTINGS));
666
667 GetSyncableService(syncer::EXTENSION_SETTINGS)->MergeDataAndStartSyncing(
668 syncer::EXTENSION_SETTINGS,
669 sync_data,
670 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
671 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
672 GetSyncableService(syncer::EXTENSION_SETTINGS)->
673 StopSyncing(syncer::EXTENSION_SETTINGS);
674 EXPECT_EQ(0u, sync_processor_->changes().size());
675
676 sync_data.clear();
677 sync_data.push_back(settings_sync_util::CreateData(
678 "s2", "bar", value2, syncer::APP_SETTINGS));
679
680 scoped_ptr<SyncChangeProcessorDelegate> app_settings_delegate_(
681 new SyncChangeProcessorDelegate(sync_processor_.get()));
682 GetSyncableService(syncer::APP_SETTINGS)->MergeDataAndStartSyncing(
683 syncer::APP_SETTINGS,
684 sync_data,
685 app_settings_delegate_.PassAs<syncer::SyncChangeProcessor>(),
686 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
687 GetSyncableService(syncer::APP_SETTINGS)->
688 StopSyncing(syncer::APP_SETTINGS);
689 EXPECT_EQ(0u, sync_processor_->changes().size());
690 }
691
692 TEST_F(ExtensionSettingsSyncTest, FailingStartSyncingDisablesSync) {
693 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
694 Extension::Type type = Extension::TYPE_EXTENSION;
695
696 StringValue fooValue("fooValue");
697 StringValue barValue("barValue");
698
699 // There is a bit of a convoluted method to get storage areas that can fail;
700 // hand out TestingValueStore object then toggle them failing/succeeding
701 // as necessary.
702 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
703 storage_factory_->Reset(testing_factory);
704
705 ValueStore* good = AddExtensionAndGetStorage("good", type);
706 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
707
708 // Make bad fail for incoming sync changes.
709 testing_factory->GetExisting("bad")->SetFailAllRequests(true);
710 {
711 syncer::SyncDataList sync_data;
712 sync_data.push_back(settings_sync_util::CreateData(
713 "good", "foo", fooValue, model_type));
714 sync_data.push_back(settings_sync_util::CreateData(
715 "bad", "foo", fooValue, model_type));
716 GetSyncableService(model_type)->MergeDataAndStartSyncing(
717 model_type,
718 sync_data,
719 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
720 scoped_ptr<syncer::SyncErrorFactory>(
721 new syncer::SyncErrorFactoryMock()));
722 }
723 testing_factory->GetExisting("bad")->SetFailAllRequests(false);
724
725 {
726 DictionaryValue dict;
727 dict.Set("foo", fooValue.DeepCopy());
728 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
729 }
730 {
731 DictionaryValue dict;
732 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
733 }
734
735 // Changes made to good should be sent to sync, changes from bad shouldn't.
736 sync_processor_->ClearChanges();
737 good->Set(DEFAULTS, "bar", barValue);
738 bad->Set(DEFAULTS, "bar", barValue);
739
740 EXPECT_EQ(
741 syncer::SyncChange::ACTION_ADD,
742 sync_processor_->GetOnlyChange("good", "bar").change_type());
743 EXPECT_EQ(1u, sync_processor_->changes().size());
744
745 {
746 DictionaryValue dict;
747 dict.Set("foo", fooValue.DeepCopy());
748 dict.Set("bar", barValue.DeepCopy());
749 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
750 }
751 {
752 DictionaryValue dict;
753 dict.Set("bar", barValue.DeepCopy());
754 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
755 }
756
757 // Changes received from sync should go to good but not bad (even when it's
758 // not failing).
759 {
760 syncer::SyncChangeList change_list;
761 change_list.push_back(settings_sync_util::CreateUpdate(
762 "good", "foo", barValue, model_type));
763 // (Sending UPDATE here even though it's adding, since that's what the state
764 // of sync is. In any case, it won't work.)
765 change_list.push_back(settings_sync_util::CreateUpdate(
766 "bad", "foo", barValue, model_type));
767 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
768 }
769
770 {
771 DictionaryValue dict;
772 dict.Set("foo", barValue.DeepCopy());
773 dict.Set("bar", barValue.DeepCopy());
774 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
775 }
776 {
777 DictionaryValue dict;
778 dict.Set("bar", barValue.DeepCopy());
779 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
780 }
781
782 // Changes made to bad still shouldn't go to sync, even though it didn't fail
783 // last time.
784 sync_processor_->ClearChanges();
785 good->Set(DEFAULTS, "bar", fooValue);
786 bad->Set(DEFAULTS, "bar", fooValue);
787
788 EXPECT_EQ(
789 syncer::SyncChange::ACTION_UPDATE,
790 sync_processor_->GetOnlyChange("good", "bar").change_type());
791 EXPECT_EQ(1u, sync_processor_->changes().size());
792
793 {
794 DictionaryValue dict;
795 dict.Set("foo", barValue.DeepCopy());
796 dict.Set("bar", fooValue.DeepCopy());
797 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
798 }
799 {
800 DictionaryValue dict;
801 dict.Set("bar", fooValue.DeepCopy());
802 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
803 }
804
805 // Failing ProcessSyncChanges shouldn't go to the storage.
806 testing_factory->GetExisting("bad")->SetFailAllRequests(true);
807 {
808 syncer::SyncChangeList change_list;
809 change_list.push_back(settings_sync_util::CreateUpdate(
810 "good", "foo", fooValue, model_type));
811 // (Ditto.)
812 change_list.push_back(settings_sync_util::CreateUpdate(
813 "bad", "foo", fooValue, model_type));
814 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
815 }
816 testing_factory->GetExisting("bad")->SetFailAllRequests(false);
817
818 {
819 DictionaryValue dict;
820 dict.Set("foo", fooValue.DeepCopy());
821 dict.Set("bar", fooValue.DeepCopy());
822 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
823 }
824 {
825 DictionaryValue dict;
826 dict.Set("bar", fooValue.DeepCopy());
827 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
828 }
829
830 // Restarting sync should make bad start syncing again.
831 sync_processor_->ClearChanges();
832 GetSyncableService(model_type)->StopSyncing(model_type);
833 sync_processor_delegate_.reset(new SyncChangeProcessorDelegate(
834 sync_processor_.get()));
835 GetSyncableService(model_type)->MergeDataAndStartSyncing(
836 model_type,
837 syncer::SyncDataList(),
838 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
839 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
840
841 // Local settings will have been pushed to sync, since it's empty (in this
842 // test; presumably it wouldn't be live, since we've been getting changes).
843 EXPECT_EQ(
844 syncer::SyncChange::ACTION_ADD,
845 sync_processor_->GetOnlyChange("good", "foo").change_type());
846 EXPECT_EQ(
847 syncer::SyncChange::ACTION_ADD,
848 sync_processor_->GetOnlyChange("good", "bar").change_type());
849 EXPECT_EQ(
850 syncer::SyncChange::ACTION_ADD,
851 sync_processor_->GetOnlyChange("bad", "bar").change_type());
852 EXPECT_EQ(3u, sync_processor_->changes().size());
853
854 // Live local changes now get pushed, too.
855 sync_processor_->ClearChanges();
856 good->Set(DEFAULTS, "bar", barValue);
857 bad->Set(DEFAULTS, "bar", barValue);
858
859 EXPECT_EQ(
860 syncer::SyncChange::ACTION_UPDATE,
861 sync_processor_->GetOnlyChange("good", "bar").change_type());
862 EXPECT_EQ(
863 syncer::SyncChange::ACTION_UPDATE,
864 sync_processor_->GetOnlyChange("bad", "bar").change_type());
865 EXPECT_EQ(2u, sync_processor_->changes().size());
866
867 // And ProcessSyncChanges work, too.
868 {
869 syncer::SyncChangeList change_list;
870 change_list.push_back(settings_sync_util::CreateUpdate(
871 "good", "bar", fooValue, model_type));
872 change_list.push_back(settings_sync_util::CreateUpdate(
873 "bad", "bar", fooValue, model_type));
874 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
875 }
876
877 {
878 DictionaryValue dict;
879 dict.Set("foo", fooValue.DeepCopy());
880 dict.Set("bar", fooValue.DeepCopy());
881 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
882 }
883 {
884 DictionaryValue dict;
885 dict.Set("bar", fooValue.DeepCopy());
886 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
887 }
888 }
889
890 TEST_F(ExtensionSettingsSyncTest, FailingProcessChangesDisablesSync) {
891 // The test above tests a failing ProcessSyncChanges too, but here test with
892 // an initially passing MergeDataAndStartSyncing.
893 syncer::ModelType model_type = syncer::APP_SETTINGS;
894 Extension::Type type = Extension::TYPE_LEGACY_PACKAGED_APP;
895
896 StringValue fooValue("fooValue");
897 StringValue barValue("barValue");
898
899 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
900 storage_factory_->Reset(testing_factory);
901
902 ValueStore* good = AddExtensionAndGetStorage("good", type);
903 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
904
905 // Unlike before, initially succeeding MergeDataAndStartSyncing.
906 {
907 syncer::SyncDataList sync_data;
908 sync_data.push_back(settings_sync_util::CreateData(
909 "good", "foo", fooValue, model_type));
910 sync_data.push_back(settings_sync_util::CreateData(
911 "bad", "foo", fooValue, model_type));
912 GetSyncableService(model_type)->MergeDataAndStartSyncing(
913 model_type,
914 sync_data,
915 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
916 scoped_ptr<syncer::SyncErrorFactory>(
917 new syncer::SyncErrorFactoryMock()));
918 }
919
920 EXPECT_EQ(0u, sync_processor_->changes().size());
921
922 {
923 DictionaryValue dict;
924 dict.Set("foo", fooValue.DeepCopy());
925 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
926 }
927 {
928 DictionaryValue dict;
929 dict.Set("foo", fooValue.DeepCopy());
930 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
931 }
932
933 // Now fail ProcessSyncChanges for bad.
934 testing_factory->GetExisting("bad")->SetFailAllRequests(true);
935 {
936 syncer::SyncChangeList change_list;
937 change_list.push_back(settings_sync_util::CreateAdd(
938 "good", "bar", barValue, model_type));
939 change_list.push_back(settings_sync_util::CreateAdd(
940 "bad", "bar", barValue, model_type));
941 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
942 }
943 testing_factory->GetExisting("bad")->SetFailAllRequests(false);
944
945 {
946 DictionaryValue dict;
947 dict.Set("foo", fooValue.DeepCopy());
948 dict.Set("bar", barValue.DeepCopy());
949 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
950 }
951 {
952 DictionaryValue dict;
953 dict.Set("foo", fooValue.DeepCopy());
954 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
955 }
956
957 // No more changes sent to sync for bad.
958 sync_processor_->ClearChanges();
959 good->Set(DEFAULTS, "foo", barValue);
960 bad->Set(DEFAULTS, "foo", barValue);
961
962 EXPECT_EQ(
963 syncer::SyncChange::ACTION_UPDATE,
964 sync_processor_->GetOnlyChange("good", "foo").change_type());
965 EXPECT_EQ(1u, sync_processor_->changes().size());
966
967 // No more changes received from sync should go to bad.
968 {
969 syncer::SyncChangeList change_list;
970 change_list.push_back(settings_sync_util::CreateAdd(
971 "good", "foo", fooValue, model_type));
972 change_list.push_back(settings_sync_util::CreateAdd(
973 "bad", "foo", fooValue, model_type));
974 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
975 }
976
977 {
978 DictionaryValue dict;
979 dict.Set("foo", fooValue.DeepCopy());
980 dict.Set("bar", barValue.DeepCopy());
981 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
982 }
983 {
984 DictionaryValue dict;
985 dict.Set("foo", barValue.DeepCopy());
986 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
987 }
988 }
989
990 TEST_F(ExtensionSettingsSyncTest, FailingGetAllSyncDataDoesntStopSync) {
991 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
992 Extension::Type type = Extension::TYPE_EXTENSION;
993
994 StringValue fooValue("fooValue");
995 StringValue barValue("barValue");
996
997 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
998 storage_factory_->Reset(testing_factory);
999
1000 ValueStore* good = AddExtensionAndGetStorage("good", type);
1001 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
1002
1003 good->Set(DEFAULTS, "foo", fooValue);
1004 bad->Set(DEFAULTS, "foo", fooValue);
1005
1006 // Even though bad will fail to get all sync data, sync data should still
1007 // include that from good.
1008 testing_factory->GetExisting("bad")->SetFailAllRequests(true);
1009 {
1010 syncer::SyncDataList all_sync_data =
1011 GetSyncableService(model_type)->GetAllSyncData(model_type);
1012 EXPECT_EQ(1u, all_sync_data.size());
1013 EXPECT_EQ("good/foo", all_sync_data[0].GetTag());
1014 }
1015 testing_factory->GetExisting("bad")->SetFailAllRequests(false);
1016
1017 // Sync shouldn't be disabled for good (nor bad -- but this is unimportant).
1018 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1019 model_type,
1020 syncer::SyncDataList(),
1021 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
1022 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1023
1024 EXPECT_EQ(
1025 syncer::SyncChange::ACTION_ADD,
1026 sync_processor_->GetOnlyChange("good", "foo").change_type());
1027 EXPECT_EQ(
1028 syncer::SyncChange::ACTION_ADD,
1029 sync_processor_->GetOnlyChange("bad", "foo").change_type());
1030 EXPECT_EQ(2u, sync_processor_->changes().size());
1031
1032 sync_processor_->ClearChanges();
1033 good->Set(DEFAULTS, "bar", barValue);
1034 bad->Set(DEFAULTS, "bar", barValue);
1035
1036 EXPECT_EQ(
1037 syncer::SyncChange::ACTION_ADD,
1038 sync_processor_->GetOnlyChange("good", "bar").change_type());
1039 EXPECT_EQ(
1040 syncer::SyncChange::ACTION_ADD,
1041 sync_processor_->GetOnlyChange("bad", "bar").change_type());
1042 EXPECT_EQ(2u, sync_processor_->changes().size());
1043 }
1044
1045 TEST_F(ExtensionSettingsSyncTest, FailureToReadChangesToPushDisablesSync) {
1046 syncer::ModelType model_type = syncer::APP_SETTINGS;
1047 Extension::Type type = Extension::TYPE_LEGACY_PACKAGED_APP;
1048
1049 StringValue fooValue("fooValue");
1050 StringValue barValue("barValue");
1051
1052 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
1053 storage_factory_->Reset(testing_factory);
1054
1055 ValueStore* good = AddExtensionAndGetStorage("good", type);
1056 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
1057
1058 good->Set(DEFAULTS, "foo", fooValue);
1059 bad->Set(DEFAULTS, "foo", fooValue);
1060
1061 // good will successfully push foo:fooValue to sync, but bad will fail to
1062 // get them so won't.
1063 testing_factory->GetExisting("bad")->SetFailAllRequests(true);
1064 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1065 model_type,
1066 syncer::SyncDataList(),
1067 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
1068 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1069 testing_factory->GetExisting("bad")->SetFailAllRequests(false);
1070
1071 EXPECT_EQ(
1072 syncer::SyncChange::ACTION_ADD,
1073 sync_processor_->GetOnlyChange("good", "foo").change_type());
1074 EXPECT_EQ(1u, sync_processor_->changes().size());
1075
1076 // bad should now be disabled for sync.
1077 sync_processor_->ClearChanges();
1078 good->Set(DEFAULTS, "bar", barValue);
1079 bad->Set(DEFAULTS, "bar", barValue);
1080
1081 EXPECT_EQ(
1082 syncer::SyncChange::ACTION_ADD,
1083 sync_processor_->GetOnlyChange("good", "bar").change_type());
1084 EXPECT_EQ(1u, sync_processor_->changes().size());
1085
1086 {
1087 syncer::SyncChangeList change_list;
1088 change_list.push_back(settings_sync_util::CreateUpdate(
1089 "good", "foo", barValue, model_type));
1090 // (Sending ADD here even though it's updating, since that's what the state
1091 // of sync is. In any case, it won't work.)
1092 change_list.push_back(settings_sync_util::CreateAdd(
1093 "bad", "foo", barValue, model_type));
1094 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1095 }
1096
1097 {
1098 DictionaryValue dict;
1099 dict.Set("foo", barValue.DeepCopy());
1100 dict.Set("bar", barValue.DeepCopy());
1101 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
1102 }
1103 {
1104 DictionaryValue dict;
1105 dict.Set("foo", fooValue.DeepCopy());
1106 dict.Set("bar", barValue.DeepCopy());
1107 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
1108 }
1109
1110 // Re-enabling sync without failing should cause the local changes from bad
1111 // to be pushed to sync successfully, as should future changes to bad.
1112 sync_processor_->ClearChanges();
1113 GetSyncableService(model_type)->StopSyncing(model_type);
1114 sync_processor_delegate_.reset(new SyncChangeProcessorDelegate(
1115 sync_processor_.get()));
1116 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1117 model_type,
1118 syncer::SyncDataList(),
1119 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
1120 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1121
1122 EXPECT_EQ(
1123 syncer::SyncChange::ACTION_ADD,
1124 sync_processor_->GetOnlyChange("good", "foo").change_type());
1125 EXPECT_EQ(
1126 syncer::SyncChange::ACTION_ADD,
1127 sync_processor_->GetOnlyChange("good", "bar").change_type());
1128 EXPECT_EQ(
1129 syncer::SyncChange::ACTION_ADD,
1130 sync_processor_->GetOnlyChange("bad", "foo").change_type());
1131 EXPECT_EQ(
1132 syncer::SyncChange::ACTION_ADD,
1133 sync_processor_->GetOnlyChange("bad", "bar").change_type());
1134 EXPECT_EQ(4u, sync_processor_->changes().size());
1135
1136 sync_processor_->ClearChanges();
1137 good->Set(DEFAULTS, "bar", fooValue);
1138 bad->Set(DEFAULTS, "bar", fooValue);
1139
1140 EXPECT_EQ(
1141 syncer::SyncChange::ACTION_UPDATE,
1142 sync_processor_->GetOnlyChange("good", "bar").change_type());
1143 EXPECT_EQ(
1144 syncer::SyncChange::ACTION_UPDATE,
1145 sync_processor_->GetOnlyChange("good", "bar").change_type());
1146 EXPECT_EQ(2u, sync_processor_->changes().size());
1147 }
1148
1149 TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalStateDisablesSync) {
1150 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
1151 Extension::Type type = Extension::TYPE_EXTENSION;
1152
1153 StringValue fooValue("fooValue");
1154 StringValue barValue("barValue");
1155
1156 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
1157 storage_factory_->Reset(testing_factory);
1158
1159 ValueStore* good = AddExtensionAndGetStorage("good", type);
1160 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
1161
1162 // Only set bad; setting good will cause it to fail below.
1163 bad->Set(DEFAULTS, "foo", fooValue);
1164
1165 sync_processor_->SetFailAllRequests(true);
1166 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1167 model_type,
1168 syncer::SyncDataList(),
1169 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
1170 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1171 sync_processor_->SetFailAllRequests(false);
1172
1173 // Changes from good will be send to sync, changes from bad won't.
1174 sync_processor_->ClearChanges();
1175 good->Set(DEFAULTS, "foo", barValue);
1176 bad->Set(DEFAULTS, "foo", barValue);
1177
1178 EXPECT_EQ(
1179 syncer::SyncChange::ACTION_ADD,
1180 sync_processor_->GetOnlyChange("good", "foo").change_type());
1181 EXPECT_EQ(1u, sync_processor_->changes().size());
1182
1183 // Changes from sync will be sent to good, not to bad.
1184 {
1185 syncer::SyncChangeList change_list;
1186 change_list.push_back(settings_sync_util::CreateAdd(
1187 "good", "bar", barValue, model_type));
1188 change_list.push_back(settings_sync_util::CreateAdd(
1189 "bad", "bar", barValue, model_type));
1190 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1191 }
1192
1193 {
1194 DictionaryValue dict;
1195 dict.Set("foo", barValue.DeepCopy());
1196 dict.Set("bar", barValue.DeepCopy());
1197 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
1198 }
1199 {
1200 DictionaryValue dict;
1201 dict.Set("foo", barValue.DeepCopy());
1202 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
1203 }
1204
1205 // Restarting sync makes everything work again.
1206 sync_processor_->ClearChanges();
1207 GetSyncableService(model_type)->StopSyncing(model_type);
1208 sync_processor_delegate_.reset(new SyncChangeProcessorDelegate(
1209 sync_processor_.get()));
1210 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1211 model_type,
1212 syncer::SyncDataList(),
1213 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
1214 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1215
1216 EXPECT_EQ(
1217 syncer::SyncChange::ACTION_ADD,
1218 sync_processor_->GetOnlyChange("good", "foo").change_type());
1219 EXPECT_EQ(
1220 syncer::SyncChange::ACTION_ADD,
1221 sync_processor_->GetOnlyChange("good", "bar").change_type());
1222 EXPECT_EQ(
1223 syncer::SyncChange::ACTION_ADD,
1224 sync_processor_->GetOnlyChange("bad", "foo").change_type());
1225 EXPECT_EQ(3u, sync_processor_->changes().size());
1226
1227 sync_processor_->ClearChanges();
1228 good->Set(DEFAULTS, "foo", fooValue);
1229 bad->Set(DEFAULTS, "foo", fooValue);
1230
1231 EXPECT_EQ(
1232 syncer::SyncChange::ACTION_UPDATE,
1233 sync_processor_->GetOnlyChange("good", "foo").change_type());
1234 EXPECT_EQ(
1235 syncer::SyncChange::ACTION_UPDATE,
1236 sync_processor_->GetOnlyChange("good", "foo").change_type());
1237 EXPECT_EQ(2u, sync_processor_->changes().size());
1238 }
1239
1240 TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalChangeDisablesSync) {
1241 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
1242 Extension::Type type = Extension::TYPE_EXTENSION;
1243
1244 StringValue fooValue("fooValue");
1245 StringValue barValue("barValue");
1246
1247 TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
1248 storage_factory_->Reset(testing_factory);
1249
1250 ValueStore* good = AddExtensionAndGetStorage("good", type);
1251 ValueStore* bad = AddExtensionAndGetStorage("bad", type);
1252
1253 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1254 model_type,
1255 syncer::SyncDataList(),
1256 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
1257 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1258
1259 // bad will fail to send changes.
1260 good->Set(DEFAULTS, "foo", fooValue);
1261 sync_processor_->SetFailAllRequests(true);
1262 bad->Set(DEFAULTS, "foo", fooValue);
1263 sync_processor_->SetFailAllRequests(false);
1264
1265 EXPECT_EQ(
1266 syncer::SyncChange::ACTION_ADD,
1267 sync_processor_->GetOnlyChange("good", "foo").change_type());
1268 EXPECT_EQ(1u, sync_processor_->changes().size());
1269
1270 // No further changes should be sent from bad.
1271 sync_processor_->ClearChanges();
1272 good->Set(DEFAULTS, "foo", barValue);
1273 bad->Set(DEFAULTS, "foo", barValue);
1274
1275 EXPECT_EQ(
1276 syncer::SyncChange::ACTION_UPDATE,
1277 sync_processor_->GetOnlyChange("good", "foo").change_type());
1278 EXPECT_EQ(1u, sync_processor_->changes().size());
1279
1280 // Changes from sync will be sent to good, not to bad.
1281 {
1282 syncer::SyncChangeList change_list;
1283 change_list.push_back(settings_sync_util::CreateAdd(
1284 "good", "bar", barValue, model_type));
1285 change_list.push_back(settings_sync_util::CreateAdd(
1286 "bad", "bar", barValue, model_type));
1287 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1288 }
1289
1290 {
1291 DictionaryValue dict;
1292 dict.Set("foo", barValue.DeepCopy());
1293 dict.Set("bar", barValue.DeepCopy());
1294 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
1295 }
1296 {
1297 DictionaryValue dict;
1298 dict.Set("foo", barValue.DeepCopy());
1299 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
1300 }
1301
1302 // Restarting sync makes everything work again.
1303 sync_processor_->ClearChanges();
1304 GetSyncableService(model_type)->StopSyncing(model_type);
1305 sync_processor_delegate_.reset(new SyncChangeProcessorDelegate(
1306 sync_processor_.get()));
1307 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1308 model_type,
1309 syncer::SyncDataList(),
1310 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
1311 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1312
1313 EXPECT_EQ(
1314 syncer::SyncChange::ACTION_ADD,
1315 sync_processor_->GetOnlyChange("good", "foo").change_type());
1316 EXPECT_EQ(
1317 syncer::SyncChange::ACTION_ADD,
1318 sync_processor_->GetOnlyChange("good", "bar").change_type());
1319 EXPECT_EQ(
1320 syncer::SyncChange::ACTION_ADD,
1321 sync_processor_->GetOnlyChange("bad", "foo").change_type());
1322 EXPECT_EQ(3u, sync_processor_->changes().size());
1323
1324 sync_processor_->ClearChanges();
1325 good->Set(DEFAULTS, "foo", fooValue);
1326 bad->Set(DEFAULTS, "foo", fooValue);
1327
1328 EXPECT_EQ(
1329 syncer::SyncChange::ACTION_UPDATE,
1330 sync_processor_->GetOnlyChange("good", "foo").change_type());
1331 EXPECT_EQ(
1332 syncer::SyncChange::ACTION_UPDATE,
1333 sync_processor_->GetOnlyChange("good", "foo").change_type());
1334 EXPECT_EQ(2u, sync_processor_->changes().size());
1335 }
1336
1337 TEST_F(ExtensionSettingsSyncTest,
1338 LargeOutgoingChangeRejectedButIncomingAccepted) {
1339 syncer::ModelType model_type = syncer::APP_SETTINGS;
1340 Extension::Type type = Extension::TYPE_LEGACY_PACKAGED_APP;
1341
1342 // This value should be larger than the limit in settings_backend.cc.
1343 std::string string_5k;
1344 for (size_t i = 0; i < 5000; ++i) {
1345 string_5k.append("a");
1346 }
1347 StringValue large_value(string_5k);
1348
1349 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1350 model_type,
1351 syncer::SyncDataList(),
1352 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
1353 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1354
1355 // Large local change rejected and doesn't get sent out.
1356 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
1357 EXPECT_TRUE(storage1->Set(DEFAULTS, "large_value", large_value)->HasError());
1358 EXPECT_EQ(0u, sync_processor_->changes().size());
1359
1360 // Large incoming change should still get accepted.
1361 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
1362 {
1363 syncer::SyncChangeList change_list;
1364 change_list.push_back(settings_sync_util::CreateAdd(
1365 "s1", "large_value", large_value, model_type));
1366 change_list.push_back(settings_sync_util::CreateAdd(
1367 "s2", "large_value", large_value, model_type));
1368 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1369 }
1370 {
1371 DictionaryValue expected;
1372 expected.Set("large_value", large_value.DeepCopy());
1373 EXPECT_PRED_FORMAT2(SettingsEq, expected, storage1->Get());
1374 EXPECT_PRED_FORMAT2(SettingsEq, expected, storage2->Get());
1375 }
1376
1377 GetSyncableService(model_type)->StopSyncing(model_type);
1378 }
1379
1380 TEST_F(ExtensionSettingsSyncTest, Dots) {
1381 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
1382 Extension::Type type = Extension::TYPE_EXTENSION;
1383
1384 ValueStore* storage = AddExtensionAndGetStorage("ext", type);
1385
1386 {
1387 syncer::SyncDataList sync_data_list;
1388 scoped_ptr<Value> string_value(Value::CreateStringValue("value"));
1389 sync_data_list.push_back(settings_sync_util::CreateData(
1390 "ext", "key.with.dot", *string_value, model_type));
1391
1392 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1393 model_type,
1394 sync_data_list,
1395 sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>(),
1396 scoped_ptr<syncer::SyncErrorFactory>(
1397 new syncer::SyncErrorFactoryMock()));
1398 }
1399
1400 // Test dots in keys that come from sync.
1401 {
1402 ValueStore::ReadResult data = storage->Get();
1403 ASSERT_FALSE(data->HasError());
1404
1405 DictionaryValue expected_data;
1406 expected_data.SetWithoutPathExpansion(
1407 "key.with.dot",
1408 Value::CreateStringValue("value"));
1409 EXPECT_TRUE(Value::Equals(&expected_data, data->settings().get()));
1410 }
1411
1412 // Test dots in keys going to sync.
1413 {
1414 scoped_ptr<Value> string_value(Value::CreateStringValue("spot"));
1415 storage->Set(DEFAULTS, "key.with.spot", *string_value);
1416
1417 ASSERT_EQ(1u, sync_processor_->changes().size());
1418 SettingSyncData sync_data = sync_processor_->changes()[0];
1419 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, sync_data.change_type());
1420 EXPECT_EQ("ext", sync_data.extension_id());
1421 EXPECT_EQ("key.with.spot", sync_data.key());
1422 EXPECT_TRUE(sync_data.value().Equals(string_value.get()));
1423 }
1424 }
1425
1426 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/settings/settings_sync_processor.cc ('k') | chrome/browser/extensions/settings/settings_sync_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698