Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / sync / engine / get_updates_processor_unittest.cc
bloba09ab4ef580f2ddda982c0ad4a4ff9648ee7e648
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)
30 .PassAs<InvalidationInterface>();
33 } // namespace
35 using sessions::MockDebugInfoGetter;
37 // A test fixture for tests exercising download updates functions.
38 class GetUpdatesProcessorTest : public ::testing::Test {
39 protected:
40 GetUpdatesProcessorTest() :
41 kTestStartTime(base::TimeTicks::Now()),
42 update_handler_deleter_(&update_handler_map_) {}
44 virtual void SetUp() {
45 AddUpdateHandler(AUTOFILL);
46 AddUpdateHandler(BOOKMARKS);
47 AddUpdateHandler(PREFERENCES);
50 ModelTypeSet enabled_types() {
51 return enabled_types_;
54 scoped_ptr<GetUpdatesProcessor> BuildGetUpdatesProcessor(
55 const GetUpdatesDelegate& delegate) {
56 return scoped_ptr<GetUpdatesProcessor>(
57 new GetUpdatesProcessor(&update_handler_map_, delegate));
60 void InitFakeUpdateResponse(sync_pb::GetUpdatesResponse* response) {
61 ModelTypeSet types = enabled_types();
63 for (ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) {
64 sync_pb::DataTypeProgressMarker* marker =
65 response->add_new_progress_marker();
66 marker->set_data_type_id(GetSpecificsFieldNumberFromModelType(it.Get()));
67 marker->set_token("foobarbaz");
68 sync_pb::DataTypeContext* context = response->add_context_mutations();
69 context->set_data_type_id(GetSpecificsFieldNumberFromModelType(it.Get()));
70 context->set_version(1);
71 context->set_context("context");
74 response->set_changes_remaining(0);
77 const UpdateHandler* GetHandler(ModelType type) {
78 UpdateHandlerMap::iterator it = update_handler_map_.find(type);
79 if (it == update_handler_map_.end())
80 return NULL;
81 return it->second;
84 const base::TimeTicks kTestStartTime;
86 protected:
87 MockUpdateHandler* AddUpdateHandler(ModelType type) {
88 enabled_types_.Put(type);
90 MockUpdateHandler* handler = new MockUpdateHandler(type);
91 update_handler_map_.insert(std::make_pair(type, handler));
93 return handler;
96 private:
97 ModelTypeSet enabled_types_;
98 UpdateHandlerMap update_handler_map_;
99 STLValueDeleter<UpdateHandlerMap> update_handler_deleter_;
100 scoped_ptr<GetUpdatesProcessor> get_updates_processor_;
102 DISALLOW_COPY_AND_ASSIGN(GetUpdatesProcessorTest);
105 // Basic test to make sure nudges are expressed properly in the request.
106 TEST_F(GetUpdatesProcessorTest, BookmarkNudge) {
107 sessions::NudgeTracker nudge_tracker;
108 nudge_tracker.RecordLocalChange(ModelTypeSet(BOOKMARKS));
110 sync_pb::ClientToServerMessage message;
111 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
112 scoped_ptr<GetUpdatesProcessor> processor(
113 BuildGetUpdatesProcessor(normal_delegate));
114 processor->PrepareGetUpdates(enabled_types(), &message);
116 const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
117 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::LOCAL,
118 gu_msg.caller_info().source());
119 EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, gu_msg.get_updates_origin());
120 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
121 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
122 gu_msg.from_progress_marker(i).data_type_id());
124 const sync_pb::DataTypeProgressMarker& progress_marker =
125 gu_msg.from_progress_marker(i);
126 const sync_pb::GetUpdateTriggers& gu_trigger =
127 progress_marker.get_update_triggers();
129 // We perform some basic tests of GU trigger and source fields here. The
130 // more complicated scenarios are tested by the NudgeTracker tests.
131 if (type == BOOKMARKS) {
132 EXPECT_TRUE(progress_marker.has_notification_hint());
133 EXPECT_EQ("", progress_marker.notification_hint());
134 EXPECT_EQ(1, gu_trigger.local_modification_nudges());
135 EXPECT_EQ(0, gu_trigger.datatype_refresh_nudges());
136 } else {
137 EXPECT_FALSE(progress_marker.has_notification_hint());
138 EXPECT_EQ(0, gu_trigger.local_modification_nudges());
139 EXPECT_EQ(0, gu_trigger.datatype_refresh_nudges());
144 // Basic test to ensure invalidation payloads are expressed in the request.
145 TEST_F(GetUpdatesProcessorTest, NotifyMany) {
146 sessions::NudgeTracker nudge_tracker;
147 nudge_tracker.RecordRemoteInvalidation(
148 AUTOFILL, BuildInvalidation(1, "autofill_payload"));
149 nudge_tracker.RecordRemoteInvalidation(
150 BOOKMARKS, BuildInvalidation(1, "bookmark_payload"));
151 nudge_tracker.RecordRemoteInvalidation(
152 PREFERENCES, BuildInvalidation(1, "preferences_payload"));
153 ModelTypeSet notified_types;
154 notified_types.Put(AUTOFILL);
155 notified_types.Put(BOOKMARKS);
156 notified_types.Put(PREFERENCES);
158 sync_pb::ClientToServerMessage message;
159 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
160 scoped_ptr<GetUpdatesProcessor> processor(
161 BuildGetUpdatesProcessor(normal_delegate));
162 processor->PrepareGetUpdates(enabled_types(), &message);
164 const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
165 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::NOTIFICATION,
166 gu_msg.caller_info().source());
167 EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, gu_msg.get_updates_origin());
168 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
169 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
170 gu_msg.from_progress_marker(i).data_type_id());
172 const sync_pb::DataTypeProgressMarker& progress_marker =
173 gu_msg.from_progress_marker(i);
174 const sync_pb::GetUpdateTriggers& gu_trigger =
175 progress_marker.get_update_triggers();
177 // We perform some basic tests of GU trigger and source fields here. The
178 // more complicated scenarios are tested by the NudgeTracker tests.
179 if (notified_types.Has(type)) {
180 EXPECT_TRUE(progress_marker.has_notification_hint());
181 EXPECT_FALSE(progress_marker.notification_hint().empty());
182 EXPECT_EQ(1, gu_trigger.notification_hint_size());
183 } else {
184 EXPECT_FALSE(progress_marker.has_notification_hint());
185 EXPECT_EQ(0, gu_trigger.notification_hint_size());
190 // Basic test to ensure initial sync requests are expressed in the request.
191 TEST_F(GetUpdatesProcessorTest, InitialSyncRequest) {
192 sessions::NudgeTracker nudge_tracker;
193 nudge_tracker.RecordInitialSyncRequired(AUTOFILL);
194 nudge_tracker.RecordInitialSyncRequired(PREFERENCES);
196 ModelTypeSet initial_sync_types = ModelTypeSet(AUTOFILL, PREFERENCES);
198 sync_pb::ClientToServerMessage message;
199 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
200 scoped_ptr<GetUpdatesProcessor> processor(
201 BuildGetUpdatesProcessor(normal_delegate));
202 processor->PrepareGetUpdates(enabled_types(), &message);
204 const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
205 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::DATATYPE_REFRESH,
206 gu_msg.caller_info().source());
207 EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, gu_msg.get_updates_origin());
208 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
209 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
210 gu_msg.from_progress_marker(i).data_type_id());
212 const sync_pb::DataTypeProgressMarker& progress_marker =
213 gu_msg.from_progress_marker(i);
214 const sync_pb::GetUpdateTriggers& gu_trigger =
215 progress_marker.get_update_triggers();
217 // We perform some basic tests of GU trigger and source fields here. The
218 // more complicated scenarios are tested by the NudgeTracker tests.
219 if (initial_sync_types.Has(type)) {
220 EXPECT_TRUE(gu_trigger.initial_sync_in_progress());
221 } else {
222 EXPECT_TRUE(gu_trigger.has_initial_sync_in_progress());
223 EXPECT_FALSE(gu_trigger.initial_sync_in_progress());
228 TEST_F(GetUpdatesProcessorTest, ConfigureTest) {
229 sync_pb::ClientToServerMessage message;
230 ConfigureGetUpdatesDelegate configure_delegate(
231 sync_pb::GetUpdatesCallerInfo::RECONFIGURATION);
232 scoped_ptr<GetUpdatesProcessor> processor(
233 BuildGetUpdatesProcessor(configure_delegate));
234 processor->PrepareGetUpdates(enabled_types(), &message);
236 const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
237 EXPECT_EQ(sync_pb::SyncEnums::RECONFIGURATION, gu_msg.get_updates_origin());
238 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RECONFIGURATION,
239 gu_msg.caller_info().source());
241 ModelTypeSet progress_types;
242 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
243 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
244 gu_msg.from_progress_marker(i).data_type_id());
245 progress_types.Put(type);
247 EXPECT_TRUE(enabled_types().Equals(progress_types));
250 TEST_F(GetUpdatesProcessorTest, PollTest) {
251 sync_pb::ClientToServerMessage message;
252 PollGetUpdatesDelegate poll_delegate;
253 scoped_ptr<GetUpdatesProcessor> processor(
254 BuildGetUpdatesProcessor(poll_delegate));
255 processor->PrepareGetUpdates(enabled_types(), &message);
257 const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
258 EXPECT_EQ(sync_pb::SyncEnums::PERIODIC, gu_msg.get_updates_origin());
259 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::PERIODIC,
260 gu_msg.caller_info().source());
262 ModelTypeSet progress_types;
263 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
264 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
265 gu_msg.from_progress_marker(i).data_type_id());
266 progress_types.Put(type);
268 EXPECT_TRUE(enabled_types().Equals(progress_types));
271 TEST_F(GetUpdatesProcessorTest, RetryTest) {
272 sessions::NudgeTracker nudge_tracker;
274 // Schedule a retry.
275 base::TimeTicks t1 = kTestStartTime;
276 nudge_tracker.SetNextRetryTime(t1);
278 // Get the nudge tracker to think the retry is due.
279 nudge_tracker.SetSyncCycleStartTime(t1 + base::TimeDelta::FromSeconds(1));
281 sync_pb::ClientToServerMessage message;
282 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
283 scoped_ptr<GetUpdatesProcessor> processor(
284 BuildGetUpdatesProcessor(normal_delegate));
285 processor->PrepareGetUpdates(enabled_types(), &message);
287 const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
288 EXPECT_EQ(sync_pb::SyncEnums::RETRY, gu_msg.get_updates_origin());
289 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RETRY,
290 gu_msg.caller_info().source());
291 EXPECT_TRUE(gu_msg.is_retry());
293 ModelTypeSet progress_types;
294 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
295 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
296 gu_msg.from_progress_marker(i).data_type_id());
297 progress_types.Put(type);
299 EXPECT_TRUE(enabled_types().Equals(progress_types));
302 TEST_F(GetUpdatesProcessorTest, NudgeWithRetryTest) {
303 sessions::NudgeTracker nudge_tracker;
305 // Schedule a retry.
306 base::TimeTicks t1 = kTestStartTime;
307 nudge_tracker.SetNextRetryTime(t1);
309 // Get the nudge tracker to think the retry is due.
310 nudge_tracker.SetSyncCycleStartTime(t1 + base::TimeDelta::FromSeconds(1));
312 // Record a local change, too.
313 nudge_tracker.RecordLocalChange(ModelTypeSet(BOOKMARKS));
315 sync_pb::ClientToServerMessage message;
316 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
317 scoped_ptr<GetUpdatesProcessor> processor(
318 BuildGetUpdatesProcessor(normal_delegate));
319 processor->PrepareGetUpdates(enabled_types(), &message);
321 const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
322 EXPECT_NE(sync_pb::SyncEnums::RETRY, gu_msg.get_updates_origin());
323 EXPECT_NE(sync_pb::GetUpdatesCallerInfo::RETRY,
324 gu_msg.caller_info().source());
326 EXPECT_TRUE(gu_msg.is_retry());
329 // Verify that a bogus response message is detected.
330 TEST_F(GetUpdatesProcessorTest, InvalidResponse) {
331 sync_pb::GetUpdatesResponse gu_response;
332 InitFakeUpdateResponse(&gu_response);
334 // This field is essential for making the client stop looping. If it's unset
335 // then something is very wrong. The client should detect this.
336 gu_response.clear_changes_remaining();
338 sessions::NudgeTracker nudge_tracker;
339 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
340 sessions::StatusController status;
341 scoped_ptr<GetUpdatesProcessor> processor(
342 BuildGetUpdatesProcessor(normal_delegate));
343 SyncerError error = processor->ProcessResponse(gu_response,
344 enabled_types(),
345 &status);
346 EXPECT_EQ(error, SERVER_RESPONSE_VALIDATION_FAILED);
349 // Verify that we correctly detect when there's more work to be done.
350 TEST_F(GetUpdatesProcessorTest, MoreToDownloadResponse) {
351 sync_pb::GetUpdatesResponse gu_response;
352 InitFakeUpdateResponse(&gu_response);
353 gu_response.set_changes_remaining(1);
355 sessions::NudgeTracker nudge_tracker;
356 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
357 sessions::StatusController status;
358 scoped_ptr<GetUpdatesProcessor> processor(
359 BuildGetUpdatesProcessor(normal_delegate));
360 SyncerError error = processor->ProcessResponse(gu_response,
361 enabled_types(),
362 &status);
363 EXPECT_EQ(error, SERVER_MORE_TO_DOWNLOAD);
366 // A simple scenario: No updates returned and nothing more to download.
367 TEST_F(GetUpdatesProcessorTest, NormalResponseTest) {
368 sync_pb::GetUpdatesResponse gu_response;
369 InitFakeUpdateResponse(&gu_response);
370 gu_response.set_changes_remaining(0);
372 sessions::NudgeTracker nudge_tracker;
373 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
374 sessions::StatusController status;
375 scoped_ptr<GetUpdatesProcessor> processor(
376 BuildGetUpdatesProcessor(normal_delegate));
377 SyncerError error = processor->ProcessResponse(gu_response,
378 enabled_types(),
379 &status);
380 EXPECT_EQ(error, SYNCER_OK);
383 // Variant of GetUpdatesProcessor test designed to test update application.
385 // Maintains two enabled types, but requests that updates be applied for only
386 // one of them.
387 class GetUpdatesProcessorApplyUpdatesTest : public GetUpdatesProcessorTest {
388 public:
389 GetUpdatesProcessorApplyUpdatesTest() {}
390 virtual ~GetUpdatesProcessorApplyUpdatesTest() {}
392 virtual void SetUp() OVERRIDE {
393 bookmarks_handler_ = AddUpdateHandler(BOOKMARKS);
394 autofill_handler_ = AddUpdateHandler(AUTOFILL);
397 ModelTypeSet GetGuTypes() {
398 return ModelTypeSet(AUTOFILL);
401 MockUpdateHandler* GetNonAppliedHandler() {
402 return bookmarks_handler_;
405 MockUpdateHandler* GetAppliedHandler() {
406 return autofill_handler_;
409 private:
410 MockUpdateHandler* bookmarks_handler_;
411 MockUpdateHandler* autofill_handler_;
414 // Verify that a normal cycle applies updates non-passively to the specified
415 // types.
416 TEST_F(GetUpdatesProcessorApplyUpdatesTest, Normal) {
417 sessions::NudgeTracker nudge_tracker;
418 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
419 scoped_ptr<GetUpdatesProcessor> processor(
420 BuildGetUpdatesProcessor(normal_delegate));
422 EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
423 EXPECT_EQ(0, GetAppliedHandler()->GetApplyUpdatesCount());
425 sessions::StatusController status;
426 processor->ApplyUpdates(GetGuTypes(), &status);
428 EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
429 EXPECT_EQ(1, GetAppliedHandler()->GetApplyUpdatesCount());
431 EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
432 EXPECT_EQ(0, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
435 // Verify that a configure cycle applies updates passively to the specified
436 // types.
437 TEST_F(GetUpdatesProcessorApplyUpdatesTest, Configure) {
438 ConfigureGetUpdatesDelegate configure_delegate(
439 sync_pb::GetUpdatesCallerInfo::RECONFIGURATION);
440 scoped_ptr<GetUpdatesProcessor> processor(
441 BuildGetUpdatesProcessor(configure_delegate));
443 EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
444 EXPECT_EQ(0, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
446 sessions::StatusController status;
447 processor->ApplyUpdates(GetGuTypes(), &status);
449 EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
450 EXPECT_EQ(1, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
452 EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
453 EXPECT_EQ(0, GetAppliedHandler()->GetApplyUpdatesCount());
456 // Verify that a poll cycle applies updates non-passively to the specified
457 // types.
458 TEST_F(GetUpdatesProcessorApplyUpdatesTest, Poll) {
459 PollGetUpdatesDelegate poll_delegate;
460 scoped_ptr<GetUpdatesProcessor> processor(
461 BuildGetUpdatesProcessor(poll_delegate));
463 EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
464 EXPECT_EQ(0, GetAppliedHandler()->GetApplyUpdatesCount());
466 sessions::StatusController status;
467 processor->ApplyUpdates(GetGuTypes(), &status);
469 EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
470 EXPECT_EQ(1, GetAppliedHandler()->GetApplyUpdatesCount());
472 EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
473 EXPECT_EQ(0, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
476 class DownloadUpdatesDebugInfoTest : public ::testing::Test {
477 public:
478 DownloadUpdatesDebugInfoTest() {}
479 virtual ~DownloadUpdatesDebugInfoTest() {}
481 sessions::StatusController* status() {
482 return &status_;
485 sessions::DebugInfoGetter* debug_info_getter() {
486 return &debug_info_getter_;
489 void AddDebugEvent() {
490 debug_info_getter_.AddDebugEvent();
493 private:
494 sessions::StatusController status_;
495 MockDebugInfoGetter debug_info_getter_;
498 // Verify CopyClientDebugInfo when there are no events to upload.
499 TEST_F(DownloadUpdatesDebugInfoTest, VerifyCopyClientDebugInfo_Empty) {
500 sync_pb::DebugInfo debug_info;
501 GetUpdatesProcessor::CopyClientDebugInfo(debug_info_getter(), &debug_info);
502 EXPECT_EQ(0, debug_info.events_size());
505 TEST_F(DownloadUpdatesDebugInfoTest, VerifyCopyOverwrites) {
506 sync_pb::DebugInfo debug_info;
507 AddDebugEvent();
508 GetUpdatesProcessor::CopyClientDebugInfo(debug_info_getter(), &debug_info);
509 EXPECT_EQ(1, debug_info.events_size());
510 GetUpdatesProcessor::CopyClientDebugInfo(debug_info_getter(), &debug_info);
511 EXPECT_EQ(1, debug_info.events_size());
514 } // namespace syncer