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 |