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.
4
5 #include "components/sync/driver/startup_controller.h"
6
7 #include <memory>
8 #include <utility>
9
10 #include "base/bind.h"
11 #include "base/command_line.h"
12 #include "base/run_loop.h"
13 #include "base/test/task_environment.h"
14 #include "components/policy/core/common/mock_policy_service.h"
15 #include "components/policy/core/common/policy_service_impl.h"
16 #include "components/sync/driver/sync_driver_switches.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 namespace syncer {
21
22 class StartupControllerTest : public testing::Test {
23 public:
StartupControllerTest()24 StartupControllerTest()
25 : preferred_types_(UserTypes()), should_start_(false), started_(false) {}
26
SetUp()27 void SetUp() override {
28 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
29 switches::kSyncDeferredStartupTimeoutSeconds, "0");
30
31 policy_service_ = CreatePolicyService();
32 controller_ = std::make_unique<StartupController>(
33 base::BindRepeating(&StartupControllerTest::GetPreferredDataTypes,
34 base::Unretained(this)),
35 base::BindRepeating(&StartupControllerTest::ShouldStart,
36 base::Unretained(this)),
37 base::BindRepeating(&StartupControllerTest::FakeStartBackend,
38 base::Unretained(this)),
39 policy_service_.get());
40 controller_->Reset();
41 }
42
CreatePolicyService()43 virtual std::unique_ptr<policy::PolicyService> CreatePolicyService() {
44 auto policy_service =
45 std::make_unique<testing::NiceMock<policy::MockPolicyService>>();
46 ON_CALL(*policy_service, IsFirstPolicyLoadComplete(testing::_))
47 .WillByDefault(testing::Return(true));
48 return policy_service;
49 }
50
SetPreferredDataTypes(const ModelTypeSet & types)51 void SetPreferredDataTypes(const ModelTypeSet& types) {
52 preferred_types_ = types;
53 }
54
SetShouldStart(bool should_start)55 void SetShouldStart(bool should_start) { should_start_ = should_start; }
56
ExpectStarted()57 void ExpectStarted() {
58 EXPECT_TRUE(started());
59 EXPECT_EQ(StartupController::State::STARTED, controller()->GetState());
60 }
61
ExpectStartDeferred()62 void ExpectStartDeferred() {
63 EXPECT_FALSE(started());
64 EXPECT_EQ(StartupController::State::STARTING_DEFERRED,
65 controller()->GetState());
66 }
67
ExpectNotStarted()68 void ExpectNotStarted() {
69 EXPECT_FALSE(started());
70 EXPECT_EQ(StartupController::State::NOT_STARTED, controller()->GetState());
71 }
72
started() const73 bool started() const { return started_; }
clear_started()74 void clear_started() { started_ = false; }
controller()75 StartupController* controller() { return controller_.get(); }
policy_service()76 policy::PolicyService* policy_service() { return policy_service_.get(); }
77
78 private:
GetPreferredDataTypes()79 ModelTypeSet GetPreferredDataTypes() { return preferred_types_; }
ShouldStart()80 bool ShouldStart() { return should_start_; }
FakeStartBackend()81 void FakeStartBackend() { started_ = true; }
82
83 ModelTypeSet preferred_types_;
84 bool should_start_;
85 bool started_;
86 std::unique_ptr<policy::PolicyService> policy_service_;
87 base::test::SingleThreadTaskEnvironment task_environment_;
88 std::unique_ptr<StartupController> controller_;
89 };
90
91 // Test that sync doesn't start if the "should sync start" callback returns
92 // false.
TEST_F(StartupControllerTest,ShouldNotStart)93 TEST_F(StartupControllerTest, ShouldNotStart) {
94 controller()->TryStart(/*force_immediate=*/false);
95 ExpectNotStarted();
96
97 controller()->TryStart(/*force_immediate=*/true);
98 ExpectNotStarted();
99 }
100
TEST_F(StartupControllerTest,DefersByDefault)101 TEST_F(StartupControllerTest, DefersByDefault) {
102 SetShouldStart(true);
103 controller()->TryStart(/*force_immediate=*/false);
104 ExpectStartDeferred();
105 }
106
107 // Test that a data type triggering startup starts sync immediately.
TEST_F(StartupControllerTest,NoDeferralDataTypeTrigger)108 TEST_F(StartupControllerTest, NoDeferralDataTypeTrigger) {
109 SetShouldStart(true);
110 controller()->OnDataTypeRequestsSyncStartup(SESSIONS);
111 ExpectStarted();
112 }
113
114 // Test that a data type trigger interrupts the deferral timer and starts
115 // sync immediately.
TEST_F(StartupControllerTest,DataTypeTriggerInterruptsDeferral)116 TEST_F(StartupControllerTest, DataTypeTriggerInterruptsDeferral) {
117 SetShouldStart(true);
118 controller()->TryStart(/*force_immediate=*/false);
119 ExpectStartDeferred();
120
121 controller()->OnDataTypeRequestsSyncStartup(SESSIONS);
122 ExpectStarted();
123
124 // The fallback timer shouldn't result in another invocation of the closure
125 // we passed to the StartupController.
126 clear_started();
127 base::RunLoop().RunUntilIdle();
128 EXPECT_FALSE(started());
129 }
130
131 // Test that the fallback timer starts sync in the event all conditions are met
132 // and no data type requests sync.
TEST_F(StartupControllerTest,FallbackTimer)133 TEST_F(StartupControllerTest, FallbackTimer) {
134 SetShouldStart(true);
135 controller()->TryStart(/*force_immediate=*/false);
136 ExpectStartDeferred();
137
138 base::RunLoop().RunUntilIdle();
139 ExpectStarted();
140 }
141
142 // Test that we start immediately if sessions is disabled.
TEST_F(StartupControllerTest,NoDeferralWithoutSessionsSync)143 TEST_F(StartupControllerTest, NoDeferralWithoutSessionsSync) {
144 ModelTypeSet types(UserTypes());
145 // Disabling sessions means disabling 4 types due to groupings.
146 types.Remove(SESSIONS);
147 types.Remove(PROXY_TABS);
148 types.Remove(TYPED_URLS);
149 types.Remove(SUPERVISED_USER_SETTINGS);
150 SetPreferredDataTypes(types);
151
152 SetShouldStart(true);
153 controller()->TryStart(/*force_immediate=*/false);
154 ExpectStarted();
155 }
156
157 // Sanity check that the fallback timer doesn't fire before startup
158 // conditions are met.
TEST_F(StartupControllerTest,FallbackTimerWaits)159 TEST_F(StartupControllerTest, FallbackTimerWaits) {
160 controller()->TryStart(/*force_immediate=*/false);
161 ExpectNotStarted();
162 base::RunLoop().RunUntilIdle();
163 ExpectNotStarted();
164 }
165
166 // Test that sync starts immediately when told to do so.
TEST_F(StartupControllerTest,NoDeferralIfForceImmediate)167 TEST_F(StartupControllerTest, NoDeferralIfForceImmediate) {
168 SetShouldStart(true);
169 ExpectNotStarted();
170 controller()->TryStart(/*force_immediate=*/true);
171 ExpectStarted();
172 }
173
174 // Test that setting |force_immediate| interrupts the deferral timer and starts
175 // sync immediately.
TEST_F(StartupControllerTest,ForceImmediateInterruptsDeferral)176 TEST_F(StartupControllerTest, ForceImmediateInterruptsDeferral) {
177 SetShouldStart(true);
178 controller()->TryStart(/*force_immediate=*/false);
179 ExpectStartDeferred();
180
181 controller()->TryStart(/*force_immediate=*/true);
182 ExpectStarted();
183 }
184
185 // Tests the startup controller with a throttled PolicyService to simulate the
186 // wait for policies load.
187 class StartupControllerThrottledPolicyInitializationTest
188 : public StartupControllerTest {
189 public:
CreatePolicyService()190 std::unique_ptr<policy::PolicyService> CreatePolicyService() override {
191 return policy::PolicyServiceImpl::CreateWithThrottledInitialization({});
192 }
193
TriggerPolicyLoad()194 void TriggerPolicyLoad() {
195 static_cast<policy::PolicyServiceImpl*>(policy_service())
196 ->UnthrottleInitialization();
197 }
198 };
199
TEST_F(StartupControllerThrottledPolicyInitializationTest,PoliciesLoadedBeforeTryStart)200 TEST_F(StartupControllerThrottledPolicyInitializationTest,
201 PoliciesLoadedBeforeTryStart) {
202 SetShouldStart(true);
203 ExpectNotStarted();
204 EXPECT_FALSE(controller()->ArePoliciesReady());
205
206 // Policies are ready, but TryStart() hasn't been called yet.
207 TriggerPolicyLoad();
208 ExpectNotStarted();
209 EXPECT_TRUE(controller()->ArePoliciesReady());
210
211 controller()->TryStart(/*force_immediate=*/true);
212 ExpectStarted();
213 }
214
TEST_F(StartupControllerThrottledPolicyInitializationTest,PoliciesLoadedAfterMultipleTryStart)215 TEST_F(StartupControllerThrottledPolicyInitializationTest,
216 PoliciesLoadedAfterMultipleTryStart) {
217 SetShouldStart(true);
218 // Once TryStart is called with |force_immediate| set to true,
219 // after the policies are loaded, the engine will bypass any deferred start.
220 controller()->TryStart(/*force_immediate=*/false);
221 controller()->TryStart(/*force_immediate=*/true);
222
223 // Still waiting for policies, so sync startup is deferred.
224 ExpectStartDeferred();
225 EXPECT_FALSE(controller()->ArePoliciesReady());
226
227 TriggerPolicyLoad();
228
229 // Once policies are ready, sync startup is triggered automatically.
230 EXPECT_TRUE(controller()->ArePoliciesReady());
231 ExpectStarted();
232 }
233
TEST_F(StartupControllerThrottledPolicyInitializationTest,PoliciesLoadedAfterTryStart)234 TEST_F(StartupControllerThrottledPolicyInitializationTest,
235 PoliciesLoadedAfterTryStart) {
236 SetShouldStart(true);
237 controller()->TryStart(/*force_immediate=*/true);
238
239 // Still waiting for policies, so sync startup is deferred.
240 ExpectStartDeferred();
241 EXPECT_FALSE(controller()->ArePoliciesReady());
242
243 TriggerPolicyLoad();
244
245 // Once policies are ready, sync startup is triggered automatically.
246 EXPECT_TRUE(controller()->ArePoliciesReady());
247 ExpectStarted();
248 }
249
TEST_F(StartupControllerThrottledPolicyInitializationTest,PoliciesLoadTimeout)250 TEST_F(StartupControllerThrottledPolicyInitializationTest,
251 PoliciesLoadTimeout) {
252 SetShouldStart(true);
253 controller()->TryStart(/*force_immediate=*/true);
254
255 // Still waiting for policies, so sync startup is deferred.
256 ExpectStartDeferred();
257 EXPECT_FALSE(controller()->ArePoliciesReady());
258
259 controller()->TriggerPolicyWaitTimeoutForTest();
260
261 // Once the wait for policies times out, sync startup is triggered
262 // automatically.
263 EXPECT_TRUE(controller()->ArePoliciesReady());
264 ExpectStarted();
265 }
266
TEST_F(StartupControllerThrottledPolicyInitializationTest,PoliciesLoadedAfterTryStartDeferred)267 TEST_F(StartupControllerThrottledPolicyInitializationTest,
268 PoliciesLoadedAfterTryStartDeferred) {
269 SetShouldStart(true);
270 controller()->TryStart(/*force_immediate=*/false);
271 ExpectStartDeferred();
272 EXPECT_FALSE(controller()->ArePoliciesReady());
273
274 TriggerPolicyLoad();
275
276 // Once policies are ready, sync startup is triggered automatically.
277 // Deferred start because TryStart was never called with |force_immediate| set
278 // to true.
279 EXPECT_TRUE(controller()->ArePoliciesReady());
280 ExpectStartDeferred();
281 }
282
TEST_F(StartupControllerThrottledPolicyInitializationTest,PoliciesLoadTimeoutDeferredStart)283 TEST_F(StartupControllerThrottledPolicyInitializationTest,
284 PoliciesLoadTimeoutDeferredStart) {
285 SetShouldStart(true);
286 controller()->TryStart(/*force_immediate=*/false);
287
288 // Still waiting for policies, so sync startup is deferred.
289 ExpectStartDeferred();
290 EXPECT_FALSE(controller()->ArePoliciesReady());
291
292 controller()->TriggerPolicyWaitTimeoutForTest();
293
294 // Once the wait for policies times out, sync startup is triggered
295 // automatically. Deferred start because TryStart was never called with
296 // |force_immediate| set to true.
297 EXPECT_TRUE(controller()->ArePoliciesReady());
298 ExpectStartDeferred();
299 }
300
301 } // namespace syncer
302