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

Side by Side Diff: chrome/browser/extensions/api/storage/settings_sync_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698