OLD | NEW |
| (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 | |
OLD | NEW |