settings_sync_unittest.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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/message_loop.h" 11#include "chrome/browser/extensions/api/storage/settings_sync_util.h" 12#include "chrome/browser/extensions/api/storage/sync_value_store_cache.h" 13#include "chrome/browser/extensions/api/storage/syncable_settings_storage.h" 14#include "content/public/test/test_browser_thread.h" 15#include "extensions/browser/api/storage/leveldb_settings_storage_factory.h" 16#include "extensions/browser/api/storage/settings_storage_factory.h" 17#include "extensions/browser/api/storage/settings_test_util.h" 18#include "extensions/browser/api/storage/storage_frontend.h" 19#include "extensions/browser/extension_system.h" 20#include "extensions/browser/value_store/testing_value_store.h" 21#include "extensions/common/manifest.h" 22#include "sync/api/sync_change_processor.h" 23#include "sync/api/sync_change_processor_wrapper_for_test.h" 24#include "sync/api/sync_error_factory.h" 25#include "sync/api/sync_error_factory_mock.h" 26#include "testing/gtest/include/gtest/gtest.h" 27 28using base::DictionaryValue; 29using base::ListValue; 30using base::Value; 31using content::BrowserThread; 32 33namespace extensions { 34 35namespace util = settings_test_util; 36 37namespace { 38 39// To save typing ValueStore::DEFAULTS everywhere. 40const ValueStore::WriteOptions DEFAULTS = ValueStore::DEFAULTS; 41 42// Gets the pretty-printed JSON for a value. 43static std::string GetJson(const base::Value& value) { 44 std::string json; 45 base::JSONWriter::WriteWithOptions(&value, 46 base::JSONWriter::OPTIONS_PRETTY_PRINT, 47 &json); 48 return json; 49} 50 51// Returns whether two Values are equal. 52testing::AssertionResult ValuesEq( 53 const char* _1, const char* _2, 54 const base::Value* expected, 55 const base::Value* actual) { 56 if (expected == actual) { 57 return testing::AssertionSuccess(); 58 } 59 if (!expected && actual) { 60 return testing::AssertionFailure() << 61 "Expected NULL, actual: " << GetJson(*actual); 62 } 63 if (expected && !actual) { 64 return testing::AssertionFailure() << 65 "Expected: " << GetJson(*expected) << ", actual NULL"; 66 } 67 if (!expected->Equals(actual)) { 68 return testing::AssertionFailure() << 69 "Expected: " << GetJson(*expected) << ", actual: " << GetJson(*actual); 70 } 71 return testing::AssertionSuccess(); 72} 73 74// Returns whether the result of a storage operation is an expected value. 75// Logs when different. 76testing::AssertionResult SettingsEq( 77 const char* _1, const char* _2, 78 const base::DictionaryValue& expected, 79 ValueStore::ReadResult actual) { 80 if (actual->HasError()) { 81 return testing::AssertionFailure() << 82 "Expected: " << expected << 83 ", actual has error: " << actual->error().message; 84 } 85 return ValuesEq(_1, _2, &expected, &actual->settings()); 86} 87 88// SyncChangeProcessor which just records the changes made, accessed after 89// being converted to the more useful SettingSyncData via changes(). 90class MockSyncChangeProcessor : public syncer::SyncChangeProcessor { 91 public: 92 MockSyncChangeProcessor() : fail_all_requests_(false) {} 93 94 // syncer::SyncChangeProcessor implementation. 95 virtual syncer::SyncError ProcessSyncChanges( 96 const tracked_objects::Location& from_here, 97 const syncer::SyncChangeList& change_list) OVERRIDE { 98 if (fail_all_requests_) { 99 return syncer::SyncError( 100 FROM_HERE, 101 syncer::SyncError::DATATYPE_ERROR, 102 "MockSyncChangeProcessor: configured to fail", 103 change_list[0].sync_data().GetDataType()); 104 } 105 for (syncer::SyncChangeList::const_iterator it = change_list.begin(); 106 it != change_list.end(); ++it) { 107 changes_.push_back(SettingSyncData(*it)); 108 } 109 return syncer::SyncError(); 110 } 111 112 virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const 113 OVERRIDE { 114 return syncer::SyncDataList(); 115 } 116 117 // Mock methods. 118 119 const SettingSyncDataList& changes() { return changes_; } 120 121 void ClearChanges() { 122 changes_.clear(); 123 } 124 125 void set_fail_all_requests(bool fail_all_requests) { 126 fail_all_requests_ = fail_all_requests; 127 } 128 129 // Returns the only change for a given extension setting. If there is not 130 // exactly 1 change for that key, a test assertion will fail. 131 SettingSyncData GetOnlyChange( 132 const std::string& extension_id, const std::string& key) { 133 SettingSyncDataList matching_changes; 134 for (SettingSyncDataList::iterator it = changes_.begin(); 135 it != changes_.end(); ++it) { 136 if (it->extension_id() == extension_id && it->key() == key) { 137 matching_changes.push_back(*it); 138 } 139 } 140 if (matching_changes.empty()) { 141 ADD_FAILURE() << "No matching changes for " << extension_id << "/" << 142 key << " (out of " << changes_.size() << ")"; 143 return SettingSyncData(syncer::SyncChange::ACTION_INVALID, 144 std::string(), 145 std::string(), 146 scoped_ptr<base::Value>( 147 new base::DictionaryValue())); 148 } 149 if (matching_changes.size() != 1u) { 150 ADD_FAILURE() << matching_changes.size() << " matching changes for " << 151 extension_id << "/" << key << " (out of " << changes_.size() << ")"; 152 } 153 return matching_changes[0]; 154 } 155 156 private: 157 SettingSyncDataList changes_; 158 bool fail_all_requests_; 159}; 160 161// SettingsStorageFactory which always returns TestingValueStore objects, 162// and allows individually created objects to be returned. 163class TestingValueStoreFactory : public SettingsStorageFactory { 164 public: 165 TestingValueStore* GetExisting(const std::string& extension_id) { 166 DCHECK(created_.count(extension_id)); 167 return created_[extension_id]; 168 } 169 170 // SettingsStorageFactory implementation. 171 virtual ValueStore* Create(const base::FilePath& base_path, 172 const std::string& extension_id) OVERRIDE { 173 TestingValueStore* new_storage = new TestingValueStore(); 174 DCHECK(!created_.count(extension_id)); 175 created_[extension_id] = new_storage; 176 return new_storage; 177 } 178 179 // Testing value stores don't actually create a real database. Don't delete 180 // any files. 181 virtual void DeleteDatabaseIfExists( 182 const base::FilePath& base_path, 183 const std::string& extension_id) OVERRIDE {} 184 185 private: 186 // SettingsStorageFactory is refcounted. 187 virtual ~TestingValueStoreFactory() {} 188 189 // None of these storage areas are owned by this factory, so care must be 190 // taken when calling GetExisting. 191 std::map<std::string, TestingValueStore*> created_; 192}; 193 194} // namespace 195 196class ExtensionSettingsSyncTest : public testing::Test { 197 public: 198 ExtensionSettingsSyncTest() 199 : ui_thread_(BrowserThread::UI, base::MessageLoop::current()), 200 file_thread_(BrowserThread::FILE, base::MessageLoop::current()), 201 storage_factory_(new util::ScopedSettingsStorageFactory()), 202 sync_processor_(new MockSyncChangeProcessor), 203 sync_processor_wrapper_(new syncer::SyncChangeProcessorWrapperForTest( 204 sync_processor_.get())) {} 205 206 virtual void SetUp() OVERRIDE { 207 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 208 profile_.reset(new util::MockProfile(temp_dir_.path())); 209 storage_factory_->Reset(new LeveldbSettingsStorageFactory()); 210 frontend_.reset( 211 StorageFrontend::CreateForTesting(storage_factory_, profile_.get())); 212 } 213 214 virtual void TearDown() OVERRIDE { 215 frontend_.reset(); 216 profile_.reset(); 217 // Execute any pending deletion tasks. 218 message_loop_.RunUntilIdle(); 219 } 220 221 protected: 222 // Adds a record of an extension or app to the extension service, then returns 223 // its storage area. 224 ValueStore* AddExtensionAndGetStorage( 225 const std::string& id, Manifest::Type type) { 226 scoped_refptr<const Extension> extension = 227 util::AddExtensionWithId(profile_.get(), id, type); 228 return util::GetStorage(extension, frontend_.get()); 229 } 230 231 // Gets the syncer::SyncableService for the given sync type. 232 syncer::SyncableService* GetSyncableService(syncer::ModelType model_type) { 233 base::MessageLoop::current()->RunUntilIdle(); 234 SyncValueStoreCache* sync_cache = static_cast<SyncValueStoreCache*>( 235 frontend_->GetValueStoreCache(settings_namespace::SYNC)); 236 return sync_cache->GetSyncableService(model_type); 237 } 238 239 // Gets all the sync data from the SyncableService for a sync type as a map 240 // from extension id to its sync data. 241 std::map<std::string, SettingSyncDataList> GetAllSyncData( 242 syncer::ModelType model_type) { 243 syncer::SyncDataList as_list = 244 GetSyncableService(model_type)->GetAllSyncData(model_type); 245 std::map<std::string, SettingSyncDataList> as_map; 246 for (syncer::SyncDataList::iterator it = as_list.begin(); 247 it != as_list.end(); ++it) { 248 SettingSyncData sync_data(*it); 249 as_map[sync_data.extension_id()].push_back(sync_data); 250 } 251 return as_map; 252 } 253 254 // Need these so that the DCHECKs for running on FILE or UI threads pass. 255 base::MessageLoop message_loop_; 256 content::TestBrowserThread ui_thread_; 257 content::TestBrowserThread file_thread_; 258 259 base::ScopedTempDir temp_dir_; 260 scoped_ptr<util::MockProfile> profile_; 261 scoped_ptr<StorageFrontend> frontend_; 262 scoped_refptr<util::ScopedSettingsStorageFactory> storage_factory_; 263 scoped_ptr<MockSyncChangeProcessor> sync_processor_; 264 scoped_ptr<syncer::SyncChangeProcessorWrapperForTest> sync_processor_wrapper_; 265}; 266 267// Get a semblance of coverage for both EXTENSION_SETTINGS and APP_SETTINGS 268// sync by roughly alternative which one to test. 269 270TEST_F(ExtensionSettingsSyncTest, NoDataDoesNotInvokeSync) { 271 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS; 272 Manifest::Type type = Manifest::TYPE_EXTENSION; 273 274 EXPECT_EQ(0u, GetAllSyncData(model_type).size()); 275 276 // Have one extension created before sync is set up, the other created after. 277 AddExtensionAndGetStorage("s1", type); 278 EXPECT_EQ(0u, GetAllSyncData(model_type).size()); 279 280 GetSyncableService(model_type)->MergeDataAndStartSyncing( 281 model_type, 282 syncer::SyncDataList(), 283 sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(), 284 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 285 286 AddExtensionAndGetStorage("s2", type); 287 EXPECT_EQ(0u, GetAllSyncData(model_type).size()); 288 289 GetSyncableService(model_type)->StopSyncing(model_type); 290 291 EXPECT_EQ(0u, sync_processor_->changes().size()); 292 EXPECT_EQ(0u, GetAllSyncData(model_type).size()); 293} 294 295TEST_F(ExtensionSettingsSyncTest, InSyncDataDoesNotInvokeSync) { 296 syncer::ModelType model_type = syncer::APP_SETTINGS; 297 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP; 298 299 base::StringValue value1("fooValue"); 300 base::ListValue value2; 301 value2.Append(new base::StringValue("barValue")); 302 303 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type); 304 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type); 305 306 storage1->Set(DEFAULTS, "foo", value1); 307 storage2->Set(DEFAULTS, "bar", value2); 308 309 std::map<std::string, SettingSyncDataList> all_sync_data = 310 GetAllSyncData(model_type); 311 EXPECT_EQ(2u, all_sync_data.size()); 312 EXPECT_EQ(1u, all_sync_data["s1"].size()); 313 EXPECT_PRED_FORMAT2(ValuesEq, &value1, &all_sync_data["s1"][0].value()); 314 EXPECT_EQ(1u, all_sync_data["s2"].size()); 315 EXPECT_PRED_FORMAT2(ValuesEq, &value2, &all_sync_data["s2"][0].value()); 316 317 syncer::SyncDataList sync_data; 318 sync_data.push_back(settings_sync_util::CreateData( 319 "s1", "foo", value1, model_type)); 320 sync_data.push_back(settings_sync_util::CreateData( 321 "s2", "bar", value2, model_type)); 322 323 GetSyncableService(model_type)->MergeDataAndStartSyncing( 324 model_type, 325 sync_data, 326 sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(), 327 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 328 329 // Already in sync, so no changes. 330 EXPECT_EQ(0u, sync_processor_->changes().size()); 331 332 // Regression test: not-changing the synced value shouldn't result in a sync 333 // change, and changing the synced value should result in an update. 334 storage1->Set(DEFAULTS, "foo", value1); 335 EXPECT_EQ(0u, sync_processor_->changes().size()); 336 337 storage1->Set(DEFAULTS, "foo", value2); 338 EXPECT_EQ(1u, sync_processor_->changes().size()); 339 SettingSyncData change = sync_processor_->GetOnlyChange("s1", "foo"); 340 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type()); 341 EXPECT_TRUE(value2.Equals(&change.value())); 342 343 GetSyncableService(model_type)->StopSyncing(model_type); 344} 345 346TEST_F(ExtensionSettingsSyncTest, LocalDataWithNoSyncDataIsPushedToSync) { 347 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS; 348 Manifest::Type type = Manifest::TYPE_EXTENSION; 349 350 base::StringValue value1("fooValue"); 351 base::ListValue value2; 352 value2.Append(new base::StringValue("barValue")); 353 354 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type); 355 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type); 356 357 storage1->Set(DEFAULTS, "foo", value1); 358 storage2->Set(DEFAULTS, "bar", value2); 359 360 GetSyncableService(model_type)->MergeDataAndStartSyncing( 361 model_type, 362 syncer::SyncDataList(), 363 sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(), 364 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 365 366 // All settings should have been pushed to sync. 367 EXPECT_EQ(2u, sync_processor_->changes().size()); 368 SettingSyncData change = sync_processor_->GetOnlyChange("s1", "foo"); 369 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type()); 370 EXPECT_TRUE(value1.Equals(&change.value())); 371 change = sync_processor_->GetOnlyChange("s2", "bar"); 372 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type()); 373 EXPECT_TRUE(value2.Equals(&change.value())); 374 375 GetSyncableService(model_type)->StopSyncing(model_type); 376} 377 378TEST_F(ExtensionSettingsSyncTest, AnySyncDataOverwritesLocalData) { 379 syncer::ModelType model_type = syncer::APP_SETTINGS; 380 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP; 381 382 base::StringValue value1("fooValue"); 383 base::ListValue value2; 384 value2.Append(new base::StringValue("barValue")); 385 386 // Maintain dictionaries mirrored to the expected values of the settings in 387 // each storage area. 388 base::DictionaryValue expected1, expected2; 389 390 // Pre-populate one of the storage areas. 391 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type); 392 storage1->Set(DEFAULTS, "overwriteMe", value1); 393 394 syncer::SyncDataList sync_data; 395 sync_data.push_back(settings_sync_util::CreateData( 396 "s1", "foo", value1, model_type)); 397 sync_data.push_back(settings_sync_util::CreateData( 398 "s2", "bar", value2, model_type)); 399 GetSyncableService(model_type)->MergeDataAndStartSyncing( 400 model_type, 401 sync_data, 402 sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(), 403 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 404 expected1.Set("foo", value1.DeepCopy()); 405 expected2.Set("bar", value2.DeepCopy()); 406 407 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type); 408 409 // All changes should be local, so no sync changes. 410 EXPECT_EQ(0u, sync_processor_->changes().size()); 411 412 // Sync settings should have been pushed to local settings. 413 EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get()); 414 EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get()); 415 416 GetSyncableService(model_type)->StopSyncing(model_type); 417} 418 419TEST_F(ExtensionSettingsSyncTest, ProcessSyncChanges) { 420 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS; 421 Manifest::Type type = Manifest::TYPE_EXTENSION; 422 423 base::StringValue value1("fooValue"); 424 base::ListValue value2; 425 value2.Append(new base::StringValue("barValue")); 426 427 // Maintain dictionaries mirrored to the expected values of the settings in 428 // each storage area. 429 base::DictionaryValue expected1, expected2; 430 431 // Make storage1 initialised from local data, storage2 initialised from sync. 432 ValueStore* storage1 = AddExtensionAndGetStorage("s1", type); 433 ValueStore* storage2 = AddExtensionAndGetStorage("s2", type); 434 435 storage1->Set(DEFAULTS, "foo", value1); 436 expected1.Set("foo", value1.DeepCopy()); 437 438 syncer::SyncDataList sync_data; 439 sync_data.push_back(settings_sync_util::CreateData( 440 "s2", "bar", value2, model_type)); 441 442 GetSyncableService(model_type)->MergeDataAndStartSyncing( 443 model_type, 444 sync_data, 445 sync_processor_wrapper_.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 493TEST_F(ExtensionSettingsSyncTest, PushToSync) { 494 syncer::ModelType model_type = syncer::APP_SETTINGS; 495 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP; 496 497 base::StringValue value1("fooValue"); 498 base::ListValue value2; 499 value2.Append(new base::StringValue("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, 519 sync_data, 520 sync_processor_wrapper_.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 636TEST_F(ExtensionSettingsSyncTest, ExtensionAndAppSettingsSyncSeparately) { 637 base::StringValue value1("fooValue"); 638 base::ListValue value2; 639 value2.Append(new base::StringValue("barValue")); 640 641 // storage1 is an extension, storage2 is an app. 642 ValueStore* storage1 = AddExtensionAndGetStorage( 643 "s1", Manifest::TYPE_EXTENSION); 644 ValueStore* storage2 = AddExtensionAndGetStorage( 645 "s2", Manifest::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_wrapper_.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<syncer::SyncChangeProcessorWrapperForTest> app_settings_delegate_( 681 new syncer::SyncChangeProcessorWrapperForTest(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 692TEST_F(ExtensionSettingsSyncTest, FailingStartSyncingDisablesSync) { 693 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS; 694 Manifest::Type type = Manifest::TYPE_EXTENSION; 695 696 base::StringValue fooValue("fooValue"); 697 base::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")->set_error_code(ValueStore::CORRUPTION); 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_wrapper_.PassAs<syncer::SyncChangeProcessor>(), 720 scoped_ptr<syncer::SyncErrorFactory>( 721 new syncer::SyncErrorFactoryMock())); 722 } 723 testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK); 724 725 { 726 base::DictionaryValue dict; 727 dict.Set("foo", fooValue.DeepCopy()); 728 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get()); 729 } 730 { 731 base::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 base::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 base::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 base::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 base::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 base::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 base::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")->set_error_code(ValueStore::CORRUPTION); 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")->set_error_code(ValueStore::OK); 817 818 { 819 base::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 base::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_wrapper_.reset( 834 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get())); 835 GetSyncableService(model_type)->MergeDataAndStartSyncing( 836 model_type, 837 syncer::SyncDataList(), 838 sync_processor_wrapper_.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 base::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 base::DictionaryValue dict; 885 dict.Set("bar", fooValue.DeepCopy()); 886 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get()); 887 } 888} 889 890TEST_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 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP; 895 896 base::StringValue fooValue("fooValue"); 897 base::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_wrapper_.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 base::DictionaryValue dict; 924 dict.Set("foo", fooValue.DeepCopy()); 925 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get()); 926 } 927 { 928 base::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")->set_error_code(ValueStore::CORRUPTION); 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")->set_error_code(ValueStore::OK); 944 945 { 946 base::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 base::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 base::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 base::DictionaryValue dict; 985 dict.Set("foo", barValue.DeepCopy()); 986 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get()); 987 } 988} 989 990TEST_F(ExtensionSettingsSyncTest, FailingGetAllSyncDataDoesntStopSync) { 991 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS; 992 Manifest::Type type = Manifest::TYPE_EXTENSION; 993 994 base::StringValue fooValue("fooValue"); 995 base::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")->set_error_code(ValueStore::CORRUPTION); 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")->set_error_code(ValueStore::OK); 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_wrapper_.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 1045TEST_F(ExtensionSettingsSyncTest, FailureToReadChangesToPushDisablesSync) { 1046 syncer::ModelType model_type = syncer::APP_SETTINGS; 1047 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP; 1048 1049 base::StringValue fooValue("fooValue"); 1050 base::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")->set_error_code(ValueStore::CORRUPTION); 1064 GetSyncableService(model_type)->MergeDataAndStartSyncing( 1065 model_type, 1066 syncer::SyncDataList(), 1067 sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(), 1068 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 1069 testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK); 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 base::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 base::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_wrapper_.reset( 1115 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get())); 1116 GetSyncableService(model_type)->MergeDataAndStartSyncing( 1117 model_type, 1118 syncer::SyncDataList(), 1119 sync_processor_wrapper_.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 1149TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalStateDisablesSync) { 1150 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS; 1151 Manifest::Type type = Manifest::TYPE_EXTENSION; 1152 1153 base::StringValue fooValue("fooValue"); 1154 base::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_->set_fail_all_requests(true); 1166 GetSyncableService(model_type)->MergeDataAndStartSyncing( 1167 model_type, 1168 syncer::SyncDataList(), 1169 sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(), 1170 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 1171 sync_processor_->set_fail_all_requests(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 base::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 base::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_wrapper_.reset( 1209 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get())); 1210 GetSyncableService(model_type)->MergeDataAndStartSyncing( 1211 model_type, 1212 syncer::SyncDataList(), 1213 sync_processor_wrapper_.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 1240TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalChangeDisablesSync) { 1241 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS; 1242 Manifest::Type type = Manifest::TYPE_EXTENSION; 1243 1244 base::StringValue fooValue("fooValue"); 1245 base::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_wrapper_.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_->set_fail_all_requests(true); 1262 bad->Set(DEFAULTS, "foo", fooValue); 1263 sync_processor_->set_fail_all_requests(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 base::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 base::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_wrapper_.reset( 1306 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get())); 1307 GetSyncableService(model_type)->MergeDataAndStartSyncing( 1308 model_type, 1309 syncer::SyncDataList(), 1310 sync_processor_wrapper_.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 1337TEST_F(ExtensionSettingsSyncTest, 1338 LargeOutgoingChangeRejectedButIncomingAccepted) { 1339 syncer::ModelType model_type = syncer::APP_SETTINGS; 1340 Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP; 1341 1342 // This value should be larger than the limit in sync_storage_backend.cc. 1343 std::string string_5k; 1344 for (size_t i = 0; i < 5000; ++i) { 1345 string_5k.append("a"); 1346 } 1347 base::StringValue large_value(string_5k); 1348 1349 GetSyncableService(model_type)->MergeDataAndStartSyncing( 1350 model_type, 1351 syncer::SyncDataList(), 1352 sync_processor_wrapper_.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 base::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 1380TEST_F(ExtensionSettingsSyncTest, Dots) { 1381 syncer::ModelType model_type = syncer::EXTENSION_SETTINGS; 1382 Manifest::Type type = Manifest::TYPE_EXTENSION; 1383 1384 ValueStore* storage = AddExtensionAndGetStorage("ext", type); 1385 1386 { 1387 syncer::SyncDataList sync_data_list; 1388 scoped_ptr<base::Value> string_value(new base::StringValue("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_wrapper_.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 base::DictionaryValue expected_data; 1406 expected_data.SetWithoutPathExpansion( 1407 "key.with.dot", 1408 new base::StringValue("value")); 1409 EXPECT_TRUE(base::Value::Equals(&expected_data, &data->settings())); 1410 } 1411 1412 // Test dots in keys going to sync. 1413 { 1414 scoped_ptr<base::Value> string_value(new base::StringValue("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 1427