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