data_type_manager_impl_unittest.cc 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644
  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. #include "components/sync/driver/data_type_manager_impl.h"
  5. #include <memory>
  6. #include <utility>
  7. #include "base/callback.h"
  8. #include "base/test/bind.h"
  9. #include "base/test/metrics/histogram_tester.h"
  10. #include "base/test/task_environment.h"
  11. #include "components/sync/base/model_type.h"
  12. #include "components/sync/base/sync_mode.h"
  13. #include "components/sync/driver/configure_context.h"
  14. #include "components/sync/driver/data_type_encryption_handler.h"
  15. #include "components/sync/driver/data_type_manager_observer.h"
  16. #include "components/sync/driver/data_type_status_table.h"
  17. #include "components/sync/driver/fake_data_type_controller.h"
  18. #include "components/sync/engine/configure_reason.h"
  19. #include "components/sync/engine/data_type_activation_response.h"
  20. #include "testing/gmock/include/gmock/gmock.h"
  21. #include "testing/gtest/include/gtest/gtest.h"
  22. using testing::_;
  23. using testing::UnorderedElementsAre;
  24. namespace syncer {
  25. namespace {
  26. // Helpers for unioning with control types.
  27. ModelTypeSet AddControlTypesTo(ModelType type) {
  28. return Union(ControlTypes(), ModelTypeSet(type));
  29. }
  30. ConfigureContext BuildConfigureContext(ConfigureReason reason,
  31. SyncMode sync_mode = SyncMode::kFull) {
  32. ConfigureContext context;
  33. context.reason = reason;
  34. context.sync_mode = sync_mode;
  35. context.cache_guid = "test_cache_guid";
  36. return context;
  37. }
  38. DataTypeStatusTable BuildStatusTable(ModelTypeSet crypto_errors,
  39. ModelTypeSet datatype_errors,
  40. ModelTypeSet unready_errors) {
  41. DataTypeStatusTable::TypeErrorMap error_map;
  42. for (ModelType type : crypto_errors) {
  43. error_map[type] = SyncError(FROM_HERE, SyncError::CRYPTO_ERROR,
  44. "crypto error expected", type);
  45. }
  46. for (ModelType type : datatype_errors) {
  47. error_map[type] = SyncError(FROM_HERE, SyncError::DATATYPE_ERROR,
  48. "association error expected", type);
  49. }
  50. for (ModelType type : unready_errors) {
  51. error_map[type] = SyncError(FROM_HERE, SyncError::UNREADY_ERROR,
  52. "unready error expected", type);
  53. }
  54. DataTypeStatusTable status_table;
  55. status_table.UpdateFailedDataTypes(error_map);
  56. return status_table;
  57. }
  58. // Fake ModelTypeConfigurer implementation that simply stores away the
  59. // callback passed into ConfigureDataTypes.
  60. class FakeModelTypeConfigurer : public ModelTypeConfigurer {
  61. public:
  62. FakeModelTypeConfigurer() = default;
  63. ~FakeModelTypeConfigurer() override = default;
  64. void ConfigureDataTypes(ConfigureParams params) override {
  65. configure_call_count_++;
  66. last_params_ = std::move(params);
  67. }
  68. void ConnectDataType(ModelType type,
  69. std::unique_ptr<DataTypeActivationResponse>
  70. activation_response) override {
  71. connected_types_.Put(type);
  72. }
  73. void DisconnectDataType(ModelType type) override {
  74. connected_types_.Remove(type);
  75. }
  76. void SetProxyTabsDatatypeEnabled(bool enabled) override {}
  77. void FinishDownload(ModelTypeSet types_to_configure,
  78. ModelTypeSet failed_download_types) {
  79. ASSERT_FALSE(last_params_.ready_task.is_null());
  80. std::move(last_params_.ready_task)
  81. .Run(Difference(types_to_configure, failed_download_types),
  82. failed_download_types);
  83. }
  84. const ModelTypeSet connected_types() { return connected_types_; }
  85. int configure_call_count() const { return configure_call_count_; }
  86. const ConfigureParams& last_params() const { return last_params_; }
  87. private:
  88. ModelTypeSet connected_types_;
  89. int configure_call_count_ = 0;
  90. ConfigureParams last_params_;
  91. };
  92. // DataTypeManagerObserver implementation.
  93. class FakeDataTypeManagerObserver : public DataTypeManagerObserver {
  94. public:
  95. FakeDataTypeManagerObserver() { ResetExpectations(); }
  96. ~FakeDataTypeManagerObserver() override {
  97. EXPECT_FALSE(start_expected_);
  98. DataTypeManager::ConfigureResult default_result;
  99. EXPECT_EQ(done_expectation_.status, default_result.status);
  100. }
  101. void ExpectStart(base::OnceClosure start_callback) {
  102. start_expected_ = true;
  103. start_callback_ = std::move(start_callback);
  104. }
  105. void ExpectDone(const DataTypeManager::ConfigureResult& result) {
  106. done_expectation_ = result;
  107. }
  108. void ResetExpectations() {
  109. start_expected_ = false;
  110. done_expectation_ = DataTypeManager::ConfigureResult();
  111. }
  112. void OnConfigureDone(
  113. const DataTypeManager::ConfigureResult& result) override {
  114. EXPECT_EQ(done_expectation_.status, result.status);
  115. DataTypeStatusTable::TypeErrorMap errors =
  116. result.data_type_status_table.GetAllErrors();
  117. DataTypeStatusTable::TypeErrorMap expected_errors =
  118. done_expectation_.data_type_status_table.GetAllErrors();
  119. ASSERT_EQ(expected_errors.size(), errors.size());
  120. for (const auto& [type, error] : expected_errors) {
  121. ASSERT_TRUE(errors.find(type) != errors.end());
  122. ASSERT_EQ(error.error_type(), errors.find(type)->second.error_type());
  123. }
  124. done_expectation_ = DataTypeManager::ConfigureResult();
  125. }
  126. void OnConfigureStart() override {
  127. EXPECT_TRUE(start_expected_);
  128. start_expected_ = false;
  129. if (start_callback_) {
  130. std::move(start_callback_).Run();
  131. }
  132. }
  133. private:
  134. bool start_expected_ = true;
  135. base::OnceClosure start_callback_;
  136. DataTypeManager::ConfigureResult done_expectation_;
  137. };
  138. class FakeDataTypeEncryptionHandler : public DataTypeEncryptionHandler {
  139. public:
  140. FakeDataTypeEncryptionHandler() = default;
  141. ~FakeDataTypeEncryptionHandler() override = default;
  142. bool HasCryptoError() const override;
  143. ModelTypeSet GetEncryptedDataTypes() const override;
  144. void set_crypto_error(bool crypto_error) { crypto_error_ = crypto_error; }
  145. void set_encrypted_types(ModelTypeSet encrypted_types) {
  146. encrypted_types_ = encrypted_types;
  147. }
  148. private:
  149. bool crypto_error_ = false;
  150. ModelTypeSet encrypted_types_;
  151. };
  152. bool FakeDataTypeEncryptionHandler::HasCryptoError() const {
  153. return crypto_error_;
  154. }
  155. ModelTypeSet FakeDataTypeEncryptionHandler::GetEncryptedDataTypes() const {
  156. return encrypted_types_;
  157. }
  158. MATCHER_P(ConfigurationStatsForType, model_type, "") {
  159. return arg.model_type == model_type;
  160. }
  161. MATCHER_P3(ConfigurationStatsForType,
  162. model_type,
  163. high_prio_types_before,
  164. same_prio_types_before,
  165. "") {
  166. return arg.model_type == model_type &&
  167. arg.high_priority_types_configured_before == high_prio_types_before &&
  168. arg.same_priority_types_configured_before == same_prio_types_before;
  169. }
  170. } // namespace
  171. class SyncDataTypeManagerImplTest : public testing::Test {
  172. public:
  173. SyncDataTypeManagerImplTest() = default;
  174. ~SyncDataTypeManagerImplTest() override = default;
  175. protected:
  176. void SetUp() override { RecreateDataTypeManager(); }
  177. void RecreateDataTypeManager() {
  178. dtm_ = std::make_unique<DataTypeManagerImpl>(
  179. &controllers_, &encryption_handler_, &configurer_, &observer_);
  180. }
  181. void SetConfigureStartExpectation(
  182. base::OnceClosure start_callback = base::OnceClosure()) {
  183. observer_.ExpectStart(std::move(start_callback));
  184. }
  185. void SetConfigureDoneExpectation(DataTypeManager::ConfigureStatus status,
  186. const DataTypeStatusTable& status_table) {
  187. DataTypeManager::ConfigureResult result;
  188. result.status = status;
  189. result.data_type_status_table = status_table;
  190. observer_.ExpectDone(result);
  191. }
  192. // Configure the given DTM with the given desired types.
  193. void Configure(ModelTypeSet desired_types,
  194. ConfigureReason reason = CONFIGURE_REASON_RECONFIGURATION) {
  195. dtm_->Configure(desired_types, BuildConfigureContext(reason));
  196. }
  197. void Configure(ModelTypeSet desired_types,
  198. SyncMode sync_mode,
  199. ConfigureReason reason = CONFIGURE_REASON_RECONFIGURATION) {
  200. dtm_->Configure(desired_types, BuildConfigureContext(reason, sync_mode));
  201. }
  202. // Finish downloading for the given DTM. Should be done only after
  203. // a call to Configure().
  204. void FinishDownload(ModelTypeSet types_to_configure,
  205. ModelTypeSet failed_download_types) {
  206. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  207. configurer_.FinishDownload(types_to_configure, failed_download_types);
  208. }
  209. void FinishDownloadWhileStopped(ModelTypeSet types_to_configure,
  210. ModelTypeSet failed_download_types) {
  211. configurer_.FinishDownload(types_to_configure, failed_download_types);
  212. }
  213. // Adds a fake controller for the given type to |controllers_|.
  214. // Should be called only before setting up the DTM.
  215. void AddController(ModelType model_type) {
  216. controllers_[model_type] =
  217. std::make_unique<FakeDataTypeController>(model_type);
  218. }
  219. // Gets the fake controller for the given type, which should have
  220. // been previously added via AddController().
  221. FakeDataTypeController* GetController(ModelType model_type) const {
  222. auto it = controllers_.find(model_type);
  223. if (it == controllers_.end()) {
  224. return nullptr;
  225. }
  226. return static_cast<FakeDataTypeController*>(it->second.get());
  227. }
  228. void FailEncryptionFor(ModelTypeSet encrypted_types) {
  229. encryption_handler_.set_crypto_error(true);
  230. encryption_handler_.set_encrypted_types(encrypted_types);
  231. }
  232. const ModelTypeConfigurer::ConfigureParams& last_configure_params() const {
  233. return configurer_.last_params();
  234. }
  235. base::test::SingleThreadTaskEnvironment task_environment_{
  236. base::test::SingleThreadTaskEnvironment::MainThreadType::UI};
  237. DataTypeController::TypeMap controllers_;
  238. FakeModelTypeConfigurer configurer_;
  239. FakeDataTypeManagerObserver observer_;
  240. std::unique_ptr<DataTypeManagerImpl> dtm_;
  241. FakeDataTypeEncryptionHandler encryption_handler_;
  242. };
  243. // Set up a DTM with no controllers, configure it, finish downloading,
  244. // and then stop it.
  245. TEST_F(SyncDataTypeManagerImplTest, NoControllers) {
  246. SetConfigureStartExpectation();
  247. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  248. Configure(ModelTypeSet());
  249. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  250. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  251. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  252. dtm_->Stop(ShutdownReason::STOP_SYNC_AND_KEEP_DATA);
  253. EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
  254. }
  255. // Set up a DTM with a single controller, configure it, finish
  256. // downloading, finish starting the controller, and then stop the DTM.
  257. TEST_F(SyncDataTypeManagerImplTest, ConfigureOne) {
  258. AddController(BOOKMARKS);
  259. SetConfigureStartExpectation();
  260. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  261. Configure(ModelTypeSet(BOOKMARKS));
  262. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  263. EXPECT_EQ(ModelTypeSet(BOOKMARKS), configurer_.connected_types());
  264. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  265. FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet());
  266. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  267. EXPECT_EQ(1U, configurer_.connected_types().Size());
  268. dtm_->Stop(ShutdownReason::STOP_SYNC_AND_KEEP_DATA);
  269. EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
  270. EXPECT_TRUE(configurer_.connected_types().Empty());
  271. EXPECT_EQ(0, GetController(BOOKMARKS)->model()->clear_metadata_call_count());
  272. }
  273. TEST_F(SyncDataTypeManagerImplTest, ConfigureOneThatSkipsEngineConnection) {
  274. AddController(BOOKMARKS);
  275. GetController(BOOKMARKS)
  276. ->model()
  277. ->EnableSkipEngineConnectionForActivationResponse();
  278. SetConfigureStartExpectation();
  279. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  280. Configure(ModelTypeSet(BOOKMARKS));
  281. ASSERT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  282. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  283. FinishDownload(ModelTypeSet(), ModelTypeSet()); // priority types
  284. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  285. EXPECT_EQ(DataTypeController::RUNNING, GetController(BOOKMARKS)->state());
  286. EXPECT_TRUE(dtm_->GetActiveDataTypes().Has(BOOKMARKS));
  287. EXPECT_TRUE(dtm_->GetActiveProxyDataTypes().Has(BOOKMARKS));
  288. // Even if all APIs above indicate the datatype is active, in reality the
  289. // configurer (SyncEngine) hasn't been activated/connected.
  290. EXPECT_TRUE(configurer_.connected_types().Empty());
  291. }
  292. // Set up a DTM with a single controller, configure it, but stop it
  293. // before finishing the download. It should still be safe to run the
  294. // download callback even after the DTM is stopped and destroyed.
  295. TEST_F(SyncDataTypeManagerImplTest, ConfigureOneStopWhileDownloadPending) {
  296. AddController(BOOKMARKS);
  297. {
  298. SetConfigureStartExpectation();
  299. SetConfigureDoneExpectation(DataTypeManager::ABORTED,
  300. DataTypeStatusTable());
  301. Configure(ModelTypeSet(BOOKMARKS));
  302. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  303. EXPECT_EQ(ModelTypeSet(BOOKMARKS), configurer_.connected_types());
  304. dtm_->Stop(ShutdownReason::STOP_SYNC_AND_KEEP_DATA);
  305. EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
  306. EXPECT_TRUE(configurer_.connected_types().Empty());
  307. }
  308. FinishDownloadWhileStopped(ModelTypeSet(BOOKMARKS), ModelTypeSet());
  309. EXPECT_TRUE(configurer_.connected_types().Empty());
  310. }
  311. // Set up a DTM with a single controller, configure it, finish
  312. // downloading, but stop the DTM before the controller finishes
  313. // starting up. It should still be safe to finish starting up the
  314. // controller even after the DTM is stopped and destroyed.
  315. TEST_F(SyncDataTypeManagerImplTest, ConfigureOneStopWhileStartingModel) {
  316. AddController(BOOKMARKS);
  317. GetController(BOOKMARKS)->model()->EnableManualModelStart();
  318. {
  319. SetConfigureStartExpectation();
  320. SetConfigureDoneExpectation(DataTypeManager::ABORTED,
  321. DataTypeStatusTable());
  322. Configure(ModelTypeSet(BOOKMARKS));
  323. ASSERT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  324. ASSERT_EQ(DataTypeController::MODEL_STARTING,
  325. GetController(BOOKMARKS)->state());
  326. dtm_->Stop(ShutdownReason::STOP_SYNC_AND_KEEP_DATA);
  327. EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
  328. EXPECT_TRUE(configurer_.connected_types().Empty());
  329. dtm_.reset();
  330. }
  331. EXPECT_EQ(DataTypeController::STOPPING, GetController(BOOKMARKS)->state());
  332. GetController(BOOKMARKS)->model()->SimulateModelStartFinished();
  333. ASSERT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state());
  334. EXPECT_TRUE(configurer_.connected_types().Empty());
  335. }
  336. // Set up a DTM with a single controller. Then:
  337. //
  338. // 1) Configure.
  339. // 2) Finish the download for step 1.
  340. // 3) The download determines a crypto error.
  341. // 4) Complete download for the reconfiguration without the controller.
  342. // 5) Stop the DTM.
  343. TEST_F(SyncDataTypeManagerImplTest, OneWaitingForCrypto) {
  344. AddController(PASSWORDS);
  345. SetConfigureStartExpectation();
  346. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  347. // Step 1.
  348. Configure(ModelTypeSet(PASSWORDS));
  349. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  350. // Step 2.
  351. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  352. FinishDownload(ModelTypeSet(), ModelTypeSet()); // priority types
  353. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  354. // Step 3.
  355. FailEncryptionFor(ModelTypeSet(PASSWORDS));
  356. // Step 4.
  357. SetConfigureStartExpectation();
  358. SetConfigureDoneExpectation(
  359. DataTypeManager::OK,
  360. BuildStatusTable(/*crypto_errors=*/ModelTypeSet(PASSWORDS),
  361. ModelTypeSet(), ModelTypeSet()));
  362. Configure(ModelTypeSet(PASSWORDS));
  363. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  364. FinishDownload(ModelTypeSet(), ModelTypeSet()); // priority types
  365. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  366. // Step 5.
  367. dtm_->Stop(ShutdownReason::STOP_SYNC_AND_KEEP_DATA);
  368. EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
  369. }
  370. // Set up a DTM with two controllers. Then:
  371. //
  372. // 1) Configure with first controller.
  373. // 2) Finish the download for step 1.
  374. // 3) Configure with both controllers.
  375. // 4) Finish the download for step 3.
  376. // 5) Stop the DTM.
  377. TEST_F(SyncDataTypeManagerImplTest, ConfigureOneThenBoth) {
  378. AddController(BOOKMARKS);
  379. AddController(PREFERENCES);
  380. SetConfigureStartExpectation();
  381. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  382. // Step 1.
  383. Configure(ModelTypeSet(BOOKMARKS));
  384. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  385. EXPECT_EQ(ModelTypeSet(BOOKMARKS), configurer_.connected_types());
  386. // Step 2.
  387. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  388. FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet());
  389. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  390. observer_.ResetExpectations();
  391. SetConfigureStartExpectation();
  392. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  393. // Step 3.
  394. Configure(ModelTypeSet(BOOKMARKS, PREFERENCES));
  395. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  396. EXPECT_EQ(ModelTypeSet(BOOKMARKS, PREFERENCES),
  397. configurer_.connected_types());
  398. EXPECT_EQ(0, GetController(BOOKMARKS)->model()->clear_metadata_call_count());
  399. // Step 4.
  400. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  401. FinishDownload(ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet());
  402. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  403. // Step 5.
  404. dtm_->Stop(ShutdownReason::STOP_SYNC_AND_KEEP_DATA);
  405. EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
  406. EXPECT_TRUE(configurer_.connected_types().Empty());
  407. }
  408. // Set up a DTM with two controllers. Then:
  409. //
  410. // 1) Configure with first controller.
  411. // 2) Finish the download for step 1.
  412. // 3) Configure with second controller.
  413. // 4) Finish the download for step 3.
  414. // 5) Stop the DTM.
  415. TEST_F(SyncDataTypeManagerImplTest, ConfigureOneThenSwitch) {
  416. AddController(BOOKMARKS);
  417. AddController(PREFERENCES);
  418. SetConfigureStartExpectation();
  419. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  420. // Step 1.
  421. Configure(ModelTypeSet(BOOKMARKS));
  422. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  423. EXPECT_EQ(ModelTypeSet(BOOKMARKS), configurer_.connected_types());
  424. // Step 2.
  425. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  426. FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet());
  427. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  428. observer_.ResetExpectations();
  429. SetConfigureStartExpectation();
  430. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  431. // Step 3.
  432. Configure(ModelTypeSet(PREFERENCES));
  433. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  434. EXPECT_EQ(ModelTypeSet(PREFERENCES), configurer_.connected_types());
  435. EXPECT_EQ(1, GetController(BOOKMARKS)->model()->clear_metadata_call_count());
  436. // Step 4.
  437. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  438. FinishDownload(ModelTypeSet(PREFERENCES), ModelTypeSet());
  439. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  440. // Step 5.
  441. dtm_->Stop(ShutdownReason::STOP_SYNC_AND_KEEP_DATA);
  442. EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
  443. EXPECT_TRUE(configurer_.connected_types().Empty());
  444. }
  445. TEST_F(SyncDataTypeManagerImplTest, ConfigureModelLoading) {
  446. // Set up a DTM with two controllers.
  447. AddController(BOOKMARKS);
  448. AddController(PREFERENCES);
  449. GetController(BOOKMARKS)->model()->EnableManualModelStart();
  450. SetConfigureStartExpectation();
  451. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  452. // Step 1: Configure with first controller (model stays loading).
  453. Configure(ModelTypeSet(BOOKMARKS));
  454. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  455. EXPECT_TRUE(configurer_.connected_types().Empty());
  456. // Step 2: Configure with both controllers, which gets postponed because
  457. // there's an ongoing configuration that cannot complete before the
  458. // model loads.
  459. ASSERT_EQ(DataTypeController::MODEL_STARTING,
  460. GetController(BOOKMARKS)->state());
  461. ASSERT_FALSE(dtm_->needs_reconfigure_for_test());
  462. Configure(ModelTypeSet(BOOKMARKS, PREFERENCES));
  463. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  464. EXPECT_TRUE(dtm_->needs_reconfigure_for_test());
  465. // Step 3: Finish starting the first controller. This triggers a
  466. // reconfiguration with both data types.
  467. ASSERT_EQ(DataTypeController::MODEL_STARTING,
  468. GetController(BOOKMARKS)->state());
  469. GetController(BOOKMARKS)->model()->SimulateModelStartFinished();
  470. EXPECT_FALSE(dtm_->needs_reconfigure_for_test());
  471. // Step 4: Finish the download of both data types. This completes the
  472. // configuration.
  473. ASSERT_EQ(DataTypeController::RUNNING, GetController(BOOKMARKS)->state());
  474. ASSERT_EQ(DataTypeController::RUNNING, GetController(PREFERENCES)->state());
  475. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  476. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  477. FinishDownload(ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet());
  478. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  479. EXPECT_EQ(ModelTypeSet(BOOKMARKS, PREFERENCES),
  480. configurer_.connected_types());
  481. // Step 5: Stop the DTM.
  482. dtm_->Stop(ShutdownReason::STOP_SYNC_AND_KEEP_DATA);
  483. EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
  484. EXPECT_TRUE(configurer_.connected_types().Empty());
  485. }
  486. // Set up a DTM with one controller. Then configure and start the controller
  487. // with a datatype error. DTM should proceed without the affected datatype.
  488. TEST_F(SyncDataTypeManagerImplTest, OneFailingController) {
  489. AddController(BOOKMARKS);
  490. GetController(BOOKMARKS)->model()->EnableManualModelStart();
  491. SetConfigureStartExpectation();
  492. SetConfigureDoneExpectation(
  493. DataTypeManager::UNKNOWN,
  494. BuildStatusTable(ModelTypeSet(),
  495. /*datatype_errors=*/ModelTypeSet(BOOKMARKS),
  496. ModelTypeSet()));
  497. Configure(ModelTypeSet(BOOKMARKS));
  498. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  499. EXPECT_TRUE(configurer_.connected_types().Empty());
  500. ASSERT_EQ(DataTypeController::MODEL_STARTING,
  501. GetController(BOOKMARKS)->state());
  502. GetController(BOOKMARKS)->model()->SimulateModelError(
  503. ModelError(FROM_HERE, "Test error"));
  504. ASSERT_EQ(DataTypeController::FAILED, GetController(BOOKMARKS)->state());
  505. // This should be CONFIGURED but is not properly handled in
  506. // DataTypeManagerImpl::OnAllDataTypesReadyForConfigure().
  507. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  508. EXPECT_TRUE(configurer_.connected_types().Empty());
  509. }
  510. // Set up a DTM with two controllers. Then:
  511. //
  512. // 1) Configure with first controller.
  513. // 2) Configure with both controllers.
  514. // 3) Finish the download for step 1.
  515. // 4) Finish the download for step 2.
  516. // 5) Stop the DTM.
  517. TEST_F(SyncDataTypeManagerImplTest, ConfigureWhileDownloadPending) {
  518. AddController(BOOKMARKS);
  519. AddController(PREFERENCES);
  520. SetConfigureStartExpectation();
  521. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  522. // Step 1.
  523. Configure(ModelTypeSet(BOOKMARKS));
  524. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  525. EXPECT_EQ(ModelTypeSet(BOOKMARKS), configurer_.connected_types());
  526. // Step 2.
  527. Configure(ModelTypeSet(BOOKMARKS, PREFERENCES));
  528. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  529. // Step 3.
  530. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  531. FinishDownload(ModelTypeSet(), ModelTypeSet()); // regular types
  532. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  533. // Step 4.
  534. FinishDownload(ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet());
  535. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  536. EXPECT_EQ(ModelTypeSet(BOOKMARKS, PREFERENCES),
  537. configurer_.connected_types());
  538. // Step 5.
  539. dtm_->Stop(ShutdownReason::STOP_SYNC_AND_KEEP_DATA);
  540. EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
  541. EXPECT_TRUE(configurer_.connected_types().Empty());
  542. }
  543. // Set up a DTM with two controllers. Then:
  544. // 1) Configure with first controller.
  545. // 2) Configure with both controllers.
  546. // 3) Finish the download for step 1 with a failed data type.
  547. // 4) Finish the download for step 2 successfully.
  548. // 5) Stop the DTM.
  549. //
  550. // The failure from step 3 should be ignored since there's a
  551. // reconfigure pending from step 2.
  552. TEST_F(SyncDataTypeManagerImplTest, ConfigureWhileDownloadPendingWithFailure) {
  553. AddController(BOOKMARKS);
  554. AddController(PREFERENCES);
  555. SetConfigureStartExpectation();
  556. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  557. // Step 1.
  558. Configure(ModelTypeSet(BOOKMARKS));
  559. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  560. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  561. EXPECT_EQ(ModelTypeSet(BOOKMARKS), configurer_.connected_types());
  562. // Step 2.
  563. Configure(ModelTypeSet(BOOKMARKS, PREFERENCES));
  564. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  565. // Step 3.
  566. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  567. FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet());
  568. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  569. // Step 4.
  570. FinishDownload(ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet());
  571. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  572. EXPECT_EQ(ModelTypeSet(BOOKMARKS, PREFERENCES),
  573. configurer_.connected_types());
  574. // Step 5.
  575. dtm_->Stop(ShutdownReason::STOP_SYNC_AND_KEEP_DATA);
  576. EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
  577. EXPECT_TRUE(configurer_.connected_types().Empty());
  578. }
  579. // Tests a Purge then Configure. This is similar to the sequence of
  580. // operations that would be invoked by the BackendMigrator.
  581. TEST_F(SyncDataTypeManagerImplTest, MigrateAll) {
  582. AddController(PRIORITY_PREFERENCES);
  583. SetConfigureStartExpectation();
  584. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  585. // Initial setup.
  586. Configure(ModelTypeSet(PRIORITY_PREFERENCES));
  587. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  588. FinishDownload(ModelTypeSet(PRIORITY_PREFERENCES), ModelTypeSet());
  589. // We've now configured priority prefs and (implicitly) the control types.
  590. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  591. observer_.ResetExpectations();
  592. // Pretend we were told to migrate all types.
  593. ModelTypeSet to_migrate;
  594. to_migrate.Put(PRIORITY_PREFERENCES);
  595. to_migrate.PutAll(ControlTypes());
  596. EXPECT_EQ(0, GetController(PRIORITY_PREFERENCES)
  597. ->model()
  598. ->clear_metadata_call_count());
  599. SetConfigureStartExpectation();
  600. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  601. dtm_->PurgeForMigration(to_migrate);
  602. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  603. EXPECT_EQ(1, GetController(PRIORITY_PREFERENCES)
  604. ->model()
  605. ->clear_metadata_call_count());
  606. // The DTM will call ConfigureDataTypes(), even though it is unnecessary.
  607. FinishDownload(ModelTypeSet(), ModelTypeSet()); // no enabled types
  608. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  609. observer_.ResetExpectations();
  610. // Re-enable the migrated types.
  611. SetConfigureStartExpectation();
  612. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  613. Configure(to_migrate);
  614. FinishDownload(ControlTypes(), ModelTypeSet()); // control types
  615. FinishDownload(ModelTypeSet(PRIORITY_PREFERENCES), ModelTypeSet());
  616. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  617. EXPECT_EQ(1, GetController(PRIORITY_PREFERENCES)
  618. ->model()
  619. ->clear_metadata_call_count());
  620. }
  621. // Test receipt of a Configure request while a purge is in flight.
  622. TEST_F(SyncDataTypeManagerImplTest, ConfigureDuringPurge) {
  623. AddController(BOOKMARKS);
  624. AddController(PREFERENCES);
  625. // Initial configure.
  626. SetConfigureStartExpectation();
  627. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  628. Configure(ModelTypeSet(BOOKMARKS));
  629. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  630. FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet());
  631. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  632. observer_.ResetExpectations();
  633. // Purge the Nigori type.
  634. SetConfigureStartExpectation();
  635. dtm_->PurgeForMigration(ModelTypeSet(NIGORI));
  636. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  637. observer_.ResetExpectations();
  638. // Before the backend configuration completes, ask for a different
  639. // set of types. This request asks for
  640. // - BOOKMARKS: which is redundant because it was already enabled,
  641. // - PREFERENCES: which is new and will need to be downloaded, and
  642. // - NIGORI: (added implicitly because it is a control type) which
  643. // the DTM is part-way through purging.
  644. Configure(ModelTypeSet(BOOKMARKS, PREFERENCES));
  645. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  646. // Invoke the callback we've been waiting for since we asked to purge NIGORI.
  647. FinishDownload(ModelTypeSet(), ModelTypeSet()); // regular types
  648. observer_.ResetExpectations();
  649. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  650. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  651. // Now invoke the callback for the second configure request.
  652. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  653. FinishDownload(ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet());
  654. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  655. EXPECT_EQ(0, GetController(BOOKMARKS)->model()->clear_metadata_call_count());
  656. EXPECT_EQ(0,
  657. GetController(PREFERENCES)->model()->clear_metadata_call_count());
  658. }
  659. TEST_F(SyncDataTypeManagerImplTest, PrioritizedConfiguration) {
  660. AddController(BOOKMARKS);
  661. AddController(PRIORITY_PREFERENCES);
  662. // Initial configure.
  663. SetConfigureStartExpectation();
  664. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  665. // Start the configuration.
  666. ASSERT_EQ(0, configurer_.configure_call_count());
  667. Configure(ModelTypeSet(BOOKMARKS, PRIORITY_PREFERENCES));
  668. // This causes an immediate ConfigureDataTypes() call for control types, i.e.
  669. // Nigori. It's important that this does *not* ask for any types to be
  670. // downloaded, see crbug.com/1170318 and crbug.com/1187914.
  671. ASSERT_NE(0, configurer_.configure_call_count());
  672. EXPECT_EQ(ModelTypeSet(), last_configure_params().to_download);
  673. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  674. // Finishing the no-op download of the control types causes the next
  675. // ConfigureDataTypes() call, for priority types.
  676. FinishDownload(ModelTypeSet(), ModelTypeSet());
  677. EXPECT_EQ(AddControlTypesTo(PRIORITY_PREFERENCES),
  678. last_configure_params().to_download);
  679. // BOOKMARKS is downloaded after PRIORITY_PREFERENCES finishes.
  680. FinishDownload(ModelTypeSet(PRIORITY_PREFERENCES), ModelTypeSet());
  681. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  682. EXPECT_EQ(AddControlTypesTo(BOOKMARKS), last_configure_params().to_download);
  683. FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet());
  684. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  685. }
  686. TEST_F(SyncDataTypeManagerImplTest, PrioritizedConfigurationReconfigure) {
  687. AddController(PRIORITY_PREFERENCES);
  688. AddController(BOOKMARKS);
  689. AddController(APPS);
  690. // Initial configure.
  691. SetConfigureStartExpectation();
  692. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  693. // Reconfigure while associating PRIORITY_PREFERENCES and downloading
  694. // BOOKMARKS.
  695. Configure(ModelTypeSet(BOOKMARKS, PRIORITY_PREFERENCES));
  696. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  697. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  698. EXPECT_EQ(AddControlTypesTo(PRIORITY_PREFERENCES),
  699. last_configure_params().to_download);
  700. FinishDownload(ModelTypeSet(PRIORITY_PREFERENCES), ModelTypeSet());
  701. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  702. EXPECT_EQ(AddControlTypesTo(BOOKMARKS), last_configure_params().to_download);
  703. // Enable syncing for APPS.
  704. Configure(ModelTypeSet(BOOKMARKS, PRIORITY_PREFERENCES, APPS));
  705. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  706. // Reconfiguration starts after downloading and association of previous
  707. // types finish.
  708. FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet());
  709. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  710. EXPECT_EQ(ModelTypeSet(), last_configure_params().to_download);
  711. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  712. FinishDownload(ModelTypeSet(PRIORITY_PREFERENCES), ModelTypeSet());
  713. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  714. EXPECT_EQ(AddControlTypesTo(APPS), last_configure_params().to_download);
  715. FinishDownload(ModelTypeSet(BOOKMARKS, APPS), ModelTypeSet());
  716. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  717. }
  718. TEST_F(SyncDataTypeManagerImplTest, PrioritizedConfigurationStop) {
  719. AddController(PRIORITY_PREFERENCES);
  720. AddController(BOOKMARKS);
  721. // Initial configure.
  722. SetConfigureStartExpectation();
  723. SetConfigureDoneExpectation(DataTypeManager::ABORTED, DataTypeStatusTable());
  724. // Initially only PRIORITY_PREFERENCES is configured.
  725. Configure(ModelTypeSet(BOOKMARKS, PRIORITY_PREFERENCES));
  726. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  727. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  728. EXPECT_EQ(AddControlTypesTo(PRIORITY_PREFERENCES),
  729. last_configure_params().to_download);
  730. // BOOKMARKS is configured after download of PRIORITY_PREFERENCES finishes.
  731. FinishDownload(ModelTypeSet(PRIORITY_PREFERENCES), ModelTypeSet());
  732. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  733. EXPECT_EQ(AddControlTypesTo(BOOKMARKS), last_configure_params().to_download);
  734. // PRIORITY_PREFERENCES controller is running while BOOKMARKS is downloading.
  735. EXPECT_EQ(DataTypeController::RUNNING,
  736. GetController(PRIORITY_PREFERENCES)->state());
  737. EXPECT_EQ(DataTypeController::RUNNING, GetController(BOOKMARKS)->state());
  738. dtm_->Stop(ShutdownReason::STOP_SYNC_AND_KEEP_DATA);
  739. EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
  740. EXPECT_EQ(DataTypeController::NOT_RUNNING,
  741. GetController(PRIORITY_PREFERENCES)->state());
  742. EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state());
  743. }
  744. TEST_F(SyncDataTypeManagerImplTest, PrioritizedConfigurationDownloadError) {
  745. AddController(PRIORITY_PREFERENCES);
  746. AddController(BOOKMARKS);
  747. // Initial configure. Bookmarks will fail to associate due to the download
  748. // failure.
  749. SetConfigureStartExpectation();
  750. SetConfigureDoneExpectation(
  751. DataTypeManager::OK,
  752. BuildStatusTable(ModelTypeSet(),
  753. /*datatype_errors=*/ModelTypeSet(BOOKMARKS),
  754. ModelTypeSet()));
  755. // Initially only PRIORITY_PREFERENCES is configured.
  756. Configure(ModelTypeSet(BOOKMARKS, PRIORITY_PREFERENCES));
  757. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  758. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  759. EXPECT_EQ(AddControlTypesTo(PRIORITY_PREFERENCES),
  760. last_configure_params().to_download);
  761. // BOOKMARKS is configured after download of PRIORITY_PREFERENCES finishes.
  762. FinishDownload(ModelTypeSet(PRIORITY_PREFERENCES), ModelTypeSet());
  763. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  764. EXPECT_EQ(AddControlTypesTo(BOOKMARKS), last_configure_params().to_download);
  765. // PRIORITY_PREFERENCES controller is running while BOOKMARKS is downloading.
  766. EXPECT_EQ(DataTypeController::RUNNING,
  767. GetController(PRIORITY_PREFERENCES)->state());
  768. EXPECT_EQ(DataTypeController::RUNNING, GetController(BOOKMARKS)->state());
  769. // Make BOOKMARKS download fail. PRIORITY_PREFERENCES is still running.
  770. FinishDownload(ModelTypeSet(), ModelTypeSet(BOOKMARKS));
  771. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  772. EXPECT_EQ(DataTypeController::RUNNING,
  773. GetController(PRIORITY_PREFERENCES)->state());
  774. // Finish downloading of PRIORITY_PREFERENCES. This will trigger a
  775. // reconfiguration to disable bookmarks.
  776. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  777. FinishDownload(ModelTypeSet(PRIORITY_PREFERENCES), ModelTypeSet());
  778. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  779. EXPECT_EQ(ModelTypeSet(), last_configure_params().to_download);
  780. EXPECT_EQ(DataTypeController::RUNNING,
  781. GetController(PRIORITY_PREFERENCES)->state());
  782. EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state());
  783. }
  784. TEST_F(SyncDataTypeManagerImplTest, FilterDesiredTypes) {
  785. AddController(BOOKMARKS);
  786. SetConfigureStartExpectation();
  787. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  788. Configure({BOOKMARKS, APPS});
  789. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  790. EXPECT_EQ(AddControlTypesTo(BOOKMARKS), last_configure_params().to_download);
  791. FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet());
  792. dtm_->Stop(ShutdownReason::STOP_SYNC_AND_KEEP_DATA);
  793. EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
  794. }
  795. TEST_F(SyncDataTypeManagerImplTest, FailingPreconditionKeepData) {
  796. AddController(BOOKMARKS);
  797. GetController(BOOKMARKS)->SetPreconditionState(
  798. DataTypeController::PreconditionState::kMustStopAndKeepData);
  799. // Bookmarks is never started due to failing preconditions.
  800. SetConfigureStartExpectation();
  801. SetConfigureDoneExpectation(
  802. DataTypeManager::OK,
  803. BuildStatusTable(ModelTypeSet(), ModelTypeSet(),
  804. /*unready_errors=*/ModelTypeSet(BOOKMARKS)));
  805. Configure(ModelTypeSet(BOOKMARKS));
  806. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  807. EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state());
  808. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  809. EXPECT_EQ(0U, configurer_.connected_types().Size());
  810. observer_.ResetExpectations();
  811. // Bookmarks should start normally now.
  812. GetController(BOOKMARKS)->SetPreconditionState(
  813. DataTypeController::PreconditionState::kPreconditionsMet);
  814. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  815. dtm_->DataTypePreconditionChanged(BOOKMARKS);
  816. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  817. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  818. FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet());
  819. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  820. EXPECT_EQ(1U, configurer_.connected_types().Size());
  821. // Should do nothing.
  822. observer_.ResetExpectations();
  823. dtm_->DataTypePreconditionChanged(BOOKMARKS);
  824. dtm_->Stop(ShutdownReason::STOP_SYNC_AND_KEEP_DATA);
  825. EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
  826. EXPECT_TRUE(configurer_.connected_types().Empty());
  827. }
  828. // Tests that unready types are not started after ResetDataTypeErrors and
  829. // reconfiguration.
  830. TEST_F(SyncDataTypeManagerImplTest, UnreadyTypeResetReconfigure) {
  831. AddController(BOOKMARKS);
  832. GetController(BOOKMARKS)->SetPreconditionState(
  833. DataTypeController::PreconditionState::kMustStopAndKeepData);
  834. // Bookmarks is never started due to failing preconditions.
  835. SetConfigureStartExpectation();
  836. SetConfigureDoneExpectation(
  837. DataTypeManager::OK,
  838. BuildStatusTable(ModelTypeSet(), ModelTypeSet(),
  839. /*unready_errors=*/ModelTypeSet(BOOKMARKS)));
  840. Configure(ModelTypeSet(BOOKMARKS));
  841. // Second Configure sets a flag to perform reconfiguration after the first one
  842. // is done.
  843. Configure(ModelTypeSet(BOOKMARKS));
  844. // Reset errors before triggering reconfiguration.
  845. dtm_->ResetDataTypeErrors();
  846. // Reconfiguration should update unready errors. Bookmarks shouldn't start.
  847. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  848. FinishDownload(ModelTypeSet(), ModelTypeSet()); // regular types
  849. EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state());
  850. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  851. EXPECT_EQ(0U, configurer_.connected_types().Size());
  852. }
  853. TEST_F(SyncDataTypeManagerImplTest, UnreadyTypeLaterReady) {
  854. AddController(BOOKMARKS);
  855. GetController(BOOKMARKS)->SetPreconditionState(
  856. DataTypeController::PreconditionState::kMustStopAndKeepData);
  857. // Bookmarks is never started due to failing preconditions.
  858. SetConfigureStartExpectation();
  859. SetConfigureDoneExpectation(
  860. DataTypeManager::OK,
  861. BuildStatusTable(ModelTypeSet(), ModelTypeSet(),
  862. /*unready_errors=*/ModelTypeSet(BOOKMARKS)));
  863. Configure(ModelTypeSet(BOOKMARKS));
  864. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  865. ASSERT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state());
  866. ASSERT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  867. ASSERT_EQ(0U, configurer_.connected_types().Size());
  868. // Bookmarks should start normally now.
  869. GetController(BOOKMARKS)->SetPreconditionState(
  870. DataTypeController::PreconditionState::kPreconditionsMet);
  871. dtm_->DataTypePreconditionChanged(BOOKMARKS);
  872. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  873. EXPECT_NE(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state());
  874. // Set the expectations for the reconfiguration - no unready errors now.
  875. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  876. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  877. FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet());
  878. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  879. EXPECT_EQ(1U, configurer_.connected_types().Size());
  880. }
  881. TEST_F(SyncDataTypeManagerImplTest,
  882. MultipleUnreadyTypesLaterReadyAtTheSameTime) {
  883. AddController(BOOKMARKS);
  884. AddController(PREFERENCES);
  885. GetController(BOOKMARKS)->SetPreconditionState(
  886. DataTypeController::PreconditionState::kMustStopAndKeepData);
  887. GetController(PREFERENCES)
  888. ->SetPreconditionState(
  889. DataTypeController::PreconditionState::kMustStopAndKeepData);
  890. // Both types are never started due to failing preconditions.
  891. SetConfigureStartExpectation();
  892. SetConfigureDoneExpectation(
  893. DataTypeManager::OK,
  894. BuildStatusTable(
  895. ModelTypeSet(), ModelTypeSet(),
  896. /*unready_errors=*/ModelTypeSet(BOOKMARKS, PREFERENCES)));
  897. Configure(ModelTypeSet(BOOKMARKS, PREFERENCES));
  898. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  899. ASSERT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state());
  900. ASSERT_EQ(DataTypeController::NOT_RUNNING,
  901. GetController(PREFERENCES)->state());
  902. ASSERT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  903. ASSERT_EQ(0U, configurer_.connected_types().Size());
  904. // Both types should start normally now.
  905. GetController(BOOKMARKS)->SetPreconditionState(
  906. DataTypeController::PreconditionState::kPreconditionsMet);
  907. GetController(PREFERENCES)
  908. ->SetPreconditionState(
  909. DataTypeController::PreconditionState::kPreconditionsMet);
  910. // Just triggering state change for one of them causes reconfiguration for all
  911. // that are ready to start (which is both BOOKMARKS and PREFERENCES).
  912. dtm_->DataTypePreconditionChanged(BOOKMARKS);
  913. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  914. EXPECT_NE(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state());
  915. EXPECT_NE(DataTypeController::NOT_RUNNING,
  916. GetController(PREFERENCES)->state());
  917. // Set new expectations for the reconfiguration - no unready errors any more.
  918. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  919. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  920. FinishDownload(ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet());
  921. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  922. EXPECT_EQ(2U, configurer_.connected_types().Size());
  923. }
  924. TEST_F(SyncDataTypeManagerImplTest, MultipleUnreadyTypesLaterOneOfThemReady) {
  925. AddController(BOOKMARKS);
  926. AddController(PREFERENCES);
  927. GetController(BOOKMARKS)->SetPreconditionState(
  928. DataTypeController::PreconditionState::kMustStopAndKeepData);
  929. GetController(PREFERENCES)
  930. ->SetPreconditionState(
  931. DataTypeController::PreconditionState::kMustStopAndKeepData);
  932. // Both types are never started due to failing preconditions.
  933. SetConfigureStartExpectation();
  934. SetConfigureDoneExpectation(
  935. DataTypeManager::OK,
  936. BuildStatusTable(
  937. ModelTypeSet(), ModelTypeSet(),
  938. /*unready_errors=*/ModelTypeSet(BOOKMARKS, PREFERENCES)));
  939. Configure(ModelTypeSet(BOOKMARKS, PREFERENCES));
  940. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  941. ASSERT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state());
  942. ASSERT_EQ(DataTypeController::NOT_RUNNING,
  943. GetController(PREFERENCES)->state());
  944. ASSERT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  945. ASSERT_EQ(0U, configurer_.connected_types().Size());
  946. // Bookmarks should start normally now. Preferences should still not start.
  947. GetController(BOOKMARKS)->SetPreconditionState(
  948. DataTypeController::PreconditionState::kPreconditionsMet);
  949. dtm_->DataTypePreconditionChanged(BOOKMARKS);
  950. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  951. EXPECT_NE(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state());
  952. EXPECT_EQ(DataTypeController::NOT_RUNNING,
  953. GetController(PREFERENCES)->state());
  954. // Set the expectations for the reconfiguration - just prefs are unready now.
  955. SetConfigureDoneExpectation(
  956. DataTypeManager::OK,
  957. BuildStatusTable(ModelTypeSet(), ModelTypeSet(),
  958. /*unready_errors=*/ModelTypeSet(PREFERENCES)));
  959. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  960. FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet());
  961. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  962. EXPECT_EQ(1U, configurer_.connected_types().Size());
  963. }
  964. TEST_F(SyncDataTypeManagerImplTest,
  965. NoOpDataTypePreconditionChangedWhileStillUnready) {
  966. AddController(BOOKMARKS);
  967. GetController(BOOKMARKS)->SetPreconditionState(
  968. DataTypeController::PreconditionState::kMustStopAndKeepData);
  969. // Bookmarks is never started due to failing preconditions.
  970. SetConfigureStartExpectation();
  971. SetConfigureDoneExpectation(
  972. DataTypeManager::OK,
  973. BuildStatusTable(ModelTypeSet(), ModelTypeSet(),
  974. /*unready_errors=*/ModelTypeSet(BOOKMARKS)));
  975. Configure(ModelTypeSet(BOOKMARKS));
  976. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  977. ASSERT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state());
  978. ASSERT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  979. ASSERT_EQ(0U, configurer_.connected_types().Size());
  980. // Bookmarks is still unready so DataTypePreconditionChanged() should be
  981. // ignored.
  982. dtm_->DataTypePreconditionChanged(BOOKMARKS);
  983. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  984. EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state());
  985. }
  986. TEST_F(SyncDataTypeManagerImplTest,
  987. NoOpDataTypePreconditionChangedWhileStillReady) {
  988. AddController(BOOKMARKS);
  989. SetConfigureStartExpectation();
  990. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  991. Configure(ModelTypeSet(BOOKMARKS));
  992. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  993. FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet());
  994. ASSERT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  995. ASSERT_EQ(DataTypeController::RUNNING, GetController(BOOKMARKS)->state());
  996. // Bookmarks is still ready so DataTypePreconditionChanged() should be
  997. // ignored.
  998. dtm_->DataTypePreconditionChanged(BOOKMARKS);
  999. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  1000. EXPECT_EQ(DataTypeController::RUNNING, GetController(BOOKMARKS)->state());
  1001. }
  1002. TEST_F(SyncDataTypeManagerImplTest, ModelLoadError) {
  1003. AddController(BOOKMARKS);
  1004. GetController(BOOKMARKS)->model()->SimulateModelError(
  1005. ModelError(FROM_HERE, "test error"));
  1006. // Bookmarks is never started due to hitting a model load error.
  1007. SetConfigureStartExpectation();
  1008. SetConfigureDoneExpectation(
  1009. DataTypeManager::OK,
  1010. BuildStatusTable(ModelTypeSet(),
  1011. /*datatype_errors=*/ModelTypeSet(BOOKMARKS),
  1012. ModelTypeSet()));
  1013. Configure(ModelTypeSet(BOOKMARKS));
  1014. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  1015. // No need to finish the download of BOOKMARKS since it was never started.
  1016. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  1017. EXPECT_EQ(DataTypeController::FAILED, GetController(BOOKMARKS)->state());
  1018. EXPECT_EQ(0U, configurer_.connected_types().Size());
  1019. }
  1020. // Checks that DTM handles the case when a controller is already in a FAILED
  1021. // state at the time the DTM is created. Regression test for crbug.com/967344.
  1022. TEST_F(SyncDataTypeManagerImplTest, ErrorBeforeStartup) {
  1023. AddController(BOOKMARKS);
  1024. AddController(PREFERENCES);
  1025. // Produce an error (FAILED) state in the BOOKMARKS controller.
  1026. GetController(BOOKMARKS)->model()->SimulateModelError(
  1027. ModelError(FROM_HERE, "test error"));
  1028. SetConfigureStartExpectation();
  1029. Configure({BOOKMARKS});
  1030. ASSERT_EQ(GetController(BOOKMARKS)->state(), DataTypeController::FAILED);
  1031. // Now create a fresh DTM, simulating a Sync restart.
  1032. RecreateDataTypeManager();
  1033. ASSERT_EQ(GetController(BOOKMARKS)->state(), DataTypeController::FAILED);
  1034. // Now a configuration attempt for both types should complete successfully,
  1035. // but exclude the failed type.
  1036. SetConfigureStartExpectation();
  1037. Configure({BOOKMARKS, PREFERENCES});
  1038. SetConfigureDoneExpectation(DataTypeManager::OK,
  1039. BuildStatusTable(/*crypto_errors=*/{},
  1040. /*datatype_errors=*/{BOOKMARKS},
  1041. /*unready_errors=*/{}));
  1042. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  1043. FinishDownload(ModelTypeSet(PREFERENCES), ModelTypeSet());
  1044. EXPECT_TRUE(dtm_->GetActiveDataTypes().Has(PREFERENCES));
  1045. EXPECT_FALSE(dtm_->GetActiveDataTypes().Has(BOOKMARKS));
  1046. }
  1047. // Test that sync configures properly if all types are already downloaded.
  1048. TEST_F(SyncDataTypeManagerImplTest, AllTypesReady) {
  1049. AddController(PRIORITY_PREFERENCES);
  1050. AddController(BOOKMARKS);
  1051. // Mark both types as already downloaded.
  1052. sync_pb::ModelTypeState already_downloaded;
  1053. already_downloaded.set_initial_sync_done(true);
  1054. GetController(PRIORITY_PREFERENCES)
  1055. ->model()
  1056. ->SetModelTypeStateForActivationResponse(already_downloaded);
  1057. GetController(BOOKMARKS)->model()->SetModelTypeStateForActivationResponse(
  1058. already_downloaded);
  1059. SetConfigureStartExpectation();
  1060. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  1061. Configure(ModelTypeSet(PRIORITY_PREFERENCES, BOOKMARKS));
  1062. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  1063. // This started the configuration of control types, which aren't tracked by
  1064. // DataTypeManagerImpl, so always considered already downloaded.
  1065. ASSERT_EQ(1, configurer_.configure_call_count());
  1066. EXPECT_TRUE(last_configure_params().to_download.Empty());
  1067. EXPECT_EQ(DataTypeController::RUNNING,
  1068. GetController(PRIORITY_PREFERENCES)->state());
  1069. EXPECT_EQ(DataTypeController::RUNNING, GetController(BOOKMARKS)->state());
  1070. // Finish downloading (configuring, really) control types.
  1071. FinishDownload(ModelTypeSet(), ModelTypeSet());
  1072. // This started the configuration of priority types, i.e.
  1073. // PRIORITY_PREFERENCES, which is already downloaded.
  1074. ASSERT_EQ(2, configurer_.configure_call_count());
  1075. EXPECT_TRUE(last_configure_params().to_download.Empty());
  1076. // Finish downloading (configuring, really) priority types.
  1077. FinishDownload(ModelTypeSet(PRIORITY_PREFERENCES), ModelTypeSet());
  1078. // This started the configuration of regular types, i.e. BOOKMARKS, which is
  1079. // already downloaded.
  1080. ASSERT_EQ(3, configurer_.configure_call_count());
  1081. EXPECT_TRUE(last_configure_params().to_download.Empty());
  1082. EXPECT_EQ(DataTypeController::RUNNING, GetController(BOOKMARKS)->state());
  1083. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  1084. // Finish downloading (configuring, really) regular types. This finishes the
  1085. // configuration.
  1086. FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet());
  1087. ASSERT_EQ(3, configurer_.configure_call_count()); // Not increased.
  1088. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  1089. EXPECT_EQ(2U, configurer_.connected_types().Size());
  1090. EXPECT_TRUE(dtm_->GetActiveProxyDataTypes().Empty());
  1091. dtm_->Stop(ShutdownReason::STOP_SYNC_AND_KEEP_DATA);
  1092. EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
  1093. EXPECT_TRUE(configurer_.connected_types().Empty());
  1094. }
  1095. // Test that DataTypeManagerImpl delays configuration until all data types
  1096. // loaded their models.
  1097. TEST_F(SyncDataTypeManagerImplTest, DelayConfigureForUSSTypes) {
  1098. AddController(BOOKMARKS);
  1099. GetController(BOOKMARKS)->model()->EnableManualModelStart();
  1100. SetConfigureStartExpectation();
  1101. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  1102. Configure(ModelTypeSet(BOOKMARKS));
  1103. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  1104. // Bookmarks model isn't loaded yet and it is required to complete before
  1105. // call to configure. Ensure that configure wasn't called.
  1106. EXPECT_EQ(0, configurer_.configure_call_count());
  1107. EXPECT_EQ(0, GetController(BOOKMARKS)->activate_call_count());
  1108. // Finishing model load should trigger configure.
  1109. GetController(BOOKMARKS)->model()->SimulateModelStartFinished();
  1110. EXPECT_EQ(1, configurer_.configure_call_count());
  1111. EXPECT_EQ(1, GetController(BOOKMARKS)->activate_call_count());
  1112. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  1113. FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet());
  1114. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  1115. EXPECT_EQ(1U, configurer_.connected_types().Size());
  1116. }
  1117. // Test that when encryption fails for a given type, the corresponding
  1118. // data type is not activated.
  1119. TEST_F(SyncDataTypeManagerImplTest, ConnectDataTypeOnEncryptionError) {
  1120. AddController(BOOKMARKS);
  1121. AddController(PASSWORDS);
  1122. GetController(BOOKMARKS)->model()->EnableManualModelStart();
  1123. GetController(PASSWORDS)->model()->EnableManualModelStart();
  1124. SetConfigureStartExpectation();
  1125. FailEncryptionFor(ModelTypeSet(BOOKMARKS));
  1126. Configure(ModelTypeSet(BOOKMARKS, PASSWORDS));
  1127. EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  1128. EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state());
  1129. EXPECT_EQ(DataTypeController::MODEL_STARTING,
  1130. GetController(PASSWORDS)->state());
  1131. EXPECT_EQ(0, GetController(BOOKMARKS)->activate_call_count());
  1132. EXPECT_EQ(0, GetController(PASSWORDS)->activate_call_count());
  1133. GetController(PASSWORDS)->model()->SimulateModelStartFinished();
  1134. EXPECT_EQ(0, GetController(BOOKMARKS)->activate_call_count());
  1135. EXPECT_EQ(1, GetController(PASSWORDS)->activate_call_count());
  1136. }
  1137. // Test that Connect is not called for datatypes that failed
  1138. // LoadModels().
  1139. TEST_F(SyncDataTypeManagerImplTest, ConnectDataTypeAfterLoadModelsError) {
  1140. // Initiate configuration for two datatypes but block them at LoadModels.
  1141. AddController(BOOKMARKS);
  1142. AddController(PASSWORDS);
  1143. GetController(BOOKMARKS)->model()->EnableManualModelStart();
  1144. GetController(PASSWORDS)->model()->EnableManualModelStart();
  1145. SetConfigureStartExpectation();
  1146. Configure(ModelTypeSet(BOOKMARKS, PASSWORDS));
  1147. EXPECT_EQ(DataTypeController::MODEL_STARTING,
  1148. GetController(BOOKMARKS)->state());
  1149. EXPECT_EQ(DataTypeController::MODEL_STARTING,
  1150. GetController(PASSWORDS)->state());
  1151. // Make bookmarks fail LoadModels. Passwords load normally.
  1152. GetController(BOOKMARKS)->model()->SimulateModelError(
  1153. ModelError(FROM_HERE, "test error"));
  1154. GetController(PASSWORDS)->model()->SimulateModelStartFinished();
  1155. // Connect should be called for passwords, but not bookmarks.
  1156. EXPECT_EQ(0, GetController(BOOKMARKS)->activate_call_count());
  1157. EXPECT_EQ(1, GetController(PASSWORDS)->activate_call_count());
  1158. }
  1159. // Test that Stop with DISABLE_SYNC_AND_CLEAR_DATA calls DTC Stop with
  1160. // CLEAR_METADATA for active data types.
  1161. TEST_F(SyncDataTypeManagerImplTest, StopWithDisableSync) {
  1162. AddController(BOOKMARKS);
  1163. SetConfigureStartExpectation();
  1164. SetConfigureDoneExpectation(DataTypeManager::ABORTED, DataTypeStatusTable());
  1165. Configure(ModelTypeSet(BOOKMARKS));
  1166. EXPECT_EQ(DataTypeController::RUNNING, GetController(BOOKMARKS)->state());
  1167. dtm_->Stop(ShutdownReason::DISABLE_SYNC_AND_CLEAR_DATA);
  1168. EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
  1169. EXPECT_TRUE(configurer_.connected_types().Empty());
  1170. EXPECT_EQ(1, GetController(BOOKMARKS)->model()->clear_metadata_call_count());
  1171. }
  1172. TEST_F(SyncDataTypeManagerImplTest, PurgeDataOnStartingPersistent) {
  1173. AddController(BOOKMARKS);
  1174. AddController(AUTOFILL_WALLET_DATA);
  1175. // Configure as usual.
  1176. SetConfigureStartExpectation();
  1177. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  1178. Configure(ModelTypeSet(BOOKMARKS, AUTOFILL_WALLET_DATA), SyncMode::kFull);
  1179. ASSERT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  1180. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  1181. FinishDownload(ModelTypeSet(BOOKMARKS, AUTOFILL_WALLET_DATA), ModelTypeSet());
  1182. ASSERT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  1183. ASSERT_EQ(2U, configurer_.connected_types().Size());
  1184. // The user temporarily turns off Sync.
  1185. dtm_->Stop(ShutdownReason::STOP_SYNC_AND_KEEP_DATA);
  1186. ASSERT_EQ(DataTypeManager::STOPPED, dtm_->state());
  1187. ASSERT_TRUE(configurer_.connected_types().Empty());
  1188. ASSERT_EQ(0, GetController(BOOKMARKS)->model()->clear_metadata_call_count());
  1189. // Now we restart with a reduced set of data types.
  1190. SetConfigureStartExpectation();
  1191. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  1192. Configure(ModelTypeSet(AUTOFILL_WALLET_DATA), SyncMode::kFull);
  1193. ASSERT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  1194. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  1195. FinishDownload(ModelTypeSet(AUTOFILL_WALLET_DATA), ModelTypeSet());
  1196. ASSERT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  1197. ASSERT_EQ(1U, configurer_.connected_types().Size());
  1198. // This should have purged the data for the excluded type.
  1199. EXPECT_TRUE(last_configure_params().to_purge.Has(BOOKMARKS));
  1200. // Stop(CLEAR_METADATA) has *not* been called on the controller though; that
  1201. // happens only when stopping or reconfiguring, not when (re)starting without
  1202. // the type.
  1203. EXPECT_EQ(0, GetController(BOOKMARKS)->model()->clear_metadata_call_count());
  1204. }
  1205. TEST_F(SyncDataTypeManagerImplTest, DontPurgeDataOnStartingEphemeral) {
  1206. AddController(BOOKMARKS);
  1207. controllers_[AUTOFILL_WALLET_DATA] = std::make_unique<FakeDataTypeController>(
  1208. AUTOFILL_WALLET_DATA,
  1209. /*enable_transport_only_model=*/true);
  1210. // Configure as usual.
  1211. SetConfigureStartExpectation();
  1212. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  1213. Configure(ModelTypeSet(BOOKMARKS, AUTOFILL_WALLET_DATA), SyncMode::kFull);
  1214. ASSERT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  1215. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  1216. FinishDownload(ModelTypeSet(BOOKMARKS, AUTOFILL_WALLET_DATA), ModelTypeSet());
  1217. ASSERT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  1218. ASSERT_EQ(2U, configurer_.connected_types().Size());
  1219. // The user temporarily turns off Sync.
  1220. dtm_->Stop(ShutdownReason::STOP_SYNC_AND_KEEP_DATA);
  1221. ASSERT_EQ(DataTypeManager::STOPPED, dtm_->state());
  1222. ASSERT_TRUE(configurer_.connected_types().Empty());
  1223. ASSERT_EQ(0, GetController(BOOKMARKS)->model()->clear_metadata_call_count());
  1224. // Now we restart in ephemeral mode, with a reduced set of data types.
  1225. SetConfigureStartExpectation();
  1226. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  1227. Configure(ModelTypeSet(AUTOFILL_WALLET_DATA), SyncMode::kTransportOnly);
  1228. ASSERT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  1229. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  1230. FinishDownload(ModelTypeSet(AUTOFILL_WALLET_DATA), ModelTypeSet());
  1231. ASSERT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  1232. ASSERT_EQ(1U, configurer_.connected_types().Size());
  1233. // This should *not* have purged the data for the excluded type.
  1234. EXPECT_TRUE(last_configure_params().to_purge.Empty());
  1235. EXPECT_EQ(0, GetController(BOOKMARKS)->model()->clear_metadata_call_count());
  1236. }
  1237. TEST_F(SyncDataTypeManagerImplTest, PurgeDataOnReconfiguringPersistent) {
  1238. AddController(BOOKMARKS);
  1239. controllers_[AUTOFILL_WALLET_DATA] = std::make_unique<FakeDataTypeController>(
  1240. AUTOFILL_WALLET_DATA,
  1241. /*enable_transport_only_model=*/true);
  1242. // Configure as usual.
  1243. SetConfigureStartExpectation();
  1244. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  1245. Configure(ModelTypeSet(BOOKMARKS, AUTOFILL_WALLET_DATA), SyncMode::kFull);
  1246. ASSERT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  1247. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  1248. FinishDownload(ModelTypeSet(BOOKMARKS, AUTOFILL_WALLET_DATA), ModelTypeSet());
  1249. ASSERT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  1250. ASSERT_EQ(2U, configurer_.connected_types().Size());
  1251. // Now we reconfigure with a reduced set of data types.
  1252. SetConfigureStartExpectation();
  1253. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  1254. Configure(ModelTypeSet(AUTOFILL_WALLET_DATA), SyncMode::kFull);
  1255. ASSERT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  1256. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  1257. FinishDownload(ModelTypeSet(AUTOFILL_WALLET_DATA), ModelTypeSet());
  1258. ASSERT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  1259. ASSERT_EQ(1U, configurer_.connected_types().Size());
  1260. // This should have purged the data for the excluded type.
  1261. EXPECT_TRUE(last_configure_params().to_purge.Has(BOOKMARKS));
  1262. // Also Stop(CLEAR_METADATA) has been called on the controller since the type
  1263. // is no longer enabled.
  1264. EXPECT_EQ(1, GetController(BOOKMARKS)->model()->clear_metadata_call_count());
  1265. }
  1266. TEST_F(SyncDataTypeManagerImplTest, DontPurgeDataOnReconfiguringEphemeral) {
  1267. AddController(BOOKMARKS);
  1268. controllers_[AUTOFILL_WALLET_DATA] = std::make_unique<FakeDataTypeController>(
  1269. AUTOFILL_WALLET_DATA,
  1270. /*enable_transport_only_model=*/true);
  1271. // Configure as usual.
  1272. SetConfigureStartExpectation();
  1273. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  1274. Configure(ModelTypeSet(BOOKMARKS, AUTOFILL_WALLET_DATA), SyncMode::kFull);
  1275. ASSERT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  1276. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  1277. FinishDownload(ModelTypeSet(BOOKMARKS, AUTOFILL_WALLET_DATA), ModelTypeSet());
  1278. ASSERT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  1279. ASSERT_EQ(2U, configurer_.connected_types().Size());
  1280. // Now we reconfigure into ephemeral mode, with a reduced set of data types.
  1281. SetConfigureStartExpectation();
  1282. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  1283. Configure(ModelTypeSet(AUTOFILL_WALLET_DATA), SyncMode::kTransportOnly);
  1284. ASSERT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  1285. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  1286. FinishDownload(ModelTypeSet(AUTOFILL_WALLET_DATA), ModelTypeSet());
  1287. ASSERT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  1288. ASSERT_EQ(1U, configurer_.connected_types().Size());
  1289. // This should *not* have cleared the data for the excluded type.
  1290. EXPECT_TRUE(last_configure_params().to_purge.Empty());
  1291. EXPECT_EQ(0, GetController(BOOKMARKS)->model()->clear_metadata_call_count());
  1292. }
  1293. TEST_F(SyncDataTypeManagerImplTest, ShouldRecordInitialConfigureTimeHistogram) {
  1294. base::HistogramTester histogram_tester;
  1295. AddController(BOOKMARKS);
  1296. // Configure as first sync.
  1297. SetConfigureStartExpectation();
  1298. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  1299. Configure(ModelTypeSet(BOOKMARKS), SyncMode::kFull,
  1300. CONFIGURE_REASON_NEW_CLIENT);
  1301. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  1302. FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet());
  1303. histogram_tester.ExpectTotalCount("Sync.ConfigureTime_Initial.OK", 1);
  1304. }
  1305. TEST_F(SyncDataTypeManagerImplTest,
  1306. ShouldRecordSubsequentConfigureTimeHistogram) {
  1307. base::HistogramTester histogram_tester;
  1308. AddController(BOOKMARKS);
  1309. // Configure as subsequent sync.
  1310. SetConfigureStartExpectation();
  1311. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  1312. Configure(ModelTypeSet(BOOKMARKS), SyncMode::kFull,
  1313. CONFIGURE_REASON_RECONFIGURATION);
  1314. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  1315. FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet());
  1316. histogram_tester.ExpectTotalCount("Sync.ConfigureTime_Subsequent.OK", 1);
  1317. }
  1318. // Regression test for crbug.com/1286204: Reentrant calls to Configure()
  1319. // shouldn't crash (or trigger DCHECKs).
  1320. TEST_F(SyncDataTypeManagerImplTest, ReentrantConfigure) {
  1321. AddController(PREFERENCES);
  1322. AddController(BOOKMARKS);
  1323. // The DataTypeManagerObserver::OnConfigureStart() call may, in some cases,
  1324. // result in a reentrant call to Configure().
  1325. SetConfigureStartExpectation(base::BindLambdaForTesting(
  1326. [&]() { Configure(ModelTypeSet(PREFERENCES)); }));
  1327. Configure(ModelTypeSet(PREFERENCES, BOOKMARKS));
  1328. // Implicit expectation: No crash here!
  1329. // Eventually, the second (reentrant) Configure() call should win, i.e. here
  1330. // only PREFERENCES gets configured.
  1331. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  1332. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  1333. FinishDownload(ModelTypeSet(PREFERENCES), ModelTypeSet());
  1334. EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  1335. EXPECT_EQ(1U, configurer_.connected_types().Size());
  1336. }
  1337. TEST_F(SyncDataTypeManagerImplTest, ProvideDebugInfo) {
  1338. AddController(PREFERENCES);
  1339. AddController(BOOKMARKS);
  1340. // Mark BOOKMARKS as already downloaded.
  1341. sync_pb::ModelTypeState bookmarks_state;
  1342. bookmarks_state.set_initial_sync_done(true);
  1343. GetController(BOOKMARKS)->model()->SetModelTypeStateForActivationResponse(
  1344. bookmarks_state);
  1345. SetConfigureStartExpectation();
  1346. SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable());
  1347. Configure(ModelTypeSet(PREFERENCES, BOOKMARKS));
  1348. ASSERT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
  1349. // Because Bookmarks are already downloaded, configuration finishes as soon
  1350. // as preferences are downloaded.
  1351. FinishDownload(ModelTypeSet(), ModelTypeSet()); // control types
  1352. FinishDownload(ModelTypeSet(PREFERENCES), ModelTypeSet());
  1353. ASSERT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
  1354. }
  1355. } // namespace syncer