| 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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 service_.reset(); | 78 service_.reset(); |
| 80 profile_.reset(); | 79 profile_.reset(); |
| 81 | 80 |
| 82 // Pump messages posted by the sync thread (which may end up | 81 // Pump messages posted by the sync thread (which may end up |
| 83 // posting on the IO thread). | 82 // posting on the IO thread). |
| 84 base::RunLoop().RunUntilIdle(); | 83 base::RunLoop().RunUntilIdle(); |
| 85 content::RunAllPendingInMessageLoop(content::BrowserThread::IO); | 84 content::RunAllPendingInMessageLoop(content::BrowserThread::IO); |
| 86 base::RunLoop().RunUntilIdle(); | 85 base::RunLoop().RunUntilIdle(); |
| 87 } | 86 } |
| 88 | 87 |
| 89 // TODO(akalin): Refactor the StartSyncService*() functions below. | 88 void StartSyncServiceAndSetInitialSyncEnded() { |
| 90 | |
| 91 void StartSyncService() { | |
| 92 StartSyncServiceAndSetInitialSyncEnded( | |
| 93 true, true, false, true, syncer::STORAGE_IN_MEMORY); | |
| 94 } | |
| 95 | |
| 96 void StartSyncServiceAndSetInitialSyncEnded( | |
| 97 bool set_initial_sync_ended, | |
| 98 bool issue_auth_token, | |
| 99 bool synchronous_sync_configuration, | |
| 100 bool sync_setup_completed, | |
| 101 syncer::StorageOption storage_option) { | |
| 102 if (service_) | 89 if (service_) |
| 103 return; | 90 return; |
| 104 | 91 |
| 105 SigninManagerBase* signin = | 92 SigninManagerBase* signin = |
| 106 SigninManagerFactory::GetForProfile(profile_.get()); | 93 SigninManagerFactory::GetForProfile(profile_.get()); |
| 107 signin->SetAuthenticatedUsername("test"); | 94 signin->SetAuthenticatedUsername("test"); |
| 108 ProfileOAuth2TokenService* oauth2_token_service = | 95 ProfileOAuth2TokenService* oauth2_token_service = |
| 109 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_.get()); | 96 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_.get()); |
| 110 ProfileSyncComponentsFactoryMock* factory = | 97 ProfileSyncComponentsFactoryMock* factory = |
| 111 new ProfileSyncComponentsFactoryMock(); | 98 new ProfileSyncComponentsFactoryMock(); |
| 112 service_.reset(new TestProfileSyncService( | 99 service_.reset(new TestProfileSyncService( |
| 113 factory, | 100 factory, |
| 114 profile_.get(), | 101 profile_.get(), |
| 115 signin, | 102 signin, |
| 116 oauth2_token_service, | 103 oauth2_token_service, |
| 117 ProfileSyncService::AUTO_START, | 104 ProfileSyncService::AUTO_START, |
| 118 true)); | 105 true)); |
| 119 if (!set_initial_sync_ended) | |
| 120 service_->dont_set_initial_sync_ended_on_init(); | |
| 121 | 106 |
| 122 if (synchronous_sync_configuration) | |
| 123 service_->set_synchronous_sync_configuration(); | |
| 124 | |
| 125 service_->set_storage_option(storage_option); | |
| 126 if (!sync_setup_completed) | |
| 127 profile_->GetPrefs()->SetBoolean(prefs::kSyncHasSetupCompleted, false); | |
| 128 | 107 |
| 129 // Register the bookmark data type. | 108 // Register the bookmark data type. |
| 130 ON_CALL(*factory, CreateDataTypeManager(_, _, _, _, _, _)). | 109 ON_CALL(*factory, CreateDataTypeManager(_, _, _, _, _, _)). |
| 131 WillByDefault(ReturnNewDataTypeManager()); | 110 WillByDefault(ReturnNewDataTypeManager()); |
| 132 | 111 |
| 133 if (issue_auth_token) | |
| 134 IssueTestTokens(); | |
| 135 | |
| 136 service_->Initialize(); | 112 service_->Initialize(); |
| 137 } | 113 } |
| 138 | 114 |
| 139 void WaitForBackendInitDone() { | 115 void WaitForBackendInitDone() { |
| 140 for (int i = 0; i < 5; ++i) { | 116 for (int i = 0; i < 5; ++i) { |
| 141 base::WaitableEvent done(false, false); | 117 base::WaitableEvent done(false, false); |
| 142 service_->GetBackendForTest()->GetSyncLoopForTesting() | 118 service_->GetBackendForTest()->GetSyncLoopForTesting() |
| 143 ->PostTask(FROM_HERE, base::Bind(&SignalDone, &done)); | 119 ->PostTask(FROM_HERE, base::Bind(&SignalDone, &done)); |
| 144 done.Wait(); | 120 done.Wait(); |
| 145 base::RunLoop().RunUntilIdle(); | 121 base::RunLoop().RunUntilIdle(); |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 EXPECT_TRUE(service()->sync_initialized()); | 422 EXPECT_TRUE(service()->sync_initialized()); |
| 447 EXPECT_FALSE(profile()->GetPrefs()->GetBoolean(prefs::kSyncSuppressStart)); | 423 EXPECT_FALSE(profile()->GetPrefs()->GetBoolean(prefs::kSyncSuppressStart)); |
| 448 | 424 |
| 449 SigninManagerFactory::GetForProfile(profile())->SignOut(); | 425 SigninManagerFactory::GetForProfile(profile())->SignOut(); |
| 450 EXPECT_FALSE(service()->sync_initialized()); | 426 EXPECT_FALSE(service()->sync_initialized()); |
| 451 } | 427 } |
| 452 | 428 |
| 453 #endif // !defined(OS_CHROMEOS) | 429 #endif // !defined(OS_CHROMEOS) |
| 454 | 430 |
| 455 TEST_F(ProfileSyncServiceTest, JsControllerHandlersBasic) { | 431 TEST_F(ProfileSyncServiceTest, JsControllerHandlersBasic) { |
| 456 StartSyncService(); | 432 StartSyncServiceAndSetInitialSyncEnded(); |
| 433 IssueTestTokens(); |
| 457 EXPECT_TRUE(service_->sync_initialized()); | 434 EXPECT_TRUE(service_->sync_initialized()); |
| 458 EXPECT_TRUE(service_->GetBackendForTest() != NULL); | 435 EXPECT_TRUE(service_->GetBackendForTest() != NULL); |
| 459 | 436 |
| 460 base::WeakPtr<syncer::JsController> js_controller = | 437 base::WeakPtr<syncer::JsController> js_controller = |
| 461 service_->GetJsController(); | 438 service_->GetJsController(); |
| 462 StrictMock<syncer::MockJsEventHandler> event_handler; | 439 StrictMock<syncer::MockJsEventHandler> event_handler; |
| 463 js_controller->AddJsEventHandler(&event_handler); | 440 js_controller->AddJsEventHandler(&event_handler); |
| 464 js_controller->RemoveJsEventHandler(&event_handler); | 441 js_controller->RemoveJsEventHandler(&event_handler); |
| 465 } | 442 } |
| 466 | 443 |
| 467 TEST_F(ProfileSyncServiceTest, | 444 TEST_F(ProfileSyncServiceTest, |
| 468 JsControllerHandlersDelayedBackendInitialization) { | 445 JsControllerHandlersDelayedBackendInitialization) { |
| 469 StartSyncServiceAndSetInitialSyncEnded(true, false, false, true, | 446 StartSyncServiceAndSetInitialSyncEnded(); |
| 470 syncer::STORAGE_IN_MEMORY); | |
| 471 | 447 |
| 472 StrictMock<syncer::MockJsEventHandler> event_handler; | 448 StrictMock<syncer::MockJsEventHandler> event_handler; |
| 473 EXPECT_CALL(event_handler, HandleJsEvent(_, _)).Times(AtLeast(1)); | 449 EXPECT_CALL(event_handler, HandleJsEvent(_, _)).Times(AtLeast(1)); |
| 474 | 450 |
| 475 EXPECT_EQ(NULL, service_->GetBackendForTest()); | 451 EXPECT_EQ(NULL, service_->GetBackendForTest()); |
| 476 EXPECT_FALSE(service_->sync_initialized()); | 452 EXPECT_FALSE(service_->sync_initialized()); |
| 477 | 453 |
| 478 base::WeakPtr<syncer::JsController> js_controller = | 454 base::WeakPtr<syncer::JsController> js_controller = |
| 479 service_->GetJsController(); | 455 service_->GetJsController(); |
| 480 js_controller->AddJsEventHandler(&event_handler); | 456 js_controller->AddJsEventHandler(&event_handler); |
| 481 // Since we're doing synchronous initialization, backend should be | 457 // Since we're doing synchronous initialization, backend should be |
| 482 // initialized by this call. | 458 // initialized by this call. |
| 483 IssueTestTokens(); | 459 IssueTestTokens(); |
| 484 EXPECT_TRUE(service_->sync_initialized()); | 460 EXPECT_TRUE(service_->sync_initialized()); |
| 485 js_controller->RemoveJsEventHandler(&event_handler); | 461 js_controller->RemoveJsEventHandler(&event_handler); |
| 486 } | 462 } |
| 487 | 463 |
| 488 TEST_F(ProfileSyncServiceTest, JsControllerProcessJsMessageBasic) { | 464 TEST_F(ProfileSyncServiceTest, JsControllerProcessJsMessageBasic) { |
| 489 StartSyncService(); | 465 StartSyncServiceAndSetInitialSyncEnded(); |
| 466 IssueTestTokens(); |
| 490 WaitForBackendInitDone(); | 467 WaitForBackendInitDone(); |
| 491 | 468 |
| 492 StrictMock<syncer::MockJsReplyHandler> reply_handler; | 469 StrictMock<syncer::MockJsReplyHandler> reply_handler; |
| 493 | 470 |
| 494 ListValue arg_list1; | 471 ListValue arg_list1; |
| 495 arg_list1.Append(Value::CreateStringValue("INVALIDATIONS_ENABLED")); | 472 arg_list1.Append(Value::CreateStringValue("INVALIDATIONS_ENABLED")); |
| 496 syncer::JsArgList args1(&arg_list1); | 473 syncer::JsArgList args1(&arg_list1); |
| 497 EXPECT_CALL(reply_handler, | 474 EXPECT_CALL(reply_handler, |
| 498 HandleJsReply("getNotificationState", HasArgs(args1))); | 475 HandleJsReply("getNotificationState", HasArgs(args1))); |
| 499 | 476 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 512 done.Wait(); | 489 done.Wait(); |
| 513 | 490 |
| 514 // Call TearDown() to flush the message loops before the mock is destroyed. | 491 // Call TearDown() to flush the message loops before the mock is destroyed. |
| 515 // TearDown() is idempotent, so it's not a problem that it gets called by the | 492 // TearDown() is idempotent, so it's not a problem that it gets called by the |
| 516 // test fixture again later. | 493 // test fixture again later. |
| 517 TearDown(); | 494 TearDown(); |
| 518 } | 495 } |
| 519 | 496 |
| 520 TEST_F(ProfileSyncServiceTest, | 497 TEST_F(ProfileSyncServiceTest, |
| 521 JsControllerProcessJsMessageBasicDelayedBackendInitialization) { | 498 JsControllerProcessJsMessageBasicDelayedBackendInitialization) { |
| 522 StartSyncServiceAndSetInitialSyncEnded(true, false, false, true, | 499 StartSyncServiceAndSetInitialSyncEnded(); |
| 523 syncer::STORAGE_IN_MEMORY); | |
| 524 | 500 |
| 525 StrictMock<syncer::MockJsReplyHandler> reply_handler; | 501 StrictMock<syncer::MockJsReplyHandler> reply_handler; |
| 526 | 502 |
| 527 ListValue arg_list1; | 503 ListValue arg_list1; |
| 528 arg_list1.Append(Value::CreateStringValue("INVALIDATIONS_ENABLED")); | 504 arg_list1.Append(Value::CreateStringValue("INVALIDATIONS_ENABLED")); |
| 529 syncer::JsArgList args1(&arg_list1); | 505 syncer::JsArgList args1(&arg_list1); |
| 530 EXPECT_CALL(reply_handler, | 506 EXPECT_CALL(reply_handler, |
| 531 HandleJsReply("getNotificationState", HasArgs(args1))); | 507 HandleJsReply("getNotificationState", HasArgs(args1))); |
| 532 | 508 |
| 533 { | 509 { |
| 534 base::WeakPtr<syncer::JsController> js_controller = | 510 base::WeakPtr<syncer::JsController> js_controller = |
| 535 service_->GetJsController(); | 511 service_->GetJsController(); |
| 536 js_controller->ProcessJsMessage("getNotificationState", | 512 js_controller->ProcessJsMessage("getNotificationState", |
| 537 args1, reply_handler.AsWeakHandle()); | 513 args1, reply_handler.AsWeakHandle()); |
| 538 } | 514 } |
| 539 | 515 |
| 540 IssueTestTokens(); | 516 IssueTestTokens(); |
| 541 WaitForBackendInitDone(); | 517 WaitForBackendInitDone(); |
| 542 | 518 |
| 543 // This forces the sync thread to process the message and reply. | 519 // This forces the sync thread to process the message and reply. |
| 544 base::WaitableEvent done(false, false); | 520 base::WaitableEvent done(false, false); |
| 545 service_->GetBackendForTest()->GetSyncLoopForTesting() | 521 service_->GetBackendForTest()->GetSyncLoopForTesting() |
| 546 ->PostTask(FROM_HERE, | 522 ->PostTask(FROM_HERE, |
| 547 base::Bind(&SignalDone, &done)); | 523 base::Bind(&SignalDone, &done)); |
| 548 done.Wait(); | 524 done.Wait(); |
| 549 } | 525 } |
| 550 | 526 |
| 551 // Make sure that things still work if sync is not enabled, but some old sync | 527 TEST_F(ProfileSyncServiceTest, GetSyncTokenStatus) { |
| 552 // databases are lingering in the "Sync Data" folder. | 528 StartSyncServiceAndSetInitialSyncEnded(); |
| 553 TEST_F(ProfileSyncServiceTest, TestStartupWithOldSyncData) { | |
| 554 const char* nonsense1 = "reginald"; | |
| 555 const char* nonsense2 = "beartato"; | |
| 556 const char* nonsense3 = "harrison"; | |
| 557 base::FilePath temp_directory = | |
| 558 profile_->GetPath().AppendASCII("Sync Data"); | |
| 559 base::FilePath sync_file1 = | |
| 560 temp_directory.AppendASCII("BookmarkSyncSettings.sqlite3"); | |
| 561 base::FilePath sync_file2 = temp_directory.AppendASCII("SyncData.sqlite3"); | |
| 562 base::FilePath sync_file3 = temp_directory.AppendASCII("nonsense_file"); | |
| 563 ASSERT_TRUE(file_util::CreateDirectory(temp_directory)); | |
| 564 ASSERT_NE(-1, | |
| 565 file_util::WriteFile(sync_file1, nonsense1, strlen(nonsense1))); | |
| 566 ASSERT_NE(-1, | |
| 567 file_util::WriteFile(sync_file2, nonsense2, strlen(nonsense2))); | |
| 568 ASSERT_NE(-1, | |
| 569 file_util::WriteFile(sync_file3, nonsense3, strlen(nonsense3))); | |
| 570 | |
| 571 StartSyncServiceAndSetInitialSyncEnded(true, false, true, false, | |
| 572 syncer::STORAGE_ON_DISK); | |
| 573 EXPECT_FALSE(service_->HasSyncSetupCompleted()); | |
| 574 EXPECT_FALSE(service_->sync_initialized()); | |
| 575 | |
| 576 // Since we're doing synchronous initialization, backend should be | |
| 577 // initialized by this call. | |
| 578 IssueTestTokens(); | 529 IssueTestTokens(); |
| 579 | |
| 580 // Stop the service so we can read the new Sync Data files that were | |
| 581 // created. | |
| 582 service_->Shutdown(); | |
| 583 service_.reset(); | |
| 584 | |
| 585 // This file should have been deleted when the whole directory was nuked. | |
| 586 ASSERT_FALSE(base::PathExists(sync_file3)); | |
| 587 ASSERT_FALSE(base::PathExists(sync_file1)); | |
| 588 | |
| 589 // This will still exist, but the text should have changed. | |
| 590 ASSERT_TRUE(base::PathExists(sync_file2)); | |
| 591 std::string file2text; | |
| 592 ASSERT_TRUE(base::ReadFileToString(sync_file2, &file2text)); | |
| 593 ASSERT_NE(file2text.compare(nonsense2), 0); | |
| 594 } | |
| 595 | |
| 596 // Simulates a scenario where a database is corrupted and it is impossible to | |
| 597 // recreate it. This test is useful mainly when it is run under valgrind. Its | |
| 598 // expectations are not very interesting. | |
| 599 TEST_F(ProfileSyncServiceTest, FailToOpenDatabase) { | |
| 600 StartSyncServiceAndSetInitialSyncEnded(false, true, true, true, | |
| 601 syncer::STORAGE_INVALID); | |
| 602 | |
| 603 // The backend is not ready. Ensure the PSS knows this. | |
| 604 EXPECT_FALSE(service_->sync_initialized()); | |
| 605 } | |
| 606 | |
| 607 // This setup will allow the database to exist, but leave it empty. The attempt | |
| 608 // to download control types will silently fail (no downloads have any effect in | |
| 609 // these tests). The sync_backend_host will notice this and inform the profile | |
| 610 // sync service of the failure to initialize the backed. | |
| 611 TEST_F(ProfileSyncServiceTest, FailToDownloadControlTypes) { | |
| 612 StartSyncServiceAndSetInitialSyncEnded(false, true, true, true, | |
| 613 syncer::STORAGE_IN_MEMORY); | |
| 614 | |
| 615 // The backend is not ready. Ensure the PSS knows this. | |
| 616 EXPECT_FALSE(service_->sync_initialized()); | |
| 617 } | |
| 618 | |
| 619 TEST_F(ProfileSyncServiceTest, GetSyncTokenStatus) { | |
| 620 StartSyncService(); | |
| 621 ProfileSyncService::SyncTokenStatus token_status = | 530 ProfileSyncService::SyncTokenStatus token_status = |
| 622 service_->GetSyncTokenStatus(); | 531 service_->GetSyncTokenStatus(); |
| 623 EXPECT_EQ(syncer::CONNECTION_NOT_ATTEMPTED, token_status.connection_status); | 532 EXPECT_EQ(syncer::CONNECTION_NOT_ATTEMPTED, token_status.connection_status); |
| 624 EXPECT_TRUE(token_status.connection_status_update_time.is_null()); | 533 EXPECT_TRUE(token_status.connection_status_update_time.is_null()); |
| 625 EXPECT_TRUE(token_status.token_request_time.is_null()); | 534 EXPECT_TRUE(token_status.token_request_time.is_null()); |
| 626 EXPECT_TRUE(token_status.token_receive_time.is_null()); | 535 EXPECT_TRUE(token_status.token_receive_time.is_null()); |
| 627 | 536 |
| 628 // Sync engine is given invalid token at initialization and will report | 537 // Sync engine is given invalid token at initialization and will report |
| 629 // auth error when trying to connect. | 538 // auth error when trying to connect. |
| 630 service_->OnConnectionStatusChange(syncer::CONNECTION_AUTH_ERROR); | 539 service_->OnConnectionStatusChange(syncer::CONNECTION_AUTH_ERROR); |
| 631 token_status = service_->GetSyncTokenStatus(); | 540 token_status = service_->GetSyncTokenStatus(); |
| 632 EXPECT_EQ(syncer::CONNECTION_AUTH_ERROR, token_status.connection_status); | 541 EXPECT_EQ(syncer::CONNECTION_AUTH_ERROR, token_status.connection_status); |
| 633 EXPECT_FALSE(token_status.connection_status_update_time.is_null()); | 542 EXPECT_FALSE(token_status.connection_status_update_time.is_null()); |
| 634 EXPECT_FALSE(token_status.token_request_time.is_null()); | 543 EXPECT_FALSE(token_status.token_request_time.is_null()); |
| 635 EXPECT_FALSE(token_status.token_receive_time.is_null()); | 544 EXPECT_FALSE(token_status.token_receive_time.is_null()); |
| 636 EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(), | 545 EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(), |
| 637 token_status.last_get_token_error); | 546 token_status.last_get_token_error); |
| 638 EXPECT_TRUE(token_status.next_token_request_time.is_null()); | 547 EXPECT_TRUE(token_status.next_token_request_time.is_null()); |
| 639 | 548 |
| 640 // Simulate successful connection. | 549 // Simulate successful connection. |
| 641 service_->OnConnectionStatusChange(syncer::CONNECTION_OK); | 550 service_->OnConnectionStatusChange(syncer::CONNECTION_OK); |
| 642 token_status = service_->GetSyncTokenStatus(); | 551 token_status = service_->GetSyncTokenStatus(); |
| 643 EXPECT_EQ(syncer::CONNECTION_OK, token_status.connection_status); | 552 EXPECT_EQ(syncer::CONNECTION_OK, token_status.connection_status); |
| 644 } | 553 } |
| 645 | 554 |
| 646 } // namespace | 555 } // namespace |
| 647 } // namespace browser_sync | 556 } // namespace browser_sync |
| OLD | NEW |