Upstream version 7.36.149.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/sessions/mock_debug_info_getter.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 namespace syncer {
22
23 using sessions::MockDebugInfoGetter;
24
25 // A test fixture for tests exercising download updates functions.
26 class GetUpdatesProcessorTest : public ::testing::Test {
27  protected:
28   GetUpdatesProcessorTest() :
29     kTestStartTime(base::TimeTicks::Now()),
30     update_handler_deleter_(&update_handler_map_) {}
31
32   virtual void SetUp() {
33     AddUpdateHandler(AUTOFILL);
34     AddUpdateHandler(BOOKMARKS);
35     AddUpdateHandler(PREFERENCES);
36   }
37
38   ModelTypeSet enabled_types() {
39     return enabled_types_;
40   }
41
42   scoped_ptr<GetUpdatesProcessor> BuildGetUpdatesProcessor(
43       const GetUpdatesDelegate& delegate) {
44     return scoped_ptr<GetUpdatesProcessor>(
45         new GetUpdatesProcessor(&update_handler_map_, delegate));
46   }
47
48   void InitFakeUpdateResponse(sync_pb::GetUpdatesResponse* response) {
49     ModelTypeSet types = enabled_types();
50
51     for (ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) {
52       sync_pb::DataTypeProgressMarker* marker =
53           response->add_new_progress_marker();
54       marker->set_data_type_id(GetSpecificsFieldNumberFromModelType(it.Get()));
55       marker->set_token("foobarbaz");
56       sync_pb::DataTypeContext* context = response->add_context_mutations();
57       context->set_data_type_id(GetSpecificsFieldNumberFromModelType(it.Get()));
58       context->set_version(1);
59       context->set_context("context");
60     }
61
62     response->set_changes_remaining(0);
63   }
64
65   const UpdateHandler* GetHandler(ModelType type) {
66     UpdateHandlerMap::iterator it = update_handler_map_.find(type);
67     if (it == update_handler_map_.end())
68       return NULL;
69     return it->second;
70   }
71
72   const base::TimeTicks kTestStartTime;
73
74  protected:
75   MockUpdateHandler* AddUpdateHandler(ModelType type) {
76     enabled_types_.Put(type);
77
78     MockUpdateHandler* handler = new MockUpdateHandler(type);
79     update_handler_map_.insert(std::make_pair(type, handler));
80
81     return handler;
82   }
83
84  private:
85   ModelTypeSet enabled_types_;
86   UpdateHandlerMap update_handler_map_;
87   STLValueDeleter<UpdateHandlerMap> update_handler_deleter_;
88   scoped_ptr<GetUpdatesProcessor> get_updates_processor_;
89
90   DISALLOW_COPY_AND_ASSIGN(GetUpdatesProcessorTest);
91 };
92
93 // Basic test to make sure nudges are expressed properly in the request.
94 TEST_F(GetUpdatesProcessorTest, BookmarkNudge) {
95   sessions::NudgeTracker nudge_tracker;
96   nudge_tracker.RecordLocalChange(ModelTypeSet(BOOKMARKS));
97
98   sync_pb::ClientToServerMessage message;
99   NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
100   scoped_ptr<GetUpdatesProcessor> processor(
101       BuildGetUpdatesProcessor(normal_delegate));
102   processor->PrepareGetUpdates(enabled_types(), &message);
103
104   const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
105   EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::LOCAL,
106             gu_msg.caller_info().source());
107   EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, gu_msg.get_updates_origin());
108   for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
109     syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
110         gu_msg.from_progress_marker(i).data_type_id());
111
112     const sync_pb::DataTypeProgressMarker& progress_marker =
113         gu_msg.from_progress_marker(i);
114     const sync_pb::GetUpdateTriggers& gu_trigger =
115         progress_marker.get_update_triggers();
116
117     // We perform some basic tests of GU trigger and source fields here.  The
118     // more complicated scenarios are tested by the NudgeTracker tests.
119     if (type == BOOKMARKS) {
120       EXPECT_TRUE(progress_marker.has_notification_hint());
121       EXPECT_EQ("", progress_marker.notification_hint());
122       EXPECT_EQ(1, gu_trigger.local_modification_nudges());
123       EXPECT_EQ(0, gu_trigger.datatype_refresh_nudges());
124     } else {
125       EXPECT_FALSE(progress_marker.has_notification_hint());
126       EXPECT_EQ(0, gu_trigger.local_modification_nudges());
127       EXPECT_EQ(0, gu_trigger.datatype_refresh_nudges());
128     }
129   }
130 }
131
132 // Basic test to ensure invalidation payloads are expressed in the request.
133 TEST_F(GetUpdatesProcessorTest, NotifyMany) {
134   sessions::NudgeTracker nudge_tracker;
135   nudge_tracker.RecordRemoteInvalidation(
136       BuildInvalidationMap(AUTOFILL, 1, "autofill_payload"));
137   nudge_tracker.RecordRemoteInvalidation(
138       BuildInvalidationMap(BOOKMARKS, 1, "bookmark_payload"));
139   nudge_tracker.RecordRemoteInvalidation(
140       BuildInvalidationMap(PREFERENCES, 1, "preferences_payload"));
141   ModelTypeSet notified_types;
142   notified_types.Put(AUTOFILL);
143   notified_types.Put(BOOKMARKS);
144   notified_types.Put(PREFERENCES);
145
146   sync_pb::ClientToServerMessage message;
147   NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
148   scoped_ptr<GetUpdatesProcessor> processor(
149       BuildGetUpdatesProcessor(normal_delegate));
150   processor->PrepareGetUpdates(enabled_types(), &message);
151
152   const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
153   EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::NOTIFICATION,
154             gu_msg.caller_info().source());
155   EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, gu_msg.get_updates_origin());
156   for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
157     syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
158         gu_msg.from_progress_marker(i).data_type_id());
159
160     const sync_pb::DataTypeProgressMarker& progress_marker =
161         gu_msg.from_progress_marker(i);
162     const sync_pb::GetUpdateTriggers& gu_trigger =
163         progress_marker.get_update_triggers();
164
165     // We perform some basic tests of GU trigger and source fields here.  The
166     // more complicated scenarios are tested by the NudgeTracker tests.
167     if (notified_types.Has(type)) {
168       EXPECT_TRUE(progress_marker.has_notification_hint());
169       EXPECT_FALSE(progress_marker.notification_hint().empty());
170       EXPECT_EQ(1, gu_trigger.notification_hint_size());
171     } else {
172       EXPECT_FALSE(progress_marker.has_notification_hint());
173       EXPECT_EQ(0, gu_trigger.notification_hint_size());
174     }
175   }
176 }
177
178 TEST_F(GetUpdatesProcessorTest, ConfigureTest) {
179   sync_pb::ClientToServerMessage message;
180   ConfigureGetUpdatesDelegate configure_delegate(
181       sync_pb::GetUpdatesCallerInfo::RECONFIGURATION);
182   scoped_ptr<GetUpdatesProcessor> processor(
183       BuildGetUpdatesProcessor(configure_delegate));
184   processor->PrepareGetUpdates(enabled_types(), &message);
185
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::RECONFIGURATION,
189             gu_msg.caller_info().source());
190
191   ModelTypeSet progress_types;
192   for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
193     syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
194         gu_msg.from_progress_marker(i).data_type_id());
195     progress_types.Put(type);
196   }
197   EXPECT_TRUE(enabled_types().Equals(progress_types));
198 }
199
200 TEST_F(GetUpdatesProcessorTest, PollTest) {
201   sync_pb::ClientToServerMessage message;
202   PollGetUpdatesDelegate poll_delegate;
203   scoped_ptr<GetUpdatesProcessor> processor(
204       BuildGetUpdatesProcessor(poll_delegate));
205   processor->PrepareGetUpdates(enabled_types(), &message);
206
207   const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
208   EXPECT_EQ(sync_pb::SyncEnums::PERIODIC, gu_msg.get_updates_origin());
209   EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::PERIODIC,
210             gu_msg.caller_info().source());
211
212   ModelTypeSet progress_types;
213   for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
214     syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
215         gu_msg.from_progress_marker(i).data_type_id());
216     progress_types.Put(type);
217   }
218   EXPECT_TRUE(enabled_types().Equals(progress_types));
219 }
220
221 TEST_F(GetUpdatesProcessorTest, RetryTest) {
222   sessions::NudgeTracker nudge_tracker;
223
224   // Schedule a retry.
225   base::TimeTicks t1 = kTestStartTime;
226   nudge_tracker.SetNextRetryTime(t1);
227
228   // Get the nudge tracker to think the retry is due.
229   nudge_tracker.SetSyncCycleStartTime(t1 + base::TimeDelta::FromSeconds(1));
230
231   sync_pb::ClientToServerMessage message;
232   NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
233   scoped_ptr<GetUpdatesProcessor> processor(
234       BuildGetUpdatesProcessor(normal_delegate));
235   processor->PrepareGetUpdates(enabled_types(), &message);
236
237   const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
238   EXPECT_EQ(sync_pb::SyncEnums::RETRY, gu_msg.get_updates_origin());
239   EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RETRY,
240             gu_msg.caller_info().source());
241   EXPECT_TRUE(gu_msg.is_retry());
242
243   ModelTypeSet progress_types;
244   for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
245     syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
246         gu_msg.from_progress_marker(i).data_type_id());
247     progress_types.Put(type);
248   }
249   EXPECT_TRUE(enabled_types().Equals(progress_types));
250 }
251
252 TEST_F(GetUpdatesProcessorTest, NudgeWithRetryTest) {
253   sessions::NudgeTracker nudge_tracker;
254
255   // Schedule a retry.
256   base::TimeTicks t1 = kTestStartTime;
257   nudge_tracker.SetNextRetryTime(t1);
258
259   // Get the nudge tracker to think the retry is due.
260   nudge_tracker.SetSyncCycleStartTime(t1 + base::TimeDelta::FromSeconds(1));
261
262   // Record a local change, too.
263   nudge_tracker.RecordLocalChange(ModelTypeSet(BOOKMARKS));
264
265   sync_pb::ClientToServerMessage message;
266   NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
267   scoped_ptr<GetUpdatesProcessor> processor(
268       BuildGetUpdatesProcessor(normal_delegate));
269   processor->PrepareGetUpdates(enabled_types(), &message);
270
271   const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
272   EXPECT_NE(sync_pb::SyncEnums::RETRY, gu_msg.get_updates_origin());
273   EXPECT_NE(sync_pb::GetUpdatesCallerInfo::RETRY,
274             gu_msg.caller_info().source());
275
276   EXPECT_TRUE(gu_msg.is_retry());
277 }
278
279 // Verify that a bogus response message is detected.
280 TEST_F(GetUpdatesProcessorTest, InvalidResponse) {
281   sync_pb::GetUpdatesResponse gu_response;
282   InitFakeUpdateResponse(&gu_response);
283
284   // This field is essential for making the client stop looping.  If it's unset
285   // then something is very wrong.  The client should detect this.
286   gu_response.clear_changes_remaining();
287
288   sessions::NudgeTracker nudge_tracker;
289   NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
290   sessions::StatusController status;
291   scoped_ptr<GetUpdatesProcessor> processor(
292       BuildGetUpdatesProcessor(normal_delegate));
293   SyncerError error = processor->ProcessResponse(gu_response,
294                                                  enabled_types(),
295                                                  &status);
296   EXPECT_EQ(error, SERVER_RESPONSE_VALIDATION_FAILED);
297 }
298
299 // Verify that we correctly detect when there's more work to be done.
300 TEST_F(GetUpdatesProcessorTest, MoreToDownloadResponse) {
301   sync_pb::GetUpdatesResponse gu_response;
302   InitFakeUpdateResponse(&gu_response);
303   gu_response.set_changes_remaining(1);
304
305   sessions::NudgeTracker nudge_tracker;
306   NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
307   sessions::StatusController status;
308   scoped_ptr<GetUpdatesProcessor> processor(
309       BuildGetUpdatesProcessor(normal_delegate));
310   SyncerError error = processor->ProcessResponse(gu_response,
311                                                  enabled_types(),
312                                                  &status);
313   EXPECT_EQ(error, SERVER_MORE_TO_DOWNLOAD);
314 }
315
316 // A simple scenario: No updates returned and nothing more to download.
317 TEST_F(GetUpdatesProcessorTest, NormalResponseTest) {
318   sync_pb::GetUpdatesResponse gu_response;
319   InitFakeUpdateResponse(&gu_response);
320   gu_response.set_changes_remaining(0);
321
322   sessions::NudgeTracker nudge_tracker;
323   NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
324   sessions::StatusController status;
325   scoped_ptr<GetUpdatesProcessor> processor(
326       BuildGetUpdatesProcessor(normal_delegate));
327   SyncerError error = processor->ProcessResponse(gu_response,
328                                                  enabled_types(),
329                                                  &status);
330   EXPECT_EQ(error, SYNCER_OK);
331 }
332
333 // Variant of GetUpdatesProcessor test designed to test update application.
334 //
335 // Maintains two enabled types, but requests that updates be applied for only
336 // one of them.
337 class GetUpdatesProcessorApplyUpdatesTest : public GetUpdatesProcessorTest {
338  public:
339   GetUpdatesProcessorApplyUpdatesTest() {}
340   virtual ~GetUpdatesProcessorApplyUpdatesTest() {}
341
342   virtual void SetUp() OVERRIDE {
343     bookmarks_handler_ = AddUpdateHandler(BOOKMARKS);
344     autofill_handler_ = AddUpdateHandler(AUTOFILL);
345   }
346
347   ModelTypeSet GetGuTypes() {
348     return ModelTypeSet(AUTOFILL);
349   }
350
351   MockUpdateHandler* GetNonAppliedHandler() {
352     return bookmarks_handler_;
353   }
354
355   MockUpdateHandler* GetAppliedHandler() {
356     return autofill_handler_;
357   }
358
359  private:
360   MockUpdateHandler* bookmarks_handler_;
361   MockUpdateHandler* autofill_handler_;
362 };
363
364 // Verify that a normal cycle applies updates non-passively to the specified
365 // types.
366 TEST_F(GetUpdatesProcessorApplyUpdatesTest, Normal) {
367   sessions::NudgeTracker nudge_tracker;
368   NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
369   scoped_ptr<GetUpdatesProcessor> processor(
370       BuildGetUpdatesProcessor(normal_delegate));
371
372   EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
373   EXPECT_EQ(0, GetAppliedHandler()->GetApplyUpdatesCount());
374
375   sessions::StatusController status;
376   processor->ApplyUpdates(GetGuTypes(), &status);
377
378   EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
379   EXPECT_EQ(1, GetAppliedHandler()->GetApplyUpdatesCount());
380
381   EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
382   EXPECT_EQ(0, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
383 }
384
385 // Verify that a configure cycle applies updates passively to the specified
386 // types.
387 TEST_F(GetUpdatesProcessorApplyUpdatesTest, Configure) {
388   ConfigureGetUpdatesDelegate configure_delegate(
389       sync_pb::GetUpdatesCallerInfo::RECONFIGURATION);
390   scoped_ptr<GetUpdatesProcessor> processor(
391       BuildGetUpdatesProcessor(configure_delegate));
392
393   EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
394   EXPECT_EQ(0, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
395
396   sessions::StatusController status;
397   processor->ApplyUpdates(GetGuTypes(), &status);
398
399   EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
400   EXPECT_EQ(1, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
401
402   EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
403   EXPECT_EQ(0, GetAppliedHandler()->GetApplyUpdatesCount());
404 }
405
406 // Verify that a poll cycle applies updates non-passively to the specified
407 // types.
408 TEST_F(GetUpdatesProcessorApplyUpdatesTest, Poll) {
409   PollGetUpdatesDelegate poll_delegate;
410   scoped_ptr<GetUpdatesProcessor> processor(
411       BuildGetUpdatesProcessor(poll_delegate));
412
413   EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
414   EXPECT_EQ(0, GetAppliedHandler()->GetApplyUpdatesCount());
415
416   sessions::StatusController status;
417   processor->ApplyUpdates(GetGuTypes(), &status);
418
419   EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
420   EXPECT_EQ(1, GetAppliedHandler()->GetApplyUpdatesCount());
421
422   EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
423   EXPECT_EQ(0, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
424 }
425
426 class DownloadUpdatesDebugInfoTest : public ::testing::Test {
427  public:
428   DownloadUpdatesDebugInfoTest() {}
429   virtual ~DownloadUpdatesDebugInfoTest() {}
430
431   sessions::StatusController* status() {
432     return &status_;
433   }
434
435   sessions::DebugInfoGetter* debug_info_getter() {
436     return &debug_info_getter_;
437   }
438
439   void AddDebugEvent() {
440     debug_info_getter_.AddDebugEvent();
441   }
442
443  private:
444   sessions::StatusController status_;
445   MockDebugInfoGetter debug_info_getter_;
446 };
447
448 // Verify CopyClientDebugInfo when there are no events to upload.
449 TEST_F(DownloadUpdatesDebugInfoTest, VerifyCopyClientDebugInfo_Empty) {
450   sync_pb::DebugInfo debug_info;
451   GetUpdatesProcessor::CopyClientDebugInfo(debug_info_getter(), &debug_info);
452   EXPECT_EQ(0, debug_info.events_size());
453 }
454
455 TEST_F(DownloadUpdatesDebugInfoTest, VerifyCopyOverwrites) {
456   sync_pb::DebugInfo debug_info;
457   AddDebugEvent();
458   GetUpdatesProcessor::CopyClientDebugInfo(debug_info_getter(), &debug_info);
459   EXPECT_EQ(1, debug_info.events_size());
460   GetUpdatesProcessor::CopyClientDebugInfo(debug_info_getter(), &debug_info);
461   EXPECT_EQ(1, debug_info.events_size());
462 }
463
464 }  // namespace syncer