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 |