[SyncFS] Build indexes from FileTracker entries on disk.
[chromium-blink-merge.git] / sync / engine / get_updates_processor_unittest.cc
blob54ce5031431ab36f6c1354b57e0d5824c380d1e6
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 TEST_F(GetUpdatesProcessorTest, ConfigureTest) {
191 sync_pb::ClientToServerMessage message;
192 ConfigureGetUpdatesDelegate configure_delegate(
193 sync_pb::GetUpdatesCallerInfo::RECONFIGURATION);
194 scoped_ptr<GetUpdatesProcessor> processor(
195 BuildGetUpdatesProcessor(configure_delegate));
196 processor->PrepareGetUpdates(enabled_types(), &message);
198 const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
199 EXPECT_EQ(sync_pb::SyncEnums::RECONFIGURATION, gu_msg.get_updates_origin());
200 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RECONFIGURATION,
201 gu_msg.caller_info().source());
203 ModelTypeSet progress_types;
204 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
205 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
206 gu_msg.from_progress_marker(i).data_type_id());
207 progress_types.Put(type);
209 EXPECT_TRUE(enabled_types().Equals(progress_types));
212 TEST_F(GetUpdatesProcessorTest, PollTest) {
213 sync_pb::ClientToServerMessage message;
214 PollGetUpdatesDelegate poll_delegate;
215 scoped_ptr<GetUpdatesProcessor> processor(
216 BuildGetUpdatesProcessor(poll_delegate));
217 processor->PrepareGetUpdates(enabled_types(), &message);
219 const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
220 EXPECT_EQ(sync_pb::SyncEnums::PERIODIC, gu_msg.get_updates_origin());
221 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::PERIODIC,
222 gu_msg.caller_info().source());
224 ModelTypeSet progress_types;
225 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
226 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
227 gu_msg.from_progress_marker(i).data_type_id());
228 progress_types.Put(type);
230 EXPECT_TRUE(enabled_types().Equals(progress_types));
233 TEST_F(GetUpdatesProcessorTest, RetryTest) {
234 sessions::NudgeTracker nudge_tracker;
236 // Schedule a retry.
237 base::TimeTicks t1 = kTestStartTime;
238 nudge_tracker.SetNextRetryTime(t1);
240 // Get the nudge tracker to think the retry is due.
241 nudge_tracker.SetSyncCycleStartTime(t1 + base::TimeDelta::FromSeconds(1));
243 sync_pb::ClientToServerMessage message;
244 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
245 scoped_ptr<GetUpdatesProcessor> processor(
246 BuildGetUpdatesProcessor(normal_delegate));
247 processor->PrepareGetUpdates(enabled_types(), &message);
249 const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
250 EXPECT_EQ(sync_pb::SyncEnums::RETRY, gu_msg.get_updates_origin());
251 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RETRY,
252 gu_msg.caller_info().source());
253 EXPECT_TRUE(gu_msg.is_retry());
255 ModelTypeSet progress_types;
256 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
257 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
258 gu_msg.from_progress_marker(i).data_type_id());
259 progress_types.Put(type);
261 EXPECT_TRUE(enabled_types().Equals(progress_types));
264 TEST_F(GetUpdatesProcessorTest, NudgeWithRetryTest) {
265 sessions::NudgeTracker nudge_tracker;
267 // Schedule a retry.
268 base::TimeTicks t1 = kTestStartTime;
269 nudge_tracker.SetNextRetryTime(t1);
271 // Get the nudge tracker to think the retry is due.
272 nudge_tracker.SetSyncCycleStartTime(t1 + base::TimeDelta::FromSeconds(1));
274 // Record a local change, too.
275 nudge_tracker.RecordLocalChange(ModelTypeSet(BOOKMARKS));
277 sync_pb::ClientToServerMessage message;
278 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
279 scoped_ptr<GetUpdatesProcessor> processor(
280 BuildGetUpdatesProcessor(normal_delegate));
281 processor->PrepareGetUpdates(enabled_types(), &message);
283 const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
284 EXPECT_NE(sync_pb::SyncEnums::RETRY, gu_msg.get_updates_origin());
285 EXPECT_NE(sync_pb::GetUpdatesCallerInfo::RETRY,
286 gu_msg.caller_info().source());
288 EXPECT_TRUE(gu_msg.is_retry());
291 // Verify that a bogus response message is detected.
292 TEST_F(GetUpdatesProcessorTest, InvalidResponse) {
293 sync_pb::GetUpdatesResponse gu_response;
294 InitFakeUpdateResponse(&gu_response);
296 // This field is essential for making the client stop looping. If it's unset
297 // then something is very wrong. The client should detect this.
298 gu_response.clear_changes_remaining();
300 sessions::NudgeTracker nudge_tracker;
301 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
302 sessions::StatusController status;
303 scoped_ptr<GetUpdatesProcessor> processor(
304 BuildGetUpdatesProcessor(normal_delegate));
305 SyncerError error = processor->ProcessResponse(gu_response,
306 enabled_types(),
307 &status);
308 EXPECT_EQ(error, SERVER_RESPONSE_VALIDATION_FAILED);
311 // Verify that we correctly detect when there's more work to be done.
312 TEST_F(GetUpdatesProcessorTest, MoreToDownloadResponse) {
313 sync_pb::GetUpdatesResponse gu_response;
314 InitFakeUpdateResponse(&gu_response);
315 gu_response.set_changes_remaining(1);
317 sessions::NudgeTracker nudge_tracker;
318 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
319 sessions::StatusController status;
320 scoped_ptr<GetUpdatesProcessor> processor(
321 BuildGetUpdatesProcessor(normal_delegate));
322 SyncerError error = processor->ProcessResponse(gu_response,
323 enabled_types(),
324 &status);
325 EXPECT_EQ(error, SERVER_MORE_TO_DOWNLOAD);
328 // A simple scenario: No updates returned and nothing more to download.
329 TEST_F(GetUpdatesProcessorTest, NormalResponseTest) {
330 sync_pb::GetUpdatesResponse gu_response;
331 InitFakeUpdateResponse(&gu_response);
332 gu_response.set_changes_remaining(0);
334 sessions::NudgeTracker nudge_tracker;
335 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
336 sessions::StatusController status;
337 scoped_ptr<GetUpdatesProcessor> processor(
338 BuildGetUpdatesProcessor(normal_delegate));
339 SyncerError error = processor->ProcessResponse(gu_response,
340 enabled_types(),
341 &status);
342 EXPECT_EQ(error, SYNCER_OK);
345 // Variant of GetUpdatesProcessor test designed to test update application.
347 // Maintains two enabled types, but requests that updates be applied for only
348 // one of them.
349 class GetUpdatesProcessorApplyUpdatesTest : public GetUpdatesProcessorTest {
350 public:
351 GetUpdatesProcessorApplyUpdatesTest() {}
352 virtual ~GetUpdatesProcessorApplyUpdatesTest() {}
354 virtual void SetUp() OVERRIDE {
355 bookmarks_handler_ = AddUpdateHandler(BOOKMARKS);
356 autofill_handler_ = AddUpdateHandler(AUTOFILL);
359 ModelTypeSet GetGuTypes() {
360 return ModelTypeSet(AUTOFILL);
363 MockUpdateHandler* GetNonAppliedHandler() {
364 return bookmarks_handler_;
367 MockUpdateHandler* GetAppliedHandler() {
368 return autofill_handler_;
371 private:
372 MockUpdateHandler* bookmarks_handler_;
373 MockUpdateHandler* autofill_handler_;
376 // Verify that a normal cycle applies updates non-passively to the specified
377 // types.
378 TEST_F(GetUpdatesProcessorApplyUpdatesTest, Normal) {
379 sessions::NudgeTracker nudge_tracker;
380 NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
381 scoped_ptr<GetUpdatesProcessor> processor(
382 BuildGetUpdatesProcessor(normal_delegate));
384 EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
385 EXPECT_EQ(0, GetAppliedHandler()->GetApplyUpdatesCount());
387 sessions::StatusController status;
388 processor->ApplyUpdates(GetGuTypes(), &status);
390 EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
391 EXPECT_EQ(1, GetAppliedHandler()->GetApplyUpdatesCount());
393 EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
394 EXPECT_EQ(0, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
397 // Verify that a configure cycle applies updates passively to the specified
398 // types.
399 TEST_F(GetUpdatesProcessorApplyUpdatesTest, Configure) {
400 ConfigureGetUpdatesDelegate configure_delegate(
401 sync_pb::GetUpdatesCallerInfo::RECONFIGURATION);
402 scoped_ptr<GetUpdatesProcessor> processor(
403 BuildGetUpdatesProcessor(configure_delegate));
405 EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
406 EXPECT_EQ(0, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
408 sessions::StatusController status;
409 processor->ApplyUpdates(GetGuTypes(), &status);
411 EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
412 EXPECT_EQ(1, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
414 EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
415 EXPECT_EQ(0, GetAppliedHandler()->GetApplyUpdatesCount());
418 // Verify that a poll cycle applies updates non-passively to the specified
419 // types.
420 TEST_F(GetUpdatesProcessorApplyUpdatesTest, Poll) {
421 PollGetUpdatesDelegate poll_delegate;
422 scoped_ptr<GetUpdatesProcessor> processor(
423 BuildGetUpdatesProcessor(poll_delegate));
425 EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
426 EXPECT_EQ(0, GetAppliedHandler()->GetApplyUpdatesCount());
428 sessions::StatusController status;
429 processor->ApplyUpdates(GetGuTypes(), &status);
431 EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
432 EXPECT_EQ(1, GetAppliedHandler()->GetApplyUpdatesCount());
434 EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
435 EXPECT_EQ(0, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
438 class DownloadUpdatesDebugInfoTest : public ::testing::Test {
439 public:
440 DownloadUpdatesDebugInfoTest() {}
441 virtual ~DownloadUpdatesDebugInfoTest() {}
443 sessions::StatusController* status() {
444 return &status_;
447 sessions::DebugInfoGetter* debug_info_getter() {
448 return &debug_info_getter_;
451 void AddDebugEvent() {
452 debug_info_getter_.AddDebugEvent();
455 private:
456 sessions::StatusController status_;
457 MockDebugInfoGetter debug_info_getter_;
460 // Verify CopyClientDebugInfo when there are no events to upload.
461 TEST_F(DownloadUpdatesDebugInfoTest, VerifyCopyClientDebugInfo_Empty) {
462 sync_pb::DebugInfo debug_info;
463 GetUpdatesProcessor::CopyClientDebugInfo(debug_info_getter(), &debug_info);
464 EXPECT_EQ(0, debug_info.events_size());
467 TEST_F(DownloadUpdatesDebugInfoTest, VerifyCopyOverwrites) {
468 sync_pb::DebugInfo debug_info;
469 AddDebugEvent();
470 GetUpdatesProcessor::CopyClientDebugInfo(debug_info_getter(), &debug_info);
471 EXPECT_EQ(1, debug_info.events_size());
472 GetUpdatesProcessor::CopyClientDebugInfo(debug_info_getter(), &debug_info);
473 EXPECT_EQ(1, debug_info.events_size());
476 } // namespace syncer