| 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/file_util.h" | 5 #include "base/file_util.h" |
| 6 #include "base/memory/scoped_ptr.h" | 6 #include "base/memory/scoped_ptr.h" |
| 7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
| 8 #include "base/values.h" | 8 #include "base/values.h" |
| 9 #include "chrome/browser/signin/signin_manager.h" | 9 #include "chrome/browser/signin/signin_manager.h" |
| 10 #include "chrome/browser/signin/signin_manager_factory.h" | 10 #include "chrome/browser/signin/signin_manager_factory.h" |
| 11 #include "chrome/browser/signin/token_service.h" | 11 #include "chrome/browser/signin/token_service.h" |
| 12 #include "chrome/browser/signin/token_service_factory.h" | 12 #include "chrome/browser/signin/token_service_factory.h" |
| 13 #include "chrome/browser/sync/glue/bookmark_data_type_controller.h" | 13 #include "chrome/browser/sync/glue/bookmark_data_type_controller.h" |
| 14 #include "chrome/browser/sync/glue/data_type_controller.h" | 14 #include "chrome/browser/sync/glue/data_type_controller.h" |
| 15 #include "chrome/browser/sync/profile_sync_components_factory_mock.h" | 15 #include "chrome/browser/sync/profile_sync_components_factory_mock.h" |
| 16 #include "chrome/browser/sync/test_profile_sync_service.h" | 16 #include "chrome/browser/sync/test_profile_sync_service.h" |
| 17 #include "chrome/common/chrome_version_info.h" | 17 #include "chrome/common/chrome_version_info.h" |
| 18 #include "chrome/common/net/gaia/gaia_constants.h" | 18 #include "chrome/common/net/gaia/gaia_constants.h" |
| 19 #include "chrome/common/pref_names.h" | 19 #include "chrome/common/pref_names.h" |
| 20 #include "chrome/test/base/testing_pref_service.h" | 20 #include "chrome/test/base/testing_pref_service.h" |
| 21 #include "chrome/test/base/testing_profile.h" | 21 #include "chrome/test/base/testing_profile.h" |
| 22 #include "content/public/common/content_client.h" | 22 #include "content/public/common/content_client.h" |
| 23 #include "content/public/test/test_browser_thread.h" | 23 #include "content/public/test/test_browser_thread.h" |
| 24 #include "google/cacheinvalidation/include/types.h" |
| 24 #include "sync/js/js_arg_list.h" | 25 #include "sync/js/js_arg_list.h" |
| 25 #include "sync/js/js_event_details.h" | 26 #include "sync/js/js_event_details.h" |
| 26 #include "sync/js/js_test_util.h" | 27 #include "sync/js/js_test_util.h" |
| 28 #include "sync/notifier/mock_sync_notifier_observer.h" |
| 27 #include "testing/gmock/include/gmock/gmock.h" | 29 #include "testing/gmock/include/gmock/gmock.h" |
| 28 #include "testing/gtest/include/gtest/gtest.h" | 30 #include "testing/gtest/include/gtest/gtest.h" |
| 29 #include "webkit/glue/webkit_glue.h" | 31 #include "webkit/glue/webkit_glue.h" |
| 30 | 32 |
| 31 // TODO(akalin): Add tests here that exercise the whole | 33 // TODO(akalin): Add tests here that exercise the whole |
| 32 // ProfileSyncService/SyncBackendHost stack while mocking out as | 34 // ProfileSyncService/SyncBackendHost stack while mocking out as |
| 33 // little as possible. | 35 // little as possible. |
| 34 | 36 |
| 35 namespace browser_sync { | 37 namespace browser_sync { |
| 36 | 38 |
| 37 namespace { | 39 namespace { |
| 38 | 40 |
| 39 using content::BrowserThread; | 41 using content::BrowserThread; |
| 40 using testing::_; | 42 using testing::_; |
| 41 using testing::AtLeast; | 43 using testing::AtLeast; |
| 42 using testing::AtMost; | 44 using testing::AtMost; |
| 45 using testing::Mock; |
| 43 using testing::Return; | 46 using testing::Return; |
| 44 using testing::StrictMock; | 47 using testing::StrictMock; |
| 45 | 48 |
| 46 class ProfileSyncServiceTest : public testing::Test { | 49 class ProfileSyncServiceTest : public testing::Test { |
| 47 protected: | 50 protected: |
| 48 ProfileSyncServiceTest() | 51 ProfileSyncServiceTest() |
| 49 : ui_thread_(BrowserThread::UI, &ui_loop_), | 52 : ui_thread_(BrowserThread::UI, &ui_loop_), |
| 50 db_thread_(BrowserThread::DB), | 53 db_thread_(BrowserThread::DB), |
| 51 file_thread_(BrowserThread::FILE), | 54 file_thread_(BrowserThread::FILE), |
| 52 io_thread_(BrowserThread::IO) {} | 55 io_thread_(BrowserThread::IO) {} |
| (...skipping 22 matching lines...) Expand all Loading... |
| 75 io_thread_.Stop(); | 78 io_thread_.Stop(); |
| 76 file_thread_.Stop(); | 79 file_thread_.Stop(); |
| 77 // Ensure that the sync objects destruct to avoid memory leaks. | 80 // Ensure that the sync objects destruct to avoid memory leaks. |
| 78 ui_loop_.RunAllPending(); | 81 ui_loop_.RunAllPending(); |
| 79 } | 82 } |
| 80 | 83 |
| 81 // TODO(akalin): Refactor the StartSyncService*() functions below. | 84 // TODO(akalin): Refactor the StartSyncService*() functions below. |
| 82 | 85 |
| 83 void StartSyncService() { | 86 void StartSyncService() { |
| 84 StartSyncServiceAndSetInitialSyncEnded( | 87 StartSyncServiceAndSetInitialSyncEnded( |
| 85 true, true, false, true, true, false); | 88 true, true, false, true, 1, false); |
| 86 } | 89 } |
| 87 | 90 |
| 88 void StartSyncServiceAndSetInitialSyncEnded( | 91 void StartSyncServiceAndSetInitialSyncEnded( |
| 89 bool set_initial_sync_ended, | 92 bool set_initial_sync_ended, |
| 90 bool issue_auth_token, | 93 bool issue_auth_token, |
| 91 bool synchronous_sync_configuration, | 94 bool synchronous_sync_configuration, |
| 92 bool sync_setup_completed, | 95 bool sync_setup_completed, |
| 93 bool expect_create_dtm, | 96 int expected_create_dtm_calls, |
| 94 bool use_real_database) { | 97 bool use_real_database) { |
| 95 if (!service_.get()) { | 98 if (!service_.get()) { |
| 96 SigninManager* signin = | 99 SigninManager* signin = |
| 97 SigninManagerFactory::GetForProfile(profile_.get()); | 100 SigninManagerFactory::GetForProfile(profile_.get()); |
| 98 signin->SetAuthenticatedUsername("test"); | 101 signin->SetAuthenticatedUsername("test"); |
| 99 ProfileSyncComponentsFactoryMock* factory = | 102 ProfileSyncComponentsFactoryMock* factory = |
| 100 new ProfileSyncComponentsFactoryMock(); | 103 new ProfileSyncComponentsFactoryMock(); |
| 101 service_.reset(new TestProfileSyncService( | 104 service_.reset(new TestProfileSyncService( |
| 102 factory, | 105 factory, |
| 103 profile_.get(), | 106 profile_.get(), |
| 104 signin, | 107 signin, |
| 105 ProfileSyncService::AUTO_START, | 108 ProfileSyncService::AUTO_START, |
| 106 true, | 109 true, |
| 107 base::Closure())); | 110 base::Closure())); |
| 108 if (!set_initial_sync_ended) | 111 if (!set_initial_sync_ended) |
| 109 service_->dont_set_initial_sync_ended_on_init(); | 112 service_->dont_set_initial_sync_ended_on_init(); |
| 110 if (synchronous_sync_configuration) | 113 if (synchronous_sync_configuration) |
| 111 service_->set_synchronous_sync_configuration(); | 114 service_->set_synchronous_sync_configuration(); |
| 112 if (use_real_database) | 115 if (use_real_database) |
| 113 service_->set_use_real_database(); | 116 service_->set_use_real_database(); |
| 114 if (!sync_setup_completed) | 117 if (!sync_setup_completed) |
| 115 profile_->GetPrefs()->SetBoolean(prefs::kSyncHasSetupCompleted, false); | 118 profile_->GetPrefs()->SetBoolean(prefs::kSyncHasSetupCompleted, false); |
| 116 | 119 |
| 117 if (expect_create_dtm) { | 120 // Register the bookmark data type. |
| 118 // Register the bookmark data type. | 121 EXPECT_CALL(*factory, CreateDataTypeManager(_, _)). |
| 119 EXPECT_CALL(*factory, CreateDataTypeManager(_, _)). | 122 Times(expected_create_dtm_calls). |
| 120 WillOnce(ReturnNewDataTypeManager()); | 123 WillRepeatedly(ReturnNewDataTypeManager()); |
| 121 } else { | |
| 122 EXPECT_CALL(*factory, CreateDataTypeManager(_, _)). | |
| 123 Times(0); | |
| 124 } | |
| 125 | 124 |
| 126 if (issue_auth_token) { | 125 if (issue_auth_token) { |
| 127 IssueTestTokens(); | 126 IssueTestTokens(); |
| 128 } | 127 } |
| 129 service_->Initialize(); | 128 service_->Initialize(); |
| 130 } | 129 } |
| 131 } | 130 } |
| 132 | 131 |
| 133 void IssueTestTokens() { | 132 void IssueTestTokens() { |
| 134 TokenService* token_service = | 133 TokenService* token_service = |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 EXPECT_TRUE(service_->GetBackendForTest() != NULL); | 245 EXPECT_TRUE(service_->GetBackendForTest() != NULL); |
| 247 | 246 |
| 248 syncer::JsController* js_controller = service_->GetJsController(); | 247 syncer::JsController* js_controller = service_->GetJsController(); |
| 249 StrictMock<syncer::MockJsEventHandler> event_handler; | 248 StrictMock<syncer::MockJsEventHandler> event_handler; |
| 250 js_controller->AddJsEventHandler(&event_handler); | 249 js_controller->AddJsEventHandler(&event_handler); |
| 251 js_controller->RemoveJsEventHandler(&event_handler); | 250 js_controller->RemoveJsEventHandler(&event_handler); |
| 252 } | 251 } |
| 253 | 252 |
| 254 TEST_F(ProfileSyncServiceTest, | 253 TEST_F(ProfileSyncServiceTest, |
| 255 JsControllerHandlersDelayedBackendInitialization) { | 254 JsControllerHandlersDelayedBackendInitialization) { |
| 256 StartSyncServiceAndSetInitialSyncEnded(true, false, false, true, true, false); | 255 StartSyncServiceAndSetInitialSyncEnded(true, false, false, true, 1, false); |
| 257 | 256 |
| 258 StrictMock<syncer::MockJsEventHandler> event_handler; | 257 StrictMock<syncer::MockJsEventHandler> event_handler; |
| 259 EXPECT_CALL(event_handler, HandleJsEvent(_, _)).Times(AtLeast(1)); | 258 EXPECT_CALL(event_handler, HandleJsEvent(_, _)).Times(AtLeast(1)); |
| 260 | 259 |
| 261 EXPECT_EQ(NULL, service_->GetBackendForTest()); | 260 EXPECT_EQ(NULL, service_->GetBackendForTest()); |
| 262 EXPECT_FALSE(service_->sync_initialized()); | 261 EXPECT_FALSE(service_->sync_initialized()); |
| 263 | 262 |
| 264 syncer::JsController* js_controller = service_->GetJsController(); | 263 syncer::JsController* js_controller = service_->GetJsController(); |
| 265 js_controller->AddJsEventHandler(&event_handler); | 264 js_controller->AddJsEventHandler(&event_handler); |
| 266 // Since we're doing synchronous initialization, backend should be | 265 // Since we're doing synchronous initialization, backend should be |
| (...skipping 20 matching lines...) Expand all Loading... |
| 287 reply_handler.AsWeakHandle()); | 286 reply_handler.AsWeakHandle()); |
| 288 } | 287 } |
| 289 | 288 |
| 290 // This forces the sync thread to process the message and reply. | 289 // This forces the sync thread to process the message and reply. |
| 291 service_.reset(); | 290 service_.reset(); |
| 292 ui_loop_.RunAllPending(); | 291 ui_loop_.RunAllPending(); |
| 293 } | 292 } |
| 294 | 293 |
| 295 TEST_F(ProfileSyncServiceTest, | 294 TEST_F(ProfileSyncServiceTest, |
| 296 JsControllerProcessJsMessageBasicDelayedBackendInitialization) { | 295 JsControllerProcessJsMessageBasicDelayedBackendInitialization) { |
| 297 StartSyncServiceAndSetInitialSyncEnded(true, false, false, true, true, false); | 296 StartSyncServiceAndSetInitialSyncEnded(true, false, false, true, 1, false); |
| 298 | 297 |
| 299 StrictMock<syncer::MockJsReplyHandler> reply_handler; | 298 StrictMock<syncer::MockJsReplyHandler> reply_handler; |
| 300 | 299 |
| 301 ListValue arg_list1; | 300 ListValue arg_list1; |
| 302 arg_list1.Append(Value::CreateBooleanValue(false)); | 301 arg_list1.Append(Value::CreateBooleanValue(false)); |
| 303 syncer::JsArgList args1(&arg_list1); | 302 syncer::JsArgList args1(&arg_list1); |
| 304 EXPECT_CALL(reply_handler, | 303 EXPECT_CALL(reply_handler, |
| 305 HandleJsReply("getNotificationState", HasArgs(args1))); | 304 HandleJsReply("getNotificationState", HasArgs(args1))); |
| 306 | 305 |
| 307 { | 306 { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 329 FilePath sync_file2 = temp_directory.AppendASCII("SyncData.sqlite3"); | 328 FilePath sync_file2 = temp_directory.AppendASCII("SyncData.sqlite3"); |
| 330 FilePath sync_file3 = temp_directory.AppendASCII("nonsense_file"); | 329 FilePath sync_file3 = temp_directory.AppendASCII("nonsense_file"); |
| 331 ASSERT_TRUE(file_util::CreateDirectory(temp_directory)); | 330 ASSERT_TRUE(file_util::CreateDirectory(temp_directory)); |
| 332 ASSERT_NE(-1, | 331 ASSERT_NE(-1, |
| 333 file_util::WriteFile(sync_file1, nonsense1, strlen(nonsense1))); | 332 file_util::WriteFile(sync_file1, nonsense1, strlen(nonsense1))); |
| 334 ASSERT_NE(-1, | 333 ASSERT_NE(-1, |
| 335 file_util::WriteFile(sync_file2, nonsense2, strlen(nonsense2))); | 334 file_util::WriteFile(sync_file2, nonsense2, strlen(nonsense2))); |
| 336 ASSERT_NE(-1, | 335 ASSERT_NE(-1, |
| 337 file_util::WriteFile(sync_file3, nonsense3, strlen(nonsense3))); | 336 file_util::WriteFile(sync_file3, nonsense3, strlen(nonsense3))); |
| 338 | 337 |
| 339 StartSyncServiceAndSetInitialSyncEnded(false, false, true, false, true, true); | 338 StartSyncServiceAndSetInitialSyncEnded(false, false, true, false, 1, true); |
| 340 EXPECT_FALSE(service_->HasSyncSetupCompleted()); | 339 EXPECT_FALSE(service_->HasSyncSetupCompleted()); |
| 341 EXPECT_FALSE(service_->sync_initialized()); | 340 EXPECT_FALSE(service_->sync_initialized()); |
| 342 | 341 |
| 343 // Since we're doing synchronous initialization, backend should be | 342 // Since we're doing synchronous initialization, backend should be |
| 344 // initialized by this call. | 343 // initialized by this call. |
| 345 IssueTestTokens(); | 344 IssueTestTokens(); |
| 346 | 345 |
| 347 // Stop the service so we can read the new Sync Data files that were | 346 // Stop the service so we can read the new Sync Data files that were |
| 348 // created. | 347 // created. |
| 349 service_.reset(); | 348 service_.reset(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 366 FilePath temp_directory = profile_->GetPath().AppendASCII("Sync Data"); | 365 FilePath temp_directory = profile_->GetPath().AppendASCII("Sync Data"); |
| 367 FilePath sync_db_file = temp_directory.AppendASCII("SyncData.sqlite3"); | 366 FilePath sync_db_file = temp_directory.AppendASCII("SyncData.sqlite3"); |
| 368 | 367 |
| 369 ASSERT_TRUE(file_util::CreateDirectory(temp_directory)); | 368 ASSERT_TRUE(file_util::CreateDirectory(temp_directory)); |
| 370 ASSERT_NE(-1, | 369 ASSERT_NE(-1, |
| 371 file_util::WriteFile(sync_db_file, nonesense, strlen(nonesense))); | 370 file_util::WriteFile(sync_db_file, nonesense, strlen(nonesense))); |
| 372 | 371 |
| 373 // Initialize with HasSyncSetupCompleted() set to true and InitialSyncEnded | 372 // Initialize with HasSyncSetupCompleted() set to true and InitialSyncEnded |
| 374 // false. This is to model the scenario that would result when opening the | 373 // false. This is to model the scenario that would result when opening the |
| 375 // sync database fails. | 374 // sync database fails. |
| 376 StartSyncServiceAndSetInitialSyncEnded(false, true, true, true, false, true); | 375 StartSyncServiceAndSetInitialSyncEnded(false, true, true, true, 0, true); |
| 377 | 376 |
| 378 // The backend is not ready. Ensure the PSS knows this. | 377 // The backend is not ready. Ensure the PSS knows this. |
| 379 EXPECT_FALSE(service_->sync_initialized()); | 378 EXPECT_FALSE(service_->sync_initialized()); |
| 380 | 379 |
| 381 // Ensure we will be prepared to initialize a fresh DB next time. | 380 // Ensure we will be prepared to initialize a fresh DB next time. |
| 382 EXPECT_FALSE(service_->HasSyncSetupCompleted()); | 381 EXPECT_FALSE(service_->HasSyncSetupCompleted()); |
| 383 } | 382 } |
| 384 | 383 |
| 384 // Register for some IDs with the ProfileSyncService and trigger some |
| 385 // invalidation messages. They should be received by the observer. |
| 386 // Then unregister and trigger the invalidation messages again. Those |
| 387 // shouldn't be received by the observer. |
| 388 TEST_F(ProfileSyncServiceTest, UpdateRegisteredIds) { |
| 389 StartSyncService(); |
| 390 |
| 391 syncer::ObjectIdSet ids; |
| 392 ids.insert(invalidation::ObjectId(1, "id1")); |
| 393 ids.insert(invalidation::ObjectId(2, "id2")); |
| 394 const syncer::ObjectIdPayloadMap& payloads = |
| 395 syncer::ObjectIdSetToPayloadMap(ids, "payload"); |
| 396 |
| 397 StrictMock<syncer::MockSyncNotifierObserver> observer; |
| 398 EXPECT_CALL(observer, OnNotificationsEnabled()); |
| 399 EXPECT_CALL(observer, OnNotificationsDisabled( |
| 400 syncer::TRANSIENT_NOTIFICATION_ERROR)); |
| 401 EXPECT_CALL(observer, OnIncomingNotification( |
| 402 payloads, syncer::REMOTE_NOTIFICATION)); |
| 403 |
| 404 service_->UpdateRegisteredIds(&observer, ids); |
| 405 |
| 406 SyncBackendHostForProfileSyncTest* const backend = |
| 407 service_->GetBackendForTest(); |
| 408 |
| 409 backend->EmitOnNotificationsEnabled(); |
| 410 backend->EmitOnNotificationsDisabled(syncer::TRANSIENT_NOTIFICATION_ERROR); |
| 411 backend->EmitOnIncomingNotification(payloads, syncer::REMOTE_NOTIFICATION); |
| 412 |
| 413 Mock::VerifyAndClearExpectations(&observer); |
| 414 |
| 415 service_->UpdateRegisteredIds(&observer, syncer::ObjectIdSet()); |
| 416 |
| 417 backend->EmitOnNotificationsEnabled(); |
| 418 backend->EmitOnNotificationsDisabled(syncer::TRANSIENT_NOTIFICATION_ERROR); |
| 419 backend->EmitOnIncomingNotification(payloads, syncer::REMOTE_NOTIFICATION); |
| 420 } |
| 421 |
| 422 // Register for some IDs with the ProfileSyncService, restart sync, |
| 423 // and trigger some invalidation messages. They should still be |
| 424 // received by the observer. |
| 425 TEST_F(ProfileSyncServiceTest, UpdateRegisteredIdsPersistence) { |
| 426 StartSyncServiceAndSetInitialSyncEnded(true, true, false, true, 2, false); |
| 427 |
| 428 StrictMock<syncer::MockSyncNotifierObserver> observer; |
| 429 EXPECT_CALL(observer, OnNotificationsEnabled()); |
| 430 |
| 431 syncer::ObjectIdSet ids; |
| 432 ids.insert(invalidation::ObjectId(3, "id3")); |
| 433 service_->UpdateRegisteredIds(&observer, ids); |
| 434 |
| 435 service_->StopAndSuppress(); |
| 436 service_->UnsuppressAndStart(); |
| 437 |
| 438 service_->GetBackendForTest()->EmitOnNotificationsEnabled(); |
| 439 } |
| 440 |
| 385 } // namespace | 441 } // namespace |
| 386 | 442 |
| 387 } // namespace browser_sync | 443 } // namespace browser_sync |
| OLD | NEW |