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