Revert "Fix broken channel icon in chrome://help on CrOS" and try again
[chromium-blink-merge.git] / sync / engine / get_updates_processor_unittest.cc
blob566a295c92d39df12804d0b89c070a40d044165a
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.
5 #include "sync/engine/get_updates_processor.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/stl_util.h"
9 #include "sync/engine/get_updates_delegate.h"
10 #include "sync/engine/update_handler.h"
11 #include "sync/internal_api/public/base/model_type_test_util.h"
12 #include "sync/protocol/sync.pb.h"
13 #include "sync/sessions/debug_info_getter.h"
14 #include "sync/sessions/nudge_tracker.h"
15 #include "sync/sessions/status_controller.h"
16 #include "sync/test/engine/fake_model_worker.h"
17 #include "sync/test/engine/mock_update_handler.h"
18 #include "sync/test/mock_invalidation.h"
19 #include "sync/test/sessions/mock_debug_info_getter.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 namespace syncer {
24 namespace {
26 scoped_ptr<InvalidationInterface> BuildInvalidation(
27 int64 version,
28 const std::string& payload) {
29 return MockInvalidation::Build(version, payload);
32 } // namespace
34 using sessions::MockDebugInfoGetter;
36 // A test fixture for tests exercising download updates functions.
37 class GetUpdatesProcessorTest : public ::testing::Test {
38 protected:
39 GetUpdatesProcessorTest() :
40 kTestStartTime(base::TimeTicks::Now()),
41 update_handler_deleter_(&update_handler_map_) {}
43 void SetUp() override {
44 AddUpdateHandler(AUTOFILL);
45 AddUpdateHandler(BOOKMARKS);
46 AddUpdateHandler(PREFERENCES);
49 ModelTypeSet enabled_types() {
50 return enabled_types_;
53 scoped_ptr<GetUpdatesProcessor> BuildGetUpdatesProcessor(
54 const GetUpdatesDelegate& delegate) {
55 return scoped_ptr<GetUpdatesProcessor>(
56 new GetUpdatesProcessor(&update_handler_map_, delegate));
59 void InitFakeUpdateResponse(sync_pb::GetUpdatesResponse* response) {
60 ModelTypeSet types = enabled_types();
62 for (ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) {
63 sync_pb::DataTypeProgressMarker* marker =
64 response->add_new_progress_marker();
65 marker->set_data_type_id(GetSpecificsFieldNumberFromModelType(it.Get()));
66 marker->set_token("foobarbaz");
67 sync_pb::DataTypeContext* context = response->add_context_mutations();
68 context->set_data_type_id(GetSpecificsFieldNumberFromModelType(it.Get()));
69 context->set_version(1);
70 context->set_context("context");
73 response->set_changes_remaining(0);
76 const UpdateHandler* GetHandler(ModelType type) {
77 UpdateHandlerMap::iterator it = update_handler_map_.find(type);
78 if (it == update_handler_map_.end())
79 return NULL;
80 return it->second;
83 const base::TimeTicks kTestStartTime;
85 protected:
86 MockUpdateHandler* AddUpdateHandler(ModelType type) {
87 enabled_types_.Put(type);
89 MockUpdateHandler* handler = new MockUpdateHandler(type);
90 update_handler_map_.insert(std::make_pair(type, handler));
92 return handler;
95 private:
96 ModelTypeSet enabled_types_;
97 UpdateHandlerMap update_handler_map_;
98 STLValueDeleter<UpdateHandlerMap> update_handler_deleter_;
99 scoped_ptr<GetUpdatesProcessor> get_updates_processor_;
101 DISALLOW_COPY_AND_ASSIGN(GetUpdatesProcessorTest);
104 // Basic test to make sure nudges are expressed properly in the request.
105 TEST_F(GetUpdatesProcessorTest, BookmarkNudge) {
106 sessions::NudgeTracker nudge_tracker;
107 nudge_tracker.RecordLocalChange(ModelTypeSet(BOOKMARKS));
109 sync_pb::ClientToServerMessage message;
110 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
111 scoped_ptr<GetUpdatesProcessor> processor(
112 BuildGetUpdatesProcessor(normal_delegate));
113 processor->PrepareGetUpdates(enabled_types(), &message);
115 const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
116 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::LOCAL,
117 gu_msg.caller_info().source());
118 EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, gu_msg.get_updates_origin());
119 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
120 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
121 gu_msg.from_progress_marker(i).data_type_id());
123 const sync_pb::DataTypeProgressMarker& progress_marker =
124 gu_msg.from_progress_marker(i);
125 const sync_pb::GetUpdateTriggers& gu_trigger =
126 progress_marker.get_update_triggers();
128 // We perform some basic tests of GU trigger and source fields here. The
129 // more complicated scenarios are tested by the NudgeTracker tests.
130 if (type == BOOKMARKS) {
131 EXPECT_TRUE(progress_marker.has_notification_hint());
132 EXPECT_EQ("", progress_marker.notification_hint());
133 EXPECT_EQ(1, gu_trigger.local_modification_nudges());
134 EXPECT_EQ(0, gu_trigger.datatype_refresh_nudges());
135 } else {
136 EXPECT_FALSE(progress_marker.has_notification_hint());
137 EXPECT_EQ(0, gu_trigger.local_modification_nudges());
138 EXPECT_EQ(0, gu_trigger.datatype_refresh_nudges());
143 // Basic test to ensure invalidation payloads are expressed in the request.
144 TEST_F(GetUpdatesProcessorTest, NotifyMany) {
145 sessions::NudgeTracker nudge_tracker;
146 nudge_tracker.RecordRemoteInvalidation(
147 AUTOFILL, BuildInvalidation(1, "autofill_payload"));
148 nudge_tracker.RecordRemoteInvalidation(
149 BOOKMARKS, BuildInvalidation(1, "bookmark_payload"));
150 nudge_tracker.RecordRemoteInvalidation(
151 PREFERENCES, BuildInvalidation(1, "preferences_payload"));
152 ModelTypeSet notified_types;
153 notified_types.Put(AUTOFILL);
154 notified_types.Put(BOOKMARKS);
155 notified_types.Put(PREFERENCES);
157 sync_pb::ClientToServerMessage message;
158 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
159 scoped_ptr<GetUpdatesProcessor> processor(
160 BuildGetUpdatesProcessor(normal_delegate));
161 processor->PrepareGetUpdates(enabled_types(), &message);
163 const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
164 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::NOTIFICATION,
165 gu_msg.caller_info().source());
166 EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, gu_msg.get_updates_origin());
167 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
168 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
169 gu_msg.from_progress_marker(i).data_type_id());
171 const sync_pb::DataTypeProgressMarker& progress_marker =
172 gu_msg.from_progress_marker(i);
173 const sync_pb::GetUpdateTriggers& gu_trigger =
174 progress_marker.get_update_triggers();
176 // We perform some basic tests of GU trigger and source fields here. The
177 // more complicated scenarios are tested by the NudgeTracker tests.
178 if (notified_types.Has(type)) {
179 EXPECT_TRUE(progress_marker.has_notification_hint());
180 EXPECT_FALSE(progress_marker.notification_hint().empty());
181 EXPECT_EQ(1, gu_trigger.notification_hint_size());
182 } else {
183 EXPECT_FALSE(progress_marker.has_notification_hint());
184 EXPECT_EQ(0, gu_trigger.notification_hint_size());
189 // Basic test to ensure initial sync requests are expressed in the request.
190 TEST_F(GetUpdatesProcessorTest, InitialSyncRequest) {
191 sessions::NudgeTracker nudge_tracker;
192 nudge_tracker.RecordInitialSyncRequired(AUTOFILL);
193 nudge_tracker.RecordInitialSyncRequired(PREFERENCES);
195 ModelTypeSet initial_sync_types = ModelTypeSet(AUTOFILL, PREFERENCES);
197 sync_pb::ClientToServerMessage message;
198 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
199 scoped_ptr<GetUpdatesProcessor> processor(
200 BuildGetUpdatesProcessor(normal_delegate));
201 processor->PrepareGetUpdates(enabled_types(), &message);
203 const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
204 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::DATATYPE_REFRESH,
205 gu_msg.caller_info().source());
206 EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, gu_msg.get_updates_origin());
207 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
208 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
209 gu_msg.from_progress_marker(i).data_type_id());
211 const sync_pb::DataTypeProgressMarker& progress_marker =
212 gu_msg.from_progress_marker(i);
213 const sync_pb::GetUpdateTriggers& gu_trigger =
214 progress_marker.get_update_triggers();
216 // We perform some basic tests of GU trigger and source fields here. The
217 // more complicated scenarios are tested by the NudgeTracker tests.
218 if (initial_sync_types.Has(type)) {
219 EXPECT_TRUE(gu_trigger.initial_sync_in_progress());
220 } else {
221 EXPECT_TRUE(gu_trigger.has_initial_sync_in_progress());
222 EXPECT_FALSE(gu_trigger.initial_sync_in_progress());
227 TEST_F(GetUpdatesProcessorTest, ConfigureTest) {
228 sync_pb::ClientToServerMessage message;
229 ConfigureGetUpdatesDelegate configure_delegate(
230 sync_pb::GetUpdatesCallerInfo::RECONFIGURATION);
231 scoped_ptr<GetUpdatesProcessor> processor(
232 BuildGetUpdatesProcessor(configure_delegate));
233 processor->PrepareGetUpdates(enabled_types(), &message);
235 const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
236 EXPECT_EQ(sync_pb::SyncEnums::RECONFIGURATION, gu_msg.get_updates_origin());
237 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RECONFIGURATION,
238 gu_msg.caller_info().source());
240 ModelTypeSet progress_types;
241 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
242 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
243 gu_msg.from_progress_marker(i).data_type_id());
244 progress_types.Put(type);
246 EXPECT_TRUE(enabled_types().Equals(progress_types));
249 TEST_F(GetUpdatesProcessorTest, PollTest) {
250 sync_pb::ClientToServerMessage message;
251 PollGetUpdatesDelegate poll_delegate;
252 scoped_ptr<GetUpdatesProcessor> processor(
253 BuildGetUpdatesProcessor(poll_delegate));
254 processor->PrepareGetUpdates(enabled_types(), &message);
256 const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
257 EXPECT_EQ(sync_pb::SyncEnums::PERIODIC, gu_msg.get_updates_origin());
258 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::PERIODIC,
259 gu_msg.caller_info().source());
261 ModelTypeSet progress_types;
262 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
263 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
264 gu_msg.from_progress_marker(i).data_type_id());
265 progress_types.Put(type);
267 EXPECT_TRUE(enabled_types().Equals(progress_types));
270 TEST_F(GetUpdatesProcessorTest, RetryTest) {
271 sessions::NudgeTracker nudge_tracker;
273 // Schedule a retry.
274 base::TimeTicks t1 = kTestStartTime;
275 nudge_tracker.SetNextRetryTime(t1);
277 // Get the nudge tracker to think the retry is due.
278 nudge_tracker.SetSyncCycleStartTime(t1 + base::TimeDelta::FromSeconds(1));
280 sync_pb::ClientToServerMessage message;
281 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
282 scoped_ptr<GetUpdatesProcessor> processor(
283 BuildGetUpdatesProcessor(normal_delegate));
284 processor->PrepareGetUpdates(enabled_types(), &message);
286 const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
287 EXPECT_EQ(sync_pb::SyncEnums::RETRY, gu_msg.get_updates_origin());
288 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RETRY,
289 gu_msg.caller_info().source());
290 EXPECT_TRUE(gu_msg.is_retry());
292 ModelTypeSet progress_types;
293 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
294 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
295 gu_msg.from_progress_marker(i).data_type_id());
296 progress_types.Put(type);
298 EXPECT_TRUE(enabled_types().Equals(progress_types));
301 TEST_F(GetUpdatesProcessorTest, NudgeWithRetryTest) {
302 sessions::NudgeTracker nudge_tracker;
304 // Schedule a retry.
305 base::TimeTicks t1 = kTestStartTime;
306 nudge_tracker.SetNextRetryTime(t1);
308 // Get the nudge tracker to think the retry is due.
309 nudge_tracker.SetSyncCycleStartTime(t1 + base::TimeDelta::FromSeconds(1));
311 // Record a local change, too.
312 nudge_tracker.RecordLocalChange(ModelTypeSet(BOOKMARKS));
314 sync_pb::ClientToServerMessage message;
315 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
316 scoped_ptr<GetUpdatesProcessor> processor(
317 BuildGetUpdatesProcessor(normal_delegate));
318 processor->PrepareGetUpdates(enabled_types(), &message);
320 const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
321 EXPECT_NE(sync_pb::SyncEnums::RETRY, gu_msg.get_updates_origin());
322 EXPECT_NE(sync_pb::GetUpdatesCallerInfo::RETRY,
323 gu_msg.caller_info().source());
325 EXPECT_TRUE(gu_msg.is_retry());
328 // Verify that a bogus response message is detected.
329 TEST_F(GetUpdatesProcessorTest, InvalidResponse) {
330 sync_pb::GetUpdatesResponse gu_response;
331 InitFakeUpdateResponse(&gu_response);
333 // This field is essential for making the client stop looping. If it's unset
334 // then something is very wrong. The client should detect this.
335 gu_response.clear_changes_remaining();
337 sessions::NudgeTracker nudge_tracker;
338 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
339 sessions::StatusController status;
340 scoped_ptr<GetUpdatesProcessor> processor(
341 BuildGetUpdatesProcessor(normal_delegate));
342 SyncerError error = processor->ProcessResponse(gu_response,
343 enabled_types(),
344 &status);
345 EXPECT_EQ(error, SERVER_RESPONSE_VALIDATION_FAILED);
348 // Verify that we correctly detect when there's more work to be done.
349 TEST_F(GetUpdatesProcessorTest, MoreToDownloadResponse) {
350 sync_pb::GetUpdatesResponse gu_response;
351 InitFakeUpdateResponse(&gu_response);
352 gu_response.set_changes_remaining(1);
354 sessions::NudgeTracker nudge_tracker;
355 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
356 sessions::StatusController status;
357 scoped_ptr<GetUpdatesProcessor> processor(
358 BuildGetUpdatesProcessor(normal_delegate));
359 SyncerError error = processor->ProcessResponse(gu_response,
360 enabled_types(),
361 &status);
362 EXPECT_EQ(error, SERVER_MORE_TO_DOWNLOAD);
365 // A simple scenario: No updates returned and nothing more to download.
366 TEST_F(GetUpdatesProcessorTest, NormalResponseTest) {
367 sync_pb::GetUpdatesResponse gu_response;
368 InitFakeUpdateResponse(&gu_response);
369 gu_response.set_changes_remaining(0);
371 sessions::NudgeTracker nudge_tracker;
372 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
373 sessions::StatusController status;
374 scoped_ptr<GetUpdatesProcessor> processor(
375 BuildGetUpdatesProcessor(normal_delegate));
376 SyncerError error = processor->ProcessResponse(gu_response,
377 enabled_types(),
378 &status);
379 EXPECT_EQ(error, SYNCER_OK);
382 // Variant of GetUpdatesProcessor test designed to test update application.
384 // Maintains two enabled types, but requests that updates be applied for only
385 // one of them.
386 class GetUpdatesProcessorApplyUpdatesTest : public GetUpdatesProcessorTest {
387 public:
388 GetUpdatesProcessorApplyUpdatesTest() {}
389 ~GetUpdatesProcessorApplyUpdatesTest() override {}
391 void SetUp() override {
392 bookmarks_handler_ = AddUpdateHandler(BOOKMARKS);
393 autofill_handler_ = AddUpdateHandler(AUTOFILL);
396 ModelTypeSet GetGuTypes() {
397 return ModelTypeSet(AUTOFILL);
400 MockUpdateHandler* GetNonAppliedHandler() {
401 return bookmarks_handler_;
404 MockUpdateHandler* GetAppliedHandler() {
405 return autofill_handler_;
408 private:
409 MockUpdateHandler* bookmarks_handler_;
410 MockUpdateHandler* autofill_handler_;
413 // Verify that a normal cycle applies updates non-passively to the specified
414 // types.
415 TEST_F(GetUpdatesProcessorApplyUpdatesTest, Normal) {
416 sessions::NudgeTracker nudge_tracker;
417 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
418 scoped_ptr<GetUpdatesProcessor> processor(
419 BuildGetUpdatesProcessor(normal_delegate));
421 EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
422 EXPECT_EQ(0, GetAppliedHandler()->GetApplyUpdatesCount());
424 sessions::StatusController status;
425 processor->ApplyUpdates(GetGuTypes(), &status);
427 EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
428 EXPECT_EQ(1, GetAppliedHandler()->GetApplyUpdatesCount());
430 EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
431 EXPECT_EQ(0, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
434 // Verify that a configure cycle applies updates passively to the specified
435 // types.
436 TEST_F(GetUpdatesProcessorApplyUpdatesTest, Configure) {
437 ConfigureGetUpdatesDelegate configure_delegate(
438 sync_pb::GetUpdatesCallerInfo::RECONFIGURATION);
439 scoped_ptr<GetUpdatesProcessor> processor(
440 BuildGetUpdatesProcessor(configure_delegate));
442 EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
443 EXPECT_EQ(0, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
445 sessions::StatusController status;
446 processor->ApplyUpdates(GetGuTypes(), &status);
448 EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
449 EXPECT_EQ(1, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
451 EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
452 EXPECT_EQ(0, GetAppliedHandler()->GetApplyUpdatesCount());
455 // Verify that a poll cycle applies updates non-passively to the specified
456 // types.
457 TEST_F(GetUpdatesProcessorApplyUpdatesTest, Poll) {
458 PollGetUpdatesDelegate poll_delegate;
459 scoped_ptr<GetUpdatesProcessor> processor(
460 BuildGetUpdatesProcessor(poll_delegate));
462 EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
463 EXPECT_EQ(0, GetAppliedHandler()->GetApplyUpdatesCount());
465 sessions::StatusController status;
466 processor->ApplyUpdates(GetGuTypes(), &status);
468 EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
469 EXPECT_EQ(1, GetAppliedHandler()->GetApplyUpdatesCount());
471 EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
472 EXPECT_EQ(0, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
475 class DownloadUpdatesDebugInfoTest : public ::testing::Test {
476 public:
477 DownloadUpdatesDebugInfoTest() {}
478 ~DownloadUpdatesDebugInfoTest() override {}
480 sessions::StatusController* status() {
481 return &status_;
484 sessions::DebugInfoGetter* debug_info_getter() {
485 return &debug_info_getter_;
488 void AddDebugEvent() {
489 debug_info_getter_.AddDebugEvent();
492 private:
493 sessions::StatusController status_;
494 MockDebugInfoGetter debug_info_getter_;
497 // Verify CopyClientDebugInfo when there are no events to upload.
498 TEST_F(DownloadUpdatesDebugInfoTest, VerifyCopyClientDebugInfo_Empty) {
499 sync_pb::DebugInfo debug_info;
500 GetUpdatesProcessor::CopyClientDebugInfo(debug_info_getter(), &debug_info);
501 EXPECT_EQ(0, debug_info.events_size());
504 TEST_F(DownloadUpdatesDebugInfoTest, VerifyCopyOverwrites) {
505 sync_pb::DebugInfo debug_info;
506 AddDebugEvent();
507 GetUpdatesProcessor::CopyClientDebugInfo(debug_info_getter(), &debug_info);
508 EXPECT_EQ(1, debug_info.events_size());
509 GetUpdatesProcessor::CopyClientDebugInfo(debug_info_getter(), &debug_info);
510 EXPECT_EQ(1, debug_info.events_size());
513 } // namespace syncer