sync_service_impl_unittest.cc 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214
  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 "components/sync/driver/sync_service_impl.h"
  5. #include <map>
  6. #include <memory>
  7. #include <string>
  8. #include <utility>
  9. #include "base/bind.h"
  10. #include "base/callback.h"
  11. #include "base/callback_helpers.h"
  12. #include "base/command_line.h"
  13. #include "base/memory/raw_ptr.h"
  14. #include "base/run_loop.h"
  15. #include "base/test/bind.h"
  16. #include "base/test/scoped_feature_list.h"
  17. #include "base/test/task_environment.h"
  18. #include "base/time/time.h"
  19. #include "base/values.h"
  20. #include "build/build_config.h"
  21. #include "build/chromeos_buildflags.h"
  22. #include "components/policy/core/common/policy_service_impl.h"
  23. #include "components/prefs/testing_pref_service.h"
  24. #include "components/signin/public/identity_manager/account_info.h"
  25. #include "components/signin/public/identity_manager/identity_test_environment.h"
  26. #include "components/signin/public/identity_manager/identity_test_utils.h"
  27. #include "components/signin/public/identity_manager/primary_account_mutator.h"
  28. #include "components/sync/base/command_line_switches.h"
  29. #include "components/sync/base/features.h"
  30. #include "components/sync/base/model_type.h"
  31. #include "components/sync/base/pref_names.h"
  32. #include "components/sync/base/sync_util.h"
  33. #include "components/sync/base/user_selectable_type.h"
  34. #include "components/sync/driver/configure_context.h"
  35. #include "components/sync/driver/data_type_manager_impl.h"
  36. #include "components/sync/driver/fake_data_type_controller.h"
  37. #include "components/sync/driver/fake_sync_api_component_factory.h"
  38. #include "components/sync/driver/mock_trusted_vault_client.h"
  39. #include "components/sync/driver/sync_client_mock.h"
  40. #include "components/sync/driver/sync_service_impl_bundle.h"
  41. #include "components/sync/driver/sync_service_observer.h"
  42. #include "components/sync/driver/sync_service_utils.h"
  43. #include "components/sync/driver/sync_token_status.h"
  44. #include "components/sync/engine/nigori/key_derivation_params.h"
  45. #include "components/sync/test/fake_sync_engine.h"
  46. #include "components/version_info/version_info_values.h"
  47. #include "testing/gmock/include/gmock/gmock.h"
  48. #include "testing/gtest/include/gtest/gtest.h"
  49. using testing::_;
  50. using testing::AllOf;
  51. using testing::AnyNumber;
  52. using testing::ByMove;
  53. using testing::Eq;
  54. using testing::Not;
  55. using testing::Return;
  56. namespace syncer {
  57. namespace {
  58. MATCHER_P(ContainsDataType, type, "") {
  59. return arg.Has(type);
  60. }
  61. constexpr char kTestUser[] = "test_user@gmail.com";
  62. class TestSyncServiceObserver : public SyncServiceObserver {
  63. public:
  64. TestSyncServiceObserver() = default;
  65. void OnStateChanged(SyncService* sync) override {
  66. setup_in_progress_ = sync->IsSetupInProgress();
  67. auth_error_ = sync->GetAuthError();
  68. }
  69. bool setup_in_progress() const { return setup_in_progress_; }
  70. GoogleServiceAuthError auth_error() const { return auth_error_; }
  71. private:
  72. bool setup_in_progress_ = false;
  73. GoogleServiceAuthError auth_error_;
  74. };
  75. // A test harness that uses a real SyncServiceImpl and in most cases a
  76. // FakeSyncEngine.
  77. //
  78. // This is useful if we want to test the SyncServiceImpl and don't care about
  79. // testing the SyncEngine.
  80. class SyncServiceImplTest : public ::testing::Test {
  81. protected:
  82. SyncServiceImplTest() = default;
  83. ~SyncServiceImplTest() override = default;
  84. void SetUp() override {
  85. base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
  86. kSyncDeferredStartupTimeoutSeconds, "0");
  87. }
  88. void TearDown() override {
  89. // Kill the service before the profile.
  90. ShutdownAndDeleteService();
  91. }
  92. void SignIn() {
  93. identity_test_env()->MakePrimaryAccountAvailable(
  94. kTestUser, signin::ConsentLevel::kSync);
  95. }
  96. void CreateService(SyncServiceImpl::StartBehavior behavior,
  97. policy::PolicyService* policy_service = nullptr,
  98. std::vector<std::pair<ModelType, bool>>
  99. registered_types_and_transport_mode_support = {
  100. {BOOKMARKS, false},
  101. {DEVICE_INFO, true}}) {
  102. DCHECK(!service_);
  103. // Default includes a regular controller and a transport-mode controller.
  104. DataTypeController::TypeVector controllers;
  105. for (const auto& [type, transport_mode_support] :
  106. registered_types_and_transport_mode_support) {
  107. auto controller = std::make_unique<FakeDataTypeController>(
  108. type, transport_mode_support);
  109. // Hold a raw pointer to directly interact with the controller.
  110. controller_map_[type] = controller.get();
  111. controllers.push_back(std::move(controller));
  112. }
  113. std::unique_ptr<SyncClientMock> sync_client =
  114. sync_service_impl_bundle_.CreateSyncClientMock();
  115. sync_client_ = sync_client.get();
  116. ON_CALL(*sync_client, CreateDataTypeControllers)
  117. .WillByDefault(Return(ByMove(std::move(controllers))));
  118. SyncServiceImpl::InitParams init_params =
  119. sync_service_impl_bundle_.CreateBasicInitParams(behavior,
  120. std::move(sync_client));
  121. init_params.policy_service = policy_service;
  122. service_ = std::make_unique<SyncServiceImpl>(std::move(init_params));
  123. }
  124. void CreateServiceWithLocalSyncBackend() {
  125. DCHECK(!service_);
  126. // Include a regular controller and a transport-mode controller.
  127. DataTypeController::TypeVector controllers;
  128. controllers.push_back(std::make_unique<FakeDataTypeController>(BOOKMARKS));
  129. controllers.push_back(std::make_unique<FakeDataTypeController>(
  130. DEVICE_INFO, /*enable_transport_only_modle=*/true));
  131. std::unique_ptr<SyncClientMock> sync_client =
  132. sync_service_impl_bundle_.CreateSyncClientMock();
  133. sync_client_ = sync_client.get();
  134. ON_CALL(*sync_client, CreateDataTypeControllers)
  135. .WillByDefault(Return(ByMove(std::move(controllers))));
  136. SyncServiceImpl::InitParams init_params =
  137. sync_service_impl_bundle_.CreateBasicInitParams(
  138. SyncServiceImpl::AUTO_START, std::move(sync_client));
  139. prefs()->SetBoolean(prefs::kEnableLocalSyncBackend, true);
  140. init_params.identity_manager = nullptr;
  141. service_ = std::make_unique<SyncServiceImpl>(std::move(init_params));
  142. }
  143. void ShutdownAndDeleteService() {
  144. if (service_)
  145. service_->Shutdown();
  146. service_.reset();
  147. }
  148. void PopulatePrefsForNthSync() {
  149. component_factory()->set_first_time_sync_configure_done(true);
  150. // Set first sync time before initialize to simulate a complete sync setup.
  151. SyncPrefs sync_prefs(prefs());
  152. sync_prefs.SetSyncRequested(true);
  153. sync_prefs.SetSelectedTypes(
  154. /*keep_everything_synced=*/true,
  155. /*registered_types=*/UserSelectableTypeSet::All(),
  156. /*selected_types=*/UserSelectableTypeSet::All());
  157. sync_prefs.SetFirstSetupComplete();
  158. }
  159. void InitializeForNthSync(bool run_until_idle = true) {
  160. PopulatePrefsForNthSync();
  161. service_->Initialize();
  162. if (run_until_idle) {
  163. task_environment_.RunUntilIdle();
  164. }
  165. }
  166. void InitializeForFirstSync(bool run_until_idle = true) {
  167. service_->Initialize();
  168. if (run_until_idle) {
  169. task_environment_.RunUntilIdle();
  170. }
  171. }
  172. void TriggerPassphraseRequired() {
  173. service_->GetEncryptionObserverForTest()->OnPassphraseRequired(
  174. KeyDerivationParams::CreateForPbkdf2(), sync_pb::EncryptedData());
  175. }
  176. void TriggerDataTypeStartRequest() {
  177. service_->OnDataTypeRequestsSyncStartup(BOOKMARKS);
  178. }
  179. signin::IdentityManager* identity_manager() {
  180. return sync_service_impl_bundle_.identity_manager();
  181. }
  182. signin::IdentityTestEnvironment* identity_test_env() {
  183. return sync_service_impl_bundle_.identity_test_env();
  184. }
  185. SyncServiceImpl* service() { return service_.get(); }
  186. SyncClientMock* sync_client() { return sync_client_; }
  187. TestingPrefServiceSimple* prefs() {
  188. return sync_service_impl_bundle_.pref_service();
  189. }
  190. FakeSyncApiComponentFactory* component_factory() {
  191. return sync_service_impl_bundle_.component_factory();
  192. }
  193. DataTypeManagerImpl* data_type_manager() {
  194. return component_factory()->last_created_data_type_manager();
  195. }
  196. FakeSyncEngine* engine() {
  197. return component_factory()->last_created_engine();
  198. }
  199. MockSyncInvalidationsService* sync_invalidations_service() {
  200. return sync_service_impl_bundle_.sync_invalidations_service();
  201. }
  202. MockTrustedVaultClient* trusted_vault_client() {
  203. return sync_service_impl_bundle_.trusted_vault_client();
  204. }
  205. FakeDataTypeController* get_controller(ModelType type) {
  206. return controller_map_[type];
  207. }
  208. private:
  209. base::test::SingleThreadTaskEnvironment task_environment_;
  210. SyncServiceImplBundle sync_service_impl_bundle_;
  211. std::unique_ptr<SyncServiceImpl> service_;
  212. raw_ptr<SyncClientMock> sync_client_; // Owned by |service_|.
  213. // The controllers are owned by |service_|.
  214. std::map<ModelType, FakeDataTypeController*> controller_map_;
  215. };
  216. class SyncServiceImplTestWithSyncInvalidationsServiceCreated
  217. : public SyncServiceImplTest {
  218. public:
  219. SyncServiceImplTestWithSyncInvalidationsServiceCreated() {
  220. override_features_.InitAndEnableFeature(kSyncSendInterestedDataTypes);
  221. }
  222. ~SyncServiceImplTestWithSyncInvalidationsServiceCreated() override = default;
  223. private:
  224. base::test::ScopedFeatureList override_features_;
  225. };
  226. // Verify that the server URLs are sane.
  227. TEST_F(SyncServiceImplTest, InitialState) {
  228. CreateService(SyncServiceImpl::MANUAL_START);
  229. InitializeForNthSync();
  230. const std::string& url = service()->GetSyncServiceUrlForDebugging().spec();
  231. EXPECT_TRUE(url == internal::kSyncServerUrl ||
  232. url == internal::kSyncDevServerUrl);
  233. }
  234. TEST_F(SyncServiceImplTest, SuccessfulInitialization) {
  235. SignIn();
  236. CreateService(SyncServiceImpl::MANUAL_START);
  237. InitializeForNthSync();
  238. EXPECT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
  239. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  240. service()->GetTransportState());
  241. }
  242. TEST_F(SyncServiceImplTest, SuccessfulLocalBackendInitialization) {
  243. CreateServiceWithLocalSyncBackend();
  244. InitializeForNthSync();
  245. EXPECT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
  246. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  247. service()->GetTransportState());
  248. }
  249. // Verify that an initialization where first setup is not complete does not
  250. // start up Sync-the-feature.
  251. TEST_F(SyncServiceImplTest, NeedsConfirmation) {
  252. SignIn();
  253. CreateService(SyncServiceImpl::MANUAL_START);
  254. // Mimic a sync cycle (transport-only) having completed earlier.
  255. SyncPrefs sync_prefs(prefs());
  256. sync_prefs.SetSyncRequested(true);
  257. sync_prefs.SetSelectedTypes(
  258. /*keep_everything_synced=*/true,
  259. /*registered_types=*/UserSelectableTypeSet::All(),
  260. /*selected_types=*/UserSelectableTypeSet::All());
  261. service()->Initialize();
  262. EXPECT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
  263. // Sync should immediately start up in transport mode.
  264. base::RunLoop().RunUntilIdle();
  265. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  266. service()->GetTransportState());
  267. EXPECT_FALSE(service()->IsSyncFeatureActive());
  268. EXPECT_FALSE(service()->IsSyncFeatureEnabled());
  269. }
  270. TEST_F(SyncServiceImplTest, ModelTypesForTransportMode) {
  271. SignIn();
  272. CreateService(SyncServiceImpl::MANUAL_START);
  273. InitializeForNthSync();
  274. // Disable sync-the-feature.
  275. service()->GetUserSettings()->SetSyncRequested(false);
  276. ASSERT_FALSE(service()->IsSyncFeatureActive());
  277. ASSERT_FALSE(service()->IsSyncFeatureEnabled());
  278. // Sync-the-transport should become active again.
  279. base::RunLoop().RunUntilIdle();
  280. ASSERT_EQ(SyncService::TransportState::ACTIVE,
  281. service()->GetTransportState());
  282. // ModelTypes for sync-the-feature are not configured.
  283. EXPECT_FALSE(service()->GetActiveDataTypes().Has(BOOKMARKS));
  284. // ModelTypes for sync-the-transport are configured.
  285. EXPECT_TRUE(service()->GetActiveDataTypes().Has(DEVICE_INFO));
  286. }
  287. // Verify that the SetSetupInProgress function call updates state
  288. // and notifies observers.
  289. TEST_F(SyncServiceImplTest, SetupInProgress) {
  290. CreateService(SyncServiceImpl::MANUAL_START);
  291. InitializeForFirstSync();
  292. TestSyncServiceObserver observer;
  293. service()->AddObserver(&observer);
  294. std::unique_ptr<SyncSetupInProgressHandle> sync_blocker =
  295. service()->GetSetupInProgressHandle();
  296. EXPECT_TRUE(observer.setup_in_progress());
  297. sync_blocker.reset();
  298. EXPECT_FALSE(observer.setup_in_progress());
  299. service()->RemoveObserver(&observer);
  300. }
  301. // Verify that we wait for policies to load before starting the sync engine.
  302. TEST_F(SyncServiceImplTest, WaitForPoliciesToStart) {
  303. base::test::ScopedFeatureList feature_list;
  304. feature_list.InitAndEnableFeature(kSyncRequiresPoliciesLoaded);
  305. std::unique_ptr<policy::PolicyServiceImpl> policy_service =
  306. policy::PolicyServiceImpl::CreateWithThrottledInitialization(
  307. policy::PolicyServiceImpl::Providers());
  308. SignIn();
  309. CreateService(SyncServiceImpl::MANUAL_START, policy_service.get());
  310. InitializeForNthSync();
  311. EXPECT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
  312. EXPECT_EQ(SyncService::TransportState::START_DEFERRED,
  313. service()->GetTransportState());
  314. EXPECT_EQ(
  315. syncer::UploadState::INITIALIZING,
  316. syncer::GetUploadToGoogleState(service(), syncer::ModelType::BOOKMARKS));
  317. policy_service->UnthrottleInitialization();
  318. base::RunLoop().RunUntilIdle();
  319. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  320. service()->GetTransportState());
  321. }
  322. // Verify that disable by enterprise policy works.
  323. TEST_F(SyncServiceImplTest, DisabledByPolicyBeforeInit) {
  324. prefs()->SetManagedPref(prefs::kSyncManaged,
  325. std::make_unique<base::Value>(true));
  326. SignIn();
  327. CreateService(SyncServiceImpl::MANUAL_START);
  328. InitializeForNthSync();
  329. // Sync was disabled due to the policy, setting SyncRequested to false and
  330. // causing DISABLE_REASON_USER_CHOICE.
  331. EXPECT_EQ(SyncService::DisableReasonSet(
  332. SyncService::DISABLE_REASON_ENTERPRISE_POLICY,
  333. SyncService::DISABLE_REASON_USER_CHOICE),
  334. service()->GetDisableReasons());
  335. EXPECT_EQ(SyncService::TransportState::DISABLED,
  336. service()->GetTransportState());
  337. }
  338. TEST_F(SyncServiceImplTest, DisabledByPolicyBeforeInitThenPolicyRemoved) {
  339. prefs()->SetManagedPref(prefs::kSyncManaged,
  340. std::make_unique<base::Value>(true));
  341. SignIn();
  342. CreateService(SyncServiceImpl::MANUAL_START);
  343. InitializeForNthSync();
  344. // Sync was disabled due to the policy, setting SyncRequested to false and
  345. // causing DISABLE_REASON_USER_CHOICE.
  346. EXPECT_EQ(SyncService::DisableReasonSet(
  347. SyncService::DISABLE_REASON_ENTERPRISE_POLICY,
  348. SyncService::DISABLE_REASON_USER_CHOICE),
  349. service()->GetDisableReasons());
  350. EXPECT_EQ(SyncService::TransportState::DISABLED,
  351. service()->GetTransportState());
  352. // Remove the policy. Sync-the-feature is still disabled, sync-the-transport
  353. // can run.
  354. prefs()->SetManagedPref(prefs::kSyncManaged,
  355. std::make_unique<base::Value>(false));
  356. EXPECT_EQ(
  357. SyncService::DisableReasonSet(SyncService::DISABLE_REASON_USER_CHOICE),
  358. service()->GetDisableReasons());
  359. base::RunLoop().RunUntilIdle();
  360. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  361. service()->GetTransportState());
  362. // Once we mark first setup complete again (it was cleared by the policy) and
  363. // set SyncRequested to true, sync starts up.
  364. service()->GetUserSettings()->SetSyncRequested(true);
  365. service()->GetUserSettings()->SetFirstSetupComplete(
  366. syncer::SyncFirstSetupCompleteSource::BASIC_FLOW);
  367. base::RunLoop().RunUntilIdle();
  368. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  369. service()->GetTransportState());
  370. EXPECT_TRUE(service()->GetDisableReasons().Empty());
  371. }
  372. // Verify that disable by enterprise policy works even after the backend has
  373. // been initialized.
  374. TEST_F(SyncServiceImplTest, DisabledByPolicyAfterInit) {
  375. SignIn();
  376. CreateService(SyncServiceImpl::MANUAL_START);
  377. InitializeForNthSync();
  378. ASSERT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
  379. ASSERT_EQ(SyncService::TransportState::ACTIVE,
  380. service()->GetTransportState());
  381. prefs()->SetManagedPref(prefs::kSyncManaged,
  382. std::make_unique<base::Value>(true));
  383. // Sync was disabled due to the policy, setting SyncRequested to false and
  384. // causing DISABLE_REASON_USER_CHOICE.
  385. EXPECT_EQ(SyncService::DisableReasonSet(
  386. SyncService::DISABLE_REASON_ENTERPRISE_POLICY,
  387. SyncService::DISABLE_REASON_USER_CHOICE),
  388. service()->GetDisableReasons());
  389. EXPECT_EQ(SyncService::TransportState::DISABLED,
  390. service()->GetTransportState());
  391. }
  392. // Exercises the SyncServiceImpl's code paths related to getting shut down
  393. // before the backend initialize call returns.
  394. TEST_F(SyncServiceImplTest, AbortedByShutdown) {
  395. SignIn();
  396. CreateService(SyncServiceImpl::MANUAL_START);
  397. component_factory()->AllowFakeEngineInitCompletion(false);
  398. InitializeForNthSync();
  399. ASSERT_EQ(SyncService::TransportState::INITIALIZING,
  400. service()->GetTransportState());
  401. ShutdownAndDeleteService();
  402. }
  403. // Test SetSyncRequested(false) before we've initialized the backend.
  404. TEST_F(SyncServiceImplTest, EarlyRequestStop) {
  405. SignIn();
  406. CreateService(SyncServiceImpl::MANUAL_START);
  407. // Set up a fake sync engine that will not immediately finish initialization.
  408. component_factory()->AllowFakeEngineInitCompletion(false);
  409. InitializeForNthSync();
  410. ASSERT_EQ(SyncService::TransportState::INITIALIZING,
  411. service()->GetTransportState());
  412. // Request stop. This should immediately restart the service in standalone
  413. // transport mode.
  414. component_factory()->AllowFakeEngineInitCompletion(true);
  415. service()->GetUserSettings()->SetSyncRequested(false);
  416. EXPECT_EQ(
  417. SyncService::DisableReasonSet(SyncService::DISABLE_REASON_USER_CHOICE),
  418. service()->GetDisableReasons());
  419. base::RunLoop().RunUntilIdle();
  420. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  421. service()->GetTransportState());
  422. EXPECT_FALSE(service()->IsSyncFeatureActive());
  423. EXPECT_FALSE(service()->IsSyncFeatureEnabled());
  424. // Request start. Now Sync-the-feature should start again.
  425. service()->GetUserSettings()->SetSyncRequested(true);
  426. EXPECT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
  427. base::RunLoop().RunUntilIdle();
  428. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  429. service()->GetTransportState());
  430. EXPECT_TRUE(service()->IsSyncFeatureActive());
  431. EXPECT_TRUE(service()->IsSyncFeatureEnabled());
  432. }
  433. // Test SetSyncRequested(false) after we've initialized the backend.
  434. TEST_F(SyncServiceImplTest, DisableAndEnableSyncTemporarily) {
  435. SignIn();
  436. CreateService(SyncServiceImpl::MANUAL_START);
  437. InitializeForNthSync();
  438. SyncPrefs sync_prefs(prefs());
  439. ASSERT_TRUE(sync_prefs.IsSyncRequested());
  440. ASSERT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
  441. ASSERT_EQ(SyncService::TransportState::ACTIVE,
  442. service()->GetTransportState());
  443. ASSERT_TRUE(service()->IsSyncFeatureActive());
  444. ASSERT_TRUE(service()->IsSyncFeatureEnabled());
  445. service()->GetUserSettings()->SetSyncRequested(false);
  446. EXPECT_FALSE(sync_prefs.IsSyncRequested());
  447. EXPECT_EQ(
  448. SyncService::DisableReasonSet(SyncService::DISABLE_REASON_USER_CHOICE),
  449. service()->GetDisableReasons());
  450. base::RunLoop().RunUntilIdle();
  451. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  452. service()->GetTransportState());
  453. EXPECT_FALSE(service()->IsSyncFeatureActive());
  454. EXPECT_FALSE(service()->IsSyncFeatureEnabled());
  455. service()->GetUserSettings()->SetSyncRequested(true);
  456. EXPECT_TRUE(sync_prefs.IsSyncRequested());
  457. EXPECT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
  458. base::RunLoop().RunUntilIdle();
  459. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  460. service()->GetTransportState());
  461. EXPECT_TRUE(service()->IsSyncFeatureActive());
  462. EXPECT_TRUE(service()->IsSyncFeatureEnabled());
  463. }
  464. // Certain SyncServiceImpl tests don't apply to Chrome OS, for example
  465. // things that deal with concepts like "signing out".
  466. #if !BUILDFLAG(IS_CHROMEOS_ASH)
  467. TEST_F(SyncServiceImplTest, SignOutDisablesSyncTransportAndSyncFeature) {
  468. // Sign-in and enable sync.
  469. SignIn();
  470. CreateService(SyncServiceImpl::MANUAL_START);
  471. InitializeForNthSync();
  472. ASSERT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
  473. ASSERT_EQ(SyncService::TransportState::ACTIVE,
  474. service()->GetTransportState());
  475. // Sign-out.
  476. signin::PrimaryAccountMutator* account_mutator =
  477. identity_manager()->GetPrimaryAccountMutator();
  478. DCHECK(account_mutator) << "Account mutator should only be null on ChromeOS.";
  479. account_mutator->ClearPrimaryAccount(
  480. signin_metrics::SIGNOUT_TEST,
  481. signin_metrics::SignoutDelete::kIgnoreMetric);
  482. // Wait for SyncServiceImpl to be notified.
  483. base::RunLoop().RunUntilIdle();
  484. // SyncRequested was set to false, causing DISABLE_REASON_USER_CHOICE.
  485. EXPECT_EQ(
  486. SyncService::DisableReasonSet(SyncService::DISABLE_REASON_NOT_SIGNED_IN,
  487. SyncService::DISABLE_REASON_USER_CHOICE),
  488. service()->GetDisableReasons());
  489. EXPECT_EQ(SyncService::TransportState::DISABLED,
  490. service()->GetTransportState());
  491. }
  492. TEST_F(SyncServiceImplTest,
  493. SignOutClearsSyncTransportDataAndSyncTheFeaturePrefs) {
  494. // Sign-in and enable sync.
  495. SignIn();
  496. CreateService(SyncServiceImpl::MANUAL_START);
  497. InitializeForNthSync();
  498. ASSERT_TRUE(service()->GetUserSettings()->IsFirstSetupComplete());
  499. ASSERT_TRUE(service()->GetUserSettings()->IsSyncRequested());
  500. ASSERT_EQ(0, component_factory()->clear_transport_data_call_count());
  501. // Sign-out.
  502. signin::PrimaryAccountMutator* account_mutator =
  503. identity_manager()->GetPrimaryAccountMutator();
  504. DCHECK(account_mutator) << "Account mutator should only be null on ChromeOS.";
  505. account_mutator->ClearPrimaryAccount(
  506. signin_metrics::SIGNOUT_TEST,
  507. signin_metrics::SignoutDelete::kIgnoreMetric);
  508. // Wait for SyncServiceImpl to be notified.
  509. base::RunLoop().RunUntilIdle();
  510. // These are specific to sync-the-feature and should be cleared.
  511. EXPECT_FALSE(service()->GetUserSettings()->IsFirstSetupComplete());
  512. EXPECT_FALSE(service()->GetUserSettings()->IsSyncRequested());
  513. EXPECT_EQ(1, component_factory()->clear_transport_data_call_count());
  514. }
  515. TEST_F(SyncServiceImplTest, SyncRequestedSetToFalseIfStartsSignedOut) {
  516. // Set up bad state.
  517. SyncPrefs sync_prefs(prefs());
  518. sync_prefs.SetSyncRequested(true);
  519. CreateService(SyncServiceImpl::MANUAL_START);
  520. service()->Initialize();
  521. // There's no signed-in user, so SyncRequested should have been set to false.
  522. EXPECT_FALSE(service()->GetUserSettings()->IsSyncRequested());
  523. }
  524. #endif // !BUILDFLAG(IS_CHROMEOS_ASH)
  525. TEST_F(SyncServiceImplTest, GetSyncTokenStatus) {
  526. SignIn();
  527. CreateService(SyncServiceImpl::MANUAL_START);
  528. InitializeForNthSync(/*run_until_idle=*/false);
  529. // Initial status: The Sync engine startup has not begun yet; no token request
  530. // has been sent.
  531. SyncTokenStatus token_status = service()->GetSyncTokenStatusForDebugging();
  532. ASSERT_EQ(CONNECTION_NOT_ATTEMPTED, token_status.connection_status);
  533. ASSERT_TRUE(token_status.connection_status_update_time.is_null());
  534. ASSERT_TRUE(token_status.token_request_time.is_null());
  535. ASSERT_TRUE(token_status.token_response_time.is_null());
  536. ASSERT_FALSE(token_status.has_token);
  537. // Sync engine startup as well as the actual token request take the form of
  538. // posted tasks. Run them.
  539. base::RunLoop().RunUntilIdle();
  540. // Now we should have an access token.
  541. token_status = service()->GetSyncTokenStatusForDebugging();
  542. EXPECT_TRUE(token_status.connection_status_update_time.is_null());
  543. EXPECT_FALSE(token_status.token_request_time.is_null());
  544. EXPECT_FALSE(token_status.token_response_time.is_null());
  545. EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
  546. token_status.last_get_token_error);
  547. EXPECT_TRUE(token_status.next_token_request_time.is_null());
  548. EXPECT_TRUE(token_status.has_token);
  549. // Simulate an auth error.
  550. service()->OnConnectionStatusChange(CONNECTION_AUTH_ERROR);
  551. // This should get reflected in the status, and we should have dropped the
  552. // invalid access token.
  553. token_status = service()->GetSyncTokenStatusForDebugging();
  554. EXPECT_EQ(CONNECTION_AUTH_ERROR, token_status.connection_status);
  555. EXPECT_FALSE(token_status.connection_status_update_time.is_null());
  556. EXPECT_FALSE(token_status.token_request_time.is_null());
  557. EXPECT_FALSE(token_status.token_response_time.is_null());
  558. EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
  559. token_status.last_get_token_error);
  560. EXPECT_FALSE(token_status.next_token_request_time.is_null());
  561. EXPECT_FALSE(token_status.has_token);
  562. // Simulate successful connection.
  563. service()->OnConnectionStatusChange(CONNECTION_OK);
  564. token_status = service()->GetSyncTokenStatusForDebugging();
  565. EXPECT_EQ(CONNECTION_OK, token_status.connection_status);
  566. }
  567. TEST_F(SyncServiceImplTest, RevokeAccessTokenFromTokenService) {
  568. SignIn();
  569. CreateService(SyncServiceImpl::MANUAL_START);
  570. InitializeForNthSync();
  571. ASSERT_EQ(SyncService::TransportState::ACTIVE,
  572. service()->GetTransportState());
  573. const CoreAccountId primary_account_id =
  574. identity_manager()->GetPrimaryAccountId(signin::ConsentLevel::kSync);
  575. // Make sure the expected account_id was passed to the SyncEngine.
  576. ASSERT_EQ(primary_account_id, engine()->authenticated_account_id());
  577. // At this point, the real SyncEngine would try to connect to the server, fail
  578. // (because it has no access token), and eventually call
  579. // OnConnectionStatusChange(CONNECTION_AUTH_ERROR). Since our fake SyncEngine
  580. // doesn't do any of this, call that explicitly here.
  581. service()->OnConnectionStatusChange(CONNECTION_AUTH_ERROR);
  582. base::RunLoop().RunUntilIdle();
  583. ASSERT_FALSE(service()->GetAccessTokenForTest().empty());
  584. AccountInfo secondary_account_info =
  585. identity_test_env()->MakeAccountAvailable("test_user2@gmail.com");
  586. identity_test_env()->RemoveRefreshTokenForAccount(
  587. secondary_account_info.account_id);
  588. EXPECT_FALSE(service()->GetAccessTokenForTest().empty());
  589. identity_test_env()->RemoveRefreshTokenForPrimaryAccount();
  590. EXPECT_TRUE(service()->GetAccessTokenForTest().empty());
  591. }
  592. // Checks that CREDENTIALS_REJECTED_BY_CLIENT resets the access token and stops
  593. // Sync. Regression test for https://crbug.com/824791.
  594. TEST_F(SyncServiceImplTest, CredentialsRejectedByClient_StopSync) {
  595. SignIn();
  596. CreateService(SyncServiceImpl::MANUAL_START);
  597. InitializeForNthSync();
  598. ASSERT_EQ(SyncService::TransportState::ACTIVE,
  599. service()->GetTransportState());
  600. TestSyncServiceObserver observer;
  601. service()->AddObserver(&observer);
  602. const CoreAccountId primary_account_id =
  603. identity_manager()->GetPrimaryAccountId(signin::ConsentLevel::kSync);
  604. // Make sure the expected account_id was passed to the SyncEngine.
  605. ASSERT_EQ(primary_account_id, engine()->authenticated_account_id());
  606. // At this point, the real SyncEngine would try to connect to the server, fail
  607. // (because it has no access token), and eventually call
  608. // OnConnectionStatusChange(CONNECTION_AUTH_ERROR). Since our fake SyncEngine
  609. // doesn't do any of this, call that explicitly here.
  610. service()->OnConnectionStatusChange(CONNECTION_AUTH_ERROR);
  611. base::RunLoop().RunUntilIdle();
  612. ASSERT_FALSE(service()->GetAccessTokenForTest().empty());
  613. ASSERT_EQ(GoogleServiceAuthError::AuthErrorNone(), service()->GetAuthError());
  614. ASSERT_EQ(GoogleServiceAuthError::AuthErrorNone(), observer.auth_error());
  615. // Simulate the credentials getting locally rejected by the client by setting
  616. // the refresh token to a special invalid value.
  617. identity_test_env()->SetInvalidRefreshTokenForPrimaryAccount();
  618. const GoogleServiceAuthError rejected_by_client =
  619. GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
  620. GoogleServiceAuthError::InvalidGaiaCredentialsReason::
  621. CREDENTIALS_REJECTED_BY_CLIENT);
  622. ASSERT_EQ(rejected_by_client,
  623. identity_test_env()
  624. ->identity_manager()
  625. ->GetErrorStateOfRefreshTokenForAccount(primary_account_id));
  626. EXPECT_TRUE(service()->GetAccessTokenForTest().empty());
  627. // The observer should have been notified of the auth error state.
  628. EXPECT_EQ(rejected_by_client, observer.auth_error());
  629. // The Sync engine should have been shut down.
  630. EXPECT_FALSE(service()->IsEngineInitialized());
  631. EXPECT_EQ(SyncService::TransportState::PAUSED,
  632. service()->GetTransportState());
  633. service()->RemoveObserver(&observer);
  634. }
  635. // CrOS does not support signout.
  636. #if !BUILDFLAG(IS_CHROMEOS_ASH)
  637. TEST_F(SyncServiceImplTest, SignOutRevokeAccessToken) {
  638. SignIn();
  639. CreateService(SyncServiceImpl::MANUAL_START);
  640. InitializeForNthSync();
  641. ASSERT_EQ(SyncService::TransportState::ACTIVE,
  642. service()->GetTransportState());
  643. const CoreAccountId primary_account_id =
  644. identity_manager()->GetPrimaryAccountId(signin::ConsentLevel::kSync);
  645. // Make sure the expected account_id was passed to the SyncEngine.
  646. ASSERT_EQ(primary_account_id, engine()->authenticated_account_id());
  647. // At this point, the real SyncEngine would try to connect to the server, fail
  648. // (because it has no access token), and eventually call
  649. // OnConnectionStatusChange(CONNECTION_AUTH_ERROR). Since our fake SyncEngine
  650. // doesn't do any of this, call that explicitly here.
  651. service()->OnConnectionStatusChange(CONNECTION_AUTH_ERROR);
  652. base::RunLoop().RunUntilIdle();
  653. EXPECT_FALSE(service()->GetAccessTokenForTest().empty());
  654. signin::PrimaryAccountMutator* account_mutator =
  655. identity_manager()->GetPrimaryAccountMutator();
  656. // GetPrimaryAccountMutator() returns nullptr on ChromeOS only.
  657. DCHECK(account_mutator);
  658. account_mutator->ClearPrimaryAccount(
  659. signin_metrics::SIGNOUT_TEST,
  660. signin_metrics::SignoutDelete::kIgnoreMetric);
  661. EXPECT_TRUE(service()->GetAccessTokenForTest().empty());
  662. }
  663. #endif
  664. TEST_F(SyncServiceImplTest, StopAndClearWillClearDataAndSwitchToTransportMode) {
  665. SignIn();
  666. CreateService(SyncServiceImpl::MANUAL_START);
  667. InitializeForNthSync();
  668. ASSERT_EQ(SyncService::TransportState::ACTIVE,
  669. service()->GetTransportState());
  670. ASSERT_EQ(0, component_factory()->clear_transport_data_call_count());
  671. service()->StopAndClear();
  672. // Even though Sync-the-feature is disabled, there's still an (unconsented)
  673. // signed-in account, so Sync-the-transport should still be running.
  674. base::RunLoop().RunUntilIdle();
  675. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  676. service()->GetTransportState());
  677. EXPECT_FALSE(service()->IsSyncFeatureEnabled());
  678. EXPECT_EQ(1, component_factory()->clear_transport_data_call_count());
  679. }
  680. // Verify that sync transport data is cleared when the service is initializing
  681. // and account is signed out.
  682. TEST_F(SyncServiceImplTest, ClearTransportDataOnInitializeWhenSignedOut) {
  683. // Clearing prefs can be triggered only after `IdentityManager` finishes
  684. // loading the list of accounts, so wait for it to complete.
  685. identity_test_env()->WaitForRefreshTokensLoaded();
  686. // Don't sign-in before creating the service.
  687. CreateService(SyncServiceImpl::MANUAL_START);
  688. ASSERT_EQ(0, component_factory()->clear_transport_data_call_count());
  689. // Initialize when signed out to trigger clearing of prefs.
  690. InitializeForNthSync();
  691. EXPECT_EQ(1, component_factory()->clear_transport_data_call_count());
  692. }
  693. TEST_F(SyncServiceImplTest, StopSyncAndClearTwiceDoesNotCrash) {
  694. SignIn();
  695. CreateService(SyncServiceImpl::MANUAL_START);
  696. InitializeForNthSync();
  697. ASSERT_EQ(SyncService::TransportState::ACTIVE,
  698. service()->GetTransportState());
  699. // Disable sync.
  700. service()->StopAndClear();
  701. EXPECT_FALSE(service()->IsSyncFeatureEnabled());
  702. // Calling StopAndClear while already stopped should not crash. This may
  703. // (under some circumstances) happen when the user enables sync again but hits
  704. // the cancel button at the end of the process.
  705. ASSERT_FALSE(service()->GetUserSettings()->IsSyncRequested());
  706. service()->StopAndClear();
  707. EXPECT_FALSE(service()->IsSyncFeatureEnabled());
  708. }
  709. // Verify that credential errors get returned from GetAuthError().
  710. TEST_F(SyncServiceImplTest, CredentialErrorReturned) {
  711. // This test needs to manually send access tokens (or errors), so disable
  712. // automatic replies to access token requests.
  713. identity_test_env()->SetAutomaticIssueOfAccessTokens(false);
  714. SignIn();
  715. CreateService(SyncServiceImpl::MANUAL_START);
  716. InitializeForNthSync();
  717. ASSERT_EQ(SyncService::TransportState::ACTIVE,
  718. service()->GetTransportState());
  719. const CoreAccountId primary_account_id =
  720. identity_manager()->GetPrimaryAccountId(signin::ConsentLevel::kSync);
  721. // Make sure the expected account_id was passed to the SyncEngine.
  722. ASSERT_EQ(primary_account_id, engine()->authenticated_account_id());
  723. TestSyncServiceObserver observer;
  724. service()->AddObserver(&observer);
  725. // At this point, the real SyncEngine would try to connect to the server, fail
  726. // (because it has no access token), and eventually call
  727. // OnConnectionStatusChange(CONNECTION_AUTH_ERROR). Since our fake SyncEngine
  728. // doesn't do any of this, call that explicitly here.
  729. service()->OnConnectionStatusChange(CONNECTION_AUTH_ERROR);
  730. // Wait for SyncServiceImpl to send an access token request.
  731. base::RunLoop().RunUntilIdle();
  732. identity_test_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
  733. primary_account_id, "access token", base::Time::Max());
  734. ASSERT_FALSE(service()->GetAccessTokenForTest().empty());
  735. ASSERT_EQ(GoogleServiceAuthError::NONE, service()->GetAuthError().state());
  736. // Emulate Chrome receiving a new, invalid LST. This happens when the user
  737. // signs out of the content area.
  738. identity_test_env()->SetRefreshTokenForPrimaryAccount();
  739. // Again, wait for SyncServiceImpl to be notified.
  740. base::RunLoop().RunUntilIdle();
  741. identity_test_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithError(
  742. GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
  743. // Check that the invalid token is returned from sync.
  744. EXPECT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS,
  745. service()->GetAuthError().state());
  746. EXPECT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS,
  747. observer.auth_error().state());
  748. // The overall state should remain ACTIVE.
  749. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  750. service()->GetTransportState());
  751. service()->RemoveObserver(&observer);
  752. }
  753. // Verify that credential errors get cleared when a new token is fetched
  754. // successfully.
  755. TEST_F(SyncServiceImplTest, CredentialErrorClearsOnNewToken) {
  756. // This test needs to manually send access tokens (or errors), so disable
  757. // automatic replies to access token requests.
  758. identity_test_env()->SetAutomaticIssueOfAccessTokens(false);
  759. SignIn();
  760. CreateService(SyncServiceImpl::MANUAL_START);
  761. InitializeForNthSync();
  762. ASSERT_EQ(SyncService::TransportState::ACTIVE,
  763. service()->GetTransportState());
  764. const CoreAccountId primary_account_id =
  765. identity_manager()->GetPrimaryAccountId(signin::ConsentLevel::kSync);
  766. // Make sure the expected account_id was passed to the SyncEngine.
  767. ASSERT_EQ(primary_account_id, engine()->authenticated_account_id());
  768. TestSyncServiceObserver observer;
  769. service()->AddObserver(&observer);
  770. // At this point, the real SyncEngine would try to connect to the server, fail
  771. // (because it has no access token), and eventually call
  772. // OnConnectionStatusChange(CONNECTION_AUTH_ERROR). Since our fake SyncEngine
  773. // doesn't do any of this, call that explicitly here.
  774. service()->OnConnectionStatusChange(CONNECTION_AUTH_ERROR);
  775. // Wait for SyncServiceImpl to send an access token request.
  776. base::RunLoop().RunUntilIdle();
  777. identity_test_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
  778. primary_account_id, "access token", base::Time::Max());
  779. ASSERT_FALSE(service()->GetAccessTokenForTest().empty());
  780. ASSERT_EQ(GoogleServiceAuthError::NONE, service()->GetAuthError().state());
  781. // Emulate Chrome receiving a new, invalid LST. This happens when the user
  782. // signs out of the content area.
  783. identity_test_env()->SetRefreshTokenForPrimaryAccount();
  784. // Wait for SyncServiceImpl to be notified of the changed credentials and
  785. // send a new access token request.
  786. base::RunLoop().RunUntilIdle();
  787. identity_test_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithError(
  788. GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
  789. // Check that the invalid token is returned from sync.
  790. ASSERT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS,
  791. service()->GetAuthError().state());
  792. // The overall state should remain ACTIVE.
  793. ASSERT_EQ(SyncService::TransportState::ACTIVE,
  794. service()->GetTransportState());
  795. // Now emulate Chrome receiving a new, valid LST.
  796. identity_test_env()->SetRefreshTokenForPrimaryAccount();
  797. // Again, wait for SyncServiceImpl to be notified.
  798. base::RunLoop().RunUntilIdle();
  799. identity_test_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
  800. "this one works", base::Time::Now() + base::Days(10));
  801. // Check that sync auth error state cleared.
  802. EXPECT_EQ(GoogleServiceAuthError::NONE, service()->GetAuthError().state());
  803. EXPECT_EQ(GoogleServiceAuthError::NONE, observer.auth_error().state());
  804. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  805. service()->GetTransportState());
  806. service()->RemoveObserver(&observer);
  807. }
  808. // Verify that the disable sync flag disables sync.
  809. TEST_F(SyncServiceImplTest, DisableSyncFlag) {
  810. base::CommandLine::ForCurrentProcess()->AppendSwitch(kDisableSync);
  811. EXPECT_FALSE(IsSyncAllowedByFlag());
  812. }
  813. // Verify that no disable sync flag enables sync.
  814. TEST_F(SyncServiceImplTest, NoDisableSyncFlag) {
  815. EXPECT_TRUE(IsSyncAllowedByFlag());
  816. }
  817. // Test that when SyncServiceImpl receives actionable error
  818. // RESET_LOCAL_SYNC_DATA it restarts sync.
  819. TEST_F(SyncServiceImplTest, ResetSyncData) {
  820. SignIn();
  821. CreateService(SyncServiceImpl::MANUAL_START);
  822. // Backend should get initialized two times: once during initialization and
  823. // once when handling actionable error.
  824. InitializeForNthSync();
  825. SyncProtocolError client_cmd;
  826. client_cmd.action = RESET_LOCAL_SYNC_DATA;
  827. service()->OnActionableError(client_cmd);
  828. }
  829. // Test that when SyncServiceImpl receives actionable error
  830. // DISABLE_SYNC_ON_CLIENT it disables sync and signs out.
  831. TEST_F(SyncServiceImplTest, DisableSyncOnClient) {
  832. SignIn();
  833. CreateService(SyncServiceImpl::MANUAL_START);
  834. InitializeForNthSync();
  835. ASSERT_EQ(SyncService::TransportState::ACTIVE,
  836. service()->GetTransportState());
  837. ASSERT_EQ(0, get_controller(BOOKMARKS)->model()->clear_metadata_call_count());
  838. EXPECT_CALL(*trusted_vault_client(),
  839. ClearDataForAccount(Eq(identity_manager()->GetPrimaryAccountInfo(
  840. signin::ConsentLevel::kSync))));
  841. SyncProtocolError client_cmd;
  842. client_cmd.action = DISABLE_SYNC_ON_CLIENT;
  843. service()->OnActionableError(client_cmd);
  844. #if BUILDFLAG(IS_CHROMEOS_ASH)
  845. // Ash does not support signout.
  846. EXPECT_TRUE(
  847. identity_manager()->HasPrimaryAccount(signin::ConsentLevel::kSync));
  848. EXPECT_EQ(
  849. SyncService::DisableReasonSet(SyncService::DISABLE_REASON_USER_CHOICE),
  850. service()->GetDisableReasons());
  851. // Since ChromeOS doesn't support signout and so the account is still there
  852. // and available, Sync will restart in standalone transport mode.
  853. base::RunLoop().RunUntilIdle();
  854. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  855. service()->GetTransportState());
  856. #else
  857. EXPECT_FALSE(
  858. identity_manager()->HasPrimaryAccount(signin::ConsentLevel::kSync));
  859. #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
  860. EXPECT_FALSE(
  861. identity_manager()->HasPrimaryAccount(signin::ConsentLevel::kSignin));
  862. #endif
  863. EXPECT_EQ(
  864. SyncService::DisableReasonSet(SyncService::DISABLE_REASON_NOT_SIGNED_IN,
  865. SyncService::DISABLE_REASON_USER_CHOICE),
  866. service()->GetDisableReasons());
  867. EXPECT_EQ(SyncService::TransportState::DISABLED,
  868. service()->GetTransportState());
  869. EXPECT_TRUE(service()->GetLastSyncedTimeForDebugging().is_null());
  870. #endif
  871. EXPECT_EQ(1, get_controller(BOOKMARKS)->model()->clear_metadata_call_count());
  872. EXPECT_FALSE(service()->IsSyncFeatureEnabled());
  873. EXPECT_FALSE(service()->IsSyncFeatureActive());
  874. }
  875. // Verify a that local sync mode isn't impacted by sync being disabled.
  876. TEST_F(SyncServiceImplTest, LocalBackendUnimpactedByPolicy) {
  877. prefs()->SetManagedPref(prefs::kSyncManaged,
  878. std::make_unique<base::Value>(false));
  879. CreateServiceWithLocalSyncBackend();
  880. InitializeForNthSync();
  881. EXPECT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
  882. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  883. service()->GetTransportState());
  884. prefs()->SetManagedPref(prefs::kSyncManaged,
  885. std::make_unique<base::Value>(true));
  886. EXPECT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
  887. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  888. service()->GetTransportState());
  889. // Note: If standalone transport is enabled, then setting kSyncManaged to
  890. // false will immediately start up the engine. Otherwise, the RequestStart
  891. // call below will trigger it.
  892. prefs()->SetManagedPref(prefs::kSyncManaged,
  893. std::make_unique<base::Value>(false));
  894. service()->GetUserSettings()->SetSyncRequested(true);
  895. EXPECT_EQ(SyncService::DisableReasonSet(), service()->GetDisableReasons());
  896. EXPECT_EQ(SyncService::TransportState::ACTIVE,
  897. service()->GetTransportState());
  898. }
  899. // Test ConfigureDataTypeManagerReason on First and Nth start.
  900. TEST_F(SyncServiceImplTest, ConfigureDataTypeManagerReason) {
  901. SignIn();
  902. // First sync.
  903. CreateService(SyncServiceImpl::MANUAL_START);
  904. InitializeForFirstSync();
  905. ASSERT_EQ(SyncService::TransportState::ACTIVE,
  906. service()->GetTransportState());
  907. EXPECT_EQ(CONFIGURE_REASON_NEW_CLIENT,
  908. data_type_manager()->last_configure_reason_for_test());
  909. // Reconfiguration.
  910. // Trigger a reconfig by grabbing a SyncSetupInProgressHandle and immediately
  911. // releasing it again (via the temporary unique_ptr going away).
  912. service()->GetSetupInProgressHandle();
  913. EXPECT_EQ(CONFIGURE_REASON_RECONFIGURATION,
  914. data_type_manager()->last_configure_reason_for_test());
  915. ShutdownAndDeleteService();
  916. // Nth sync.
  917. CreateService(SyncServiceImpl::MANUAL_START);
  918. InitializeForNthSync();
  919. ASSERT_EQ(SyncService::TransportState::ACTIVE,
  920. service()->GetTransportState());
  921. EXPECT_EQ(CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE,
  922. data_type_manager()->last_configure_reason_for_test());
  923. // Reconfiguration.
  924. // Trigger a reconfig by grabbing a SyncSetupInProgressHandle and immediately
  925. // releasing it again (via the temporary unique_ptr going away).
  926. service()->GetSetupInProgressHandle();
  927. EXPECT_EQ(CONFIGURE_REASON_RECONFIGURATION,
  928. data_type_manager()->last_configure_reason_for_test());
  929. ShutdownAndDeleteService();
  930. }
  931. // Regression test for crbug.com/1043642, can be removed once
  932. // SyncServiceImpl usages after shutdown are addressed.
  933. TEST_F(SyncServiceImplTest, ShouldProvideDisableReasonsAfterShutdown) {
  934. SignIn();
  935. CreateService(SyncServiceImpl::MANUAL_START);
  936. InitializeForFirstSync();
  937. service()->Shutdown();
  938. EXPECT_FALSE(service()->GetDisableReasons().Empty());
  939. }
  940. TEST_F(SyncServiceImplTestWithSyncInvalidationsServiceCreated,
  941. ShouldSendDataTypesToSyncInvalidationsService) {
  942. SignIn();
  943. CreateService(SyncServiceImpl::MANUAL_START, /*policy_service=*/nullptr,
  944. /*registered_types_and_transport_mode_support=*/
  945. {
  946. {BOOKMARKS, false},
  947. {DEVICE_INFO, true},
  948. });
  949. EXPECT_CALL(*sync_invalidations_service(),
  950. SetInterestedDataTypes(AllOf(ContainsDataType(BOOKMARKS),
  951. ContainsDataType(DEVICE_INFO))));
  952. InitializeForNthSync();
  953. EXPECT_TRUE(engine()->started_handling_invalidations());
  954. }
  955. TEST_F(SyncServiceImplTestWithSyncInvalidationsServiceCreated,
  956. ShouldEnableAndDisableInvalidationsForSessions) {
  957. SignIn();
  958. CreateService(SyncServiceImpl::MANUAL_START, nullptr,
  959. {{SESSIONS, false}, {TYPED_URLS, false}});
  960. InitializeForNthSync();
  961. EXPECT_CALL(*sync_invalidations_service(),
  962. SetInterestedDataTypes(ContainsDataType(SESSIONS)));
  963. service()->SetInvalidationsForSessionsEnabled(true);
  964. EXPECT_CALL(*sync_invalidations_service(),
  965. SetInterestedDataTypes(Not(ContainsDataType(SESSIONS))));
  966. service()->SetInvalidationsForSessionsEnabled(false);
  967. }
  968. TEST_F(SyncServiceImplTestWithSyncInvalidationsServiceCreated,
  969. ShouldNotSubscribeToProxyTypes) {
  970. SignIn();
  971. CreateService(SyncServiceImpl::MANUAL_START, /*policy_service=*/nullptr,
  972. /*registered_types_and_transport_mode_support=*/
  973. {
  974. {BOOKMARKS, false},
  975. {DEVICE_INFO, true},
  976. });
  977. get_controller(BOOKMARKS)
  978. ->model()
  979. ->EnableSkipEngineConnectionForActivationResponse();
  980. EXPECT_CALL(*sync_invalidations_service(),
  981. SetInterestedDataTypes(AllOf(ContainsDataType(DEVICE_INFO),
  982. Not(ContainsDataType(BOOKMARKS)))));
  983. InitializeForNthSync();
  984. }
  985. TEST_F(SyncServiceImplTestWithSyncInvalidationsServiceCreated,
  986. ShouldActivateSyncInvalidationsServiceWhenSyncIsInitialized) {
  987. SignIn();
  988. CreateService(SyncServiceImpl::MANUAL_START);
  989. EXPECT_CALL(*sync_invalidations_service(), SetActive(false)).Times(0);
  990. EXPECT_CALL(*sync_invalidations_service(), SetActive(true));
  991. InitializeForFirstSync();
  992. }
  993. TEST_F(SyncServiceImplTestWithSyncInvalidationsServiceCreated,
  994. ShouldActivateSyncInvalidationsServiceOnSignIn) {
  995. CreateService(SyncServiceImpl::MANUAL_START);
  996. EXPECT_CALL(*sync_invalidations_service(), SetActive(false))
  997. .Times(AnyNumber());
  998. InitializeForFirstSync();
  999. EXPECT_CALL(*sync_invalidations_service(), SetActive(true));
  1000. SignIn();
  1001. }
  1002. // CrOS does not support signout.
  1003. #if !BUILDFLAG(IS_CHROMEOS_ASH)
  1004. TEST_F(SyncServiceImplTestWithSyncInvalidationsServiceCreated,
  1005. ShouldDectivateSyncInvalidationsServiceOnSignOut) {
  1006. SignIn();
  1007. CreateService(SyncServiceImpl::MANUAL_START);
  1008. EXPECT_CALL(*sync_invalidations_service(), SetActive(true));
  1009. InitializeForFirstSync();
  1010. signin::PrimaryAccountMutator* account_mutator =
  1011. identity_manager()->GetPrimaryAccountMutator();
  1012. // GetPrimaryAccountMutator() returns nullptr on ChromeOS only.
  1013. DCHECK(account_mutator);
  1014. // Sign out.
  1015. EXPECT_CALL(*sync_invalidations_service(), SetActive(false));
  1016. account_mutator->ClearPrimaryAccount(
  1017. signin_metrics::SIGNOUT_TEST,
  1018. signin_metrics::SignoutDelete::kIgnoreMetric);
  1019. }
  1020. #endif
  1021. } // namespace
  1022. } // namespace syncer