sync_service_impl_startup_unittest.cc 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748
  1. // Copyright (c) 2012 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. #include "base/run_loop.h"
  5. #include "components/sync/driver/sync_service_impl.h"
  6. #include "base/bind.h"
  7. #include "base/test/task_environment.h"
  8. #include "build/chromeos_buildflags.h"
  9. #include "components/prefs/pref_service.h"
  10. #include "components/signin/public/identity_manager/identity_test_environment.h"
  11. #include "components/sync/base/pref_names.h"
  12. #include "components/sync/driver/data_type_manager_impl.h"
  13. #include "components/sync/driver/fake_data_type_controller.h"
  14. #include "components/sync/driver/fake_sync_api_component_factory.h"
  15. #include "components/sync/driver/sync_client_mock.h"
  16. #include "components/sync/driver/sync_service_impl_bundle.h"
  17. #include "components/sync/test/fake_sync_engine.h"
  18. #include "testing/gmock/include/gmock/gmock.h"
  19. #include "testing/gtest/include/gtest/gtest.h"
  20. using testing::_;
  21. using testing::ByMove;
  22. using testing::Return;
  23. namespace syncer {
  24. namespace {
  25. const char kEmail[] = "test_user@gmail.com";
  26. class MockSyncServiceObserver : public SyncServiceObserver {
  27. public:
  28. MockSyncServiceObserver() = default;
  29. MOCK_METHOD(void, OnStateChanged, (SyncService*), (override));
  30. };
  31. } // namespace
  32. class SyncServiceImplStartupTest : public testing::Test {
  33. public:
  34. SyncServiceImplStartupTest()
  35. : task_environment_(
  36. base::test::SingleThreadTaskEnvironment::TimeSource::MOCK_TIME),
  37. sync_prefs_(sync_service_impl_bundle_.pref_service()) {
  38. sync_service_impl_bundle_.identity_test_env()
  39. ->SetAutomaticIssueOfAccessTokens(true);
  40. }
  41. ~SyncServiceImplStartupTest() override { sync_service_->Shutdown(); }
  42. void CreateSyncService(
  43. SyncServiceImpl::StartBehavior start_behavior,
  44. ModelTypeSet registered_types = ModelTypeSet(BOOKMARKS)) {
  45. DataTypeController::TypeVector controllers;
  46. for (ModelType type : registered_types) {
  47. auto controller = std::make_unique<FakeDataTypeController>(type);
  48. // Hold a raw pointer to directly interact with the controller.
  49. controller_map_[type] = controller.get();
  50. controllers.push_back(std::move(controller));
  51. }
  52. std::unique_ptr<SyncClientMock> sync_client =
  53. sync_service_impl_bundle_.CreateSyncClientMock();
  54. ON_CALL(*sync_client, CreateDataTypeControllers)
  55. .WillByDefault(Return(ByMove(std::move(controllers))));
  56. sync_service_ = std::make_unique<SyncServiceImpl>(
  57. sync_service_impl_bundle_.CreateBasicInitParams(
  58. start_behavior, std::move(sync_client)));
  59. }
  60. void SimulateTestUserSignin() {
  61. sync_service_impl_bundle_.identity_test_env()->MakePrimaryAccountAvailable(
  62. kEmail, signin::ConsentLevel::kSync);
  63. }
  64. void SimulateTestUserSigninWithoutRefreshToken() {
  65. // Set the primary account *without* providing an OAuth token.
  66. sync_service_impl_bundle_.identity_test_env()->SetPrimaryAccount(
  67. kEmail, signin::ConsentLevel::kSync);
  68. }
  69. void UpdateCredentials() {
  70. sync_service_impl_bundle_.identity_test_env()
  71. ->SetRefreshTokenForPrimaryAccount();
  72. }
  73. // Sets a special invalid refresh token. This is what happens when the primary
  74. // (and sync-consented) account signs out on the web.
  75. void SimulateWebSignout() {
  76. sync_service_impl_bundle_.identity_test_env()
  77. ->SetInvalidRefreshTokenForPrimaryAccount();
  78. }
  79. void DisableAutomaticIssueOfAccessTokens() {
  80. sync_service_impl_bundle_.identity_test_env()
  81. ->SetAutomaticIssueOfAccessTokens(false);
  82. }
  83. void RespondToTokenRequest() {
  84. sync_service_impl_bundle_.identity_test_env()
  85. ->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
  86. "access_token", base::Time::Max());
  87. }
  88. SyncPrefs* sync_prefs() { return &sync_prefs_; }
  89. SyncServiceImpl* sync_service() { return sync_service_.get(); }
  90. PrefService* pref_service() {
  91. return sync_service_impl_bundle_.pref_service();
  92. }
  93. FakeSyncApiComponentFactory* component_factory() {
  94. return sync_service_impl_bundle_.component_factory();
  95. }
  96. DataTypeManagerImpl* data_type_manager() {
  97. return component_factory()->last_created_data_type_manager();
  98. }
  99. FakeSyncEngine* engine() {
  100. return component_factory()->last_created_engine();
  101. }
  102. FakeDataTypeController* get_controller(ModelType type) {
  103. return controller_map_[type];
  104. }
  105. void FastForwardUntilNoTasksRemain() {
  106. task_environment_.FastForwardUntilNoTasksRemain();
  107. }
  108. private:
  109. base::test::SingleThreadTaskEnvironment task_environment_;
  110. SyncServiceImplBundle sync_service_impl_bundle_;
  111. SyncPrefs sync_prefs_;
  112. std::unique_ptr<SyncServiceImpl> sync_service_;
  113. // The controllers are owned by |sync_service_|.
  114. std::map<ModelType, FakeDataTypeController*> controller_map_;
  115. };
  116. // ChromeOS does not support sign-in after startup
  117. #if !BUILDFLAG(IS_CHROMEOS_ASH)
  118. TEST_F(SyncServiceImplStartupTest, StartFirstTime) {
  119. // We've never completed startup.
  120. ASSERT_FALSE(sync_prefs()->IsFirstSetupComplete());
  121. CreateSyncService(SyncServiceImpl::MANUAL_START);
  122. // Should not actually start, rather just clean things up and wait
  123. // to be enabled.
  124. sync_service()->Initialize();
  125. EXPECT_EQ(
  126. SyncService::DisableReasonSet(SyncService::DISABLE_REASON_NOT_SIGNED_IN,
  127. SyncService::DISABLE_REASON_USER_CHOICE),
  128. sync_service()->GetDisableReasons());
  129. EXPECT_EQ(SyncService::TransportState::DISABLED,
  130. sync_service()->GetTransportState());
  131. EXPECT_EQ(nullptr, data_type_manager());
  132. EXPECT_FALSE(engine());
  133. // Preferences should be back to defaults.
  134. EXPECT_EQ(base::Time(), sync_service()->GetLastSyncedTimeForDebugging());
  135. EXPECT_FALSE(sync_prefs()->IsFirstSetupComplete());
  136. // This tells the SyncServiceImpl that setup is now in progress, which
  137. // causes it to try starting up the engine. We're not signed in yet though, so
  138. // that won't work.
  139. sync_service()->GetUserSettings()->SetSyncRequested(true);
  140. std::unique_ptr<SyncSetupInProgressHandle> sync_blocker =
  141. sync_service()->GetSetupInProgressHandle();
  142. EXPECT_FALSE(sync_service()->IsEngineInitialized());
  143. EXPECT_EQ(
  144. SyncService::DisableReasonSet(SyncService::DISABLE_REASON_NOT_SIGNED_IN),
  145. sync_service()->GetDisableReasons());
  146. EXPECT_EQ(SyncService::TransportState::DISABLED,
  147. sync_service()->GetTransportState());
  148. SimulateTestUserSignin();
  149. base::RunLoop().RunUntilIdle();
  150. // Now we're signed in, so the engine can start. Engine initialization is
  151. // immediate in this test, so we bypass the INITIALIZING state.
  152. EXPECT_TRUE(sync_service()->IsEngineInitialized());
  153. EXPECT_EQ(SyncService::DisableReasonSet(),
  154. sync_service()->GetDisableReasons());
  155. EXPECT_EQ(SyncService::TransportState::PENDING_DESIRED_CONFIGURATION,
  156. sync_service()->GetTransportState());
  157. // Simulate the UI telling sync it has finished setting up. Note that this is
  158. // a two-step process: Releasing the SetupInProgressHandle, and marking first
  159. // setup complete.
  160. // Since standalone transport is enabled, completed first-time setup is not a
  161. // requirement, so the service will start up as soon as the setup handle is
  162. // released.
  163. sync_blocker.reset();
  164. ASSERT_FALSE(sync_service()->IsSetupInProgress());
  165. EXPECT_EQ(DataTypeManager::CONFIGURED, data_type_manager()->state());
  166. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  167. sync_service()->GetTransportState());
  168. // Sync-the-feature is still not active, but rather pending confirmation.
  169. EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
  170. EXPECT_FALSE(sync_service()->IsSyncFeatureActive());
  171. // Marking first setup complete will let SyncServiceImpl reconfigure the
  172. // DataTypeManager in full Sync-the-feature mode.
  173. sync_service()->GetUserSettings()->SetFirstSetupComplete(
  174. syncer::SyncFirstSetupCompleteSource::BASIC_FLOW);
  175. EXPECT_EQ(DataTypeManager::CONFIGURED, data_type_manager()->state());
  176. // This should have fully enabled sync.
  177. EXPECT_TRUE(sync_service()->IsSyncFeatureEnabled());
  178. EXPECT_TRUE(sync_service()->IsSyncFeatureActive());
  179. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  180. sync_service()->GetTransportState());
  181. }
  182. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  183. TEST_F(SyncServiceImplStartupTest, StartNoCredentials) {
  184. // We're already signed in, but don't have a refresh token.
  185. SimulateTestUserSigninWithoutRefreshToken();
  186. sync_prefs()->SetFirstSetupComplete();
  187. CreateSyncService(SyncServiceImpl::MANUAL_START);
  188. sync_service()->Initialize();
  189. base::RunLoop().RunUntilIdle();
  190. // SyncServiceImpl should now be active, but of course not have an access
  191. // token.
  192. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  193. sync_service()->GetTransportState());
  194. EXPECT_TRUE(sync_service()->GetAccessTokenForTest().empty());
  195. // Note that SyncServiceImpl is not in an auth error state - no auth was
  196. // attempted, so no error.
  197. }
  198. TEST_F(SyncServiceImplStartupTest, WebSignoutBeforeInitialization) {
  199. // There is a primary account, but it's in a "web signout" aka sync-paused
  200. // state.
  201. SimulateTestUserSignin();
  202. SimulateWebSignout();
  203. sync_prefs()->SetFirstSetupComplete();
  204. CreateSyncService(SyncServiceImpl::MANUAL_START);
  205. sync_service()->Initialize();
  206. // SyncServiceImpl should now be in the paused state.
  207. EXPECT_EQ(SyncService::TransportState::PAUSED,
  208. sync_service()->GetTransportState());
  209. }
  210. TEST_F(SyncServiceImplStartupTest, WebSignoutDuringDeferredStartup) {
  211. // There is a primary account. It is theoretically in the "web signout" aka
  212. // sync-paused error state, but the identity code hasn't detected that yet
  213. // (because auth errors are not persisted).
  214. SimulateTestUserSignin();
  215. sync_prefs()->SetFirstSetupComplete();
  216. // Note: Deferred startup is only enabled if SESSIONS is among the preferred
  217. // data types.
  218. CreateSyncService(SyncServiceImpl::MANUAL_START, {TYPED_URLS, SESSIONS});
  219. sync_service()->Initialize();
  220. ASSERT_EQ(SyncService::TransportState::START_DEFERRED,
  221. sync_service()->GetTransportState());
  222. MockSyncServiceObserver observer;
  223. sync_service()->AddObserver(&observer);
  224. // Entering the sync-paused state should trigger a notification.
  225. EXPECT_CALL(observer, OnStateChanged(sync_service())).WillOnce([&]() {
  226. EXPECT_EQ(SyncService::TransportState::PAUSED,
  227. sync_service()->GetTransportState());
  228. });
  229. // Now sign out on the web to enter the sync-paused state.
  230. SimulateWebSignout();
  231. // SyncServiceImpl should now be in the paused state.
  232. EXPECT_EQ(SyncService::TransportState::PAUSED,
  233. sync_service()->GetTransportState());
  234. sync_service()->RemoveObserver(&observer);
  235. }
  236. TEST_F(SyncServiceImplStartupTest, WebSignoutAfterInitialization) {
  237. // This test has to wait for the access token request to complete, so disable
  238. // automatic issuing of tokens.
  239. DisableAutomaticIssueOfAccessTokens();
  240. SimulateTestUserSignin();
  241. sync_prefs()->SetFirstSetupComplete();
  242. CreateSyncService(SyncServiceImpl::MANUAL_START);
  243. sync_service()->Initialize();
  244. // Respond to the token request to finish the initialization flow.
  245. RespondToTokenRequest();
  246. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  247. sync_service()->GetTransportState());
  248. MockSyncServiceObserver observer;
  249. sync_service()->AddObserver(&observer);
  250. // Entering the sync-paused state should trigger a notification.
  251. EXPECT_CALL(observer, OnStateChanged(sync_service())).WillOnce([&]() {
  252. EXPECT_EQ(SyncService::TransportState::PAUSED,
  253. sync_service()->GetTransportState());
  254. });
  255. // Now sign out on the web to enter the sync-paused state.
  256. SimulateWebSignout();
  257. // SyncServiceImpl should now be in the paused state.
  258. EXPECT_EQ(SyncService::TransportState::PAUSED,
  259. sync_service()->GetTransportState());
  260. sync_service()->RemoveObserver(&observer);
  261. }
  262. TEST_F(SyncServiceImplStartupTest, StartInvalidCredentials) {
  263. SimulateTestUserSignin();
  264. sync_prefs()->SetSyncRequested(true);
  265. sync_prefs()->SetFirstSetupComplete();
  266. CreateSyncService(SyncServiceImpl::MANUAL_START);
  267. // Prevent automatic (and successful) completion of engine initialization.
  268. component_factory()->AllowFakeEngineInitCompletion(false);
  269. sync_service()->Initialize();
  270. base::RunLoop().RunUntilIdle();
  271. // Simulate an auth error while downloading control types.
  272. engine()->TriggerInitializationCompletion(/*success=*/false);
  273. // Engine initialization failures puts the service into an unrecoverable error
  274. // state. It'll take either a browser restart or a full sign-out+sign-in to
  275. // get out of this.
  276. EXPECT_TRUE(sync_service()->HasUnrecoverableError());
  277. EXPECT_EQ(SyncService::DisableReasonSet(
  278. SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR),
  279. sync_service()->GetDisableReasons());
  280. EXPECT_EQ(SyncService::TransportState::DISABLED,
  281. sync_service()->GetTransportState());
  282. }
  283. TEST_F(SyncServiceImplStartupTest, StartCrosNoCredentials) {
  284. // We've never completed startup.
  285. ASSERT_FALSE(sync_prefs()->IsFirstSetupComplete());
  286. // On ChromeOS, the user is always immediately signed in, but a refresh token
  287. // isn't necessarily available yet.
  288. SimulateTestUserSigninWithoutRefreshToken();
  289. CreateSyncService(SyncServiceImpl::AUTO_START);
  290. // Calling Initialize should cause the service to immediately create and
  291. // initialize the engine, and configure the DataTypeManager.
  292. sync_service()->Initialize();
  293. base::RunLoop().RunUntilIdle();
  294. EXPECT_EQ(DataTypeManager::CONFIGURED, data_type_manager()->state());
  295. // Sync should be considered active, even though there is no refresh token.
  296. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  297. sync_service()->GetTransportState());
  298. // Since we're in AUTO_START mode, FirstSetupComplete gets set automatically.
  299. EXPECT_TRUE(sync_service()->GetUserSettings()->IsFirstSetupComplete());
  300. }
  301. TEST_F(SyncServiceImplStartupTest, StartCrosFirstTime) {
  302. // On ChromeOS, the user is always immediately signed in, but a refresh token
  303. // isn't necessarily available yet.
  304. SimulateTestUserSigninWithoutRefreshToken();
  305. CreateSyncService(SyncServiceImpl::AUTO_START);
  306. ASSERT_FALSE(sync_prefs()->IsFirstSetupComplete());
  307. // The primary account is already populated, all that's left to do is provide
  308. // a refresh token.
  309. UpdateCredentials();
  310. sync_service()->Initialize();
  311. base::RunLoop().RunUntilIdle();
  312. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  313. sync_service()->GetTransportState());
  314. }
  315. TEST_F(SyncServiceImplStartupTest, StartNormal) {
  316. // We have previously completed the initial Sync setup, and the user is
  317. // already signed in.
  318. sync_prefs()->SetFirstSetupComplete();
  319. SimulateTestUserSignin();
  320. CreateSyncService(SyncServiceImpl::MANUAL_START);
  321. // Since all conditions for starting Sync are already fulfilled, calling
  322. // Initialize should immediately create and initialize the engine and
  323. // configure the DataTypeManager. In this test, all of these operations are
  324. // synchronous.
  325. sync_service()->Initialize();
  326. base::RunLoop().RunUntilIdle();
  327. EXPECT_NE(nullptr, data_type_manager());
  328. EXPECT_EQ(DataTypeManager::CONFIGURED, data_type_manager()->state());
  329. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  330. sync_service()->GetTransportState());
  331. }
  332. TEST_F(SyncServiceImplStartupTest, StopSync) {
  333. sync_prefs()->SetFirstSetupComplete();
  334. CreateSyncService(SyncServiceImpl::MANUAL_START);
  335. SimulateTestUserSignin();
  336. sync_service()->Initialize();
  337. base::RunLoop().RunUntilIdle();
  338. ASSERT_EQ(DataTypeManager::CONFIGURED, data_type_manager()->state());
  339. ASSERT_EQ(SyncService::TransportState::ACTIVE,
  340. sync_service()->GetTransportState());
  341. // On SetSyncRequested(false), the sync service will immediately start up
  342. // again in transport mode.
  343. sync_service()->GetUserSettings()->SetSyncRequested(false);
  344. base::RunLoop().RunUntilIdle();
  345. // Sync-the-feature is still considered off.
  346. EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
  347. EXPECT_FALSE(sync_service()->IsSyncFeatureActive());
  348. EXPECT_EQ(DataTypeManager::CONFIGURED, data_type_manager()->state());
  349. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  350. sync_service()->GetTransportState());
  351. }
  352. TEST_F(SyncServiceImplStartupTest, DisableSync) {
  353. sync_prefs()->SetSyncRequested(true);
  354. sync_prefs()->SetFirstSetupComplete();
  355. SimulateTestUserSignin();
  356. CreateSyncService(SyncServiceImpl::MANUAL_START);
  357. sync_service()->Initialize();
  358. base::RunLoop().RunUntilIdle();
  359. ASSERT_TRUE(sync_service()->IsSyncFeatureActive());
  360. ASSERT_EQ(DataTypeManager::CONFIGURED, data_type_manager()->state());
  361. ASSERT_EQ(SyncService::TransportState::ACTIVE,
  362. sync_service()->GetTransportState());
  363. // On StopAndClear(), the sync service will immediately start up again in
  364. // transport mode.
  365. sync_service()->StopAndClear();
  366. base::RunLoop().RunUntilIdle();
  367. EXPECT_EQ(DataTypeManager::CONFIGURED, data_type_manager()->state());
  368. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  369. sync_service()->GetTransportState());
  370. // Sync-the-feature is still considered off.
  371. EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
  372. EXPECT_FALSE(sync_service()->IsSyncFeatureActive());
  373. // Call StopAndClear() again while the sync service is already in transport
  374. // mode. It should immediately start up again in transport mode.
  375. sync_service()->StopAndClear();
  376. base::RunLoop().RunUntilIdle();
  377. EXPECT_EQ(DataTypeManager::CONFIGURED, data_type_manager()->state());
  378. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  379. sync_service()->GetTransportState());
  380. }
  381. // Test that we can recover from a case where a bug in the code resulted in
  382. // OnUserChoseDatatypes not being properly called and datatype preferences
  383. // therefore being left unset.
  384. TEST_F(SyncServiceImplStartupTest, StartRecoverDatatypePrefs) {
  385. // Clear the datatype preference fields (simulating bug 154940).
  386. pref_service()->ClearPref(prefs::kSyncKeepEverythingSynced);
  387. for (UserSelectableType type : UserSelectableTypeSet::All()) {
  388. pref_service()->ClearPref(SyncPrefs::GetPrefNameForType(type));
  389. }
  390. sync_prefs()->SetFirstSetupComplete();
  391. CreateSyncService(SyncServiceImpl::MANUAL_START);
  392. SimulateTestUserSignin();
  393. sync_service()->Initialize();
  394. EXPECT_TRUE(sync_prefs()->HasKeepEverythingSynced());
  395. }
  396. // Verify that the recovery of datatype preferences doesn't overwrite a valid
  397. // case where only bookmarks are enabled.
  398. TEST_F(SyncServiceImplStartupTest, StartDontRecoverDatatypePrefs) {
  399. // Explicitly set Keep Everything Synced to false and have only bookmarks
  400. // enabled.
  401. sync_prefs()->SetSelectedTypes(
  402. /*keep_everything_synced=*/false,
  403. /*choosable_types=*/UserSelectableTypeSet::All(),
  404. /*chosen_types=*/{UserSelectableType::kBookmarks});
  405. sync_prefs()->SetFirstSetupComplete();
  406. CreateSyncService(SyncServiceImpl::MANUAL_START);
  407. SimulateTestUserSignin();
  408. sync_service()->Initialize();
  409. EXPECT_FALSE(sync_prefs()->HasKeepEverythingSynced());
  410. }
  411. TEST_F(SyncServiceImplStartupTest, ManagedStartup) {
  412. // Sync was previously enabled, but a policy was set while Chrome wasn't
  413. // running.
  414. pref_service()->SetBoolean(prefs::kSyncManaged, true);
  415. sync_prefs()->SetSyncRequested(true);
  416. sync_prefs()->SetFirstSetupComplete();
  417. SimulateTestUserSignin();
  418. CreateSyncService(SyncServiceImpl::MANUAL_START);
  419. sync_service()->Initialize();
  420. // Sync was disabled due to the policy, setting SyncRequested to false and
  421. // causing DISABLE_REASON_USER_CHOICE.
  422. EXPECT_EQ(SyncService::DisableReasonSet(
  423. SyncService::DISABLE_REASON_ENTERPRISE_POLICY,
  424. SyncService::DISABLE_REASON_USER_CHOICE),
  425. sync_service()->GetDisableReasons());
  426. // Service should not be started by Initialize() since it's managed.
  427. EXPECT_EQ(nullptr, data_type_manager());
  428. EXPECT_FALSE(engine());
  429. }
  430. TEST_F(SyncServiceImplStartupTest, SwitchManaged) {
  431. // Sync starts out fully set up and enabled.
  432. sync_prefs()->SetSyncRequested(true);
  433. sync_prefs()->SetFirstSetupComplete();
  434. SimulateTestUserSignin();
  435. CreateSyncService(SyncServiceImpl::MANUAL_START);
  436. // Initialize() should be enough to kick off Sync startup (which is instant in
  437. // this test).
  438. sync_service()->Initialize();
  439. base::RunLoop().RunUntilIdle();
  440. EXPECT_TRUE(sync_service()->IsEngineInitialized());
  441. EXPECT_EQ(SyncService::DisableReasonSet(),
  442. sync_service()->GetDisableReasons());
  443. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  444. sync_service()->GetTransportState());
  445. EXPECT_TRUE(sync_service()->IsSyncFeatureEnabled());
  446. EXPECT_TRUE(sync_service()->IsSyncFeatureActive());
  447. ASSERT_EQ(0, get_controller(BOOKMARKS)->model()->clear_metadata_call_count());
  448. // The service should stop when switching to managed mode.
  449. pref_service()->SetBoolean(prefs::kSyncManaged, true);
  450. // Give re-startup a chance to happen (it shouldn't!).
  451. base::RunLoop().RunUntilIdle();
  452. // Sync was disabled due to the policy, setting SyncRequested to false and
  453. // causing DISABLE_REASON_USER_CHOICE.
  454. ASSERT_EQ(SyncService::DisableReasonSet(
  455. SyncService::DISABLE_REASON_ENTERPRISE_POLICY,
  456. SyncService::DISABLE_REASON_USER_CHOICE),
  457. sync_service()->GetDisableReasons());
  458. EXPECT_FALSE(sync_service()->IsEngineInitialized());
  459. EXPECT_EQ(SyncService::TransportState::DISABLED,
  460. sync_service()->GetTransportState());
  461. EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
  462. EXPECT_FALSE(sync_service()->IsSyncFeatureActive());
  463. EXPECT_EQ(1, get_controller(BOOKMARKS)->model()->clear_metadata_call_count());
  464. // When switching back to unmanaged, Sync-the-transport should start up
  465. // automatically, which causes (re)creation of SyncEngine and
  466. // DataTypeManager.
  467. pref_service()->SetBoolean(prefs::kSyncManaged, false);
  468. base::RunLoop().RunUntilIdle();
  469. ASSERT_EQ(
  470. SyncService::DisableReasonSet(SyncService::DISABLE_REASON_USER_CHOICE),
  471. sync_service()->GetDisableReasons());
  472. EXPECT_TRUE(sync_service()->IsEngineInitialized());
  473. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  474. sync_service()->GetTransportState());
  475. // Sync-the-feature is still considered off because disabling Sync through
  476. // policy also reset the sync-requested and first-setup-complete flags.
  477. EXPECT_FALSE(sync_service()->GetUserSettings()->IsFirstSetupComplete());
  478. EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
  479. EXPECT_FALSE(sync_service()->IsSyncFeatureActive());
  480. }
  481. TEST_F(SyncServiceImplStartupTest, StartDownloadFailed) {
  482. sync_prefs()->SetSyncRequested(true);
  483. CreateSyncService(SyncServiceImpl::MANUAL_START);
  484. SimulateTestUserSignin();
  485. ASSERT_FALSE(sync_prefs()->IsFirstSetupComplete());
  486. // Prevent automatic (and successful) completion of engine initialization.
  487. component_factory()->AllowFakeEngineInitCompletion(false);
  488. sync_service()->Initialize();
  489. base::RunLoop().RunUntilIdle();
  490. // Simulate a failure while downloading control types.
  491. engine()->TriggerInitializationCompletion(/*success=*/false);
  492. std::unique_ptr<SyncSetupInProgressHandle> sync_blocker =
  493. sync_service()->GetSetupInProgressHandle();
  494. sync_blocker.reset();
  495. EXPECT_EQ(SyncService::DisableReasonSet(
  496. SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR),
  497. sync_service()->GetDisableReasons());
  498. EXPECT_EQ(SyncService::TransportState::DISABLED,
  499. sync_service()->GetTransportState());
  500. }
  501. // ChromeOS does not support sign-in after startup
  502. #if !BUILDFLAG(IS_CHROMEOS_ASH)
  503. TEST_F(SyncServiceImplStartupTest, FullStartupSequenceFirstTime) {
  504. // We've never completed startup.
  505. ASSERT_FALSE(sync_prefs()->IsFirstSetupComplete());
  506. // Note: Deferred startup is only enabled if SESSIONS is among the preferred
  507. // data types.
  508. CreateSyncService(SyncServiceImpl::MANUAL_START,
  509. ModelTypeSet(SESSIONS, TYPED_URLS));
  510. sync_service()->Initialize();
  511. ASSERT_FALSE(sync_service()->CanSyncFeatureStart());
  512. // There is no signed-in user, so also nobody has decided that Sync should be
  513. // started.
  514. EXPECT_EQ(
  515. SyncService::DisableReasonSet(SyncService::DISABLE_REASON_NOT_SIGNED_IN,
  516. SyncService::DISABLE_REASON_USER_CHOICE),
  517. sync_service()->GetDisableReasons());
  518. EXPECT_EQ(SyncService::TransportState::DISABLED,
  519. sync_service()->GetTransportState());
  520. // Sign in. Now Sync-the-transport can start. Since this was triggered by an
  521. // explicit user event, deferred startup is bypassed.
  522. // Sync-the-feature still doesn't start until the user says they want it.
  523. component_factory()->AllowFakeEngineInitCompletion(false);
  524. SimulateTestUserSignin();
  525. base::RunLoop().RunUntilIdle();
  526. EXPECT_EQ(
  527. SyncService::DisableReasonSet(SyncService::DISABLE_REASON_USER_CHOICE),
  528. sync_service()->GetDisableReasons());
  529. EXPECT_EQ(SyncService::TransportState::INITIALIZING,
  530. sync_service()->GetTransportState());
  531. EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
  532. ASSERT_TRUE(engine());
  533. // Initiate Sync (the feature) setup before the engine initializes itself in
  534. // transport mode.
  535. sync_service()->GetUserSettings()->SetSyncRequested(true);
  536. std::unique_ptr<SyncSetupInProgressHandle> setup_in_progress_handle =
  537. sync_service()->GetSetupInProgressHandle();
  538. // Once the engine calls back and says it's initialized, we're just waiting
  539. // for the user to finish the initial configuration (choosing data types etc.)
  540. // before actually syncing data.
  541. engine()->TriggerInitializationCompletion(/*success=*/true);
  542. ASSERT_TRUE(sync_service()->IsEngineInitialized());
  543. EXPECT_EQ(SyncService::TransportState::PENDING_DESIRED_CONFIGURATION,
  544. sync_service()->GetTransportState());
  545. EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
  546. // Once the user finishes the initial setup, the service can actually start
  547. // configuring the data types. Just marking the initial setup as complete
  548. // isn't enough though, because setup is still considered in progress (we
  549. // haven't released the setup-in-progress handle).
  550. sync_service()->GetUserSettings()->SetFirstSetupComplete(
  551. syncer::SyncFirstSetupCompleteSource::BASIC_FLOW);
  552. EXPECT_EQ(SyncService::TransportState::PENDING_DESIRED_CONFIGURATION,
  553. sync_service()->GetTransportState());
  554. EXPECT_TRUE(sync_service()->IsSyncFeatureEnabled());
  555. // Prevent immediate configuration of one datatype, to verify the state
  556. // during CONFIGURING.
  557. ASSERT_EQ(DataTypeController::NOT_RUNNING, get_controller(SESSIONS)->state());
  558. get_controller(SESSIONS)->model()->EnableManualModelStart();
  559. // Releasing the setup in progress handle lets the service actually configure
  560. // the DataTypeManager.
  561. setup_in_progress_handle.reset();
  562. // While DataTypeManager configuration is ongoing, the overall state is still
  563. // CONFIGURING.
  564. EXPECT_EQ(SyncService::TransportState::CONFIGURING,
  565. sync_service()->GetTransportState());
  566. EXPECT_TRUE(sync_service()->IsSyncFeatureActive());
  567. EXPECT_NE(nullptr, data_type_manager());
  568. EXPECT_TRUE(engine());
  569. // Finally, once the DataTypeManager says it's done with configuration, Sync
  570. // is actually fully up and running.
  571. get_controller(SESSIONS)->model()->SimulateModelStartFinished();
  572. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  573. sync_service()->GetTransportState());
  574. EXPECT_TRUE(sync_service()->IsSyncFeatureActive());
  575. }
  576. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  577. TEST_F(SyncServiceImplStartupTest, FullStartupSequenceNthTime) {
  578. // The user is already signed in and has completed Sync setup before.
  579. SimulateTestUserSignin();
  580. sync_prefs()->SetFirstSetupComplete();
  581. sync_prefs()->SetSyncRequested(true);
  582. // Note: Deferred startup is only enabled if SESSIONS is among the preferred
  583. // data types.
  584. CreateSyncService(SyncServiceImpl::MANUAL_START,
  585. ModelTypeSet(SESSIONS, TYPED_URLS));
  586. sync_service()->Initialize();
  587. ASSERT_TRUE(sync_service()->CanSyncFeatureStart());
  588. // Nothing is preventing Sync from starting, but it should be deferred so as
  589. // to now slow down browser startup.
  590. EXPECT_EQ(SyncService::TransportState::START_DEFERRED,
  591. sync_service()->GetTransportState());
  592. EXPECT_EQ(nullptr, data_type_manager());
  593. EXPECT_FALSE(engine());
  594. // Wait for the deferred startup timer to expire. The Sync service will start
  595. // and initialize the engine.
  596. component_factory()->AllowFakeEngineInitCompletion(false);
  597. FastForwardUntilNoTasksRemain();
  598. EXPECT_EQ(SyncService::TransportState::INITIALIZING,
  599. sync_service()->GetTransportState());
  600. EXPECT_EQ(nullptr, data_type_manager());
  601. EXPECT_TRUE(engine());
  602. // Prevent immediate configuration of one datatype, to verify the state
  603. // during CONFIGURING.
  604. ASSERT_EQ(DataTypeController::NOT_RUNNING, get_controller(SESSIONS)->state());
  605. get_controller(SESSIONS)->model()->EnableManualModelStart();
  606. // Once the engine calls back and says it's initialized, the DataTypeManager
  607. // will start configuring, since initial setup is already done.
  608. engine()->TriggerInitializationCompletion(/*success=*/true);
  609. ASSERT_EQ(DataTypeController::MODEL_STARTING,
  610. get_controller(SESSIONS)->state());
  611. EXPECT_NE(nullptr, data_type_manager());
  612. EXPECT_TRUE(engine());
  613. // Finally, once the DataTypeManager says it's done with configuration, Sync
  614. // is actually fully up and running.
  615. get_controller(SESSIONS)->model()->SimulateModelStartFinished();
  616. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  617. sync_service()->GetTransportState());
  618. }
  619. } // namespace syncer