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 "chrome/browser/sync/glue/data_type_manager_impl.h" 6 7 #include "base/compiler_specific.h" 8 #include "base/message_loop/message_loop.h" 9 #include "chrome/browser/chrome_notification_types.h" 10 #include "chrome/browser/sync/glue/backend_data_type_configurer.h" 11 #include "chrome/browser/sync/glue/data_type_controller.h" 12 #include "chrome/browser/sync/glue/data_type_encryption_handler.h" 13 #include "chrome/browser/sync/glue/data_type_manager_observer.h" 14 #include "chrome/browser/sync/glue/failed_data_types_handler.h" 15 #include "chrome/browser/sync/glue/fake_data_type_controller.h" 16 #include "content/public/test/test_browser_thread.h" 17 #include "sync/internal_api/public/base/model_type.h" 18 #include "sync/internal_api/public/configure_reason.h" 19 #include "testing/gmock/include/gmock/gmock.h" 20 #include "testing/gtest/include/gtest/gtest.h" 21 22 namespace browser_sync { 23 24 using syncer::ModelType; 25 using syncer::ModelTypeSet; 26 using syncer::ModelTypeToString; 27 using syncer::BOOKMARKS; 28 using syncer::APPS; 29 using syncer::PASSWORDS; 30 using syncer::PREFERENCES; 31 using syncer::NIGORI; 32 using testing::_; 33 using testing::Mock; 34 using testing::ResultOf; 35 36 namespace { 37 38 // Used by SetConfigureDoneExpectation. 39 DataTypeManager::ConfigureStatus GetStatus( 40 const DataTypeManager::ConfigureResult& result) { 41 return result.status; 42 } 43 44 // Those types that are priority AND always configured. 45 syncer::ModelTypeSet HighPriorityTypes() { 46 syncer::ModelTypeSet result = syncer::PriorityCoreTypes(); 47 return result; 48 } 49 50 // Helper for unioning with priority types. 51 syncer::ModelTypeSet AddHighPriorityTypesTo(syncer::ModelTypeSet types) { 52 syncer::ModelTypeSet result = HighPriorityTypes(); 53 result.PutAll(types); 54 return result; 55 } 56 57 // Helper for unioning with core types. 58 syncer::ModelTypeSet AddLowPriorityCoreTypesTo(syncer::ModelTypeSet types) { 59 syncer::ModelTypeSet result = syncer::Difference(syncer::CoreTypes(), 60 syncer::PriorityCoreTypes()); 61 result.PutAll(types); 62 return result; 63 } 64 65 // Fake BackendDataTypeConfigurer implementation that simply stores away the 66 // callback passed into ConfigureDataTypes. 67 class FakeBackendDataTypeConfigurer : public BackendDataTypeConfigurer { 68 public: 69 FakeBackendDataTypeConfigurer() {} 70 virtual ~FakeBackendDataTypeConfigurer() {} 71 72 virtual void ConfigureDataTypes( 73 syncer::ConfigureReason reason, 74 const DataTypeConfigStateMap& config_state_map, 75 const base::Callback<void(ModelTypeSet, 76 ModelTypeSet)>& ready_task, 77 const base::Callback<void()>& retry_callback) OVERRIDE { 78 last_ready_task_ = ready_task; 79 80 if (!expected_configure_types_.Empty()) { 81 EXPECT_TRUE( 82 expected_configure_types_.Equals( 83 GetDataTypesInState(CONFIGURE_ACTIVE, config_state_map))) 84 << syncer::ModelTypeSetToString(expected_configure_types_) 85 << " v.s. " 86 << syncer::ModelTypeSetToString( 87 GetDataTypesInState(CONFIGURE_ACTIVE, config_state_map)); 88 } 89 } 90 91 base::Callback<void(ModelTypeSet, ModelTypeSet)> last_ready_task() const { 92 return last_ready_task_; 93 } 94 95 void set_expected_configure_types(syncer::ModelTypeSet types) { 96 expected_configure_types_ = types; 97 } 98 99 private: 100 base::Callback<void(ModelTypeSet, ModelTypeSet)> last_ready_task_; 101 syncer::ModelTypeSet expected_configure_types_; 102 }; 103 104 // Mock DataTypeManagerObserver implementation. 105 class DataTypeManagerObserverMock : public DataTypeManagerObserver { 106 public: 107 DataTypeManagerObserverMock() {} 108 virtual ~DataTypeManagerObserverMock() {} 109 110 MOCK_METHOD1(OnConfigureDone, 111 void(const browser_sync::DataTypeManager::ConfigureResult&)); 112 MOCK_METHOD0(OnConfigureRetry, void()); 113 MOCK_METHOD0(OnConfigureStart, void()); 114 }; 115 116 class FakeDataTypeEncryptionHandler : public DataTypeEncryptionHandler { 117 public: 118 FakeDataTypeEncryptionHandler(); 119 virtual ~FakeDataTypeEncryptionHandler(); 120 121 virtual bool IsPassphraseRequired() const OVERRIDE; 122 virtual syncer::ModelTypeSet GetEncryptedDataTypes() const OVERRIDE; 123 124 void set_passphrase_required(bool passphrase_required) { 125 passphrase_required_ = passphrase_required; 126 } 127 void set_encrypted_types(syncer::ModelTypeSet encrypted_types) { 128 encrypted_types_ = encrypted_types; 129 } 130 private: 131 bool passphrase_required_; 132 syncer::ModelTypeSet encrypted_types_; 133 }; 134 135 FakeDataTypeEncryptionHandler::FakeDataTypeEncryptionHandler() 136 : passphrase_required_(false) {} 137 FakeDataTypeEncryptionHandler::~FakeDataTypeEncryptionHandler() {} 138 139 bool FakeDataTypeEncryptionHandler::IsPassphraseRequired() const { 140 return passphrase_required_; 141 } 142 143 syncer::ModelTypeSet 144 FakeDataTypeEncryptionHandler::GetEncryptedDataTypes() const { 145 return encrypted_types_; 146 } 147 148 } // namespace 149 150 class TestDataTypeManager : public DataTypeManagerImpl { 151 public: 152 TestDataTypeManager( 153 const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& 154 debug_info_listener, 155 BackendDataTypeConfigurer* configurer, 156 const DataTypeController::TypeMap* controllers, 157 const DataTypeEncryptionHandler* encryption_handler, 158 DataTypeManagerObserver* observer, 159 FailedDataTypesHandler* failed_data_types_handler) 160 : DataTypeManagerImpl(debug_info_listener, 161 controllers, 162 encryption_handler, 163 configurer, 164 observer, 165 failed_data_types_handler), 166 custom_priority_types_(HighPriorityTypes()) {} 167 168 void set_priority_types(const syncer::ModelTypeSet& priority_types) { 169 custom_priority_types_ = priority_types; 170 } 171 172 private: 173 virtual syncer::ModelTypeSet GetPriorityTypes() const OVERRIDE { 174 return custom_priority_types_; 175 } 176 177 syncer::ModelTypeSet custom_priority_types_; 178 }; 179 180 // The actual test harness class, parametrized on nigori state (i.e., tests are 181 // run both configuring with nigori, and configuring without). 182 class SyncDataTypeManagerImplTest : public testing::Test { 183 public: 184 SyncDataTypeManagerImplTest() 185 : ui_thread_(content::BrowserThread::UI, &ui_loop_) {} 186 187 virtual ~SyncDataTypeManagerImplTest() { 188 } 189 190 protected: 191 virtual void SetUp() { 192 dtm_.reset( 193 new TestDataTypeManager( 194 syncer::WeakHandle<syncer::DataTypeDebugInfoListener>(), 195 &configurer_, 196 &controllers_, 197 &encryption_handler_, 198 &observer_, 199 &failed_data_types_handler_)); 200 } 201 202 void SetConfigureStartExpectation() { 203 EXPECT_CALL(observer_, OnConfigureStart()); 204 } 205 206 void SetConfigureDoneExpectation(DataTypeManager::ConfigureStatus status) { 207 EXPECT_CALL(observer_, OnConfigureDone(ResultOf(&GetStatus, status))); 208 } 209 210 // Configure the given DTM with the given desired types. 211 void Configure(DataTypeManagerImpl* dtm, 212 const syncer::ModelTypeSet& desired_types) { 213 dtm->Configure(desired_types, syncer::CONFIGURE_REASON_RECONFIGURATION); 214 } 215 216 // Finish downloading for the given DTM. Should be done only after 217 // a call to Configure(). 218 void FinishDownload(const DataTypeManager& dtm, 219 ModelTypeSet types_to_configure, 220 ModelTypeSet failed_download_types) { 221 EXPECT_TRUE(DataTypeManager::DOWNLOAD_PENDING == dtm.state() || 222 DataTypeManager::CONFIGURING == dtm.state()); 223 ASSERT_FALSE(configurer_.last_ready_task().is_null()); 224 configurer_.last_ready_task().Run( 225 syncer::Difference(types_to_configure, failed_download_types), 226 failed_download_types); 227 } 228 229 // Adds a fake controller for the given type to |controllers_|. 230 // Should be called only before setting up the DTM. 231 void AddController(ModelType model_type) { 232 controllers_[model_type] = new FakeDataTypeController(model_type); 233 } 234 235 // Gets the fake controller for the given type, which should have 236 // been previously added via AddController(). 237 scoped_refptr<FakeDataTypeController> GetController( 238 ModelType model_type) const { 239 DataTypeController::TypeMap::const_iterator it = 240 controllers_.find(model_type); 241 if (it == controllers_.end()) { 242 return NULL; 243 } 244 return make_scoped_refptr( 245 static_cast<FakeDataTypeController*>(it->second.get())); 246 } 247 248 void FailEncryptionFor(syncer::ModelTypeSet encrypted_types) { 249 encryption_handler_.set_passphrase_required(true); 250 encryption_handler_.set_encrypted_types(encrypted_types); 251 } 252 253 base::MessageLoopForUI ui_loop_; 254 content::TestBrowserThread ui_thread_; 255 DataTypeController::TypeMap controllers_; 256 FakeBackendDataTypeConfigurer configurer_; 257 DataTypeManagerObserverMock observer_; 258 scoped_ptr<TestDataTypeManager> dtm_; 259 FailedDataTypesHandler failed_data_types_handler_; 260 FakeDataTypeEncryptionHandler encryption_handler_; 261 }; 262 263 // Set up a DTM with no controllers, configure it, finish downloading, 264 // and then stop it. 265 TEST_F(SyncDataTypeManagerImplTest, NoControllers) { 266 SetConfigureStartExpectation(); 267 SetConfigureDoneExpectation(DataTypeManager::OK); 268 269 Configure(dtm_.get(), ModelTypeSet()); 270 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 271 272 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 273 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 274 EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); 275 276 dtm_->Stop(); 277 EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); 278 } 279 280 // Set up a DTM with a single controller, configure it, finish 281 // downloading, finish starting the controller, and then stop the DTM. 282 TEST_F(SyncDataTypeManagerImplTest, ConfigureOne) { 283 AddController(BOOKMARKS); 284 285 SetConfigureStartExpectation(); 286 SetConfigureDoneExpectation(DataTypeManager::OK); 287 288 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); 289 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 290 291 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 292 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); 293 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 294 295 GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); 296 EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); 297 298 dtm_->Stop(); 299 EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); 300 } 301 302 // Set up a DTM with 2 controllers. configure it. One of them finishes loading 303 // after the timeout. Make sure eventually all are configured. 304 TEST_F(SyncDataTypeManagerImplTest, ConfigureSlowLoadingType) { 305 AddController(BOOKMARKS); 306 AddController(APPS); 307 308 GetController(BOOKMARKS)->SetDelayModelLoad(); 309 310 SetConfigureStartExpectation(); 311 SetConfigureDoneExpectation(DataTypeManager::PARTIAL_SUCCESS); 312 313 syncer::ModelTypeSet types; 314 types.Put(BOOKMARKS); 315 types.Put(APPS); 316 317 Configure(dtm_.get(), types); 318 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 319 320 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 321 FinishDownload(*dtm_, types, ModelTypeSet()); 322 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 323 324 base::OneShotTimer<ModelAssociationManager>* timer = 325 dtm_->GetModelAssociationManagerForTesting()->GetTimerForTesting(); 326 327 base::Closure task = timer->user_task(); 328 timer->Stop(); 329 task.Run(); 330 331 SetConfigureDoneExpectation(DataTypeManager::OK); 332 GetController(APPS)->FinishStart(DataTypeController::OK); 333 334 SetConfigureStartExpectation(); 335 GetController(BOOKMARKS)->SimulateModelLoadFinishing(); 336 337 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 338 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 339 GetController(BOOKMARKS)->SimulateModelLoadFinishing(); 340 341 GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); 342 EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); 343 344 dtm_->Stop(); 345 EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); 346 } 347 348 349 // Set up a DTM with a single controller, configure it, but stop it 350 // before finishing the download. It should still be safe to run the 351 // download callback even after the DTM is stopped and destroyed. 352 TEST_F(SyncDataTypeManagerImplTest, ConfigureOneStopWhileDownloadPending) { 353 AddController(BOOKMARKS); 354 355 { 356 SetConfigureStartExpectation(); 357 SetConfigureDoneExpectation(DataTypeManager::ABORTED); 358 359 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); 360 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 361 362 dtm_->Stop(); 363 EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); 364 } 365 366 configurer_.last_ready_task().Run(ModelTypeSet(BOOKMARKS), ModelTypeSet()); 367 } 368 369 // Set up a DTM with a single controller, configure it, finish 370 // downloading, but stop the DTM before the controller finishes 371 // starting up. It should still be safe to finish starting up the 372 // controller even after the DTM is stopped and destroyed. 373 TEST_F(SyncDataTypeManagerImplTest, ConfigureOneStopWhileStartingModel) { 374 AddController(BOOKMARKS); 375 376 { 377 SetConfigureStartExpectation(); 378 SetConfigureDoneExpectation(DataTypeManager::ABORTED); 379 380 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); 381 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 382 383 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 384 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); 385 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 386 387 dtm_->Stop(); 388 EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); 389 dtm_.reset(); 390 } 391 392 GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); 393 } 394 395 // Set up a DTM with a single controller, configure it, finish 396 // downloading, start the controller's model, but stop the DTM before 397 // the controller finishes starting up. It should still be safe to 398 // finish starting up the controller even after the DTM is stopped and 399 // destroyed. 400 TEST_F(SyncDataTypeManagerImplTest, ConfigureOneStopWhileAssociating) { 401 AddController(BOOKMARKS); 402 403 { 404 SetConfigureStartExpectation(); 405 SetConfigureDoneExpectation(DataTypeManager::ABORTED); 406 407 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); 408 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 409 410 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 411 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); 412 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 413 414 dtm_->Stop(); 415 EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); 416 dtm_.reset(); 417 } 418 419 GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); 420 } 421 422 // Set up a DTM with a single controller. Then: 423 // 424 // 1) Configure. 425 // 2) Finish the download for step 1. 426 // 3) Finish starting the controller with the NEEDS_CRYPTO status. 427 // 4) Complete download for the reconfiguration without the controller. 428 // 5) Stop the DTM. 429 TEST_F(SyncDataTypeManagerImplTest, OneWaitingForCrypto) { 430 AddController(PASSWORDS); 431 432 SetConfigureStartExpectation(); 433 SetConfigureDoneExpectation(DataTypeManager::PARTIAL_SUCCESS); 434 435 const ModelTypeSet types(PASSWORDS); 436 437 // Step 1. 438 Configure(dtm_.get(), types); 439 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 440 441 // Step 2. 442 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 443 FinishDownload(*dtm_, types, ModelTypeSet()); 444 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 445 446 // Step 3. 447 FailEncryptionFor(types); 448 GetController(PASSWORDS)->FinishStart(DataTypeController::NEEDS_CRYPTO); 449 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 450 451 // Step 4. 452 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 453 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 454 EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); 455 456 // Step 5. 457 dtm_->Stop(); 458 EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); 459 } 460 461 // Set up a DTM with two controllers. Then: 462 // 463 // 1) Configure with first controller. 464 // 2) Finish the download for step 1. 465 // 3) Finish starting the first controller. 466 // 4) Configure with both controllers. 467 // 5) Finish the download for step 4. 468 // 6) Finish starting the second controller. 469 // 7) Stop the DTM. 470 TEST_F(SyncDataTypeManagerImplTest, ConfigureOneThenBoth) { 471 AddController(BOOKMARKS); 472 AddController(PREFERENCES); 473 474 SetConfigureStartExpectation(); 475 SetConfigureDoneExpectation(DataTypeManager::OK); 476 477 // Step 1. 478 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); 479 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 480 481 // Step 2. 482 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 483 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); 484 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 485 486 // Step 3. 487 GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); 488 EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); 489 490 Mock::VerifyAndClearExpectations(&observer_); 491 SetConfigureStartExpectation(); 492 SetConfigureDoneExpectation(DataTypeManager::OK); 493 494 // Step 4. 495 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); 496 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 497 498 // Step 5. 499 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 500 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet()); 501 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 502 503 // Step 6. 504 GetController(PREFERENCES)->FinishStart(DataTypeController::OK); 505 EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); 506 507 // Step 7. 508 dtm_->Stop(); 509 EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); 510 } 511 512 // Set up a DTM with two controllers. Then: 513 // 514 // 1) Configure with first controller. 515 // 2) Finish the download for step 1. 516 // 3) Finish starting the first controller. 517 // 4) Configure with second controller. 518 // 5) Finish the download for step 4. 519 // 6) Finish starting the second controller. 520 // 7) Stop the DTM. 521 TEST_F(SyncDataTypeManagerImplTest, ConfigureOneThenSwitch) { 522 AddController(BOOKMARKS); 523 AddController(PREFERENCES); 524 525 SetConfigureStartExpectation(); 526 SetConfigureDoneExpectation(DataTypeManager::OK); 527 528 // Step 1. 529 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); 530 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 531 532 // Step 2. 533 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 534 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); 535 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 536 537 // Step 3. 538 GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); 539 EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); 540 541 Mock::VerifyAndClearExpectations(&observer_); 542 SetConfigureStartExpectation(); 543 SetConfigureDoneExpectation(DataTypeManager::OK); 544 545 // Step 4. 546 Configure(dtm_.get(), ModelTypeSet(PREFERENCES)); 547 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 548 549 // Step 5. 550 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 551 FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); 552 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 553 554 // Step 6. 555 GetController(PREFERENCES)->FinishStart(DataTypeController::OK); 556 EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); 557 558 // Step 7. 559 dtm_->Stop(); 560 EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); 561 } 562 563 // Set up a DTM with two controllers. Then: 564 // 565 // 1) Configure with first controller. 566 // 2) Finish the download for step 1. 567 // 3) Configure with both controllers. 568 // 4) Finish starting the first controller. 569 // 5) Finish the download for step 3. 570 // 6) Finish starting the second controller. 571 // 7) Stop the DTM. 572 TEST_F(SyncDataTypeManagerImplTest, ConfigureWhileOneInFlight) { 573 AddController(BOOKMARKS); 574 AddController(PREFERENCES); 575 576 SetConfigureStartExpectation(); 577 SetConfigureDoneExpectation(DataTypeManager::OK); 578 579 // Step 1. 580 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); 581 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 582 583 // Step 2. 584 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 585 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); 586 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 587 588 // Step 3. 589 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); 590 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 591 592 // Step 4. 593 GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); 594 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 595 596 // Step 5. 597 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 598 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet()); 599 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 600 601 // Step 6. 602 GetController(PREFERENCES)->FinishStart(DataTypeController::OK); 603 EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); 604 605 // Step 7. 606 dtm_->Stop(); 607 EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); 608 } 609 610 // Set up a DTM with one controller. Then configure, finish 611 // downloading, and start the controller with an unrecoverable error. 612 // The unrecoverable error should cause the DTM to stop. 613 TEST_F(SyncDataTypeManagerImplTest, OneFailingController) { 614 AddController(BOOKMARKS); 615 616 SetConfigureStartExpectation(); 617 SetConfigureDoneExpectation(DataTypeManager::UNRECOVERABLE_ERROR); 618 619 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); 620 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 621 622 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 623 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); 624 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 625 626 GetController(BOOKMARKS)->FinishStart( 627 DataTypeController::UNRECOVERABLE_ERROR); 628 EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); 629 } 630 631 // Set up a DTM with two controllers. Then: 632 // 633 // 1) Configure with both controllers. 634 // 2) Finish the download for step 1. 635 // 3) Finish starting the first controller successfully. 636 // 4) Finish starting the second controller with an unrecoverable error. 637 // 638 // The failure from step 4 should cause the DTM to stop. 639 TEST_F(SyncDataTypeManagerImplTest, SecondControllerFails) { 640 AddController(BOOKMARKS); 641 AddController(PREFERENCES); 642 643 SetConfigureStartExpectation(); 644 SetConfigureDoneExpectation(DataTypeManager::UNRECOVERABLE_ERROR); 645 646 // Step 1. 647 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); 648 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 649 650 // Step 2. 651 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 652 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet()); 653 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 654 655 // Step 3. 656 GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); 657 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 658 659 // Step 4. 660 GetController(PREFERENCES)->FinishStart( 661 DataTypeController::UNRECOVERABLE_ERROR); 662 EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); 663 } 664 665 // Set up a DTM with two controllers. Then: 666 // 667 // 1) Configure with both controllers. 668 // 2) Finish the download for step 1. 669 // 3) Finish starting the first controller successfully. 670 // 4) Finish starting the second controller with an association failure. 671 // 5) Finish the purge/reconfigure without the failed type. 672 // 6) Stop the DTM. 673 // 674 // The association failure from step 3 should be ignored. 675 // 676 // TODO(akalin): Check that the data type that failed association is 677 // recorded in the CONFIGURE_DONE notification. 678 TEST_F(SyncDataTypeManagerImplTest, OneControllerFailsAssociation) { 679 AddController(BOOKMARKS); 680 AddController(PREFERENCES); 681 682 SetConfigureStartExpectation(); 683 SetConfigureDoneExpectation(DataTypeManager::PARTIAL_SUCCESS); 684 685 // Step 1. 686 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); 687 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 688 689 // Step 2. 690 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 691 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet()); 692 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 693 694 // Step 3. 695 GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); 696 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 697 698 // Step 4. 699 GetController(PREFERENCES)->FinishStart( 700 DataTypeController::ASSOCIATION_FAILED); 701 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 702 703 // Step 5. 704 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 705 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); 706 EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); 707 708 // Step 6. 709 dtm_->Stop(); 710 EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); 711 } 712 713 // Set up a DTM with two controllers. Then: 714 // 715 // 1) Configure with first controller. 716 // 2) Configure with both controllers. 717 // 3) Finish the download for step 1. 718 // 4) Finish the download for step 2. 719 // 5) Finish starting both controllers. 720 // 6) Stop the DTM. 721 TEST_F(SyncDataTypeManagerImplTest, ConfigureWhileDownloadPending) { 722 AddController(BOOKMARKS); 723 AddController(PREFERENCES); 724 725 SetConfigureStartExpectation(); 726 SetConfigureDoneExpectation(DataTypeManager::OK); 727 728 // Step 1. 729 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); 730 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 731 732 // Step 2. 733 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); 734 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 735 736 // Step 3. 737 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 738 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 739 740 // Step 4. 741 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 742 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet()); 743 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 744 745 // Step 5. 746 GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); 747 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 748 GetController(PREFERENCES)->FinishStart(DataTypeController::OK); 749 EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); 750 751 // Step 6. 752 dtm_->Stop(); 753 EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); 754 } 755 756 // Set up a DTM with two controllers. Then: 757 // 758 // 1) Configure with first controller. 759 // 2) Configure with both controllers. 760 // 3) Finish the download for step 1 with a failed data type. 761 // 4) Finish the download for step 2 successfully. 762 // 5) Finish starting both controllers. 763 // 6) Stop the DTM. 764 // 765 // The failure from step 3 should be ignored since there's a 766 // reconfigure pending from step 2. 767 TEST_F(SyncDataTypeManagerImplTest, ConfigureWhileDownloadPendingWithFailure) { 768 AddController(BOOKMARKS); 769 AddController(PREFERENCES); 770 771 SetConfigureStartExpectation(); 772 SetConfigureDoneExpectation(DataTypeManager::OK); 773 774 // Step 1. 775 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); 776 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 777 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 778 779 // Step 2. 780 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); 781 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 782 783 // Step 3. 784 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 785 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); 786 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 787 788 // Step 4. 789 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet()); 790 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 791 792 // Step 5. 793 GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); 794 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 795 GetController(PREFERENCES)->FinishStart(DataTypeController::OK); 796 EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); 797 798 // Step 6. 799 dtm_->Stop(); 800 EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); 801 } 802 803 // Tests a Purge then Configure. This is similar to the sequence of 804 // operations that would be invoked by the BackendMigrator. 805 TEST_F(SyncDataTypeManagerImplTest, MigrateAll) { 806 AddController(BOOKMARKS); 807 808 SetConfigureStartExpectation(); 809 SetConfigureDoneExpectation(DataTypeManager::OK); 810 811 // Initial setup. 812 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); 813 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 814 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); 815 GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); 816 817 // We've now configured bookmarks and (implicitly) the control types. 818 EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); 819 Mock::VerifyAndClearExpectations(&observer_); 820 821 // Pretend we were told to migrate all types. 822 ModelTypeSet to_migrate; 823 to_migrate.Put(BOOKMARKS); 824 to_migrate.PutAll(syncer::ControlTypes()); 825 826 SetConfigureStartExpectation(); 827 SetConfigureDoneExpectation(DataTypeManager::OK); 828 dtm_->PurgeForMigration(to_migrate, 829 syncer::CONFIGURE_REASON_MIGRATION); 830 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 831 832 // The DTM will call ConfigureDataTypes(), even though it is unnecessary. 833 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 834 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 835 EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); 836 Mock::VerifyAndClearExpectations(&observer_); 837 838 // Re-enable the migrated types. 839 SetConfigureStartExpectation(); 840 SetConfigureDoneExpectation(DataTypeManager::OK); 841 Configure(dtm_.get(), to_migrate); 842 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 843 FinishDownload(*dtm_, to_migrate, ModelTypeSet()); 844 GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); 845 EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); 846 } 847 848 // Test receipt of a Configure request while a purge is in flight. 849 TEST_F(SyncDataTypeManagerImplTest, ConfigureDuringPurge) { 850 AddController(BOOKMARKS); 851 AddController(PREFERENCES); 852 853 // Initial configure. 854 SetConfigureStartExpectation(); 855 SetConfigureDoneExpectation(DataTypeManager::OK); 856 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); 857 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 858 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); 859 GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); 860 EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); 861 Mock::VerifyAndClearExpectations(&observer_); 862 863 // Purge the Nigori type. 864 SetConfigureStartExpectation(); 865 dtm_->PurgeForMigration(ModelTypeSet(NIGORI), 866 syncer::CONFIGURE_REASON_MIGRATION); 867 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 868 Mock::VerifyAndClearExpectations(&observer_); 869 870 // Before the backend configuration completes, ask for a different 871 // set of types. This request asks for 872 // - BOOKMARKS: which is redundant because it was already enabled, 873 // - PREFERENCES: which is new and will need to be downloaded, and 874 // - NIGORI: (added implicitly because it is a control type) which 875 // the DTM is part-way through purging. 876 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); 877 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 878 879 // Invoke the callback we've been waiting for since we asked to purge NIGORI. 880 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 881 Mock::VerifyAndClearExpectations(&observer_); 882 883 SetConfigureDoneExpectation(DataTypeManager::OK); 884 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 885 886 // Now invoke the callback for the second configure request. 887 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 888 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet()); 889 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 890 891 // Start the preferences controller. We don't need to start controller for 892 // the NIGORI because it has none. We don't need to start the controller for 893 // the BOOKMARKS because it was never stopped. 894 GetController(PREFERENCES)->FinishStart(DataTypeController::OK); 895 EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); 896 } 897 898 TEST_F(SyncDataTypeManagerImplTest, PrioritizedConfiguration) { 899 AddController(BOOKMARKS); 900 AddController(PREFERENCES); 901 902 dtm_->set_priority_types( 903 AddHighPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES))); 904 905 // Initial configure. 906 SetConfigureStartExpectation(); 907 SetConfigureDoneExpectation(DataTypeManager::OK); 908 909 // Initially only PREFERENCES is configured. 910 configurer_.set_expected_configure_types( 911 AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES))); 912 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); 913 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 914 915 // BOOKMARKS is configured after download of PREFERENCES finishes. 916 configurer_.set_expected_configure_types( 917 AddLowPriorityCoreTypesTo(ModelTypeSet(BOOKMARKS))); 918 FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); 919 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 920 921 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); 922 GetController(PREFERENCES)->FinishStart(DataTypeController::OK); 923 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 924 925 GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); 926 EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); 927 } 928 929 TEST_F(SyncDataTypeManagerImplTest, PrioritizedConfigurationReconfigure) { 930 AddController(BOOKMARKS); 931 AddController(PREFERENCES); 932 AddController(APPS); 933 934 dtm_->set_priority_types( 935 AddHighPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES))); 936 937 // Initial configure. 938 SetConfigureStartExpectation(); 939 SetConfigureDoneExpectation(DataTypeManager::OK); 940 941 // Reconfigure while associating PREFERENCES and downloading BOOKMARKS. 942 configurer_.set_expected_configure_types( 943 AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES))); 944 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); 945 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 946 947 configurer_.set_expected_configure_types( 948 AddLowPriorityCoreTypesTo(ModelTypeSet(BOOKMARKS))); 949 FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); 950 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 951 952 // Enable syncing for APPS. 953 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES, APPS)); 954 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 955 956 // Reconfiguration starts after downloading and association of previous 957 // types finish. 958 configurer_.set_expected_configure_types( 959 AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES))); 960 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); 961 GetController(PREFERENCES)->FinishStart(DataTypeController::OK); 962 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 963 964 configurer_.set_expected_configure_types( 965 AddLowPriorityCoreTypesTo(ModelTypeSet(BOOKMARKS, APPS))); 966 FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); 967 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 968 969 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, APPS), ModelTypeSet()); 970 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 971 972 // Skip calling FinishStart() for PREFENCES because it's already started in 973 // first configuration. 974 GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); 975 GetController(APPS)->FinishStart(DataTypeController::OK); 976 EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); 977 } 978 979 TEST_F(SyncDataTypeManagerImplTest, PrioritizedConfigurationStop) { 980 AddController(BOOKMARKS); 981 AddController(PREFERENCES); 982 983 dtm_->set_priority_types( 984 AddHighPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES))); 985 986 // Initial configure. 987 SetConfigureStartExpectation(); 988 SetConfigureDoneExpectation(DataTypeManager::ABORTED); 989 990 // Initially only PREFERENCES is configured. 991 configurer_.set_expected_configure_types( 992 AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES))); 993 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); 994 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 995 996 // BOOKMARKS is configured after download of PREFERENCES finishes. 997 configurer_.set_expected_configure_types( 998 AddLowPriorityCoreTypesTo(ModelTypeSet(BOOKMARKS))); 999 FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); 1000 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 1001 1002 // PERFERENCES controller is associating while BOOKMARKS is downloading. 1003 EXPECT_EQ(DataTypeController::ASSOCIATING, 1004 GetController(PREFERENCES)->state()); 1005 EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); 1006 1007 dtm_->Stop(); 1008 EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); 1009 EXPECT_EQ(DataTypeController::NOT_RUNNING, 1010 GetController(PREFERENCES)->state()); 1011 EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); 1012 } 1013 1014 TEST_F(SyncDataTypeManagerImplTest, PrioritizedConfigurationDownloadError) { 1015 AddController(BOOKMARKS); 1016 AddController(PREFERENCES); 1017 1018 dtm_->set_priority_types( 1019 AddHighPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES))); 1020 1021 // Initial configure. 1022 SetConfigureStartExpectation(); 1023 SetConfigureDoneExpectation(DataTypeManager::UNRECOVERABLE_ERROR); 1024 1025 // Initially only PREFERENCES is configured. 1026 configurer_.set_expected_configure_types( 1027 AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES))); 1028 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); 1029 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 1030 1031 // BOOKMARKS is configured after download of PREFERENCES finishes. 1032 configurer_.set_expected_configure_types( 1033 AddLowPriorityCoreTypesTo(ModelTypeSet(BOOKMARKS))); 1034 FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); 1035 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 1036 1037 // PERFERENCES controller is associating while BOOKMARKS is downloading. 1038 EXPECT_EQ(DataTypeController::ASSOCIATING, 1039 GetController(PREFERENCES)->state()); 1040 EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); 1041 1042 // Make BOOKMARKS download fail. 1043 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet(BOOKMARKS)); 1044 EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); 1045 EXPECT_EQ(DataTypeController::NOT_RUNNING, 1046 GetController(PREFERENCES)->state()); 1047 EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); 1048 } 1049 1050 TEST_F(SyncDataTypeManagerImplTest, HighPriorityAssociationFailure) { 1051 AddController(PREFERENCES); // Will fail. 1052 AddController(BOOKMARKS); // Will succeed. 1053 1054 dtm_->set_priority_types( 1055 AddHighPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES))); 1056 1057 // Initial configure. 1058 SetConfigureStartExpectation(); 1059 SetConfigureDoneExpectation(DataTypeManager::PARTIAL_SUCCESS); 1060 1061 // Initially only PREFERENCES is configured. 1062 configurer_.set_expected_configure_types( 1063 AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES))); 1064 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); 1065 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 1066 1067 // BOOKMARKS is configured after download of PREFERENCES finishes. 1068 configurer_.set_expected_configure_types( 1069 AddLowPriorityCoreTypesTo(ModelTypeSet(BOOKMARKS))); 1070 FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); 1071 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 1072 1073 // PERFERENCES controller is associating while BOOKMARKS is downloading. 1074 EXPECT_EQ(DataTypeController::ASSOCIATING, 1075 GetController(PREFERENCES)->state()); 1076 EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); 1077 1078 // Make PREFERENCES association fail. 1079 GetController(PREFERENCES)->FinishStart( 1080 DataTypeController::ASSOCIATION_FAILED); 1081 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 1082 1083 // Reconfigure without PREFERENCES after the BOOKMARKS download completes, 1084 // then reconfigure with BOOKMARKS. 1085 configurer_.set_expected_configure_types(HighPriorityTypes()); 1086 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); 1087 configurer_.set_expected_configure_types( 1088 AddLowPriorityCoreTypesTo(ModelTypeSet(BOOKMARKS))); 1089 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 1090 1091 // Reconfigure with BOOKMARKS. 1092 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); 1093 EXPECT_EQ(DataTypeController::ASSOCIATING, 1094 GetController(BOOKMARKS)->state()); 1095 GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); 1096 1097 EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); 1098 EXPECT_EQ(DataTypeController::NOT_RUNNING, 1099 GetController(PREFERENCES)->state()); 1100 EXPECT_EQ(DataTypeController::RUNNING, GetController(BOOKMARKS)->state()); 1101 } 1102 1103 TEST_F(SyncDataTypeManagerImplTest, LowPriorityAssociationFailure) { 1104 AddController(PREFERENCES); // Will succeed. 1105 AddController(BOOKMARKS); // Will fail. 1106 1107 dtm_->set_priority_types( 1108 AddHighPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES))); 1109 1110 // Initial configure. 1111 SetConfigureStartExpectation(); 1112 SetConfigureDoneExpectation(DataTypeManager::PARTIAL_SUCCESS); 1113 1114 // Initially only PREFERENCES is configured. 1115 configurer_.set_expected_configure_types( 1116 AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES))); 1117 Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); 1118 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 1119 1120 // BOOKMARKS is configured after download of PREFERENCES finishes. 1121 configurer_.set_expected_configure_types( 1122 AddLowPriorityCoreTypesTo(ModelTypeSet(BOOKMARKS))); 1123 FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); 1124 EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); 1125 1126 // PERFERENCES controller is associating while BOOKMARKS is downloading. 1127 EXPECT_EQ(DataTypeController::ASSOCIATING, 1128 GetController(PREFERENCES)->state()); 1129 EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); 1130 1131 // BOOKMARKS finishes downloading and PREFERENCES finishes associating. 1132 FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); 1133 GetController(PREFERENCES)->FinishStart(DataTypeController::OK); 1134 EXPECT_EQ(DataTypeController::RUNNING, GetController(PREFERENCES)->state()); 1135 1136 // Make BOOKMARKS association fail, which triggers reconfigure with only 1137 // PREFERENCES. 1138 configurer_.set_expected_configure_types( 1139 AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES))); 1140 GetController(BOOKMARKS)->FinishStart(DataTypeController::ASSOCIATION_FAILED); 1141 EXPECT_EQ(DataTypeController::NOT_RUNNING, 1142 GetController(BOOKMARKS)->state()); 1143 EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state()); 1144 1145 // Finish configuration with only PREFERENCES. 1146 configurer_.set_expected_configure_types( 1147 AddLowPriorityCoreTypesTo(ModelTypeSet())); 1148 FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); 1149 FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); 1150 EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); 1151 EXPECT_EQ(DataTypeController::RUNNING, GetController(PREFERENCES)->state()); 1152 EXPECT_EQ(DataTypeController::NOT_RUNNING, 1153 GetController(BOOKMARKS)->state()); 1154 } 1155 1156 } // namespace browser_sync 1157