get_updates_processor_unittest.cc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  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/engine/get_updates_processor.h"
  5. #include <stdint.h>
  6. #include <memory>
  7. #include <set>
  8. #include <string>
  9. #include <utility>
  10. #include "base/memory/raw_ptr.h"
  11. #include "base/time/time.h"
  12. #include "components/sync/base/model_type_test_util.h"
  13. #include "components/sync/engine/cycle/debug_info_getter.h"
  14. #include "components/sync/engine/cycle/mock_debug_info_getter.h"
  15. #include "components/sync/engine/cycle/nudge_tracker.h"
  16. #include "components/sync/engine/cycle/status_controller.h"
  17. #include "components/sync/engine/get_updates_delegate.h"
  18. #include "components/sync/engine/update_handler.h"
  19. #include "components/sync/protocol/data_type_progress_marker.pb.h"
  20. #include "components/sync/test/mock_invalidation.h"
  21. #include "components/sync/test/mock_update_handler.h"
  22. #include "testing/gtest/include/gtest/gtest.h"
  23. namespace syncer {
  24. namespace {
  25. std::unique_ptr<SyncInvalidation> BuildInvalidation(
  26. int64_t version,
  27. const std::string& payload) {
  28. return MockInvalidation::Build(version, payload);
  29. }
  30. } // namespace
  31. // A test fixture for tests exercising download updates functions.
  32. class GetUpdatesProcessorTest : public ::testing::Test {
  33. public:
  34. GetUpdatesProcessorTest() = default;
  35. GetUpdatesProcessorTest(const GetUpdatesProcessorTest&) = delete;
  36. GetUpdatesProcessorTest& operator=(const GetUpdatesProcessorTest&) = delete;
  37. void SetUp() override {
  38. AddUpdateHandler(AUTOFILL);
  39. AddUpdateHandler(BOOKMARKS);
  40. AddUpdateHandler(PREFERENCES);
  41. }
  42. ModelTypeSet enabled_types() { return enabled_types_; }
  43. std::unique_ptr<GetUpdatesProcessor> BuildGetUpdatesProcessor(
  44. const GetUpdatesDelegate& delegate) {
  45. return std::make_unique<GetUpdatesProcessor>(&update_handler_map_,
  46. delegate);
  47. }
  48. void InitFakeUpdateResponse(sync_pb::GetUpdatesResponse* response) {
  49. ModelTypeSet types = enabled_types();
  50. for (ModelType type : types) {
  51. sync_pb::DataTypeProgressMarker* marker =
  52. response->add_new_progress_marker();
  53. marker->set_data_type_id(GetSpecificsFieldNumberFromModelType(type));
  54. marker->set_token("foobarbaz");
  55. sync_pb::DataTypeContext* context = response->add_context_mutations();
  56. context->set_data_type_id(GetSpecificsFieldNumberFromModelType(type));
  57. context->set_version(1);
  58. context->set_context("context");
  59. }
  60. response->set_changes_remaining(0);
  61. }
  62. MockUpdateHandler* AddUpdateHandler(ModelType type) {
  63. enabled_types_.Put(type);
  64. std::unique_ptr<MockUpdateHandler> handler =
  65. std::make_unique<MockUpdateHandler>(type);
  66. MockUpdateHandler* handler_ptr = handler.get();
  67. update_handler_map_.insert(std::make_pair(type, handler_ptr));
  68. update_handlers_.insert(std::move(handler));
  69. return handler_ptr;
  70. }
  71. const base::TimeTicks kTestStartTime = base::TimeTicks::Now();
  72. private:
  73. ModelTypeSet enabled_types_;
  74. std::set<std::unique_ptr<MockUpdateHandler>> update_handlers_;
  75. UpdateHandlerMap update_handler_map_;
  76. std::unique_ptr<GetUpdatesProcessor> get_updates_processor_;
  77. };
  78. // Basic test to make sure nudges are expressed properly in the request.
  79. TEST_F(GetUpdatesProcessorTest, BookmarkNudge) {
  80. NudgeTracker nudge_tracker;
  81. nudge_tracker.RecordLocalChange(BOOKMARKS);
  82. sync_pb::ClientToServerMessage message;
  83. NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
  84. std::unique_ptr<GetUpdatesProcessor> processor(
  85. BuildGetUpdatesProcessor(normal_delegate));
  86. processor->PrepareGetUpdates(enabled_types(), &message);
  87. const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
  88. EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::UNKNOWN,
  89. gu_msg.caller_info().source());
  90. EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, gu_msg.get_updates_origin());
  91. for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
  92. ModelType type = GetModelTypeFromSpecificsFieldNumber(
  93. gu_msg.from_progress_marker(i).data_type_id());
  94. const sync_pb::DataTypeProgressMarker& progress_marker =
  95. gu_msg.from_progress_marker(i);
  96. const sync_pb::GetUpdateTriggers& gu_trigger =
  97. progress_marker.get_update_triggers();
  98. // We perform some basic tests of GU trigger and source fields here. The
  99. // more complicated scenarios are tested by the NudgeTracker tests.
  100. if (type == BOOKMARKS) {
  101. EXPECT_EQ(1, gu_trigger.local_modification_nudges());
  102. EXPECT_EQ(0, gu_trigger.datatype_refresh_nudges());
  103. } else {
  104. EXPECT_EQ(0, gu_trigger.local_modification_nudges());
  105. EXPECT_EQ(0, gu_trigger.datatype_refresh_nudges());
  106. }
  107. }
  108. }
  109. // Basic test to ensure invalidation payloads are expressed in the request.
  110. TEST_F(GetUpdatesProcessorTest, NotifyMany) {
  111. NudgeTracker nudge_tracker;
  112. nudge_tracker.RecordRemoteInvalidation(
  113. AUTOFILL, BuildInvalidation(1, "autofill_payload"));
  114. nudge_tracker.RecordRemoteInvalidation(
  115. BOOKMARKS, BuildInvalidation(1, "bookmark_payload"));
  116. nudge_tracker.RecordRemoteInvalidation(
  117. PREFERENCES, BuildInvalidation(1, "preferences_payload"));
  118. ModelTypeSet notified_types;
  119. notified_types.Put(AUTOFILL);
  120. notified_types.Put(BOOKMARKS);
  121. notified_types.Put(PREFERENCES);
  122. sync_pb::ClientToServerMessage message;
  123. NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
  124. std::unique_ptr<GetUpdatesProcessor> processor(
  125. BuildGetUpdatesProcessor(normal_delegate));
  126. processor->PrepareGetUpdates(enabled_types(), &message);
  127. const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
  128. EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::UNKNOWN,
  129. gu_msg.caller_info().source());
  130. EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, gu_msg.get_updates_origin());
  131. for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
  132. ModelType type = GetModelTypeFromSpecificsFieldNumber(
  133. gu_msg.from_progress_marker(i).data_type_id());
  134. const sync_pb::DataTypeProgressMarker& progress_marker =
  135. gu_msg.from_progress_marker(i);
  136. const sync_pb::GetUpdateTriggers& gu_trigger =
  137. progress_marker.get_update_triggers();
  138. // We perform some basic tests of GU trigger and source fields here. The
  139. // more complicated scenarios are tested by the NudgeTracker tests.
  140. if (notified_types.Has(type)) {
  141. EXPECT_EQ(1, gu_trigger.notification_hint_size());
  142. } else {
  143. EXPECT_EQ(0, gu_trigger.notification_hint_size());
  144. }
  145. }
  146. }
  147. // Basic test to ensure initial sync requests are expressed in the request.
  148. TEST_F(GetUpdatesProcessorTest, InitialSyncRequest) {
  149. NudgeTracker nudge_tracker;
  150. nudge_tracker.RecordInitialSyncRequired(AUTOFILL);
  151. nudge_tracker.RecordInitialSyncRequired(PREFERENCES);
  152. ModelTypeSet initial_sync_types = ModelTypeSet(AUTOFILL, PREFERENCES);
  153. sync_pb::ClientToServerMessage message;
  154. NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
  155. std::unique_ptr<GetUpdatesProcessor> processor(
  156. BuildGetUpdatesProcessor(normal_delegate));
  157. processor->PrepareGetUpdates(enabled_types(), &message);
  158. const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
  159. EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::UNKNOWN,
  160. gu_msg.caller_info().source());
  161. EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, gu_msg.get_updates_origin());
  162. for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
  163. ModelType type = GetModelTypeFromSpecificsFieldNumber(
  164. gu_msg.from_progress_marker(i).data_type_id());
  165. const sync_pb::DataTypeProgressMarker& progress_marker =
  166. gu_msg.from_progress_marker(i);
  167. const sync_pb::GetUpdateTriggers& gu_trigger =
  168. progress_marker.get_update_triggers();
  169. // We perform some basic tests of GU trigger and source fields here. The
  170. // more complicated scenarios are tested by the NudgeTracker tests.
  171. if (initial_sync_types.Has(type)) {
  172. EXPECT_TRUE(gu_trigger.initial_sync_in_progress());
  173. } else {
  174. EXPECT_TRUE(gu_trigger.has_initial_sync_in_progress());
  175. EXPECT_FALSE(gu_trigger.initial_sync_in_progress());
  176. }
  177. }
  178. }
  179. TEST_F(GetUpdatesProcessorTest, ConfigureTest) {
  180. sync_pb::ClientToServerMessage message;
  181. ConfigureGetUpdatesDelegate configure_delegate(
  182. sync_pb::SyncEnums::RECONFIGURATION);
  183. std::unique_ptr<GetUpdatesProcessor> processor(
  184. BuildGetUpdatesProcessor(configure_delegate));
  185. processor->PrepareGetUpdates(enabled_types(), &message);
  186. const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
  187. EXPECT_EQ(sync_pb::SyncEnums::RECONFIGURATION, gu_msg.get_updates_origin());
  188. EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::UNKNOWN,
  189. gu_msg.caller_info().source());
  190. ModelTypeSet progress_types;
  191. for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
  192. ModelType type = GetModelTypeFromSpecificsFieldNumber(
  193. gu_msg.from_progress_marker(i).data_type_id());
  194. progress_types.Put(type);
  195. }
  196. EXPECT_EQ(enabled_types(), progress_types);
  197. }
  198. TEST_F(GetUpdatesProcessorTest, PollTest) {
  199. sync_pb::ClientToServerMessage message;
  200. PollGetUpdatesDelegate poll_delegate;
  201. std::unique_ptr<GetUpdatesProcessor> processor(
  202. BuildGetUpdatesProcessor(poll_delegate));
  203. processor->PrepareGetUpdates(enabled_types(), &message);
  204. const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
  205. EXPECT_EQ(sync_pb::SyncEnums::PERIODIC, gu_msg.get_updates_origin());
  206. EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::UNKNOWN,
  207. gu_msg.caller_info().source());
  208. ModelTypeSet progress_types;
  209. for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
  210. ModelType type = GetModelTypeFromSpecificsFieldNumber(
  211. gu_msg.from_progress_marker(i).data_type_id());
  212. progress_types.Put(type);
  213. }
  214. EXPECT_EQ(enabled_types(), progress_types);
  215. }
  216. TEST_F(GetUpdatesProcessorTest, RetryTest) {
  217. NudgeTracker nudge_tracker;
  218. // Schedule a retry.
  219. base::TimeTicks t1 = kTestStartTime;
  220. nudge_tracker.SetNextRetryTime(t1);
  221. // Get the nudge tracker to think the retry is due.
  222. nudge_tracker.SetSyncCycleStartTime(t1 + base::Seconds(1));
  223. sync_pb::ClientToServerMessage message;
  224. NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
  225. std::unique_ptr<GetUpdatesProcessor> processor(
  226. BuildGetUpdatesProcessor(normal_delegate));
  227. processor->PrepareGetUpdates(enabled_types(), &message);
  228. const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
  229. EXPECT_EQ(sync_pb::SyncEnums::RETRY, gu_msg.get_updates_origin());
  230. EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::UNKNOWN,
  231. gu_msg.caller_info().source());
  232. EXPECT_TRUE(gu_msg.is_retry());
  233. ModelTypeSet progress_types;
  234. for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
  235. ModelType type = GetModelTypeFromSpecificsFieldNumber(
  236. gu_msg.from_progress_marker(i).data_type_id());
  237. progress_types.Put(type);
  238. }
  239. EXPECT_EQ(enabled_types(), progress_types);
  240. }
  241. TEST_F(GetUpdatesProcessorTest, NudgeWithRetryTest) {
  242. NudgeTracker nudge_tracker;
  243. // Schedule a retry.
  244. base::TimeTicks t1 = kTestStartTime;
  245. nudge_tracker.SetNextRetryTime(t1);
  246. // Get the nudge tracker to think the retry is due.
  247. nudge_tracker.SetSyncCycleStartTime(t1 + base::Seconds(1));
  248. // Record a local change, too.
  249. nudge_tracker.RecordLocalChange(BOOKMARKS);
  250. sync_pb::ClientToServerMessage message;
  251. NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
  252. std::unique_ptr<GetUpdatesProcessor> processor(
  253. BuildGetUpdatesProcessor(normal_delegate));
  254. processor->PrepareGetUpdates(enabled_types(), &message);
  255. const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
  256. EXPECT_NE(sync_pb::SyncEnums::RETRY, gu_msg.get_updates_origin());
  257. EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::UNKNOWN,
  258. gu_msg.caller_info().source());
  259. EXPECT_TRUE(gu_msg.is_retry());
  260. }
  261. // Verify that a bogus response message is detected.
  262. TEST_F(GetUpdatesProcessorTest, InvalidResponse) {
  263. sync_pb::GetUpdatesResponse gu_response;
  264. InitFakeUpdateResponse(&gu_response);
  265. // This field is essential for making the client stop looping. If it's unset
  266. // then something is very wrong. The client should detect this.
  267. gu_response.clear_changes_remaining();
  268. NudgeTracker nudge_tracker;
  269. NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
  270. StatusController status;
  271. std::unique_ptr<GetUpdatesProcessor> processor(
  272. BuildGetUpdatesProcessor(normal_delegate));
  273. SyncerError error =
  274. processor->ProcessResponse(gu_response, enabled_types(), &status);
  275. EXPECT_EQ(error.value(), SyncerError::SERVER_RESPONSE_VALIDATION_FAILED);
  276. }
  277. // Verify that we correctly detect when there's more work to be done.
  278. TEST_F(GetUpdatesProcessorTest, MoreToDownloadResponse) {
  279. sync_pb::GetUpdatesResponse gu_response;
  280. InitFakeUpdateResponse(&gu_response);
  281. gu_response.set_changes_remaining(1);
  282. NudgeTracker nudge_tracker;
  283. NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
  284. StatusController status;
  285. std::unique_ptr<GetUpdatesProcessor> processor(
  286. BuildGetUpdatesProcessor(normal_delegate));
  287. SyncerError error =
  288. processor->ProcessResponse(gu_response, enabled_types(), &status);
  289. EXPECT_EQ(error.value(), SyncerError::SERVER_MORE_TO_DOWNLOAD);
  290. }
  291. // A simple scenario: No updates returned and nothing more to download.
  292. TEST_F(GetUpdatesProcessorTest, NormalResponseTest) {
  293. sync_pb::GetUpdatesResponse gu_response;
  294. InitFakeUpdateResponse(&gu_response);
  295. gu_response.set_changes_remaining(0);
  296. NudgeTracker nudge_tracker;
  297. NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
  298. StatusController status;
  299. std::unique_ptr<GetUpdatesProcessor> processor(
  300. BuildGetUpdatesProcessor(normal_delegate));
  301. SyncerError error =
  302. processor->ProcessResponse(gu_response, enabled_types(), &status);
  303. EXPECT_EQ(error.value(), SyncerError::SYNCER_OK);
  304. }
  305. // Variant of GetUpdatesProcessor test designed to test update application.
  306. //
  307. // Maintains two enabled types, but requests that updates be applied for only
  308. // one of them.
  309. class GetUpdatesProcessorApplyUpdatesTest : public GetUpdatesProcessorTest {
  310. public:
  311. GetUpdatesProcessorApplyUpdatesTest() = default;
  312. ~GetUpdatesProcessorApplyUpdatesTest() override = default;
  313. void SetUp() override {
  314. bookmarks_handler_ = AddUpdateHandler(BOOKMARKS);
  315. autofill_handler_ = AddUpdateHandler(AUTOFILL);
  316. }
  317. ModelTypeSet GetGuTypes() { return ModelTypeSet(AUTOFILL); }
  318. MockUpdateHandler* GetNonAppliedHandler() { return bookmarks_handler_; }
  319. MockUpdateHandler* GetAppliedHandler() { return autofill_handler_; }
  320. private:
  321. raw_ptr<MockUpdateHandler> bookmarks_handler_;
  322. raw_ptr<MockUpdateHandler> autofill_handler_;
  323. };
  324. // Verify that a normal cycle applies updates to the specified types.
  325. TEST_F(GetUpdatesProcessorApplyUpdatesTest, Normal) {
  326. NudgeTracker nudge_tracker;
  327. NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
  328. std::unique_ptr<GetUpdatesProcessor> processor(
  329. BuildGetUpdatesProcessor(normal_delegate));
  330. EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
  331. EXPECT_EQ(0, GetAppliedHandler()->GetApplyUpdatesCount());
  332. StatusController status;
  333. processor->ApplyUpdates(GetGuTypes(), &status);
  334. EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
  335. EXPECT_EQ(1, GetAppliedHandler()->GetApplyUpdatesCount());
  336. }
  337. // Verify that a configure cycle applies updates to the specified types.
  338. TEST_F(GetUpdatesProcessorApplyUpdatesTest, Configure) {
  339. ConfigureGetUpdatesDelegate configure_delegate(
  340. sync_pb::SyncEnums::RECONFIGURATION);
  341. std::unique_ptr<GetUpdatesProcessor> processor(
  342. BuildGetUpdatesProcessor(configure_delegate));
  343. EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
  344. EXPECT_EQ(0, GetAppliedHandler()->GetApplyUpdatesCount());
  345. StatusController status;
  346. processor->ApplyUpdates(GetGuTypes(), &status);
  347. EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
  348. EXPECT_EQ(1, GetAppliedHandler()->GetApplyUpdatesCount());
  349. }
  350. // Verify that a poll cycle applies updates to the specified types.
  351. TEST_F(GetUpdatesProcessorApplyUpdatesTest, Poll) {
  352. PollGetUpdatesDelegate poll_delegate;
  353. std::unique_ptr<GetUpdatesProcessor> processor(
  354. BuildGetUpdatesProcessor(poll_delegate));
  355. EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
  356. EXPECT_EQ(0, GetAppliedHandler()->GetApplyUpdatesCount());
  357. StatusController status;
  358. processor->ApplyUpdates(GetGuTypes(), &status);
  359. EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
  360. EXPECT_EQ(1, GetAppliedHandler()->GetApplyUpdatesCount());
  361. }
  362. class DownloadUpdatesDebugInfoTest : public ::testing::Test {
  363. public:
  364. DownloadUpdatesDebugInfoTest() = default;
  365. ~DownloadUpdatesDebugInfoTest() override = default;
  366. StatusController* status() { return &status_; }
  367. DebugInfoGetter* debug_info_getter() { return &debug_info_getter_; }
  368. void AddDebugEvent() { debug_info_getter_.AddDebugEvent(); }
  369. private:
  370. StatusController status_;
  371. MockDebugInfoGetter debug_info_getter_;
  372. };
  373. } // namespace syncer