| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/basictypes.h" | 5 #include "base/basictypes.h" |
| 6 #include "base/compiler_specific.h" | 6 #include "base/compiler_specific.h" |
| 7 #include "base/file_util.h" | |
| 8 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/run_loop.h" | 8 #include "base/run_loop.h" |
| 10 #include "base/values.h" | 9 #include "base/values.h" |
| 11 #include "chrome/browser/invalidation/invalidation_service_factory.h" | 10 #include "chrome/browser/invalidation/invalidation_service_factory.h" |
| 12 #include "chrome/browser/signin/signin_manager.h" | 11 #include "chrome/browser/signin/signin_manager.h" |
| 13 #include "chrome/browser/signin/signin_manager_factory.h" | 12 #include "chrome/browser/signin/signin_manager_factory.h" |
| 14 #include "chrome/browser/signin/token_service.h" | 13 #include "chrome/browser/signin/token_service.h" |
| 15 #include "chrome/browser/signin/token_service_factory.h" | 14 #include "chrome/browser/signin/token_service_factory.h" |
| 16 #include "chrome/browser/sync/fake_oauth2_token_service.h" | 15 #include "chrome/browser/sync/fake_oauth2_token_service.h" |
| 17 #include "chrome/browser/sync/glue/bookmark_data_type_controller.h" | 16 #include "chrome/browser/sync/glue/bookmark_data_type_controller.h" |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 service_.reset(); | 75 service_.reset(); |
| 77 profile_.reset(); | 76 profile_.reset(); |
| 78 | 77 |
| 79 // Pump messages posted by the sync thread (which may end up | 78 // Pump messages posted by the sync thread (which may end up |
| 80 // posting on the IO thread). | 79 // posting on the IO thread). |
| 81 base::RunLoop().RunUntilIdle(); | 80 base::RunLoop().RunUntilIdle(); |
| 82 content::RunAllPendingInMessageLoop(content::BrowserThread::IO); | 81 content::RunAllPendingInMessageLoop(content::BrowserThread::IO); |
| 83 base::RunLoop().RunUntilIdle(); | 82 base::RunLoop().RunUntilIdle(); |
| 84 } | 83 } |
| 85 | 84 |
| 86 // TODO(akalin): Refactor the StartSyncService*() functions below. | 85 void StartSyncServiceAndSetInitialSyncEnded() { |
| 87 | |
| 88 void StartSyncService() { | |
| 89 StartSyncServiceAndSetInitialSyncEnded( | |
| 90 true, true, false, true, syncer::STORAGE_IN_MEMORY); | |
| 91 } | |
| 92 | |
| 93 void StartSyncServiceAndSetInitialSyncEnded( | |
| 94 bool set_initial_sync_ended, | |
| 95 bool issue_auth_token, | |
| 96 bool synchronous_sync_configuration, | |
| 97 bool sync_setup_completed, | |
| 98 syncer::StorageOption storage_option) { | |
| 99 if (service_) | 86 if (service_) |
| 100 return; | 87 return; |
| 101 | 88 |
| 102 SigninManagerBase* signin = | 89 SigninManagerBase* signin = |
| 103 SigninManagerFactory::GetForProfile(profile_.get()); | 90 SigninManagerFactory::GetForProfile(profile_.get()); |
| 104 signin->SetAuthenticatedUsername("test"); | 91 signin->SetAuthenticatedUsername("test"); |
| 105 ProfileOAuth2TokenService* oauth2_token_service = | 92 ProfileOAuth2TokenService* oauth2_token_service = |
| 106 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_.get()); | 93 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_.get()); |
| 107 ProfileSyncComponentsFactoryMock* factory = | 94 ProfileSyncComponentsFactoryMock* factory = |
| 108 new ProfileSyncComponentsFactoryMock(); | 95 new ProfileSyncComponentsFactoryMock(); |
| 109 service_.reset(new TestProfileSyncService( | 96 service_.reset(new TestProfileSyncService( |
| 110 factory, | 97 factory, |
| 111 profile_.get(), | 98 profile_.get(), |
| 112 signin, | 99 signin, |
| 113 oauth2_token_service, | 100 oauth2_token_service, |
| 114 ProfileSyncService::AUTO_START, | 101 ProfileSyncService::AUTO_START, |
| 115 true)); | 102 true)); |
| 116 if (!set_initial_sync_ended) | |
| 117 service_->dont_set_initial_sync_ended_on_init(); | |
| 118 | 103 |
| 119 if (synchronous_sync_configuration) | |
| 120 service_->set_synchronous_sync_configuration(); | |
| 121 | |
| 122 service_->set_storage_option(storage_option); | |
| 123 if (!sync_setup_completed) | |
| 124 profile_->GetPrefs()->SetBoolean(prefs::kSyncHasSetupCompleted, false); | |
| 125 | 104 |
| 126 // Register the bookmark data type. | 105 // Register the bookmark data type. |
| 127 ON_CALL(*factory, CreateDataTypeManager(_, _, _, _, _, _)). | 106 ON_CALL(*factory, CreateDataTypeManager(_, _, _, _, _, _)). |
| 128 WillByDefault(ReturnNewDataTypeManager()); | 107 WillByDefault(ReturnNewDataTypeManager()); |
| 129 | 108 |
| 130 if (issue_auth_token) | |
| 131 IssueTestTokens(); | |
| 132 | |
| 133 service_->Initialize(); | 109 service_->Initialize(); |
| 134 } | 110 } |
| 135 | 111 |
| 136 void WaitForBackendInitDone() { | 112 void WaitForBackendInitDone() { |
| 137 for (int i = 0; i < 5; ++i) { | 113 for (int i = 0; i < 5; ++i) { |
| 138 base::WaitableEvent done(false, false); | 114 base::WaitableEvent done(false, false); |
| 139 service_->GetBackendForTest()->GetSyncLoopForTesting() | 115 service_->GetBackendForTest()->GetSyncLoopForTesting() |
| 140 ->PostTask(FROM_HERE, base::Bind(&SignalDone, &done)); | 116 ->PostTask(FROM_HERE, base::Bind(&SignalDone, &done)); |
| 141 done.Wait(); | 117 done.Wait(); |
| 142 base::RunLoop().RunUntilIdle(); | 118 base::RunLoop().RunUntilIdle(); |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 EXPECT_FALSE( | 298 EXPECT_FALSE( |
| 323 profile_->GetPrefs()->GetBoolean(prefs::kSyncSuppressStart)); | 299 profile_->GetPrefs()->GetBoolean(prefs::kSyncSuppressStart)); |
| 324 | 300 |
| 325 signin->SignOut(); | 301 signin->SignOut(); |
| 326 EXPECT_FALSE(service_->sync_initialized()); | 302 EXPECT_FALSE(service_->sync_initialized()); |
| 327 } | 303 } |
| 328 | 304 |
| 329 #endif // !defined(OS_CHROMEOS) | 305 #endif // !defined(OS_CHROMEOS) |
| 330 | 306 |
| 331 TEST_F(ProfileSyncServiceTest, JsControllerHandlersBasic) { | 307 TEST_F(ProfileSyncServiceTest, JsControllerHandlersBasic) { |
| 332 StartSyncService(); | 308 StartSyncServiceAndSetInitialSyncEnded(); |
| 309 IssueTestTokens(); |
| 333 EXPECT_TRUE(service_->sync_initialized()); | 310 EXPECT_TRUE(service_->sync_initialized()); |
| 334 EXPECT_TRUE(service_->GetBackendForTest() != NULL); | 311 EXPECT_TRUE(service_->GetBackendForTest() != NULL); |
| 335 | 312 |
| 336 base::WeakPtr<syncer::JsController> js_controller = | 313 base::WeakPtr<syncer::JsController> js_controller = |
| 337 service_->GetJsController(); | 314 service_->GetJsController(); |
| 338 StrictMock<syncer::MockJsEventHandler> event_handler; | 315 StrictMock<syncer::MockJsEventHandler> event_handler; |
| 339 js_controller->AddJsEventHandler(&event_handler); | 316 js_controller->AddJsEventHandler(&event_handler); |
| 340 js_controller->RemoveJsEventHandler(&event_handler); | 317 js_controller->RemoveJsEventHandler(&event_handler); |
| 341 } | 318 } |
| 342 | 319 |
| 343 TEST_F(ProfileSyncServiceTest, | 320 TEST_F(ProfileSyncServiceTest, |
| 344 JsControllerHandlersDelayedBackendInitialization) { | 321 JsControllerHandlersDelayedBackendInitialization) { |
| 345 StartSyncServiceAndSetInitialSyncEnded(true, false, false, true, | 322 StartSyncServiceAndSetInitialSyncEnded(); |
| 346 syncer::STORAGE_IN_MEMORY); | |
| 347 | 323 |
| 348 StrictMock<syncer::MockJsEventHandler> event_handler; | 324 StrictMock<syncer::MockJsEventHandler> event_handler; |
| 349 EXPECT_CALL(event_handler, HandleJsEvent(_, _)).Times(AtLeast(1)); | 325 EXPECT_CALL(event_handler, HandleJsEvent(_, _)).Times(AtLeast(1)); |
| 350 | 326 |
| 351 EXPECT_EQ(NULL, service_->GetBackendForTest()); | 327 EXPECT_EQ(NULL, service_->GetBackendForTest()); |
| 352 EXPECT_FALSE(service_->sync_initialized()); | 328 EXPECT_FALSE(service_->sync_initialized()); |
| 353 | 329 |
| 354 base::WeakPtr<syncer::JsController> js_controller = | 330 base::WeakPtr<syncer::JsController> js_controller = |
| 355 service_->GetJsController(); | 331 service_->GetJsController(); |
| 356 js_controller->AddJsEventHandler(&event_handler); | 332 js_controller->AddJsEventHandler(&event_handler); |
| 357 // Since we're doing synchronous initialization, backend should be | 333 // Since we're doing synchronous initialization, backend should be |
| 358 // initialized by this call. | 334 // initialized by this call. |
| 359 IssueTestTokens(); | 335 IssueTestTokens(); |
| 360 EXPECT_TRUE(service_->sync_initialized()); | 336 EXPECT_TRUE(service_->sync_initialized()); |
| 361 js_controller->RemoveJsEventHandler(&event_handler); | 337 js_controller->RemoveJsEventHandler(&event_handler); |
| 362 } | 338 } |
| 363 | 339 |
| 364 TEST_F(ProfileSyncServiceTest, JsControllerProcessJsMessageBasic) { | 340 TEST_F(ProfileSyncServiceTest, JsControllerProcessJsMessageBasic) { |
| 365 StartSyncService(); | 341 StartSyncServiceAndSetInitialSyncEnded(); |
| 342 IssueTestTokens(); |
| 366 WaitForBackendInitDone(); | 343 WaitForBackendInitDone(); |
| 367 | 344 |
| 368 StrictMock<syncer::MockJsReplyHandler> reply_handler; | 345 StrictMock<syncer::MockJsReplyHandler> reply_handler; |
| 369 | 346 |
| 370 ListValue arg_list1; | 347 ListValue arg_list1; |
| 371 arg_list1.Append(Value::CreateStringValue("INVALIDATIONS_ENABLED")); | 348 arg_list1.Append(Value::CreateStringValue("INVALIDATIONS_ENABLED")); |
| 372 syncer::JsArgList args1(&arg_list1); | 349 syncer::JsArgList args1(&arg_list1); |
| 373 EXPECT_CALL(reply_handler, | 350 EXPECT_CALL(reply_handler, |
| 374 HandleJsReply("getNotificationState", HasArgs(args1))); | 351 HandleJsReply("getNotificationState", HasArgs(args1))); |
| 375 | 352 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 388 done.Wait(); | 365 done.Wait(); |
| 389 | 366 |
| 390 // Call TearDown() to flush the message loops before the mock is destroyed. | 367 // Call TearDown() to flush the message loops before the mock is destroyed. |
| 391 // TearDown() is idempotent, so it's not a problem that it gets called by the | 368 // TearDown() is idempotent, so it's not a problem that it gets called by the |
| 392 // test fixture again later. | 369 // test fixture again later. |
| 393 TearDown(); | 370 TearDown(); |
| 394 } | 371 } |
| 395 | 372 |
| 396 TEST_F(ProfileSyncServiceTest, | 373 TEST_F(ProfileSyncServiceTest, |
| 397 JsControllerProcessJsMessageBasicDelayedBackendInitialization) { | 374 JsControllerProcessJsMessageBasicDelayedBackendInitialization) { |
| 398 StartSyncServiceAndSetInitialSyncEnded(true, false, false, true, | 375 StartSyncServiceAndSetInitialSyncEnded(); |
| 399 syncer::STORAGE_IN_MEMORY); | |
| 400 | 376 |
| 401 StrictMock<syncer::MockJsReplyHandler> reply_handler; | 377 StrictMock<syncer::MockJsReplyHandler> reply_handler; |
| 402 | 378 |
| 403 ListValue arg_list1; | 379 ListValue arg_list1; |
| 404 arg_list1.Append(Value::CreateStringValue("INVALIDATIONS_ENABLED")); | 380 arg_list1.Append(Value::CreateStringValue("INVALIDATIONS_ENABLED")); |
| 405 syncer::JsArgList args1(&arg_list1); | 381 syncer::JsArgList args1(&arg_list1); |
| 406 EXPECT_CALL(reply_handler, | 382 EXPECT_CALL(reply_handler, |
| 407 HandleJsReply("getNotificationState", HasArgs(args1))); | 383 HandleJsReply("getNotificationState", HasArgs(args1))); |
| 408 | 384 |
| 409 { | 385 { |
| 410 base::WeakPtr<syncer::JsController> js_controller = | 386 base::WeakPtr<syncer::JsController> js_controller = |
| 411 service_->GetJsController(); | 387 service_->GetJsController(); |
| 412 js_controller->ProcessJsMessage("getNotificationState", | 388 js_controller->ProcessJsMessage("getNotificationState", |
| 413 args1, reply_handler.AsWeakHandle()); | 389 args1, reply_handler.AsWeakHandle()); |
| 414 } | 390 } |
| 415 | 391 |
| 416 IssueTestTokens(); | 392 IssueTestTokens(); |
| 417 WaitForBackendInitDone(); | 393 WaitForBackendInitDone(); |
| 418 | 394 |
| 419 // This forces the sync thread to process the message and reply. | 395 // This forces the sync thread to process the message and reply. |
| 420 base::WaitableEvent done(false, false); | 396 base::WaitableEvent done(false, false); |
| 421 service_->GetBackendForTest()->GetSyncLoopForTesting() | 397 service_->GetBackendForTest()->GetSyncLoopForTesting() |
| 422 ->PostTask(FROM_HERE, | 398 ->PostTask(FROM_HERE, |
| 423 base::Bind(&SignalDone, &done)); | 399 base::Bind(&SignalDone, &done)); |
| 424 done.Wait(); | 400 done.Wait(); |
| 425 } | 401 } |
| 426 | 402 |
| 427 // Make sure that things still work if sync is not enabled, but some old sync | |
| 428 // databases are lingering in the "Sync Data" folder. | |
| 429 TEST_F(ProfileSyncServiceTest, TestStartupWithOldSyncData) { | |
| 430 const char* nonsense1 = "reginald"; | |
| 431 const char* nonsense2 = "beartato"; | |
| 432 const char* nonsense3 = "harrison"; | |
| 433 base::FilePath temp_directory = | |
| 434 profile_->GetPath().AppendASCII("Sync Data"); | |
| 435 base::FilePath sync_file1 = | |
| 436 temp_directory.AppendASCII("BookmarkSyncSettings.sqlite3"); | |
| 437 base::FilePath sync_file2 = temp_directory.AppendASCII("SyncData.sqlite3"); | |
| 438 base::FilePath sync_file3 = temp_directory.AppendASCII("nonsense_file"); | |
| 439 ASSERT_TRUE(file_util::CreateDirectory(temp_directory)); | |
| 440 ASSERT_NE(-1, | |
| 441 file_util::WriteFile(sync_file1, nonsense1, strlen(nonsense1))); | |
| 442 ASSERT_NE(-1, | |
| 443 file_util::WriteFile(sync_file2, nonsense2, strlen(nonsense2))); | |
| 444 ASSERT_NE(-1, | |
| 445 file_util::WriteFile(sync_file3, nonsense3, strlen(nonsense3))); | |
| 446 | |
| 447 StartSyncServiceAndSetInitialSyncEnded(true, false, true, false, | |
| 448 syncer::STORAGE_ON_DISK); | |
| 449 EXPECT_FALSE(service_->HasSyncSetupCompleted()); | |
| 450 EXPECT_FALSE(service_->sync_initialized()); | |
| 451 | |
| 452 // Since we're doing synchronous initialization, backend should be | |
| 453 // initialized by this call. | |
| 454 IssueTestTokens(); | |
| 455 | |
| 456 // Stop the service so we can read the new Sync Data files that were | |
| 457 // created. | |
| 458 service_->Shutdown(); | |
| 459 service_.reset(); | |
| 460 | |
| 461 // This file should have been deleted when the whole directory was nuked. | |
| 462 ASSERT_FALSE(base::PathExists(sync_file3)); | |
| 463 ASSERT_FALSE(base::PathExists(sync_file1)); | |
| 464 | |
| 465 // This will still exist, but the text should have changed. | |
| 466 ASSERT_TRUE(base::PathExists(sync_file2)); | |
| 467 std::string file2text; | |
| 468 ASSERT_TRUE(base::ReadFileToString(sync_file2, &file2text)); | |
| 469 ASSERT_NE(file2text.compare(nonsense2), 0); | |
| 470 } | |
| 471 | |
| 472 // Simulates a scenario where a database is corrupted and it is impossible to | |
| 473 // recreate it. This test is useful mainly when it is run under valgrind. Its | |
| 474 // expectations are not very interesting. | |
| 475 TEST_F(ProfileSyncServiceTest, FailToOpenDatabase) { | |
| 476 StartSyncServiceAndSetInitialSyncEnded(false, true, true, true, | |
| 477 syncer::STORAGE_INVALID); | |
| 478 | |
| 479 // The backend is not ready. Ensure the PSS knows this. | |
| 480 EXPECT_FALSE(service_->sync_initialized()); | |
| 481 } | |
| 482 | |
| 483 // This setup will allow the database to exist, but leave it empty. The attempt | |
| 484 // to download control types will silently fail (no downloads have any effect in | |
| 485 // these tests). The sync_backend_host will notice this and inform the profile | |
| 486 // sync service of the failure to initialize the backed. | |
| 487 TEST_F(ProfileSyncServiceTest, FailToDownloadControlTypes) { | |
| 488 StartSyncServiceAndSetInitialSyncEnded(false, true, true, true, | |
| 489 syncer::STORAGE_IN_MEMORY); | |
| 490 | |
| 491 // The backend is not ready. Ensure the PSS knows this. | |
| 492 EXPECT_FALSE(service_->sync_initialized()); | |
| 493 } | |
| 494 | |
| 495 TEST_F(ProfileSyncServiceTest, GetSyncTokenStatus) { | 403 TEST_F(ProfileSyncServiceTest, GetSyncTokenStatus) { |
| 496 StartSyncService(); | 404 StartSyncService(); |
| 497 ProfileSyncService::SyncTokenStatus token_status = | 405 ProfileSyncService::SyncTokenStatus token_status = |
| 498 service_->GetSyncTokenStatus(); | 406 service_->GetSyncTokenStatus(); |
| 499 EXPECT_EQ(syncer::CONNECTION_NOT_ATTEMPTED, token_status.connection_status); | 407 EXPECT_EQ(syncer::CONNECTION_NOT_ATTEMPTED, token_status.connection_status); |
| 500 EXPECT_TRUE(token_status.connection_status_update_time.is_null()); | 408 EXPECT_TRUE(token_status.connection_status_update_time.is_null()); |
| 501 EXPECT_TRUE(token_status.token_request_time.is_null()); | 409 EXPECT_TRUE(token_status.token_request_time.is_null()); |
| 502 EXPECT_TRUE(token_status.token_receive_time.is_null()); | 410 EXPECT_TRUE(token_status.token_receive_time.is_null()); |
| 503 | 411 |
| 504 // Sync engine is given invalid token at initialization and will report | 412 // Sync engine is given invalid token at initialization and will report |
| 505 // auth error when trying to connect. | 413 // auth error when trying to connect. |
| 506 service_->OnConnectionStatusChange(syncer::CONNECTION_AUTH_ERROR); | 414 service_->OnConnectionStatusChange(syncer::CONNECTION_AUTH_ERROR); |
| 507 token_status = service_->GetSyncTokenStatus(); | 415 token_status = service_->GetSyncTokenStatus(); |
| 508 EXPECT_EQ(syncer::CONNECTION_AUTH_ERROR, token_status.connection_status); | 416 EXPECT_EQ(syncer::CONNECTION_AUTH_ERROR, token_status.connection_status); |
| 509 EXPECT_FALSE(token_status.connection_status_update_time.is_null()); | 417 EXPECT_FALSE(token_status.connection_status_update_time.is_null()); |
| 510 EXPECT_FALSE(token_status.token_request_time.is_null()); | 418 EXPECT_FALSE(token_status.token_request_time.is_null()); |
| 511 EXPECT_FALSE(token_status.token_receive_time.is_null()); | 419 EXPECT_FALSE(token_status.token_receive_time.is_null()); |
| 512 EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(), | 420 EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(), |
| 513 token_status.last_get_token_error); | 421 token_status.last_get_token_error); |
| 514 EXPECT_TRUE(token_status.next_token_request_time.is_null()); | 422 EXPECT_TRUE(token_status.next_token_request_time.is_null()); |
| 515 | 423 |
| 516 // Simulate successful connection. | 424 // Simulate successful connection. |
| 517 service_->OnConnectionStatusChange(syncer::CONNECTION_OK); | 425 service_->OnConnectionStatusChange(syncer::CONNECTION_OK); |
| 518 token_status = service_->GetSyncTokenStatus(); | 426 token_status = service_->GetSyncTokenStatus(); |
| 519 EXPECT_EQ(syncer::CONNECTION_OK, token_status.connection_status); | 427 EXPECT_EQ(syncer::CONNECTION_OK, token_status.connection_status); |
| 520 } | 428 } |
| 521 | 429 |
| 522 } // namespace | 430 } // namespace |
| 523 } // namespace browser_sync | 431 } // namespace browser_sync |
| OLD | NEW |