Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / sync / engine / get_updates_processor_unittest.cc
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
5 #include "sync/engine/get_updates_processor.h"
6
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"
21
22 namespace syncer {
23
24 namespace {
25
26 scoped_ptr<InvalidationInterface> BuildInvalidation(
27     int64 version,
28     const std::string& payload) {
29   return MockInvalidation::Build(version, payload);
30 }
31
32 }  // namespace
33
34 using sessions::MockDebugInfoGetter;
35
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_) {}
42
43   virtual void SetUp() {
44     AddUpdateHandler(AUTOFILL);
45     AddUpdateHandler(BOOKMARKS);
46     AddUpdateHandler(PREFERENCES);
47   }
48
49   ModelTypeSet enabled_types() {
50     return enabled_types_;
51   }
52
53   scoped_ptr<GetUpdatesProcessor> BuildGetUpdatesProcessor(
54       const GetUpdatesDelegate& delegate) {
55     return scoped_ptr<GetUpdatesProcessor>(
56         new GetUpdatesProcessor(&update_handler_map_, delegate));
57   }
58
59   void InitFakeUpdateResponse(sync_pb::GetUpdatesResponse* response) {
60     ModelTypeSet types = enabled_types();
61
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");
71     }
72
73     response->set_changes_remaining(0);
74   }
75
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;
81   }
82
83   const base::TimeTicks kTestStartTime;
84
85  protected:
86   MockUpdateHandler* AddUpdateHandler(ModelType type) {
87     enabled_types_.Put(type);
88
89     MockUpdateHandler* handler = new MockUpdateHandler(type);
90     update_handler_map_.insert(std::make_pair(type, handler));
91
92     return handler;
93   }
94
95  private:
96   ModelTypeSet enabled_types_;
97   UpdateHandlerMap update_handler_map_;
98   STLValueDeleter<UpdateHandlerMap> update_handler_deleter_;
99   scoped_ptr<GetUpdatesProcessor> get_updates_processor_;
100
101   DISALLOW_COPY_AND_ASSIGN(GetUpdatesProcessorTest);
102 };
103
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));
108
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);
114
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());
122
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();
127
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());
139     }
140   }
141 }
142
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);
156
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);
162
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());
170
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();
175
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());
185     }
186   }
187 }
188
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);
194
195   ModelTypeSet initial_sync_types = ModelTypeSet(AUTOFILL, PREFERENCES);
196
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);
202
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());
210
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();
215
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());
223     }
224   }
225 }
226
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);
234
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());
239
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);
245   }
246   EXPECT_TRUE(enabled_types().Equals(progress_types));
247 }
248
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);
255
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());
260
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);
266   }
267   EXPECT_TRUE(enabled_types().Equals(progress_types));
268 }
269
270 TEST_F(GetUpdatesProcessorTest, RetryTest) {
271   sessions::NudgeTracker nudge_tracker;
272
273   // Schedule a retry.
274   base::TimeTicks t1 = kTestStartTime;
275   nudge_tracker.SetNextRetryTime(t1);
276
277   // Get the nudge tracker to think the retry is due.
278   nudge_tracker.SetSyncCycleStartTime(t1 + base::TimeDelta::FromSeconds(1));
279
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);
285
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());
291
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);
297   }
298   EXPECT_TRUE(enabled_types().Equals(progress_types));
299 }
300
301 TEST_F(GetUpdatesProcessorTest, NudgeWithRetryTest) {
302   sessions::NudgeTracker nudge_tracker;
303
304   // Schedule a retry.
305   base::TimeTicks t1 = kTestStartTime;
306   nudge_tracker.SetNextRetryTime(t1);
307
308   // Get the nudge tracker to think the retry is due.
309   nudge_tracker.SetSyncCycleStartTime(t1 + base::TimeDelta::FromSeconds(1));
310
311   // Record a local change, too.
312   nudge_tracker.RecordLocalChange(ModelTypeSet(BOOKMARKS));
313
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);
319
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());
324
325   EXPECT_TRUE(gu_msg.is_retry());
326 }
327
328 // Verify that a bogus response message is detected.
329 TEST_F(GetUpdatesProcessorTest, InvalidResponse) {
330   sync_pb::GetUpdatesResponse gu_response;
331   InitFakeUpdateResponse(&gu_response);
332
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();
336
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);
346 }
347
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);
353
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);
363 }
364
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);
370
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);
380 }
381
382 // Variant of GetUpdatesProcessor test designed to test update application.
383 //
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   virtual ~GetUpdatesProcessorApplyUpdatesTest() {}
390
391   virtual void SetUp() override {
392     bookmarks_handler_ = AddUpdateHandler(BOOKMARKS);
393     autofill_handler_ = AddUpdateHandler(AUTOFILL);
394   }
395
396   ModelTypeSet GetGuTypes() {
397     return ModelTypeSet(AUTOFILL);
398   }
399
400   MockUpdateHandler* GetNonAppliedHandler() {
401     return bookmarks_handler_;
402   }
403
404   MockUpdateHandler* GetAppliedHandler() {
405     return autofill_handler_;
406   }
407
408  private:
409   MockUpdateHandler* bookmarks_handler_;
410   MockUpdateHandler* autofill_handler_;
411 };
412
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));
420
421   EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
422   EXPECT_EQ(0, GetAppliedHandler()->GetApplyUpdatesCount());
423
424   sessions::StatusController status;
425   processor->ApplyUpdates(GetGuTypes(), &status);
426
427   EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
428   EXPECT_EQ(1, GetAppliedHandler()->GetApplyUpdatesCount());
429
430   EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
431   EXPECT_EQ(0, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
432 }
433
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));
441
442   EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
443   EXPECT_EQ(0, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
444
445   sessions::StatusController status;
446   processor->ApplyUpdates(GetGuTypes(), &status);
447
448   EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
449   EXPECT_EQ(1, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
450
451   EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
452   EXPECT_EQ(0, GetAppliedHandler()->GetApplyUpdatesCount());
453 }
454
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));
461
462   EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
463   EXPECT_EQ(0, GetAppliedHandler()->GetApplyUpdatesCount());
464
465   sessions::StatusController status;
466   processor->ApplyUpdates(GetGuTypes(), &status);
467
468   EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
469   EXPECT_EQ(1, GetAppliedHandler()->GetApplyUpdatesCount());
470
471   EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
472   EXPECT_EQ(0, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
473 }
474
475 class DownloadUpdatesDebugInfoTest : public ::testing::Test {
476  public:
477   DownloadUpdatesDebugInfoTest() {}
478   virtual ~DownloadUpdatesDebugInfoTest() {}
479
480   sessions::StatusController* status() {
481     return &status_;
482   }
483
484   sessions::DebugInfoGetter* debug_info_getter() {
485     return &debug_info_getter_;
486   }
487
488   void AddDebugEvent() {
489     debug_info_getter_.AddDebugEvent();
490   }
491
492  private:
493   sessions::StatusController status_;
494   MockDebugInfoGetter debug_info_getter_;
495 };
496
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());
502 }
503
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());
511 }
512
513 }  // namespace syncer