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
3 // found in the LICENSE file.
5 #include "base/file_util.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/prefs/pref_service.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/prefs/pref_service_syncable.h"
10 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
11 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
12 #include "chrome/browser/signin/fake_signin_manager.h"
13 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
14 #include "chrome/browser/signin/signin_manager_factory.h"
15 #include "chrome/browser/sync/glue/sync_backend_host_mock.h"
16 #include "chrome/browser/sync/managed_user_signin_manager_wrapper.h"
17 #include "chrome/browser/sync/profile_sync_components_factory_mock.h"
18 #include "chrome/browser/sync/profile_sync_service_factory.h"
19 #include "chrome/browser/sync/profile_sync_test_util.h"
20 #include "chrome/common/pref_names.h"
21 #include "chrome/test/base/testing_browser_process.h"
22 #include "chrome/test/base/testing_profile.h"
23 #include "chrome/test/base/testing_profile_manager.h"
24 #include "components/signin/core/browser/profile_oauth2_token_service.h"
25 #include "components/signin/core/browser/signin_manager.h"
26 #include "components/sync_driver/data_type_manager.h"
27 #include "components/sync_driver/data_type_manager_mock.h"
28 #include "components/sync_driver/pref_names.h"
29 #include "components/sync_driver/sync_prefs.h"
30 #include "content/public/test/test_browser_thread_bundle.h"
31 #include "content/public/test/test_utils.h"
32 #include "google_apis/gaia/gaia_auth_consumer.h"
33 #include "google_apis/gaia/gaia_constants.h"
34 #include "google_apis/gaia/oauth2_token_service.h"
35 #include "testing/gmock/include/gmock/gmock.h"
36 #include "testing/gtest/include/gtest/gtest.h"
38 using browser_sync::DataTypeManager;
39 using browser_sync::DataTypeManagerMock;
40 using browser_sync::SyncBackendHostMock;
41 using content::BrowserThread;
43 using testing::AnyNumber;
45 using testing::InvokeArgument;
47 using testing::Return;
49 ACTION_P(InvokeOnConfigureStart, pss) {
50 ProfileSyncService* service =
51 static_cast<ProfileSyncService*>(pss);
52 service->OnConfigureStart();
55 ACTION_P2(InvokeOnConfigureDone, pss, result) {
56 ProfileSyncService* service =
57 static_cast<ProfileSyncService*>(pss);
58 DataTypeManager::ConfigureResult configure_result =
59 static_cast<DataTypeManager::ConfigureResult>(result);
60 service->OnConfigureDone(configure_result);
63 class ProfileSyncServiceStartupTest : public testing::Test {
65 ProfileSyncServiceStartupTest()
66 : thread_bundle_(content::TestBrowserThreadBundle::REAL_DB_THREAD |
67 content::TestBrowserThreadBundle::REAL_FILE_THREAD |
68 content::TestBrowserThreadBundle::REAL_IO_THREAD),
69 profile_manager_(TestingBrowserProcess::GetGlobal()),
72 virtual ~ProfileSyncServiceStartupTest() {
75 virtual void SetUp() {
76 CHECK(profile_manager_.SetUp());
78 TestingProfile::TestingFactories testing_facotries;
79 testing_facotries.push_back(
80 std::make_pair(SigninManagerFactory::GetInstance(),
81 FakeSigninManagerBase::Build));
82 testing_facotries.push_back(
83 std::make_pair(ProfileOAuth2TokenServiceFactory::GetInstance(),
84 BuildAutoIssuingFakeProfileOAuth2TokenService));
85 testing_facotries.push_back(
86 std::make_pair(ProfileSyncServiceFactory::GetInstance(),
89 profile_ = profile_manager_.CreateTestingProfile(
90 "sync-startup-test", scoped_ptr<PrefServiceSyncable>(),
91 base::UTF8ToUTF16("sync-startup-test"), 0, std::string(),
95 virtual void TearDown() {
96 sync_->RemoveObserver(&observer_);
99 static KeyedService* BuildService(content::BrowserContext* browser_context) {
100 Profile* profile = static_cast<Profile*>(browser_context);
101 return new ProfileSyncService(
102 new ProfileSyncComponentsFactoryMock(),
104 make_scoped_ptr(new ManagedUserSigninManagerWrapper(
105 profile, SigninManagerFactory::GetForProfile(profile))),
106 ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
107 browser_sync::MANUAL_START);
110 void CreateSyncService() {
111 sync_ = static_cast<ProfileSyncService*>(
112 ProfileSyncServiceFactory::GetForProfile(profile_));
113 sync_->AddObserver(&observer_);
116 void IssueTestTokens() {
117 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)
118 ->UpdateCredentials("test_user@gmail.com", "oauth2_login_token");
121 ProfileSyncComponentsFactoryMock* components_factory_mock() {
122 return static_cast<ProfileSyncComponentsFactoryMock*>(sync_->factory());
125 FakeSigninManagerForTesting* fake_signin() {
126 return static_cast<FakeSigninManagerForTesting*>(sync_->signin());
130 void SimulateTestUserSignin() {
131 profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
132 "test_user@gmail.com");
133 #if !defined(OS_CHROMEOS)
134 fake_signin()->SignIn("test_user@gmail.com", "");
136 fake_signin()->SetAuthenticatedUsername("test_user@gmail.com");
137 sync_->GoogleSigninSucceeded("test_user@gmail.com", "");
141 DataTypeManagerMock* SetUpDataTypeManager() {
142 DataTypeManagerMock* data_type_manager = new DataTypeManagerMock();
143 EXPECT_CALL(*components_factory_mock(),
144 CreateDataTypeManager(_, _, _, _, _, _)).
145 WillOnce(Return(data_type_manager));
146 return data_type_manager;
149 browser_sync::SyncBackendHostMock* SetUpSyncBackendHost() {
150 browser_sync::SyncBackendHostMock* sync_backend_host =
151 new browser_sync::SyncBackendHostMock();
152 EXPECT_CALL(*components_factory_mock(),
153 CreateSyncBackendHost(_, _, _, _, _)).
154 WillOnce(Return(sync_backend_host));
155 return sync_backend_host;
158 content::TestBrowserThreadBundle thread_bundle_;
159 TestingProfileManager profile_manager_;
160 TestingProfile* profile_;
161 ProfileSyncService* sync_;
162 ProfileSyncServiceObserverMock observer_;
165 class ProfileSyncServiceStartupCrosTest : public ProfileSyncServiceStartupTest {
167 virtual void SetUp() {
168 ProfileSyncServiceStartupTest::SetUp();
169 sync_ = static_cast<ProfileSyncService*>(
170 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
171 profile_, BuildCrosService));
172 sync_->AddObserver(&observer_);
175 static KeyedService* BuildCrosService(content::BrowserContext* context) {
176 Profile* profile = static_cast<Profile*>(context);
177 SigninManagerBase* signin =
178 SigninManagerFactory::GetForProfile(profile);
179 profile->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
180 "test_user@gmail.com");
181 signin->SetAuthenticatedUsername("test_user@gmail.com");
182 ProfileOAuth2TokenService* oauth2_token_service =
183 ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
184 EXPECT_FALSE(signin->GetAuthenticatedUsername().empty());
185 return new ProfileSyncService(
186 new ProfileSyncComponentsFactoryMock(),
188 make_scoped_ptr(new ManagedUserSigninManagerWrapper(profile, signin)),
189 oauth2_token_service,
190 browser_sync::AUTO_START);
194 TEST_F(ProfileSyncServiceStartupTest, StartFirstTime) {
195 // We've never completed startup.
196 profile_->GetPrefs()->ClearPref(sync_driver::prefs::kSyncHasSetupCompleted);
198 SetUpSyncBackendHost();
199 DataTypeManagerMock* data_type_manager = SetUpDataTypeManager();
200 EXPECT_CALL(*data_type_manager, Configure(_, _)).Times(0);
202 // Should not actually start, rather just clean things up and wait
204 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
207 // Preferences should be back to defaults.
210 profile_->GetPrefs()->GetInt64(sync_driver::prefs::kSyncLastSyncedTime));
211 EXPECT_FALSE(profile_->GetPrefs()->GetBoolean(
212 sync_driver::prefs::kSyncHasSetupCompleted));
213 Mock::VerifyAndClearExpectations(data_type_manager);
215 // Then start things up.
216 EXPECT_CALL(*data_type_manager, Configure(_, _)).Times(1);
217 EXPECT_CALL(*data_type_manager, state()).
218 WillOnce(Return(DataTypeManager::CONFIGURED)).
219 WillOnce(Return(DataTypeManager::CONFIGURED));
220 EXPECT_CALL(*data_type_manager, Stop()).Times(1);
221 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
223 sync_->SetSetupInProgress(true);
225 // Simulate successful signin as test_user.
226 SimulateTestUserSignin();
227 // Create some tokens in the token service.
230 // Simulate the UI telling sync it has finished setting up.
231 sync_->SetSetupInProgress(false);
232 EXPECT_TRUE(sync_->ShouldPushChanges());
235 // TODO(pavely): Reenable test once android is switched to oauth2.
236 TEST_F(ProfileSyncServiceStartupTest, DISABLED_StartNoCredentials) {
237 // We've never completed startup.
238 profile_->GetPrefs()->ClearPref(sync_driver::prefs::kSyncHasSetupCompleted);
241 // Should not actually start, rather just clean things up and wait
243 EXPECT_CALL(*components_factory_mock(),
244 CreateDataTypeManager(_, _, _, _, _, _)).Times(0);
245 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
248 // Preferences should be back to defaults.
251 profile_->GetPrefs()->GetInt64(sync_driver::prefs::kSyncLastSyncedTime));
252 EXPECT_FALSE(profile_->GetPrefs()->GetBoolean(
253 sync_driver::prefs::kSyncHasSetupCompleted));
255 // Then start things up.
256 sync_->SetSetupInProgress(true);
258 // Simulate successful signin as test_user.
259 SimulateTestUserSignin();
261 ProfileOAuth2TokenService* token_service =
262 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
263 token_service->LoadCredentials("test_user@gmail.com");
265 sync_->SetSetupInProgress(false);
266 // ProfileSyncService should try to start by requesting access token.
267 // This request should fail as login token was not issued.
268 EXPECT_FALSE(sync_->ShouldPushChanges());
269 EXPECT_EQ(GoogleServiceAuthError::USER_NOT_SIGNED_UP,
270 sync_->GetAuthError().state());
273 // TODO(pavely): Reenable test once android is switched to oauth2.
274 TEST_F(ProfileSyncServiceStartupTest, DISABLED_StartInvalidCredentials) {
275 profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
276 "test_user@gmail.com");
277 sync_->signin()->SetAuthenticatedUsername("test_user@gmail.com");
279 SyncBackendHostMock* mock_sbh = SetUpSyncBackendHost();
281 // Tell the backend to stall while downloading control types (simulating an
283 mock_sbh->set_fail_initial_download(true);
285 DataTypeManagerMock* data_type_manager = SetUpDataTypeManager();
286 EXPECT_CALL(*data_type_manager, Configure(_, _)).Times(0);
288 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
290 EXPECT_FALSE(sync_->sync_initialized());
291 Mock::VerifyAndClearExpectations(data_type_manager);
293 // Update the credentials, unstalling the backend.
294 EXPECT_CALL(*data_type_manager, Configure(_, _));
295 EXPECT_CALL(*data_type_manager, state()).
296 WillRepeatedly(Return(DataTypeManager::CONFIGURED));
297 EXPECT_CALL(*data_type_manager, Stop()).Times(1);
298 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
299 sync_->SetSetupInProgress(true);
301 // Simulate successful signin.
302 SimulateTestUserSignin();
304 sync_->SetSetupInProgress(false);
306 // Verify we successfully finish startup and configuration.
307 EXPECT_TRUE(sync_->ShouldPushChanges());
310 TEST_F(ProfileSyncServiceStartupCrosTest, StartCrosNoCredentials) {
311 EXPECT_CALL(*components_factory_mock(),
312 CreateDataTypeManager(_, _, _, _, _, _)).Times(0);
313 EXPECT_CALL(*components_factory_mock(),
314 CreateSyncBackendHost(_, _, _, _, _)).Times(0);
315 profile_->GetPrefs()->ClearPref(sync_driver::prefs::kSyncHasSetupCompleted);
316 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
319 // Sync should not start because there are no tokens yet.
320 EXPECT_FALSE(sync_->ShouldPushChanges());
321 sync_->SetSetupInProgress(false);
323 // Sync should not start because there are still no tokens.
324 EXPECT_FALSE(sync_->ShouldPushChanges());
327 TEST_F(ProfileSyncServiceStartupCrosTest, StartFirstTime) {
328 SetUpSyncBackendHost();
329 DataTypeManagerMock* data_type_manager = SetUpDataTypeManager();
330 profile_->GetPrefs()->ClearPref(sync_driver::prefs::kSyncHasSetupCompleted);
331 EXPECT_CALL(*data_type_manager, Configure(_, _));
332 EXPECT_CALL(*data_type_manager, state()).
333 WillRepeatedly(Return(DataTypeManager::CONFIGURED));
334 EXPECT_CALL(*data_type_manager, Stop()).Times(1);
335 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
339 EXPECT_TRUE(sync_->ShouldPushChanges());
342 TEST_F(ProfileSyncServiceStartupTest, StartNormal) {
343 // Pre load the tokens
344 profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
345 "test_user@gmail.com");
346 SigninManagerFactory::GetForProfile(profile_)
347 ->SetAuthenticatedUsername("test_user@gmail.com");
349 sync_->SetSyncSetupCompleted();
350 SetUpSyncBackendHost();
351 DataTypeManagerMock* data_type_manager = SetUpDataTypeManager();
352 EXPECT_CALL(*data_type_manager, Configure(_, _));
353 EXPECT_CALL(*data_type_manager, state()).
354 WillRepeatedly(Return(DataTypeManager::CONFIGURED));
355 EXPECT_CALL(*data_type_manager, Stop()).Times(1);
356 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
363 // Test that we can recover from a case where a bug in the code resulted in
364 // OnUserChoseDatatypes not being properly called and datatype preferences
365 // therefore being left unset.
366 TEST_F(ProfileSyncServiceStartupTest, StartRecoverDatatypePrefs) {
367 // Clear the datatype preference fields (simulating bug 154940).
368 profile_->GetPrefs()->ClearPref(
369 sync_driver::prefs::kSyncKeepEverythingSynced);
370 syncer::ModelTypeSet user_types = syncer::UserTypes();
371 for (syncer::ModelTypeSet::Iterator iter = user_types.First();
372 iter.Good(); iter.Inc()) {
373 profile_->GetPrefs()->ClearPref(
374 sync_driver::SyncPrefs::GetPrefNameForDataType(iter.Get()));
377 // Pre load the tokens
378 profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
379 "test_user@gmail.com");
380 SigninManagerFactory::GetForProfile(profile_)
381 ->SetAuthenticatedUsername("test_user@gmail.com");
383 sync_->SetSyncSetupCompleted();
384 SetUpSyncBackendHost();
385 DataTypeManagerMock* data_type_manager = SetUpDataTypeManager();
386 EXPECT_CALL(*data_type_manager, Configure(_, _));
387 EXPECT_CALL(*data_type_manager, state()).
388 WillRepeatedly(Return(DataTypeManager::CONFIGURED));
389 EXPECT_CALL(*data_type_manager, Stop()).Times(1);
390 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
395 EXPECT_TRUE(profile_->GetPrefs()->GetBoolean(
396 sync_driver::prefs::kSyncKeepEverythingSynced));
399 // Verify that the recovery of datatype preferences doesn't overwrite a valid
400 // case where only bookmarks are enabled.
401 TEST_F(ProfileSyncServiceStartupTest, StartDontRecoverDatatypePrefs) {
402 // Explicitly set Keep Everything Synced to false and have only bookmarks
404 profile_->GetPrefs()->SetBoolean(
405 sync_driver::prefs::kSyncKeepEverythingSynced, false);
407 // Pre load the tokens
408 profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
409 "test_user@gmail.com");
410 SigninManagerFactory::GetForProfile(profile_)
411 ->SetAuthenticatedUsername("test_user@gmail.com");
413 sync_->SetSyncSetupCompleted();
414 SetUpSyncBackendHost();
415 DataTypeManagerMock* data_type_manager = SetUpDataTypeManager();
416 EXPECT_CALL(*data_type_manager, Configure(_, _));
417 EXPECT_CALL(*data_type_manager, state()).
418 WillRepeatedly(Return(DataTypeManager::CONFIGURED));
419 EXPECT_CALL(*data_type_manager, Stop()).Times(1);
420 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
424 EXPECT_FALSE(profile_->GetPrefs()->GetBoolean(
425 sync_driver::prefs::kSyncKeepEverythingSynced));
428 TEST_F(ProfileSyncServiceStartupTest, ManagedStartup) {
429 // Service should not be started by Initialize() since it's managed.
430 profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
431 "test_user@gmail.com");
434 // Disable sync through policy.
435 profile_->GetPrefs()->SetBoolean(sync_driver::prefs::kSyncManaged, true);
436 EXPECT_CALL(*components_factory_mock(),
437 CreateDataTypeManager(_, _, _, _, _, _)).Times(0);
438 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
443 TEST_F(ProfileSyncServiceStartupTest, SwitchManaged) {
444 profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
445 "test_user@gmail.com");
446 SigninManagerFactory::GetForProfile(profile_)
447 ->SetAuthenticatedUsername("test_user@gmail.com");
449 sync_->SetSyncSetupCompleted();
450 SetUpSyncBackendHost();
451 DataTypeManagerMock* data_type_manager = SetUpDataTypeManager();
452 EXPECT_CALL(*data_type_manager, Configure(_, _));
453 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
457 // The service should stop when switching to managed mode.
458 Mock::VerifyAndClearExpectations(data_type_manager);
459 EXPECT_CALL(*data_type_manager, state()).
460 WillOnce(Return(DataTypeManager::CONFIGURED));
461 EXPECT_CALL(*data_type_manager, Stop()).Times(1);
462 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
463 profile_->GetPrefs()->SetBoolean(sync_driver::prefs::kSyncManaged, true);
465 // When switching back to unmanaged, the state should change, but the service
466 // should not start up automatically (kSyncSetupCompleted will be false).
467 Mock::VerifyAndClearExpectations(data_type_manager);
468 EXPECT_CALL(*components_factory_mock(),
469 CreateDataTypeManager(_, _, _, _, _, _)).Times(0);
470 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
471 profile_->GetPrefs()->ClearPref(sync_driver::prefs::kSyncManaged);
474 TEST_F(ProfileSyncServiceStartupTest, StartFailure) {
475 profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
476 "test_user@gmail.com");
477 SigninManagerFactory::GetForProfile(profile_)
478 ->SetAuthenticatedUsername("test_user@gmail.com");
480 sync_->SetSyncSetupCompleted();
481 SetUpSyncBackendHost();
482 DataTypeManagerMock* data_type_manager = SetUpDataTypeManager();
483 DataTypeManager::ConfigureStatus status = DataTypeManager::ABORTED;
484 syncer::SyncError error(
486 syncer::SyncError::DATATYPE_ERROR,
487 "Association failed.",
489 std::map<syncer::ModelType, syncer::SyncError> errors;
490 errors[syncer::BOOKMARKS] = error;
491 DataTypeManager::ConfigureResult result(
493 syncer::ModelTypeSet(),
495 syncer::ModelTypeSet(),
496 syncer::ModelTypeSet());
497 EXPECT_CALL(*data_type_manager, Configure(_, _)).
499 DoAll(InvokeOnConfigureStart(sync_),
500 InvokeOnConfigureDone(sync_, result)));
501 EXPECT_CALL(*data_type_manager, state()).
502 WillOnce(Return(DataTypeManager::STOPPED));
503 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
506 EXPECT_TRUE(sync_->HasUnrecoverableError());
509 TEST_F(ProfileSyncServiceStartupTest, StartDownloadFailed) {
510 // Pre load the tokens
511 profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
512 "test_user@gmail.com");
513 SigninManagerFactory::GetForProfile(profile_)
514 ->SetAuthenticatedUsername("test_user@gmail.com");
516 SyncBackendHostMock* mock_sbh = SetUpSyncBackendHost();
517 mock_sbh->set_fail_initial_download(true);
519 profile_->GetPrefs()->ClearPref(sync_driver::prefs::kSyncHasSetupCompleted);
521 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
524 sync_->SetSetupInProgress(true);
526 sync_->SetSetupInProgress(false);
527 EXPECT_FALSE(sync_->sync_initialized());