1// Copyright (c) 2011 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. 4 5#include "testing/gtest/include/gtest/gtest.h" 6 7#include "base/memory/scoped_ptr.h" 8#include "base/message_loop.h" 9#include "chrome/browser/net/gaia/token_service.h" 10#include "chrome/browser/prefs/pref_service.h" 11#include "chrome/browser/sync/glue/data_type_manager.h" 12#include "chrome/browser/sync/glue/data_type_manager_mock.h" 13#include "chrome/browser/sync/profile_sync_factory_mock.h" 14#include "chrome/browser/sync/profile_sync_test_util.h" 15#include "chrome/browser/sync/test_profile_sync_service.h" 16#include "chrome/common/net/gaia/gaia_auth_consumer.h" 17#include "chrome/common/net/gaia/gaia_constants.h" 18#include "chrome/common/pref_names.h" 19#include "chrome/test/testing_profile.h" 20#include "content/browser/browser_thread.h" 21#include "content/common/notification_type.h" 22#include "testing/gmock/include/gmock/gmock.h" 23 24using browser_sync::DataTypeManager; 25using browser_sync::DataTypeManagerMock; 26using testing::_; 27using testing::AnyNumber; 28using testing::DoAll; 29using testing::InvokeArgument; 30using testing::Mock; 31using testing::Return; 32 33ACTION_P(InvokeCallback, callback_result) { 34 arg0->Run(callback_result); 35 delete arg0; 36} 37 38// TODO(skrul) This test fails on the mac. See http://crbug.com/33443 39#if defined(OS_MACOSX) 40#define SKIP_MACOSX(test) DISABLED_##test 41#else 42#define SKIP_MACOSX(test) test 43#endif 44 45// TODO(chron): Test not using cros_user flag and use signin_ 46class ProfileSyncServiceStartupTest : public testing::Test { 47 public: 48 ProfileSyncServiceStartupTest() 49 : ui_thread_(BrowserThread::UI, &message_loop_) {} 50 51 virtual ~ProfileSyncServiceStartupTest() { 52 // The PSS has some deletes that are scheduled on the main thread 53 // so we must delete the service and run the message loop. 54 service_.reset(); 55 MessageLoop::current()->RunAllPending(); 56 } 57 58 virtual void SetUp() { 59 profile_.CreateRequestContext(); 60 service_.reset(new TestProfileSyncService(&factory_, &profile_, 61 "test", true, NULL)); 62 service_->AddObserver(&observer_); 63 service_->set_synchronous_sync_configuration(); 64 } 65 66 virtual void TearDown() { 67 service_->RemoveObserver(&observer_); 68 { 69 // The request context gets deleted on the I/O thread. To prevent a leak 70 // supply one here. 71 BrowserThread io_thread(BrowserThread::IO, MessageLoop::current()); 72 profile_.ResetRequestContext(); 73 } 74 MessageLoop::current()->RunAllPending(); 75 } 76 77 protected: 78 DataTypeManagerMock* SetUpDataTypeManager() { 79 DataTypeManagerMock* data_type_manager = new DataTypeManagerMock(); 80 EXPECT_CALL(factory_, CreateDataTypeManager(_, _)). 81 WillOnce(Return(data_type_manager)); 82 return data_type_manager; 83 } 84 85 MessageLoop message_loop_; 86 BrowserThread ui_thread_; 87 TestingProfile profile_; 88 ProfileSyncFactoryMock factory_; 89 scoped_ptr<TestProfileSyncService> service_; 90 ProfileSyncServiceObserverMock observer_; 91}; 92 93TEST_F(ProfileSyncServiceStartupTest, SKIP_MACOSX(StartFirstTime)) { 94 DataTypeManagerMock* data_type_manager = SetUpDataTypeManager(); 95 EXPECT_CALL(*data_type_manager, Configure(_)).Times(0); 96 97 // We've never completed startup. 98 profile_.GetPrefs()->ClearPref(prefs::kSyncHasSetupCompleted); 99 100 // Should not actually start, rather just clean things up and wait 101 // to be enabled. 102 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber()); 103 service_->Initialize(); 104 105 // Preferences should be back to defaults. 106 EXPECT_EQ(0, profile_.GetPrefs()->GetInt64(prefs::kSyncLastSyncedTime)); 107 EXPECT_FALSE(profile_.GetPrefs()->GetBoolean(prefs::kSyncHasSetupCompleted)); 108 Mock::VerifyAndClearExpectations(data_type_manager); 109 110 // Then start things up. 111 EXPECT_CALL(*data_type_manager, Configure(_)).Times(3); 112 EXPECT_CALL(*data_type_manager, state()). 113 WillOnce(Return(DataTypeManager::CONFIGURED)); 114 EXPECT_CALL(*data_type_manager, Stop()).Times(1); 115 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber()); 116 117 // Create some tokens in the token service; the service will startup when 118 // it is notified that tokens are available. 119 profile_.GetTokenService()->IssueAuthTokenForTest( 120 GaiaConstants::kSyncService, "sync_token"); 121 122 syncable::ModelTypeSet set; 123 set.insert(syncable::BOOKMARKS); 124 service_->OnUserChoseDatatypes(false, set); 125} 126 127TEST_F(ProfileSyncServiceStartupTest, SKIP_MACOSX(StartNormal)) { 128 DataTypeManagerMock* data_type_manager = SetUpDataTypeManager(); 129 EXPECT_CALL(*data_type_manager, Configure(_)).Times(2); 130 EXPECT_CALL(*data_type_manager, state()). 131 WillOnce(Return(DataTypeManager::CONFIGURED)); 132 EXPECT_CALL(*data_type_manager, Stop()).Times(1); 133 134 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber()); 135 136 // Pre load the tokens 137 profile_.GetTokenService()->IssueAuthTokenForTest( 138 GaiaConstants::kSyncService, "sync_token"); 139 service_->Initialize(); 140} 141 142TEST_F(ProfileSyncServiceStartupTest, SKIP_MACOSX(ManagedStartup)) { 143 // Disable sync through policy. 144 profile_.GetPrefs()->SetBoolean(prefs::kSyncManaged, true); 145 146 EXPECT_CALL(factory_, CreateDataTypeManager(_, _)).Times(0); 147 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber()); 148 149 // Service should not be started by Initialize() since it's managed. 150 profile_.GetTokenService()->IssueAuthTokenForTest( 151 GaiaConstants::kSyncService, "sync_token"); 152 service_->Initialize(); 153} 154 155TEST_F(ProfileSyncServiceStartupTest, SKIP_MACOSX(SwitchManaged)) { 156 DataTypeManagerMock* data_type_manager = SetUpDataTypeManager(); 157 EXPECT_CALL(*data_type_manager, Configure(_)).Times(2); 158 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber()); 159 160 profile_.GetTokenService()->IssueAuthTokenForTest( 161 GaiaConstants::kSyncService, "sync_token"); 162 service_->Initialize(); 163 164 // The service should stop when switching to managed mode. 165 Mock::VerifyAndClearExpectations(data_type_manager); 166 EXPECT_CALL(*data_type_manager, state()). 167 WillOnce(Return(DataTypeManager::CONFIGURED)); 168 EXPECT_CALL(*data_type_manager, Stop()).Times(1); 169 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber()); 170 profile_.GetPrefs()->SetBoolean(prefs::kSyncManaged, true); 171 172 // When switching back to unmanaged, the state should change, but the service 173 // should not start up automatically (kSyncSetupCompleted will be false). 174 Mock::VerifyAndClearExpectations(data_type_manager); 175 EXPECT_CALL(factory_, CreateDataTypeManager(_, _)).Times(0); 176 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber()); 177 profile_.GetPrefs()->ClearPref(prefs::kSyncManaged); 178} 179 180TEST_F(ProfileSyncServiceStartupTest, ClearServerData) { 181 DataTypeManagerMock* data_type_manager = SetUpDataTypeManager(); 182 EXPECT_CALL(*data_type_manager, Configure(_)).Times(2); 183 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber()); 184 185 profile_.GetTokenService()->IssueAuthTokenForTest( 186 GaiaConstants::kSyncService, "sync_token"); 187 service_->Initialize(); 188 Mock::VerifyAndClearExpectations(data_type_manager); 189 190 // Success can overwrite failure, failure cannot overwrite success. We want 191 // this behavior because once clear has succeeded, sync gets disabled, and 192 // we don't care about any subsequent failures (e.g. timeouts) 193 service_->ResetClearServerDataState(); 194 EXPECT_TRUE(ProfileSyncService::CLEAR_NOT_STARTED == 195 service_->GetClearServerDataState()); 196 197 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber()); 198 service_->OnClearServerDataFailed(); 199 EXPECT_TRUE(ProfileSyncService::CLEAR_FAILED == 200 service_->GetClearServerDataState()); 201 202 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber()); 203 service_->OnClearServerDataSucceeded(); 204 EXPECT_TRUE(ProfileSyncService::CLEAR_SUCCEEDED == 205 service_->GetClearServerDataState()); 206 207 service_->OnClearServerDataFailed(); 208 EXPECT_TRUE(ProfileSyncService::CLEAR_SUCCEEDED == 209 service_->GetClearServerDataState()); 210 211 // Now test the timeout states 212 service_->ResetClearServerDataState(); 213 EXPECT_TRUE(ProfileSyncService::CLEAR_NOT_STARTED == 214 service_->GetClearServerDataState()); 215 216 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber()); 217 service_->OnClearServerDataTimeout(); 218 EXPECT_TRUE(ProfileSyncService::CLEAR_FAILED == 219 service_->GetClearServerDataState()); 220 221 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber()); 222 service_->OnClearServerDataSucceeded(); 223 EXPECT_TRUE(ProfileSyncService::CLEAR_SUCCEEDED == 224 service_->GetClearServerDataState()); 225 226 service_->OnClearServerDataFailed(); 227 EXPECT_TRUE(ProfileSyncService::CLEAR_SUCCEEDED == 228 service_->GetClearServerDataState()); 229 230 // Test the pending state, doesn't matter what state 231 // the back end syncmgr returns 232 EXPECT_CALL(*data_type_manager, state()). 233 WillOnce(Return(DataTypeManager::STOPPED)); 234 service_->ResetClearServerDataState(); 235 service_->ClearServerData(); 236 EXPECT_TRUE(ProfileSyncService::CLEAR_CLEARING == 237 service_->GetClearServerDataState()); 238 239 // Stop the timer and reset the state 240 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber()); 241 service_->OnClearServerDataSucceeded(); 242 service_->ResetClearServerDataState(); 243} 244 245TEST_F(ProfileSyncServiceStartupTest, SKIP_MACOSX(StartFailure)) { 246 DataTypeManagerMock* data_type_manager = SetUpDataTypeManager(); 247 DataTypeManager::ConfigureResult configure_result = 248 DataTypeManager::ASSOCIATION_FAILED; 249 browser_sync::DataTypeManager::ConfigureResultWithErrorLocation result( 250 configure_result, FROM_HERE, syncable::ModelTypeSet()); 251 EXPECT_CALL(*data_type_manager, Configure(_)). 252 WillRepeatedly(DoAll(NotifyFromDataTypeManager(data_type_manager, 253 NotificationType::SYNC_CONFIGURE_START), 254 NotifyFromDataTypeManagerWithResult(data_type_manager, 255 NotificationType::SYNC_CONFIGURE_DONE, 256 &result))); 257 EXPECT_CALL(*data_type_manager, state()). 258 WillOnce(Return(DataTypeManager::STOPPED)); 259 260 EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber()); 261 262 profile_.GetTokenService()->IssueAuthTokenForTest( 263 GaiaConstants::kSyncService, "sync_token"); 264 service_->Initialize(); 265 EXPECT_TRUE(service_->unrecoverable_error_detected()); 266} 267