OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "sync/engine/download.h" | 5 #include "sync/engine/download.h" |
6 | 6 |
7 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
9 #include "sync/engine/sync_directory_update_handler.h" | 9 #include "sync/engine/sync_directory_update_handler.h" |
10 #include "sync/internal_api/public/base/model_type_test_util.h" | 10 #include "sync/internal_api/public/base/model_type_test_util.h" |
11 #include "sync/protocol/sync.pb.h" | 11 #include "sync/protocol/sync.pb.h" |
12 #include "sync/sessions/debug_info_getter.h" | 12 #include "sync/sessions/debug_info_getter.h" |
13 #include "sync/sessions/nudge_tracker.h" | 13 #include "sync/sessions/nudge_tracker.h" |
14 #include "sync/sessions/status_controller.h" | 14 #include "sync/sessions/status_controller.h" |
15 #include "sync/syncable/directory.h" | 15 #include "sync/syncable/directory.h" |
16 #include "sync/test/engine/fake_model_worker.h" | 16 #include "sync/test/engine/fake_model_worker.h" |
17 #include "sync/test/engine/test_directory_setter_upper.h" | 17 #include "sync/test/engine/test_directory_setter_upper.h" |
18 #include "sync/test/sessions/mock_debug_info_getter.h" | 18 #include "sync/test/sessions/mock_debug_info_getter.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
20 | 20 |
21 namespace syncer { | 21 namespace syncer { |
22 | 22 |
23 using sessions::MockDebugInfoGetter; | 23 using sessions::MockDebugInfoGetter; |
24 | 24 |
25 // A test fixture for tests exercising download updates functions. | 25 // A test fixture for tests exercising download updates functions. |
26 class DownloadUpdatesTest : public ::testing::Test { | 26 class DownloadUpdatesTest : public ::testing::Test { |
27 protected: | 27 protected: |
28 DownloadUpdatesTest() | 28 DownloadUpdatesTest() {} |
29 : update_handler_map_deleter_(&update_handler_map_) { | |
30 } | |
31 | 29 |
32 virtual void SetUp() { | 30 virtual void SetUp() { |
33 dir_maker_.SetUp(); | 31 dir_maker_.SetUp(); |
34 | 32 |
35 AddUpdateHandler(AUTOFILL, GROUP_DB); | 33 AddUpdateHandler(AUTOFILL, GROUP_DB); |
36 AddUpdateHandler(BOOKMARKS, GROUP_UI); | 34 AddUpdateHandler(BOOKMARKS, GROUP_UI); |
37 AddUpdateHandler(PREFERENCES, GROUP_UI); | 35 AddUpdateHandler(PREFERENCES, GROUP_UI); |
38 } | 36 } |
39 | 37 |
40 virtual void TearDown() { | 38 virtual void TearDown() { |
41 dir_maker_.TearDown(); | 39 dir_maker_.TearDown(); |
42 } | 40 } |
43 | 41 |
44 ModelTypeSet proto_request_types() { | 42 ModelTypeSet proto_request_types() { |
45 ModelTypeSet types; | 43 return proto_request_types_; |
46 for (UpdateHandlerMap::iterator it = update_handler_map_.begin(); | |
47 it != update_handler_map_.end(); ++it) { | |
48 types.Put(it->first); | |
49 } | |
50 return types; | |
51 } | 44 } |
52 | 45 |
53 syncable::Directory* directory() { | 46 syncable::Directory* directory() { |
54 return dir_maker_.directory(); | 47 return dir_maker_.directory(); |
55 } | 48 } |
56 | 49 |
57 UpdateHandlerMap* update_handler_map() { | 50 GetUpdatesProcessor* get_updates_processor() { |
58 return &update_handler_map_; | 51 return get_updates_processor_.get(); |
59 } | 52 } |
60 | 53 |
61 void InitFakeUpdateResponse(sync_pb::GetUpdatesResponse* response) { | 54 void InitFakeUpdateResponse(sync_pb::GetUpdatesResponse* response) { |
62 ModelTypeSet types = proto_request_types(); | 55 ModelTypeSet types = proto_request_types(); |
63 | 56 |
64 for (ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) { | 57 for (ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) { |
65 sync_pb::DataTypeProgressMarker* marker = | 58 sync_pb::DataTypeProgressMarker* marker = |
66 response->add_new_progress_marker(); | 59 response->add_new_progress_marker(); |
67 marker->set_data_type_id(GetSpecificsFieldNumberFromModelType(it.Get())); | 60 marker->set_data_type_id(GetSpecificsFieldNumberFromModelType(it.Get())); |
68 marker->set_token("foobarbaz"); | 61 marker->set_token("foobarbaz"); |
69 } | 62 } |
70 | 63 |
71 response->set_changes_remaining(0); | 64 response->set_changes_remaining(0); |
72 } | 65 } |
73 | 66 |
74 private: | 67 private: |
75 void AddUpdateHandler(ModelType type, ModelSafeGroup group) { | 68 void AddUpdateHandler(ModelType type, ModelSafeGroup group) { |
76 DCHECK(directory()); | 69 DCHECK(directory()); |
| 70 |
| 71 proto_request_types_.Put(type); |
| 72 |
77 scoped_refptr<ModelSafeWorker> worker = new FakeModelWorker(group); | 73 scoped_refptr<ModelSafeWorker> worker = new FakeModelWorker(group); |
78 SyncDirectoryUpdateHandler* handler = | 74 SyncDirectoryUpdateHandler* handler = |
79 new SyncDirectoryUpdateHandler(directory(), type, worker); | 75 new SyncDirectoryUpdateHandler(directory(), type, worker); |
80 update_handler_map_.insert(std::make_pair(type, handler)); | 76 update_handler_map_.insert(std::make_pair(type, handler)); |
| 77 get_updates_processor_.reset(new GetUpdatesProcessor(&update_handler_map_)); |
81 } | 78 } |
82 | 79 |
83 base::MessageLoop loop_; // Needed for directory init. | 80 base::MessageLoop loop_; // Needed for directory init. |
84 TestDirectorySetterUpper dir_maker_; | 81 TestDirectorySetterUpper dir_maker_; |
85 | 82 |
| 83 ModelTypeSet proto_request_types_; |
86 UpdateHandlerMap update_handler_map_; | 84 UpdateHandlerMap update_handler_map_; |
87 STLValueDeleter<UpdateHandlerMap> update_handler_map_deleter_; | 85 scoped_ptr<GetUpdatesProcessor> get_updates_processor_; |
88 | 86 |
89 DISALLOW_COPY_AND_ASSIGN(DownloadUpdatesTest); | 87 DISALLOW_COPY_AND_ASSIGN(DownloadUpdatesTest); |
90 }; | 88 }; |
91 | 89 |
92 // Basic test to make sure nudges are expressed properly in the request. | 90 // Basic test to make sure nudges are expressed properly in the request. |
93 TEST_F(DownloadUpdatesTest, BookmarkNudge) { | 91 TEST_F(DownloadUpdatesTest, BookmarkNudge) { |
94 sessions::NudgeTracker nudge_tracker; | 92 sessions::NudgeTracker nudge_tracker; |
95 nudge_tracker.RecordLocalChange(ModelTypeSet(BOOKMARKS)); | 93 nudge_tracker.RecordLocalChange(ModelTypeSet(BOOKMARKS)); |
96 | 94 |
97 sync_pb::ClientToServerMessage msg; | 95 sync_pb::ClientToServerMessage msg; |
98 download::BuildNormalDownloadUpdatesImpl(proto_request_types(), | 96 download::BuildNormalDownloadUpdatesImpl(proto_request_types(), |
99 update_handler_map(), | 97 get_updates_processor(), |
100 nudge_tracker, | 98 nudge_tracker, |
101 msg.mutable_get_updates()); | 99 msg.mutable_get_updates()); |
102 | 100 |
103 const sync_pb::GetUpdatesMessage& gu_msg = msg.get_updates(); | 101 const sync_pb::GetUpdatesMessage& gu_msg = msg.get_updates(); |
104 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::LOCAL, | 102 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::LOCAL, |
105 gu_msg.caller_info().source()); | 103 gu_msg.caller_info().source()); |
106 EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, gu_msg.get_updates_origin()); | 104 EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, gu_msg.get_updates_origin()); |
107 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) { | 105 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) { |
108 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber( | 106 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber( |
109 gu_msg.from_progress_marker(i).data_type_id()); | 107 gu_msg.from_progress_marker(i).data_type_id()); |
(...skipping 27 matching lines...) Expand all Loading... |
137 BuildInvalidationMap(BOOKMARKS, 1, "bookmark_payload")); | 135 BuildInvalidationMap(BOOKMARKS, 1, "bookmark_payload")); |
138 nudge_tracker.RecordRemoteInvalidation( | 136 nudge_tracker.RecordRemoteInvalidation( |
139 BuildInvalidationMap(PREFERENCES, 1, "preferences_payload")); | 137 BuildInvalidationMap(PREFERENCES, 1, "preferences_payload")); |
140 ModelTypeSet notified_types; | 138 ModelTypeSet notified_types; |
141 notified_types.Put(AUTOFILL); | 139 notified_types.Put(AUTOFILL); |
142 notified_types.Put(BOOKMARKS); | 140 notified_types.Put(BOOKMARKS); |
143 notified_types.Put(PREFERENCES); | 141 notified_types.Put(PREFERENCES); |
144 | 142 |
145 sync_pb::ClientToServerMessage msg; | 143 sync_pb::ClientToServerMessage msg; |
146 download::BuildNormalDownloadUpdatesImpl(proto_request_types(), | 144 download::BuildNormalDownloadUpdatesImpl(proto_request_types(), |
147 update_handler_map(), | 145 get_updates_processor(), |
148 nudge_tracker, | 146 nudge_tracker, |
149 msg.mutable_get_updates()); | 147 msg.mutable_get_updates()); |
150 | 148 |
151 const sync_pb::GetUpdatesMessage& gu_msg = msg.get_updates(); | 149 const sync_pb::GetUpdatesMessage& gu_msg = msg.get_updates(); |
152 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::NOTIFICATION, | 150 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::NOTIFICATION, |
153 gu_msg.caller_info().source()); | 151 gu_msg.caller_info().source()); |
154 EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, gu_msg.get_updates_origin()); | 152 EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, gu_msg.get_updates_origin()); |
155 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) { | 153 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) { |
156 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber( | 154 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber( |
157 gu_msg.from_progress_marker(i).data_type_id()); | 155 gu_msg.from_progress_marker(i).data_type_id()); |
(...skipping 13 matching lines...) Expand all Loading... |
171 EXPECT_FALSE(progress_marker.has_notification_hint()); | 169 EXPECT_FALSE(progress_marker.has_notification_hint()); |
172 EXPECT_EQ(0, gu_trigger.notification_hint_size()); | 170 EXPECT_EQ(0, gu_trigger.notification_hint_size()); |
173 } | 171 } |
174 } | 172 } |
175 } | 173 } |
176 | 174 |
177 TEST_F(DownloadUpdatesTest, ConfigureTest) { | 175 TEST_F(DownloadUpdatesTest, ConfigureTest) { |
178 sync_pb::ClientToServerMessage msg; | 176 sync_pb::ClientToServerMessage msg; |
179 download::BuildDownloadUpdatesForConfigureImpl( | 177 download::BuildDownloadUpdatesForConfigureImpl( |
180 proto_request_types(), | 178 proto_request_types(), |
181 update_handler_map(), | 179 get_updates_processor(), |
182 sync_pb::GetUpdatesCallerInfo::RECONFIGURATION, | 180 sync_pb::GetUpdatesCallerInfo::RECONFIGURATION, |
183 msg.mutable_get_updates()); | 181 msg.mutable_get_updates()); |
184 | 182 |
185 const sync_pb::GetUpdatesMessage& gu_msg = msg.get_updates(); | 183 const sync_pb::GetUpdatesMessage& gu_msg = msg.get_updates(); |
186 | 184 |
187 EXPECT_EQ(sync_pb::SyncEnums::RECONFIGURATION, gu_msg.get_updates_origin()); | 185 EXPECT_EQ(sync_pb::SyncEnums::RECONFIGURATION, gu_msg.get_updates_origin()); |
188 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RECONFIGURATION, | 186 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RECONFIGURATION, |
189 gu_msg.caller_info().source()); | 187 gu_msg.caller_info().source()); |
190 | 188 |
191 ModelTypeSet progress_types; | 189 ModelTypeSet progress_types; |
192 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) { | 190 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) { |
193 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber( | 191 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber( |
194 gu_msg.from_progress_marker(i).data_type_id()); | 192 gu_msg.from_progress_marker(i).data_type_id()); |
195 progress_types.Put(type); | 193 progress_types.Put(type); |
196 } | 194 } |
197 EXPECT_TRUE(proto_request_types().Equals(progress_types)); | 195 EXPECT_TRUE(proto_request_types().Equals(progress_types)); |
198 } | 196 } |
199 | 197 |
200 TEST_F(DownloadUpdatesTest, PollTest) { | 198 TEST_F(DownloadUpdatesTest, PollTest) { |
201 sync_pb::ClientToServerMessage msg; | 199 sync_pb::ClientToServerMessage msg; |
202 download::BuildDownloadUpdatesForPollImpl( | 200 download::BuildDownloadUpdatesForPollImpl( |
203 proto_request_types(), | 201 proto_request_types(), |
204 update_handler_map(), | 202 get_updates_processor(), |
205 msg.mutable_get_updates()); | 203 msg.mutable_get_updates()); |
206 | 204 |
207 const sync_pb::GetUpdatesMessage& gu_msg = msg.get_updates(); | 205 const sync_pb::GetUpdatesMessage& gu_msg = msg.get_updates(); |
208 | 206 |
209 EXPECT_EQ(sync_pb::SyncEnums::PERIODIC, gu_msg.get_updates_origin()); | 207 EXPECT_EQ(sync_pb::SyncEnums::PERIODIC, gu_msg.get_updates_origin()); |
210 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::PERIODIC, | 208 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::PERIODIC, |
211 gu_msg.caller_info().source()); | 209 gu_msg.caller_info().source()); |
212 | 210 |
213 ModelTypeSet progress_types; | 211 ModelTypeSet progress_types; |
214 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) { | 212 for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) { |
215 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber( | 213 syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber( |
216 gu_msg.from_progress_marker(i).data_type_id()); | 214 gu_msg.from_progress_marker(i).data_type_id()); |
217 progress_types.Put(type); | 215 progress_types.Put(type); |
218 } | 216 } |
219 EXPECT_TRUE(proto_request_types().Equals(progress_types)); | 217 EXPECT_TRUE(proto_request_types().Equals(progress_types)); |
220 } | 218 } |
221 | 219 |
222 // Verify that a bogus response message is detected. | 220 // Verify that a bogus response message is detected. |
223 TEST_F(DownloadUpdatesTest, InvalidResponse) { | 221 TEST_F(DownloadUpdatesTest, InvalidResponse) { |
224 sync_pb::GetUpdatesResponse gu_response; | 222 sync_pb::GetUpdatesResponse gu_response; |
225 InitFakeUpdateResponse(&gu_response); | 223 InitFakeUpdateResponse(&gu_response); |
226 | 224 |
227 // This field is essential for making the client stop looping. If it's unset | 225 // This field is essential for making the client stop looping. If it's unset |
228 // then something is very wrong. The client should detect this. | 226 // then something is very wrong. The client should detect this. |
229 gu_response.clear_changes_remaining(); | 227 gu_response.clear_changes_remaining(); |
230 | 228 |
231 sessions::StatusController status; | 229 sessions::StatusController status; |
232 SyncerError error = download::ProcessResponse(gu_response, | 230 SyncerError error = download::ProcessResponse(gu_response, |
233 proto_request_types(), | 231 proto_request_types(), |
234 update_handler_map(), | 232 get_updates_processor(), |
235 &status); | 233 &status); |
236 EXPECT_EQ(error, SERVER_RESPONSE_VALIDATION_FAILED); | 234 EXPECT_EQ(error, SERVER_RESPONSE_VALIDATION_FAILED); |
237 } | 235 } |
238 | 236 |
239 // Verify that we correctly detect when there's more work to be done. | 237 // Verify that we correctly detect when there's more work to be done. |
240 TEST_F(DownloadUpdatesTest, MoreToDownloadResponse) { | 238 TEST_F(DownloadUpdatesTest, MoreToDownloadResponse) { |
241 sync_pb::GetUpdatesResponse gu_response; | 239 sync_pb::GetUpdatesResponse gu_response; |
242 InitFakeUpdateResponse(&gu_response); | 240 InitFakeUpdateResponse(&gu_response); |
243 gu_response.set_changes_remaining(1); | 241 gu_response.set_changes_remaining(1); |
244 | 242 |
245 sessions::StatusController status; | 243 sessions::StatusController status; |
246 SyncerError error = download::ProcessResponse(gu_response, | 244 SyncerError error = download::ProcessResponse(gu_response, |
247 proto_request_types(), | 245 proto_request_types(), |
248 update_handler_map(), | 246 get_updates_processor(), |
249 &status); | 247 &status); |
250 EXPECT_EQ(error, SERVER_MORE_TO_DOWNLOAD); | 248 EXPECT_EQ(error, SERVER_MORE_TO_DOWNLOAD); |
251 } | 249 } |
252 | 250 |
253 // A simple scenario: No updates returned and nothing more to download. | 251 // A simple scenario: No updates returned and nothing more to download. |
254 TEST_F(DownloadUpdatesTest, NormalResponseTest) { | 252 TEST_F(DownloadUpdatesTest, NormalResponseTest) { |
255 sync_pb::GetUpdatesResponse gu_response; | 253 sync_pb::GetUpdatesResponse gu_response; |
256 InitFakeUpdateResponse(&gu_response); | 254 InitFakeUpdateResponse(&gu_response); |
257 gu_response.set_changes_remaining(0); | 255 gu_response.set_changes_remaining(0); |
258 | 256 |
259 sessions::StatusController status; | 257 sessions::StatusController status; |
260 SyncerError error = download::ProcessResponse(gu_response, | 258 SyncerError error = download::ProcessResponse(gu_response, |
261 proto_request_types(), | 259 proto_request_types(), |
262 update_handler_map(), | 260 get_updates_processor(), |
263 &status); | 261 &status); |
264 EXPECT_EQ(error, SYNCER_OK); | 262 EXPECT_EQ(error, SYNCER_OK); |
265 } | 263 } |
266 | 264 |
267 class DownloadUpdatesDebugInfoTest : public ::testing::Test { | 265 class DownloadUpdatesDebugInfoTest : public ::testing::Test { |
268 public: | 266 public: |
269 DownloadUpdatesDebugInfoTest() {} | 267 DownloadUpdatesDebugInfoTest() {} |
270 virtual ~DownloadUpdatesDebugInfoTest() {} | 268 virtual ~DownloadUpdatesDebugInfoTest() {} |
271 | 269 |
272 sessions::StatusController* status() { | 270 sessions::StatusController* status() { |
(...skipping 24 matching lines...) Expand all Loading... |
297 TEST_F(DownloadUpdatesDebugInfoTest, VerifyCopyOverwrites) { | 295 TEST_F(DownloadUpdatesDebugInfoTest, VerifyCopyOverwrites) { |
298 sync_pb::DebugInfo debug_info; | 296 sync_pb::DebugInfo debug_info; |
299 AddDebugEvent(); | 297 AddDebugEvent(); |
300 download::CopyClientDebugInfo(debug_info_getter(), &debug_info); | 298 download::CopyClientDebugInfo(debug_info_getter(), &debug_info); |
301 EXPECT_EQ(1, debug_info.events_size()); | 299 EXPECT_EQ(1, debug_info.events_size()); |
302 download::CopyClientDebugInfo(debug_info_getter(), &debug_info); | 300 download::CopyClientDebugInfo(debug_info_getter(), &debug_info); |
303 EXPECT_EQ(1, debug_info.events_size()); | 301 EXPECT_EQ(1, debug_info.events_size()); |
304 } | 302 } |
305 | 303 |
306 } // namespace syncer | 304 } // namespace syncer |
OLD | NEW |