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 "chrome/browser/signin/fake_profile_oauth2_token_service.h"
9 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
10 #include "chrome/browser/signin/fake_signin_manager.h"
11 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
12 #include "chrome/browser/signin/signin_manager_factory.h"
13 #include "chrome/browser/sync/glue/sync_backend_host_mock.h"
14 #include "chrome/browser/sync/managed_user_signin_manager_wrapper.h"
15 #include "chrome/browser/sync/profile_sync_components_factory_mock.h"
16 #include "chrome/browser/sync/profile_sync_service_factory.h"
17 #include "chrome/browser/sync/profile_sync_test_util.h"
18 #include "chrome/common/pref_names.h"
19 #include "chrome/test/base/testing_profile.h"
20 #include "components/signin/core/browser/profile_oauth2_token_service.h"
21 #include "components/signin/core/browser/signin_manager.h"
22 #include "components/sync_driver/data_type_manager.h"
23 #include "components/sync_driver/data_type_manager_mock.h"
24 #include "components/sync_driver/pref_names.h"
25 #include "components/sync_driver/sync_prefs.h"
26 #include "content/public/test/test_browser_thread_bundle.h"
27 #include "content/public/test/test_utils.h"
28 #include "google_apis/gaia/gaia_auth_consumer.h"
29 #include "google_apis/gaia/gaia_constants.h"
30 #include "google_apis/gaia/oauth2_token_service.h"
31 #include "testing/gmock/include/gmock/gmock.h"
32 #include "testing/gtest/include/gtest/gtest.h"
34 using browser_sync::DataTypeManager
;
35 using browser_sync::DataTypeManagerMock
;
36 using browser_sync::SyncBackendHostMock
;
37 using content::BrowserThread
;
39 using testing::AnyNumber
;
41 using testing::InvokeArgument
;
43 using testing::Return
;
45 ACTION_P(InvokeOnConfigureStart
, pss
) {
46 ProfileSyncService
* service
=
47 static_cast<ProfileSyncService
*>(pss
);
48 service
->OnConfigureStart();
51 ACTION_P2(InvokeOnConfigureDone
, pss
, result
) {
52 ProfileSyncService
* service
=
53 static_cast<ProfileSyncService
*>(pss
);
54 DataTypeManager::ConfigureResult configure_result
=
55 static_cast<DataTypeManager::ConfigureResult
>(result
);
56 service
->OnConfigureDone(configure_result
);
59 class ProfileSyncServiceStartupTest
: public testing::Test
{
61 ProfileSyncServiceStartupTest()
62 : thread_bundle_(content::TestBrowserThreadBundle::REAL_DB_THREAD
|
63 content::TestBrowserThreadBundle::REAL_FILE_THREAD
|
64 content::TestBrowserThreadBundle::REAL_IO_THREAD
),
67 virtual ~ProfileSyncServiceStartupTest() {
70 virtual void SetUp() {
71 profile_
= CreateProfile();
74 virtual scoped_ptr
<TestingProfile
> CreateProfile() {
75 TestingProfile::Builder builder
;
76 builder
.AddTestingFactory(SigninManagerFactory::GetInstance(),
77 FakeSigninManagerBase::Build
);
78 builder
.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
79 BuildAutoIssuingFakeProfileOAuth2TokenService
);
80 builder
.AddTestingFactory(ProfileSyncServiceFactory::GetInstance(),
82 return builder
.Build();
85 virtual void TearDown() {
86 sync_
->RemoveObserver(&observer_
);
90 static KeyedService
* BuildService(content::BrowserContext
* browser_context
) {
91 Profile
* profile
= static_cast<Profile
*>(browser_context
);
92 return new ProfileSyncService(
93 new ProfileSyncComponentsFactoryMock(),
95 new ManagedUserSigninManagerWrapper(
96 profile
, SigninManagerFactory::GetForProfile(profile
)),
97 ProfileOAuth2TokenServiceFactory::GetForProfile(profile
),
98 browser_sync::MANUAL_START
);
101 void CreateSyncService() {
102 sync_
= static_cast<ProfileSyncService
*>(
103 ProfileSyncServiceFactory::GetForProfile(profile_
.get()));
104 sync_
->AddObserver(&observer_
);
107 void IssueTestTokens() {
108 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_
.get())
109 ->UpdateCredentials("test_user@gmail.com", "oauth2_login_token");
112 ProfileSyncComponentsFactoryMock
* components_factory_mock() {
113 return static_cast<ProfileSyncComponentsFactoryMock
*>(sync_
->factory());
116 FakeSigninManagerForTesting
* fake_signin() {
117 return static_cast<FakeSigninManagerForTesting
*>(sync_
->signin());
121 void SimulateTestUserSignin() {
122 profile_
->GetPrefs()->SetString(prefs::kGoogleServicesUsername
,
123 "test_user@gmail.com");
124 #if !defined(OS_CHROMEOS)
125 fake_signin()->SignIn("test_user@gmail.com", "");
127 fake_signin()->SetAuthenticatedUsername("test_user@gmail.com");
128 sync_
->GoogleSigninSucceeded("test_user@gmail.com", "");
132 DataTypeManagerMock
* SetUpDataTypeManager() {
133 DataTypeManagerMock
* data_type_manager
= new DataTypeManagerMock();
134 EXPECT_CALL(*components_factory_mock(),
135 CreateDataTypeManager(_
, _
, _
, _
, _
, _
)).
136 WillOnce(Return(data_type_manager
));
137 return data_type_manager
;
140 browser_sync::SyncBackendHostMock
* SetUpSyncBackendHost() {
141 browser_sync::SyncBackendHostMock
* sync_backend_host
=
142 new browser_sync::SyncBackendHostMock();
143 EXPECT_CALL(*components_factory_mock(),
144 CreateSyncBackendHost(_
, _
, _
)).
145 WillOnce(Return(sync_backend_host
));
146 return sync_backend_host
;
149 content::TestBrowserThreadBundle thread_bundle_
;
150 scoped_ptr
<TestingProfile
> profile_
;
151 ProfileSyncService
* sync_
;
152 ProfileSyncServiceObserverMock observer_
;
155 class ProfileSyncServiceStartupCrosTest
: public ProfileSyncServiceStartupTest
{
157 virtual void SetUp() {
158 ProfileSyncServiceStartupTest::SetUp();
159 sync_
= static_cast<ProfileSyncService
*>(
160 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
161 profile_
.get(), BuildCrosService
));
162 sync_
->AddObserver(&observer_
);
165 static KeyedService
* BuildCrosService(content::BrowserContext
* context
) {
166 Profile
* profile
= static_cast<Profile
*>(context
);
167 SigninManagerBase
* signin
=
168 SigninManagerFactory::GetForProfile(profile
);
169 profile
->GetPrefs()->SetString(prefs::kGoogleServicesUsername
,
170 "test_user@gmail.com");
171 signin
->SetAuthenticatedUsername("test_user@gmail.com");
172 ProfileOAuth2TokenService
* oauth2_token_service
=
173 ProfileOAuth2TokenServiceFactory::GetForProfile(profile
);
174 EXPECT_FALSE(signin
->GetAuthenticatedUsername().empty());
175 return new ProfileSyncService(
176 new ProfileSyncComponentsFactoryMock(),
178 new ManagedUserSigninManagerWrapper(profile
, signin
),
179 oauth2_token_service
,
180 browser_sync::AUTO_START
);
184 TEST_F(ProfileSyncServiceStartupTest
, StartFirstTime
) {
185 // We've never completed startup.
186 profile_
->GetPrefs()->ClearPref(sync_driver::prefs::kSyncHasSetupCompleted
);
188 SetUpSyncBackendHost();
189 DataTypeManagerMock
* data_type_manager
= SetUpDataTypeManager();
190 EXPECT_CALL(*data_type_manager
, Configure(_
, _
)).Times(0);
192 // Should not actually start, rather just clean things up and wait
194 EXPECT_CALL(observer_
, OnStateChanged()).Times(AnyNumber());
197 // Preferences should be back to defaults.
200 profile_
->GetPrefs()->GetInt64(sync_driver::prefs::kSyncLastSyncedTime
));
201 EXPECT_FALSE(profile_
->GetPrefs()->GetBoolean(
202 sync_driver::prefs::kSyncHasSetupCompleted
));
203 Mock::VerifyAndClearExpectations(data_type_manager
);
205 // Then start things up.
206 EXPECT_CALL(*data_type_manager
, Configure(_
, _
)).Times(1);
207 EXPECT_CALL(*data_type_manager
, state()).
208 WillOnce(Return(DataTypeManager::CONFIGURED
)).
209 WillOnce(Return(DataTypeManager::CONFIGURED
));
210 EXPECT_CALL(*data_type_manager
, Stop()).Times(1);
211 EXPECT_CALL(observer_
, OnStateChanged()).Times(AnyNumber());
213 sync_
->SetSetupInProgress(true);
215 // Simulate successful signin as test_user.
216 SimulateTestUserSignin();
217 // Create some tokens in the token service.
220 // Simulate the UI telling sync it has finished setting up.
221 sync_
->SetSetupInProgress(false);
222 EXPECT_TRUE(sync_
->ShouldPushChanges());
225 // TODO(pavely): Reenable test once android is switched to oauth2.
226 TEST_F(ProfileSyncServiceStartupTest
, DISABLED_StartNoCredentials
) {
227 // We've never completed startup.
228 profile_
->GetPrefs()->ClearPref(sync_driver::prefs::kSyncHasSetupCompleted
);
231 // Should not actually start, rather just clean things up and wait
233 EXPECT_CALL(*components_factory_mock(),
234 CreateDataTypeManager(_
, _
, _
, _
, _
, _
)).Times(0);
235 EXPECT_CALL(observer_
, OnStateChanged()).Times(AnyNumber());
238 // Preferences should be back to defaults.
241 profile_
->GetPrefs()->GetInt64(sync_driver::prefs::kSyncLastSyncedTime
));
242 EXPECT_FALSE(profile_
->GetPrefs()->GetBoolean(
243 sync_driver::prefs::kSyncHasSetupCompleted
));
245 // Then start things up.
246 sync_
->SetSetupInProgress(true);
248 // Simulate successful signin as test_user.
249 SimulateTestUserSignin();
251 ProfileOAuth2TokenService
* token_service
=
252 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_
.get());
253 token_service
->LoadCredentials("test_user@gmail.com");
255 sync_
->SetSetupInProgress(false);
256 // ProfileSyncService should try to start by requesting access token.
257 // This request should fail as login token was not issued.
258 EXPECT_FALSE(sync_
->ShouldPushChanges());
259 EXPECT_EQ(GoogleServiceAuthError::USER_NOT_SIGNED_UP
,
260 sync_
->GetAuthError().state());
263 // TODO(pavely): Reenable test once android is switched to oauth2.
264 TEST_F(ProfileSyncServiceStartupTest
, DISABLED_StartInvalidCredentials
) {
265 profile_
->GetPrefs()->SetString(prefs::kGoogleServicesUsername
,
266 "test_user@gmail.com");
267 sync_
->signin()->SetAuthenticatedUsername("test_user@gmail.com");
269 SyncBackendHostMock
* mock_sbh
= SetUpSyncBackendHost();
271 // Tell the backend to stall while downloading control types (simulating an
273 mock_sbh
->set_fail_initial_download(true);
275 DataTypeManagerMock
* data_type_manager
= SetUpDataTypeManager();
276 EXPECT_CALL(*data_type_manager
, Configure(_
, _
)).Times(0);
278 EXPECT_CALL(observer_
, OnStateChanged()).Times(AnyNumber());
280 EXPECT_FALSE(sync_
->sync_initialized());
281 Mock::VerifyAndClearExpectations(data_type_manager
);
283 // Update the credentials, unstalling the backend.
284 EXPECT_CALL(*data_type_manager
, Configure(_
, _
));
285 EXPECT_CALL(*data_type_manager
, state()).
286 WillRepeatedly(Return(DataTypeManager::CONFIGURED
));
287 EXPECT_CALL(*data_type_manager
, Stop()).Times(1);
288 EXPECT_CALL(observer_
, OnStateChanged()).Times(AnyNumber());
289 sync_
->SetSetupInProgress(true);
291 // Simulate successful signin.
292 SimulateTestUserSignin();
294 sync_
->SetSetupInProgress(false);
296 // Verify we successfully finish startup and configuration.
297 EXPECT_TRUE(sync_
->ShouldPushChanges());
300 TEST_F(ProfileSyncServiceStartupCrosTest
, StartCrosNoCredentials
) {
301 EXPECT_CALL(*components_factory_mock(),
302 CreateDataTypeManager(_
, _
, _
, _
, _
, _
)).Times(0);
303 EXPECT_CALL(*components_factory_mock(),
304 CreateSyncBackendHost(_
, _
, _
)).Times(0);
305 profile_
->GetPrefs()->ClearPref(sync_driver::prefs::kSyncHasSetupCompleted
);
306 EXPECT_CALL(observer_
, OnStateChanged()).Times(AnyNumber());
309 // Sync should not start because there are no tokens yet.
310 EXPECT_FALSE(sync_
->ShouldPushChanges());
311 sync_
->SetSetupInProgress(false);
313 // Sync should not start because there are still no tokens.
314 EXPECT_FALSE(sync_
->ShouldPushChanges());
317 TEST_F(ProfileSyncServiceStartupCrosTest
, StartFirstTime
) {
318 SetUpSyncBackendHost();
319 DataTypeManagerMock
* data_type_manager
= SetUpDataTypeManager();
320 profile_
->GetPrefs()->ClearPref(sync_driver::prefs::kSyncHasSetupCompleted
);
321 EXPECT_CALL(*data_type_manager
, Configure(_
, _
));
322 EXPECT_CALL(*data_type_manager
, state()).
323 WillRepeatedly(Return(DataTypeManager::CONFIGURED
));
324 EXPECT_CALL(*data_type_manager
, Stop()).Times(1);
325 EXPECT_CALL(observer_
, OnStateChanged()).Times(AnyNumber());
329 EXPECT_TRUE(sync_
->ShouldPushChanges());
332 TEST_F(ProfileSyncServiceStartupTest
, StartNormal
) {
333 // Pre load the tokens
334 profile_
->GetPrefs()->SetString(prefs::kGoogleServicesUsername
,
335 "test_user@gmail.com");
336 SigninManagerFactory::GetForProfile(profile_
.get())
337 ->SetAuthenticatedUsername("test_user@gmail.com");
339 sync_
->SetSyncSetupCompleted();
340 SetUpSyncBackendHost();
341 DataTypeManagerMock
* data_type_manager
= SetUpDataTypeManager();
342 EXPECT_CALL(*data_type_manager
, Configure(_
, _
));
343 EXPECT_CALL(*data_type_manager
, state()).
344 WillRepeatedly(Return(DataTypeManager::CONFIGURED
));
345 EXPECT_CALL(*data_type_manager
, Stop()).Times(1);
346 EXPECT_CALL(observer_
, OnStateChanged()).Times(AnyNumber());
353 // Test that we can recover from a case where a bug in the code resulted in
354 // OnUserChoseDatatypes not being properly called and datatype preferences
355 // therefore being left unset.
356 TEST_F(ProfileSyncServiceStartupTest
, StartRecoverDatatypePrefs
) {
357 // Clear the datatype preference fields (simulating bug 154940).
358 profile_
->GetPrefs()->ClearPref(
359 sync_driver::prefs::kSyncKeepEverythingSynced
);
360 syncer::ModelTypeSet user_types
= syncer::UserTypes();
361 for (syncer::ModelTypeSet::Iterator iter
= user_types
.First();
362 iter
.Good(); iter
.Inc()) {
363 profile_
->GetPrefs()->ClearPref(
364 sync_driver::SyncPrefs::GetPrefNameForDataType(iter
.Get()));
367 // Pre load the tokens
368 profile_
->GetPrefs()->SetString(prefs::kGoogleServicesUsername
,
369 "test_user@gmail.com");
370 SigninManagerFactory::GetForProfile(profile_
.get())
371 ->SetAuthenticatedUsername("test_user@gmail.com");
373 sync_
->SetSyncSetupCompleted();
374 SetUpSyncBackendHost();
375 DataTypeManagerMock
* data_type_manager
= SetUpDataTypeManager();
376 EXPECT_CALL(*data_type_manager
, Configure(_
, _
));
377 EXPECT_CALL(*data_type_manager
, state()).
378 WillRepeatedly(Return(DataTypeManager::CONFIGURED
));
379 EXPECT_CALL(*data_type_manager
, Stop()).Times(1);
380 EXPECT_CALL(observer_
, OnStateChanged()).Times(AnyNumber());
385 EXPECT_TRUE(profile_
->GetPrefs()->GetBoolean(
386 sync_driver::prefs::kSyncKeepEverythingSynced
));
389 // Verify that the recovery of datatype preferences doesn't overwrite a valid
390 // case where only bookmarks are enabled.
391 TEST_F(ProfileSyncServiceStartupTest
, StartDontRecoverDatatypePrefs
) {
392 // Explicitly set Keep Everything Synced to false and have only bookmarks
394 profile_
->GetPrefs()->SetBoolean(
395 sync_driver::prefs::kSyncKeepEverythingSynced
, false);
397 // Pre load the tokens
398 profile_
->GetPrefs()->SetString(prefs::kGoogleServicesUsername
,
399 "test_user@gmail.com");
400 SigninManagerFactory::GetForProfile(profile_
.get())
401 ->SetAuthenticatedUsername("test_user@gmail.com");
403 sync_
->SetSyncSetupCompleted();
404 SetUpSyncBackendHost();
405 DataTypeManagerMock
* data_type_manager
= SetUpDataTypeManager();
406 EXPECT_CALL(*data_type_manager
, Configure(_
, _
));
407 EXPECT_CALL(*data_type_manager
, state()).
408 WillRepeatedly(Return(DataTypeManager::CONFIGURED
));
409 EXPECT_CALL(*data_type_manager
, Stop()).Times(1);
410 EXPECT_CALL(observer_
, OnStateChanged()).Times(AnyNumber());
414 EXPECT_FALSE(profile_
->GetPrefs()->GetBoolean(
415 sync_driver::prefs::kSyncKeepEverythingSynced
));
418 TEST_F(ProfileSyncServiceStartupTest
, ManagedStartup
) {
419 // Service should not be started by Initialize() since it's managed.
420 profile_
->GetPrefs()->SetString(prefs::kGoogleServicesUsername
,
421 "test_user@gmail.com");
424 // Disable sync through policy.
425 profile_
->GetPrefs()->SetBoolean(sync_driver::prefs::kSyncManaged
, true);
426 EXPECT_CALL(*components_factory_mock(),
427 CreateDataTypeManager(_
, _
, _
, _
, _
, _
)).Times(0);
428 EXPECT_CALL(observer_
, OnStateChanged()).Times(AnyNumber());
433 TEST_F(ProfileSyncServiceStartupTest
, SwitchManaged
) {
434 profile_
->GetPrefs()->SetString(prefs::kGoogleServicesUsername
,
435 "test_user@gmail.com");
436 SigninManagerFactory::GetForProfile(profile_
.get())
437 ->SetAuthenticatedUsername("test_user@gmail.com");
439 sync_
->SetSyncSetupCompleted();
440 SetUpSyncBackendHost();
441 DataTypeManagerMock
* data_type_manager
= SetUpDataTypeManager();
442 EXPECT_CALL(*data_type_manager
, Configure(_
, _
));
443 EXPECT_CALL(observer_
, OnStateChanged()).Times(AnyNumber());
447 // The service should stop when switching to managed mode.
448 Mock::VerifyAndClearExpectations(data_type_manager
);
449 EXPECT_CALL(*data_type_manager
, state()).
450 WillOnce(Return(DataTypeManager::CONFIGURED
));
451 EXPECT_CALL(*data_type_manager
, Stop()).Times(1);
452 EXPECT_CALL(observer_
, OnStateChanged()).Times(AnyNumber());
453 profile_
->GetPrefs()->SetBoolean(sync_driver::prefs::kSyncManaged
, true);
455 // When switching back to unmanaged, the state should change, but the service
456 // should not start up automatically (kSyncSetupCompleted will be false).
457 Mock::VerifyAndClearExpectations(data_type_manager
);
458 EXPECT_CALL(*components_factory_mock(),
459 CreateDataTypeManager(_
, _
, _
, _
, _
, _
)).Times(0);
460 EXPECT_CALL(observer_
, OnStateChanged()).Times(AnyNumber());
461 profile_
->GetPrefs()->ClearPref(sync_driver::prefs::kSyncManaged
);
464 TEST_F(ProfileSyncServiceStartupTest
, StartFailure
) {
465 profile_
->GetPrefs()->SetString(prefs::kGoogleServicesUsername
,
466 "test_user@gmail.com");
467 SigninManagerFactory::GetForProfile(profile_
.get())
468 ->SetAuthenticatedUsername("test_user@gmail.com");
470 sync_
->SetSyncSetupCompleted();
471 SetUpSyncBackendHost();
472 DataTypeManagerMock
* data_type_manager
= SetUpDataTypeManager();
473 DataTypeManager::ConfigureStatus status
= DataTypeManager::ABORTED
;
474 syncer::SyncError
error(
476 syncer::SyncError::DATATYPE_ERROR
,
477 "Association failed.",
479 std::map
<syncer::ModelType
, syncer::SyncError
> errors
;
480 errors
[syncer::BOOKMARKS
] = error
;
481 DataTypeManager::ConfigureResult
result(
483 syncer::ModelTypeSet(),
485 syncer::ModelTypeSet(),
486 syncer::ModelTypeSet());
487 EXPECT_CALL(*data_type_manager
, Configure(_
, _
)).
489 DoAll(InvokeOnConfigureStart(sync_
),
490 InvokeOnConfigureDone(sync_
, result
)));
491 EXPECT_CALL(*data_type_manager
, state()).
492 WillOnce(Return(DataTypeManager::STOPPED
));
493 EXPECT_CALL(observer_
, OnStateChanged()).Times(AnyNumber());
496 EXPECT_TRUE(sync_
->HasUnrecoverableError());
499 TEST_F(ProfileSyncServiceStartupTest
, StartDownloadFailed
) {
500 // Pre load the tokens
501 profile_
->GetPrefs()->SetString(prefs::kGoogleServicesUsername
,
502 "test_user@gmail.com");
503 SigninManagerFactory::GetForProfile(profile_
.get())
504 ->SetAuthenticatedUsername("test_user@gmail.com");
506 SyncBackendHostMock
* mock_sbh
= SetUpSyncBackendHost();
507 mock_sbh
->set_fail_initial_download(true);
509 profile_
->GetPrefs()->ClearPref(sync_driver::prefs::kSyncHasSetupCompleted
);
511 EXPECT_CALL(observer_
, OnStateChanged()).Times(AnyNumber());
514 sync_
->SetSetupInProgress(true);
516 sync_
->SetSetupInProgress(false);
517 EXPECT_FALSE(sync_
->sync_initialized());