1 // Copyright 2013 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/sync_backend_host_impl.h" 6 7 #include <cstddef> 8 9 #include "base/files/file_util.h" 10 #include "base/location.h" 11 #include "base/memory/scoped_ptr.h" 12 #include "base/message_loop/message_loop.h" 13 #include "base/synchronization/waitable_event.h" 14 #include "base/test/test_timeouts.h" 15 #include "chrome/browser/chrome_notification_types.h" 16 #include "chrome/browser/invalidation/profile_invalidation_provider_factory.h" 17 #include "chrome/browser/prefs/pref_service_syncable.h" 18 #include "chrome/test/base/testing_browser_process.h" 19 #include "chrome/test/base/testing_profile.h" 20 #include "chrome/test/base/testing_profile_manager.h" 21 #include "components/invalidation/invalidator_state.h" 22 #include "components/invalidation/invalidator_storage.h" 23 #include "components/invalidation/profile_invalidation_provider.h" 24 #include "components/sync_driver/device_info.h" 25 #include "components/sync_driver/sync_frontend.h" 26 #include "components/sync_driver/sync_prefs.h" 27 #include "content/public/browser/notification_service.h" 28 #include "content/public/test/test_browser_thread_bundle.h" 29 #include "content/public/test/test_utils.h" 30 #include "google/cacheinvalidation/include/types.h" 31 #include "google_apis/gaia/gaia_constants.h" 32 #include "net/url_request/test_url_fetcher_factory.h" 33 #include "sync/internal_api/public/base/model_type.h" 34 #include "sync/internal_api/public/engine/model_safe_worker.h" 35 #include "sync/internal_api/public/http_bridge_network_resources.h" 36 #include "sync/internal_api/public/network_resources.h" 37 #include "sync/internal_api/public/sessions/commit_counters.h" 38 #include "sync/internal_api/public/sessions/status_counters.h" 39 #include "sync/internal_api/public/sessions/update_counters.h" 40 #include "sync/internal_api/public/sync_manager_factory.h" 41 #include "sync/internal_api/public/test/fake_sync_manager.h" 42 #include "sync/internal_api/public/util/experiments.h" 43 #include "sync/protocol/encryption.pb.h" 44 #include "sync/protocol/sync_protocol_error.h" 45 #include "sync/util/test_unrecoverable_error_handler.h" 46 #include "testing/gmock/include/gmock/gmock.h" 47 #include "testing/gtest/include/gtest/gtest.h" 48 #include "url/gurl.h" 49 50 using content::BrowserThread; 51 using syncer::FakeSyncManager; 52 using syncer::SyncManager; 53 using ::testing::InvokeWithoutArgs; 54 using ::testing::StrictMock; 55 using ::testing::_; 56 57 namespace browser_sync { 58 59 namespace { 60 61 const char kTestProfileName[] = "test-profile"; 62 63 static const base::FilePath::CharType kTestSyncDir[] = 64 FILE_PATH_LITERAL("sync-test"); 65 66 ACTION_P(Signal, event) { 67 event->Signal(); 68 } 69 70 void QuitMessageLoop() { 71 base::MessageLoop::current()->Quit(); 72 } 73 74 class MockSyncFrontend : public sync_driver::SyncFrontend { 75 public: 76 virtual ~MockSyncFrontend() {} 77 78 MOCK_METHOD4( 79 OnBackendInitialized, 80 void(const syncer::WeakHandle<syncer::JsBackend>&, 81 const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&, 82 const std::string&, 83 bool)); 84 MOCK_METHOD0(OnSyncCycleCompleted, void()); 85 MOCK_METHOD1(OnConnectionStatusChange, 86 void(syncer::ConnectionStatus status)); 87 MOCK_METHOD0(OnClearServerDataSucceeded, void()); 88 MOCK_METHOD0(OnClearServerDataFailed, void()); 89 MOCK_METHOD2(OnPassphraseRequired, 90 void(syncer::PassphraseRequiredReason, 91 const sync_pb::EncryptedData&)); 92 MOCK_METHOD0(OnPassphraseAccepted, void()); 93 MOCK_METHOD2(OnEncryptedTypesChanged, 94 void(syncer::ModelTypeSet, bool)); 95 MOCK_METHOD0(OnEncryptionComplete, void()); 96 MOCK_METHOD1(OnMigrationNeededForTypes, void(syncer::ModelTypeSet)); 97 MOCK_METHOD1(OnProtocolEvent, void(const syncer::ProtocolEvent&)); 98 MOCK_METHOD2(OnDirectoryTypeCommitCounterUpdated, 99 void(syncer::ModelType, const syncer::CommitCounters&)); 100 MOCK_METHOD2(OnDirectoryTypeUpdateCounterUpdated, 101 void(syncer::ModelType, const syncer::UpdateCounters&)); 102 MOCK_METHOD2(OnDirectoryTypeStatusCounterUpdated, 103 void(syncer::ModelType, const syncer::StatusCounters&)); 104 MOCK_METHOD1(OnExperimentsChanged, 105 void(const syncer::Experiments&)); 106 MOCK_METHOD1(OnActionableError, 107 void(const syncer::SyncProtocolError& sync_error)); 108 MOCK_METHOD0(OnSyncConfigureRetry, void()); 109 }; 110 111 class FakeSyncManagerFactory : public syncer::SyncManagerFactory { 112 public: 113 explicit FakeSyncManagerFactory(FakeSyncManager** fake_manager) 114 : SyncManagerFactory(NORMAL), 115 fake_manager_(fake_manager) { 116 *fake_manager_ = NULL; 117 } 118 virtual ~FakeSyncManagerFactory() {} 119 120 // SyncManagerFactory implementation. Called on the sync thread. 121 virtual scoped_ptr<SyncManager> CreateSyncManager( 122 std::string name) OVERRIDE { 123 *fake_manager_ = new FakeSyncManager(initial_sync_ended_types_, 124 progress_marker_types_, 125 configure_fail_types_); 126 return scoped_ptr<SyncManager>(*fake_manager_); 127 } 128 129 void set_initial_sync_ended_types(syncer::ModelTypeSet types) { 130 initial_sync_ended_types_ = types; 131 } 132 133 void set_progress_marker_types(syncer::ModelTypeSet types) { 134 progress_marker_types_ = types; 135 } 136 137 void set_configure_fail_types(syncer::ModelTypeSet types) { 138 configure_fail_types_ = types; 139 } 140 141 private: 142 syncer::ModelTypeSet initial_sync_ended_types_; 143 syncer::ModelTypeSet progress_marker_types_; 144 syncer::ModelTypeSet configure_fail_types_; 145 FakeSyncManager** fake_manager_; 146 }; 147 148 class SyncBackendHostTest : public testing::Test { 149 protected: 150 SyncBackendHostTest() 151 : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD), 152 profile_manager_(TestingBrowserProcess::GetGlobal()), 153 fake_manager_(NULL) {} 154 155 virtual ~SyncBackendHostTest() {} 156 157 virtual void SetUp() OVERRIDE { 158 ASSERT_TRUE(profile_manager_.SetUp()); 159 profile_ = profile_manager_.CreateTestingProfile(kTestProfileName); 160 sync_prefs_.reset(new sync_driver::SyncPrefs(profile_->GetPrefs())); 161 backend_.reset(new SyncBackendHostImpl( 162 profile_->GetDebugName(), 163 profile_, 164 invalidation::ProfileInvalidationProviderFactory::GetForProfile( 165 profile_)->GetInvalidationService(), 166 sync_prefs_->AsWeakPtr(), 167 base::FilePath(kTestSyncDir))); 168 credentials_.email = "user (at) example.com"; 169 credentials_.sync_token = "sync_token"; 170 credentials_.scope_set.insert(GaiaConstants::kChromeSyncOAuth2Scope); 171 172 fake_manager_factory_.reset(new FakeSyncManagerFactory(&fake_manager_)); 173 174 // These types are always implicitly enabled. 175 enabled_types_.PutAll(syncer::ControlTypes()); 176 177 // NOTE: We can't include Passwords or Typed URLs due to the Sync Backend 178 // Registrar removing them if it can't find their model workers. 179 enabled_types_.Put(syncer::BOOKMARKS); 180 enabled_types_.Put(syncer::NIGORI); 181 enabled_types_.Put(syncer::DEVICE_INFO); 182 enabled_types_.Put(syncer::PREFERENCES); 183 enabled_types_.Put(syncer::SESSIONS); 184 enabled_types_.Put(syncer::SEARCH_ENGINES); 185 enabled_types_.Put(syncer::AUTOFILL); 186 enabled_types_.Put(syncer::EXPERIMENTS); 187 188 network_resources_.reset(new syncer::HttpBridgeNetworkResources()); 189 } 190 191 virtual void TearDown() OVERRIDE { 192 if (backend_) { 193 backend_->StopSyncingForShutdown(); 194 backend_->Shutdown(syncer::STOP_SYNC); 195 } 196 backend_.reset(); 197 sync_prefs_.reset(); 198 profile_ = NULL; 199 profile_manager_.DeleteTestingProfile(kTestProfileName); 200 // Pump messages posted by the sync thread (which may end up 201 // posting on the IO thread). 202 base::RunLoop().RunUntilIdle(); 203 content::RunAllPendingInMessageLoop(BrowserThread::IO); 204 // Pump any messages posted by the IO thread. 205 base::RunLoop().RunUntilIdle(); 206 } 207 208 // Synchronously initializes the backend. 209 void InitializeBackend(bool expect_success) { 210 EXPECT_CALL(mock_frontend_, OnBackendInitialized(_, _, _, expect_success)). 211 WillOnce(InvokeWithoutArgs(QuitMessageLoop)); 212 backend_->Initialize( 213 &mock_frontend_, 214 scoped_ptr<base::Thread>(), 215 syncer::WeakHandle<syncer::JsEventHandler>(), 216 GURL(std::string()), 217 credentials_, 218 true, 219 fake_manager_factory_.PassAs<syncer::SyncManagerFactory>(), 220 scoped_ptr<syncer::UnrecoverableErrorHandler>( 221 new syncer::TestUnrecoverableErrorHandler).Pass(), 222 NULL, 223 network_resources_.get()); 224 base::RunLoop run_loop; 225 BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE, 226 run_loop.QuitClosure(), 227 TestTimeouts::action_timeout()); 228 run_loop.Run(); 229 // |fake_manager_factory_|'s fake_manager() is set on the sync 230 // thread, but we can rely on the message loop barriers to 231 // guarantee that we see the updated value. 232 DCHECK(fake_manager_); 233 } 234 235 // Synchronously configures the backend's datatypes. 236 void ConfigureDataTypes(syncer::ModelTypeSet types_to_add, 237 syncer::ModelTypeSet types_to_remove, 238 syncer::ModelTypeSet types_to_unapply) { 239 sync_driver::BackendDataTypeConfigurer::DataTypeConfigStateMap 240 config_state_map; 241 sync_driver::BackendDataTypeConfigurer::SetDataTypesState( 242 sync_driver::BackendDataTypeConfigurer::CONFIGURE_ACTIVE, 243 types_to_add, 244 &config_state_map); 245 sync_driver::BackendDataTypeConfigurer::SetDataTypesState( 246 sync_driver::BackendDataTypeConfigurer::DISABLED, 247 types_to_remove, &config_state_map); 248 sync_driver::BackendDataTypeConfigurer::SetDataTypesState( 249 sync_driver::BackendDataTypeConfigurer::UNREADY, 250 types_to_unapply, &config_state_map); 251 252 types_to_add.PutAll(syncer::ControlTypes()); 253 backend_->ConfigureDataTypes( 254 syncer::CONFIGURE_REASON_RECONFIGURATION, 255 config_state_map, 256 base::Bind(&SyncBackendHostTest::DownloadReady, 257 base::Unretained(this)), 258 base::Bind(&SyncBackendHostTest::OnDownloadRetry, 259 base::Unretained(this))); 260 base::RunLoop run_loop; 261 BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE, 262 run_loop.QuitClosure(), 263 TestTimeouts::action_timeout()); 264 run_loop.Run(); 265 } 266 267 void IssueRefreshRequest(syncer::ModelTypeSet types) { 268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 269 270 content::NotificationService::current()->Notify( 271 chrome::NOTIFICATION_SYNC_REFRESH_LOCAL, 272 content::Source<Profile>(profile_), 273 content::Details<syncer::ModelTypeSet>(&types)); 274 } 275 276 protected: 277 void DownloadReady(syncer::ModelTypeSet succeeded_types, 278 syncer::ModelTypeSet failed_types) { 279 base::MessageLoop::current()->Quit(); 280 } 281 282 void OnDownloadRetry() { 283 NOTIMPLEMENTED(); 284 } 285 286 content::TestBrowserThreadBundle thread_bundle_; 287 StrictMock<MockSyncFrontend> mock_frontend_; 288 syncer::SyncCredentials credentials_; 289 TestingProfileManager profile_manager_; 290 TestingProfile* profile_; 291 scoped_ptr<sync_driver::SyncPrefs> sync_prefs_; 292 scoped_ptr<SyncBackendHost> backend_; 293 scoped_ptr<FakeSyncManagerFactory> fake_manager_factory_; 294 FakeSyncManager* fake_manager_; 295 syncer::ModelTypeSet enabled_types_; 296 scoped_ptr<syncer::NetworkResources> network_resources_; 297 }; 298 299 // Test basic initialization with no initial types (first time initialization). 300 // Only the nigori should be configured. 301 TEST_F(SyncBackendHostTest, InitShutdown) { 302 InitializeBackend(true); 303 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals( 304 syncer::ControlTypes())); 305 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals( 306 syncer::ControlTypes())); 307 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 308 syncer::ControlTypes()).Empty()); 309 } 310 311 // Test first time sync scenario. All types should be properly configured. 312 TEST_F(SyncBackendHostTest, FirstTimeSync) { 313 InitializeBackend(true); 314 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals( 315 syncer::ControlTypes())); 316 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals( 317 syncer::ControlTypes())); 318 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 319 syncer::ControlTypes()).Empty()); 320 321 ConfigureDataTypes(enabled_types_, 322 Difference(syncer::ModelTypeSet::All(), 323 enabled_types_), 324 syncer::ModelTypeSet()); 325 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll( 326 Difference(enabled_types_, syncer::ControlTypes()))); 327 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_)); 328 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_)); 329 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 330 enabled_types_).Empty()); 331 } 332 333 // Test the restart after setting up sync scenario. No enabled types should be 334 // downloaded or cleaned. 335 TEST_F(SyncBackendHostTest, Restart) { 336 sync_prefs_->SetSyncSetupCompleted(); 337 syncer::ModelTypeSet all_but_nigori = enabled_types_; 338 fake_manager_factory_->set_progress_marker_types(enabled_types_); 339 fake_manager_factory_->set_initial_sync_ended_types(enabled_types_); 340 InitializeBackend(true); 341 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty()); 342 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), 343 enabled_types_).Empty()); 344 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_)); 345 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 346 enabled_types_).Empty()); 347 348 ConfigureDataTypes(enabled_types_, 349 Difference(syncer::ModelTypeSet::All(), 350 enabled_types_), 351 syncer::ModelTypeSet()); 352 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty()); 353 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), 354 enabled_types_).Empty()); 355 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_)); 356 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_)); 357 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 358 enabled_types_).Empty()); 359 } 360 361 // Test a sync restart scenario where some types had never finished configuring. 362 // The partial types should be purged, then reconfigured properly. 363 TEST_F(SyncBackendHostTest, PartialTypes) { 364 sync_prefs_->SetSyncSetupCompleted(); 365 // Set sync manager behavior before passing it down. All types have progress 366 // markers, but nigori and bookmarks are missing initial sync ended. 367 syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS); 368 syncer::ModelTypeSet full_types = 369 Difference(enabled_types_, partial_types); 370 fake_manager_factory_->set_progress_marker_types(enabled_types_); 371 fake_manager_factory_->set_initial_sync_ended_types(full_types); 372 373 // Bringing up the backend should purge all partial types, then proceed to 374 // download the Nigori. 375 InitializeBackend(true); 376 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals( 377 syncer::ModelTypeSet(syncer::NIGORI))); 378 EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types)); 379 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals( 380 Union(full_types, syncer::ModelTypeSet(syncer::NIGORI)))); 381 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 382 enabled_types_).Equals( 383 Difference(partial_types, syncer::ModelTypeSet(syncer::NIGORI)))); 384 385 // Now do the actual configuration, which should download and apply bookmarks. 386 ConfigureDataTypes(enabled_types_, 387 Difference(syncer::ModelTypeSet::All(), 388 enabled_types_), 389 syncer::ModelTypeSet()); 390 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), 391 enabled_types_).Empty()); 392 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals( 393 partial_types)); 394 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_)); 395 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_)); 396 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 397 enabled_types_).Empty()); 398 } 399 400 // Test the behavior when we lose the sync db. Although we already have types 401 // enabled, we should re-download all of them because we lost their data. 402 TEST_F(SyncBackendHostTest, LostDB) { 403 sync_prefs_->SetSyncSetupCompleted(); 404 // Initialization should fetch the Nigori node. Everything else should be 405 // left untouched. 406 InitializeBackend(true); 407 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals( 408 syncer::ModelTypeSet(syncer::ControlTypes()))); 409 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals( 410 syncer::ModelTypeSet(syncer::ControlTypes()))); 411 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 412 enabled_types_).Equals( 413 Difference(enabled_types_, syncer::ControlTypes()))); 414 415 // The database was empty, so any cleaning is entirely optional. We want to 416 // reset this value before running the next part of the test, though. 417 fake_manager_->GetAndResetCleanedTypes(); 418 419 // The actual configuration should redownload and apply all the enabled types. 420 ConfigureDataTypes(enabled_types_, 421 Difference(syncer::ModelTypeSet::All(), 422 enabled_types_), 423 syncer::ModelTypeSet()); 424 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll( 425 Difference(enabled_types_, syncer::ControlTypes()))); 426 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), 427 enabled_types_).Empty()); 428 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_)); 429 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_)); 430 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 431 enabled_types_).Empty()); 432 } 433 434 TEST_F(SyncBackendHostTest, DisableTypes) { 435 // Simulate first time sync. 436 InitializeBackend(true); 437 fake_manager_->GetAndResetCleanedTypes(); 438 ConfigureDataTypes(enabled_types_, 439 Difference(syncer::ModelTypeSet::All(), 440 enabled_types_), 441 syncer::ModelTypeSet()); 442 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals( 443 enabled_types_)); 444 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), 445 enabled_types_).Empty()); 446 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_)); 447 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 448 enabled_types_).Empty()); 449 450 // Then disable two datatypes. 451 syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS, 452 syncer::SEARCH_ENGINES); 453 syncer::ModelTypeSet old_types = enabled_types_; 454 enabled_types_.RemoveAll(disabled_types); 455 ConfigureDataTypes(enabled_types_, 456 Difference(syncer::ModelTypeSet::All(), 457 enabled_types_), 458 syncer::ModelTypeSet()); 459 460 // Only those datatypes disabled should be cleaned. Nothing should be 461 // downloaded. 462 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty()); 463 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), 464 old_types).Equals(disabled_types)); 465 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_)); 466 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_)); 467 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 468 enabled_types_).Empty()); 469 } 470 471 TEST_F(SyncBackendHostTest, AddTypes) { 472 // Simulate first time sync. 473 InitializeBackend(true); 474 fake_manager_->GetAndResetCleanedTypes(); 475 ConfigureDataTypes(enabled_types_, 476 Difference(syncer::ModelTypeSet::All(), 477 enabled_types_), 478 syncer::ModelTypeSet()); 479 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals( 480 enabled_types_)); 481 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), 482 enabled_types_).Empty()); 483 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_)); 484 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 485 enabled_types_).Empty()); 486 487 // Then add two datatypes. 488 syncer::ModelTypeSet new_types(syncer::EXTENSIONS, 489 syncer::APPS); 490 enabled_types_.PutAll(new_types); 491 ConfigureDataTypes(enabled_types_, 492 Difference(syncer::ModelTypeSet::All(), 493 enabled_types_), 494 syncer::ModelTypeSet()); 495 496 // Only those datatypes added should be downloaded (plus nigori). Nothing 497 // should be cleaned aside from the disabled types. 498 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals( 499 Union(new_types, syncer::ModelTypeSet(syncer::NIGORI)))); 500 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), 501 enabled_types_).Empty()); 502 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_)); 503 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_)); 504 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 505 enabled_types_).Empty()); 506 } 507 508 // And and disable in the same configuration. 509 TEST_F(SyncBackendHostTest, AddDisableTypes) { 510 // Simulate first time sync. 511 InitializeBackend(true); 512 fake_manager_->GetAndResetCleanedTypes(); 513 ConfigureDataTypes(enabled_types_, 514 Difference(syncer::ModelTypeSet::All(), 515 enabled_types_), 516 syncer::ModelTypeSet()); 517 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals( 518 enabled_types_)); 519 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), 520 enabled_types_).Empty()); 521 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_)); 522 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 523 enabled_types_).Empty()); 524 525 // Then add two datatypes. 526 syncer::ModelTypeSet old_types = enabled_types_; 527 syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS, 528 syncer::SEARCH_ENGINES); 529 syncer::ModelTypeSet new_types(syncer::EXTENSIONS, 530 syncer::APPS); 531 enabled_types_.PutAll(new_types); 532 enabled_types_.RemoveAll(disabled_types); 533 ConfigureDataTypes(enabled_types_, 534 Difference(syncer::ModelTypeSet::All(), 535 enabled_types_), 536 syncer::ModelTypeSet()); 537 538 // Only those datatypes added should be downloaded (plus nigori). Nothing 539 // should be cleaned aside from the disabled types. 540 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals( 541 Union(new_types, syncer::ModelTypeSet(syncer::NIGORI)))); 542 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), 543 old_types).Equals(disabled_types)); 544 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_)); 545 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_)); 546 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 547 old_types).Equals(disabled_types)); 548 } 549 550 // Test restarting the browser to newly supported datatypes. The new datatypes 551 // should be downloaded on the configuration after backend initialization. 552 TEST_F(SyncBackendHostTest, NewlySupportedTypes) { 553 sync_prefs_->SetSyncSetupCompleted(); 554 // Set sync manager behavior before passing it down. All types have progress 555 // markers and initial sync ended except the new types. 556 syncer::ModelTypeSet old_types = enabled_types_; 557 fake_manager_factory_->set_progress_marker_types(old_types); 558 fake_manager_factory_->set_initial_sync_ended_types(old_types); 559 syncer::ModelTypeSet new_types(syncer::APP_SETTINGS, 560 syncer::EXTENSION_SETTINGS); 561 enabled_types_.PutAll(new_types); 562 563 // Does nothing. 564 InitializeBackend(true); 565 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty()); 566 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), 567 old_types).Empty()); 568 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(old_types)); 569 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 570 enabled_types_).Equals(new_types)); 571 572 // Downloads and applies the new types. 573 ConfigureDataTypes(enabled_types_, 574 Difference(syncer::ModelTypeSet::All(), 575 enabled_types_), 576 syncer::ModelTypeSet()); 577 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals( 578 Union(new_types, syncer::ModelTypeSet(syncer::NIGORI)))); 579 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), 580 enabled_types_).Empty()); 581 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_)); 582 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_)); 583 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 584 enabled_types_).Empty()); 585 } 586 587 // Test the newly supported types scenario, but with the presence of partial 588 // types as well. Both partial and newly supported types should be downloaded 589 // the configuration. 590 TEST_F(SyncBackendHostTest, NewlySupportedTypesWithPartialTypes) { 591 sync_prefs_->SetSyncSetupCompleted(); 592 // Set sync manager behavior before passing it down. All types have progress 593 // markers and initial sync ended except the new types. 594 syncer::ModelTypeSet old_types = enabled_types_; 595 syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS); 596 syncer::ModelTypeSet full_types = 597 Difference(enabled_types_, partial_types); 598 fake_manager_factory_->set_progress_marker_types(old_types); 599 fake_manager_factory_->set_initial_sync_ended_types(full_types); 600 syncer::ModelTypeSet new_types(syncer::APP_SETTINGS, 601 syncer::EXTENSION_SETTINGS); 602 enabled_types_.PutAll(new_types); 603 604 // Purge the partial types. The nigori will be among the purged types, but 605 // the syncer will re-download it by the time the initialization is complete. 606 InitializeBackend(true); 607 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals( 608 syncer::ModelTypeSet(syncer::NIGORI))); 609 EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types)); 610 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals( 611 syncer::Union(full_types, syncer::ModelTypeSet(syncer::NIGORI)))); 612 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 613 enabled_types_).Equals(Union(new_types, Difference( 614 partial_types, syncer::ModelTypeSet(syncer::NIGORI))))); 615 616 // Downloads and applies the new types and partial types (which includes 617 // nigori anyways). 618 ConfigureDataTypes(enabled_types_, 619 Difference(syncer::ModelTypeSet::All(), 620 enabled_types_), 621 syncer::ModelTypeSet()); 622 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals( 623 Union(new_types, partial_types))); 624 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), 625 enabled_types_).Empty()); 626 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_)); 627 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_)); 628 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 629 enabled_types_).Empty()); 630 } 631 632 // Verify that downloading control types only downloads those types that do 633 // not have initial sync ended set. 634 TEST_F(SyncBackendHostTest, DownloadControlTypes) { 635 sync_prefs_->SetSyncSetupCompleted(); 636 // Set sync manager behavior before passing it down. Experiments and device 637 // info are new types without progress markers or initial sync ended, while 638 // all other types have been fully downloaded and applied. 639 syncer::ModelTypeSet new_types(syncer::EXPERIMENTS, syncer::NIGORI); 640 syncer::ModelTypeSet old_types = 641 Difference(enabled_types_, new_types); 642 fake_manager_factory_->set_progress_marker_types(old_types); 643 fake_manager_factory_->set_initial_sync_ended_types(old_types); 644 645 // Bringing up the backend should download the new types without downloading 646 // any old types. 647 InitializeBackend(true); 648 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(new_types)); 649 EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().Equals( 650 Difference(syncer::ModelTypeSet::All(), 651 enabled_types_))); 652 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_)); 653 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 654 enabled_types_).Empty()); 655 } 656 657 // Fail to download control types. It's believed that there is a server bug 658 // which can allow this to happen (crbug.com/164288). The sync backend host 659 // should detect this condition and fail to initialize the backend. 660 // 661 // The failure is "silent" in the sense that the GetUpdates request appears to 662 // be successful, but it returned no results. This means that the usual 663 // download retry logic will not be invoked. 664 TEST_F(SyncBackendHostTest, SilentlyFailToDownloadControlTypes) { 665 fake_manager_factory_->set_configure_fail_types(syncer::ModelTypeSet::All()); 666 InitializeBackend(false); 667 } 668 669 // Test that local refresh requests are delivered to sync. 670 TEST_F(SyncBackendHostTest, ForwardLocalRefreshRequest) { 671 InitializeBackend(true); 672 673 syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All(); 674 IssueRefreshRequest(set1); 675 fake_manager_->WaitForSyncThread(); 676 EXPECT_TRUE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes())); 677 678 syncer::ModelTypeSet set2 = syncer::ModelTypeSet(syncer::SESSIONS); 679 IssueRefreshRequest(set2); 680 fake_manager_->WaitForSyncThread(); 681 EXPECT_TRUE(set2.Equals(fake_manager_->GetLastRefreshRequestTypes())); 682 } 683 684 // Test that local invalidations issued before sync is initialized are ignored. 685 TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestEarly) { 686 syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All(); 687 IssueRefreshRequest(set1); 688 689 InitializeBackend(true); 690 691 fake_manager_->WaitForSyncThread(); 692 EXPECT_FALSE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes())); 693 } 694 695 // Test that local invalidations issued while sync is shutting down are ignored. 696 TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestLate) { 697 InitializeBackend(true); 698 699 backend_->StopSyncingForShutdown(); 700 701 syncer::ModelTypeSet types = syncer::ModelTypeSet::All(); 702 IssueRefreshRequest(types); 703 fake_manager_->WaitForSyncThread(); 704 EXPECT_FALSE(types.Equals(fake_manager_->GetLastRefreshRequestTypes())); 705 706 backend_->Shutdown(syncer::STOP_SYNC); 707 backend_.reset(); 708 } 709 710 // Test that configuration on signin sends the proper GU source. 711 TEST_F(SyncBackendHostTest, DownloadControlTypesNewClient) { 712 InitializeBackend(true); 713 EXPECT_EQ(syncer::CONFIGURE_REASON_NEW_CLIENT, 714 fake_manager_->GetAndResetConfigureReason()); 715 } 716 717 // Test that configuration on restart sends the proper GU source. 718 TEST_F(SyncBackendHostTest, DownloadControlTypesRestart) { 719 sync_prefs_->SetSyncSetupCompleted(); 720 fake_manager_factory_->set_progress_marker_types(enabled_types_); 721 fake_manager_factory_->set_initial_sync_ended_types(enabled_types_); 722 InitializeBackend(true); 723 EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE, 724 fake_manager_->GetAndResetConfigureReason()); 725 } 726 727 // It is SyncBackendHostCore responsibility to cleanup Sync Data folder if sync 728 // setup hasn't been completed. This test ensures that cleanup happens. 729 TEST_F(SyncBackendHostTest, TestStartupWithOldSyncData) { 730 const char* nonsense = "slon"; 731 base::FilePath temp_directory = 732 profile_->GetPath().Append(base::FilePath(kTestSyncDir)); 733 base::FilePath sync_file = temp_directory.AppendASCII("SyncData.sqlite3"); 734 ASSERT_TRUE(base::CreateDirectory(temp_directory)); 735 ASSERT_NE(-1, base::WriteFile(sync_file, nonsense, strlen(nonsense))); 736 737 InitializeBackend(true); 738 739 EXPECT_FALSE(base::PathExists(sync_file)); 740 } 741 742 // If bookmarks encounter an error that results in disabling without purging 743 // (such as when the type is unready), and then is explicitly disabled, the 744 // SyncBackendHost needs to tell the manager to purge the type, even though 745 // it's already disabled (crbug.com/386778). 746 TEST_F(SyncBackendHostTest, DisableThenPurgeType) { 747 syncer::ModelTypeSet error_types(syncer::BOOKMARKS); 748 749 InitializeBackend(true); 750 751 // First enable the types. 752 ConfigureDataTypes(enabled_types_, 753 Difference(syncer::ModelTypeSet::All(), 754 enabled_types_), 755 syncer::ModelTypeSet()); 756 757 // Then mark the error types as unready (disables without purging). 758 ConfigureDataTypes(enabled_types_, 759 Difference(syncer::ModelTypeSet::All(), 760 enabled_types_), 761 error_types); 762 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 763 error_types).Empty()); 764 765 // Lastly explicitly disable the error types, which should result in a purge. 766 enabled_types_.RemoveAll(error_types); 767 ConfigureDataTypes(enabled_types_, 768 Difference(syncer::ModelTypeSet::All(), 769 enabled_types_), 770 syncer::ModelTypeSet()); 771 EXPECT_FALSE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( 772 error_types).Empty()); 773 } 774 775 } // namespace 776 777 } // namespace browser_sync 778