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