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
24 using browser_sync::DataTypeManager;
25 using browser_sync::DataTypeManagerMock;
26 using testing::_;
27 using testing::AnyNumber;
28 using testing::DoAll;
29 using testing::InvokeArgument;
30 using testing::Mock;
31 using testing::Return;
32
ACTION_P(InvokeCallback,callback_result)33 ACTION_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_
46 class ProfileSyncServiceStartupTest : public testing::Test {
47 public:
ProfileSyncServiceStartupTest()48 ProfileSyncServiceStartupTest()
49 : ui_thread_(BrowserThread::UI, &message_loop_) {}
50
~ProfileSyncServiceStartupTest()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
SetUp()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
TearDown()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:
SetUpDataTypeManager()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
TEST_F(ProfileSyncServiceStartupTest,SKIP_MACOSX (StartFirstTime))93 TEST_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
TEST_F(ProfileSyncServiceStartupTest,SKIP_MACOSX (StartNormal))127 TEST_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
TEST_F(ProfileSyncServiceStartupTest,SKIP_MACOSX (ManagedStartup))142 TEST_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
TEST_F(ProfileSyncServiceStartupTest,SKIP_MACOSX (SwitchManaged))155 TEST_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
TEST_F(ProfileSyncServiceStartupTest,ClearServerData)180 TEST_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
TEST_F(ProfileSyncServiceStartupTest,SKIP_MACOSX (StartFailure))245 TEST_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