1 // Copyright 2014 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 "chrome/browser/sync/startup_controller.h"
7 #include "base/command_line.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "base/time/time.h"
11 #include "chrome/browser/defaults.h"
12 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
13 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
14 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
15 #include "chrome/browser/sync/supervised_user_signin_manager_wrapper.h"
16 #include "chrome/common/chrome_switches.h"
17 #include "chrome/test/base/testing_profile.h"
18 #include "components/sync_driver/sync_prefs.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 namespace browser_sync
{
23 static const char kTestUser
[] = "test@gmail.com";
24 static const char kTestToken
[] = "testToken";
26 // These are coupled to the implementation of StartupController's
27 // GetBackendInitializationStateString which is used by about:sync. We use it
28 // as a convenient way to verify internal state and that the class is
29 // outputting the correct values for the debug string.
30 static const char kStateStringStarted
[] = "Started";
31 static const char kStateStringDeferred
[] = "Deferred";
32 static const char kStateStringNotStarted
[] = "Not started";
34 class FakeSupervisedUserSigninManagerWrapper
35 : public SupervisedUserSigninManagerWrapper
{
37 FakeSupervisedUserSigninManagerWrapper()
38 : SupervisedUserSigninManagerWrapper(NULL
, NULL
) {}
39 std::string
GetEffectiveUsername() const override
{ return account_
; }
41 std::string
GetAccountIdToUse() const override
{ return account_
; }
43 void set_account(const std::string
& account
) { account_
= account
; }
49 class StartupControllerTest
: public testing::Test
{
51 StartupControllerTest() : started_(false) {}
53 void SetUp() override
{
54 profile_
.reset(new TestingProfile());
55 sync_prefs_
.reset(new sync_driver::SyncPrefs(profile_
->GetPrefs()));
56 token_service_
.reset(static_cast<FakeProfileOAuth2TokenService
*>(
57 BuildFakeProfileOAuth2TokenService(profile_
.get())));
58 signin_
.reset(new FakeSupervisedUserSigninManagerWrapper());
60 ProfileSyncServiceStartBehavior behavior
=
61 browser_defaults::kSyncAutoStarts
? AUTO_START
: MANUAL_START
;
62 base::Closure fake_start_backend
= base::Bind(
63 &StartupControllerTest::FakeStartBackend
, base::Unretained(this));
64 controller_
.reset(new StartupController(behavior
, token_service(),
65 sync_prefs_
.get(), signin_
.get(),
67 controller_
->Reset(syncer::UserTypes());
68 controller_
->OverrideFallbackTimeoutForTest(
69 base::TimeDelta::FromSeconds(0));
72 void TearDown() override
{
75 token_service_
->Shutdown();
76 token_service_
.reset();
81 void FakeStartBackend() {
85 bool started() const { return started_
; }
86 void clear_started() { started_
= false; }
87 StartupController
* controller() { return controller_
.get(); }
88 FakeSupervisedUserSigninManagerWrapper
* signin() { return signin_
.get(); }
89 FakeProfileOAuth2TokenService
* token_service() {
90 return token_service_
.get();
92 sync_driver::SyncPrefs
* sync_prefs() { return sync_prefs_
.get(); }
93 Profile
* profile() { return profile_
.get(); }
97 base::MessageLoop message_loop_
;
98 scoped_ptr
<StartupController
> controller_
;
99 scoped_ptr
<FakeSupervisedUserSigninManagerWrapper
> signin_
;
100 scoped_ptr
<FakeProfileOAuth2TokenService
> token_service_
;
101 scoped_ptr
<sync_driver::SyncPrefs
> sync_prefs_
;
102 scoped_ptr
<TestingProfile
> profile_
;
105 // Test that sync doesn't start until all conditions are met.
106 TEST_F(StartupControllerTest
, Basic
) {
107 controller()->TryStart();
108 EXPECT_FALSE(started());
109 sync_prefs()->SetSyncSetupCompleted();
110 controller()->TryStart();
111 EXPECT_FALSE(started());
112 signin()->set_account(kTestUser
);
113 controller()->TryStart();
114 EXPECT_FALSE(started());
115 token_service()->IssueRefreshTokenForUser(kTestUser
, kTestToken
);
116 const bool deferred_start
=
117 !base::CommandLine::ForCurrentProcess()->HasSwitch(
118 switches::kSyncDisableDeferredStartup
);
119 controller()->TryStart();
120 EXPECT_EQ(!deferred_start
, started());
121 std::string
state(controller()->GetBackendInitializationStateString());
122 EXPECT_TRUE(deferred_start
? state
== kStateStringDeferred
:
123 state
== kStateStringStarted
);
126 // Test that sync doesn't when suppressed even if all other conditons are met.
127 TEST_F(StartupControllerTest
, Suppressed
) {
128 sync_prefs()->SetSyncSetupCompleted();
129 sync_prefs()->SetStartSuppressed(true);
130 signin()->set_account(kTestUser
);
131 token_service()->IssueRefreshTokenForUser(kTestUser
, kTestToken
);
132 controller()->TryStart();
133 EXPECT_FALSE(started());
134 EXPECT_EQ(kStateStringNotStarted
,
135 controller()->GetBackendInitializationStateString());
138 // Test that sync doesn't when managed even if all other conditons are met.
139 TEST_F(StartupControllerTest
, Managed
) {
140 sync_prefs()->SetSyncSetupCompleted();
141 sync_prefs()->SetManagedForTest(true);
142 signin()->set_account(kTestUser
);
143 token_service()->IssueRefreshTokenForUser(kTestUser
, kTestToken
);
144 controller()->TryStart();
145 EXPECT_FALSE(started());
146 EXPECT_EQ(kStateStringNotStarted
,
147 controller()->GetBackendInitializationStateString());
150 // Test that sync doesn't start until all conditions are met and a
151 // data type triggers sync startup.
152 TEST_F(StartupControllerTest
, DataTypeTriggered
) {
153 sync_prefs()->SetSyncSetupCompleted();
154 signin()->set_account(kTestUser
);
155 token_service()->IssueRefreshTokenForUser(kTestUser
, kTestToken
);
156 controller()->TryStart();
157 EXPECT_FALSE(started());
158 EXPECT_EQ(kStateStringDeferred
,
159 controller()->GetBackendInitializationStateString());
160 controller()->OnDataTypeRequestsSyncStartup(syncer::SESSIONS
);
161 EXPECT_TRUE(started());
162 EXPECT_EQ(kStateStringStarted
,
163 controller()->GetBackendInitializationStateString());
165 // The fallback timer shouldn't result in another invocation of the closure
166 // we passed to the StartupController.
168 base::RunLoop().RunUntilIdle();
169 EXPECT_FALSE(started());
172 // Test that the fallback timer starts sync in the event all
173 // conditions are met and no data type requests sync.
174 TEST_F(StartupControllerTest
, FallbackTimer
) {
175 sync_prefs()->SetSyncSetupCompleted();
176 signin()->set_account(kTestUser
);
177 token_service()->IssueRefreshTokenForUser(kTestUser
, kTestToken
);
178 controller()->TryStart();
179 EXPECT_FALSE(started());
180 base::RunLoop().RunUntilIdle();
181 EXPECT_TRUE(started());
184 // Test that we start immediately if sessions is disabled.
185 TEST_F(StartupControllerTest
, NoDeferralWithoutSessionsSync
) {
186 syncer::ModelTypeSet
types(syncer::UserTypes());
187 // Disabling sessions means disabling 4 types due to groupings.
188 types
.Remove(syncer::SESSIONS
);
189 types
.Remove(syncer::PROXY_TABS
);
190 types
.Remove(syncer::TYPED_URLS
);
191 types
.Remove(syncer::SUPERVISED_USER_SETTINGS
);
192 sync_prefs()->SetKeepEverythingSynced(false);
193 sync_prefs()->SetPreferredDataTypes(syncer::UserTypes(), types
);
194 controller()->Reset(syncer::UserTypes());
195 sync_prefs()->SetSyncSetupCompleted();
196 signin()->set_account(kTestUser
);
197 token_service()->IssueRefreshTokenForUser(kTestUser
, kTestToken
);
198 controller()->TryStart();
199 EXPECT_TRUE(started());
202 // Sanity check that the fallback timer doesn't fire before startup
203 // conditions are met.
204 TEST_F(StartupControllerTest
, FallbackTimerWaits
) {
205 controller()->TryStart();
206 EXPECT_FALSE(started());
207 base::RunLoop().RunUntilIdle();
208 EXPECT_FALSE(started());
211 // Test that sync starts when the user first asks to setup sync (which
212 // may be implicit due to the platform).
213 TEST_F(StartupControllerTest
, FirstSetup
) {
214 signin()->set_account(kTestUser
);
215 token_service()->IssueRefreshTokenForUser(kTestUser
, kTestToken
);
216 controller()->TryStart();
218 if (browser_defaults::kSyncAutoStarts
) {
219 EXPECT_TRUE(started());
221 controller()->set_setup_in_progress(true);
222 controller()->TryStart();
223 EXPECT_TRUE(started());
227 TEST_F(StartupControllerTest
, Reset
) {
228 sync_prefs()->SetSyncSetupCompleted();
229 signin()->set_account(kTestUser
);
230 token_service()->IssueRefreshTokenForUser(kTestUser
, kTestToken
);
231 controller()->TryStart();
232 const bool deferred_start
=
233 !base::CommandLine::ForCurrentProcess()->HasSwitch(
234 switches::kSyncDisableDeferredStartup
);
235 EXPECT_EQ(!deferred_start
, started());
236 controller()->OnDataTypeRequestsSyncStartup(syncer::SESSIONS
);
237 EXPECT_TRUE(started());
239 controller()->Reset(syncer::UserTypes());
240 EXPECT_FALSE(started());
241 controller()->TryStart();
242 // Restart is not deferred.
243 EXPECT_TRUE(started());
246 // Test that setup-in-progress tracking is persistent across a Reset.
247 TEST_F(StartupControllerTest
, ResetDuringSetup
) {
248 signin()->set_account(kTestUser
);
249 token_service()->IssueRefreshTokenForUser(kTestUser
, kTestToken
);
251 // Simulate UI telling us setup is in progress.
252 controller()->set_setup_in_progress(true);
254 // This could happen if the UI triggers a stop-syncing permanently call.
255 controller()->Reset(syncer::UserTypes());
257 // From the UI's point of view, setup is still in progress.
258 EXPECT_TRUE(controller()->setup_in_progress());
261 } // namespace browser_sync