OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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/directory_update_handler.h" | 5 #include "sync/engine/directory_update_handler.h" |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "sync/engine/syncer_proto_util.h" | 10 #include "sync/engine/syncer_proto_util.h" |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 return ui_worker_; | 77 return ui_worker_; |
78 } | 78 } |
79 | 79 |
80 bool EntryExists(const std::string& id) { | 80 bool EntryExists(const std::string& id) { |
81 syncable::ReadTransaction trans(FROM_HERE, dir()); | 81 syncable::ReadTransaction trans(FROM_HERE, dir()); |
82 syncable::Entry e(&trans, syncable::GET_BY_ID, | 82 syncable::Entry e(&trans, syncable::GET_BY_ID, |
83 Id::CreateFromServerId(id)); | 83 Id::CreateFromServerId(id)); |
84 return e.good() && !e.GetIsDel(); | 84 return e.good() && !e.GetIsDel(); |
85 } | 85 } |
86 | 86 |
| 87 bool TypeRootExists(ModelType model_type) { |
| 88 syncable::ReadTransaction trans(FROM_HERE, dir()); |
| 89 syncable::Entry e(&trans, syncable::GET_TYPE_ROOT, model_type); |
| 90 return e.good() && !e.GetIsDel(); |
| 91 } |
| 92 |
87 protected: | 93 protected: |
88 // Used in the construction of DirectoryTypeDebugInfoEmitters. | 94 // Used in the construction of DirectoryTypeDebugInfoEmitters. |
89 ObserverList<TypeDebugInfoObserver> type_observers_; | 95 ObserverList<TypeDebugInfoObserver> type_observers_; |
90 | 96 |
91 private: | 97 private: |
92 base::MessageLoop loop_; // Needed to initialize the directory. | 98 base::MessageLoop loop_; // Needed to initialize the directory. |
93 TestDirectorySetterUpper dir_maker_; | 99 TestDirectorySetterUpper dir_maker_; |
94 scoped_refptr<FakeModelWorker> ui_worker_; | 100 scoped_refptr<FakeModelWorker> ui_worker_; |
95 }; | 101 }; |
96 | 102 |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 GetSpecificsFieldNumberFromModelType(SYNCED_NOTIFICATIONS)); | 266 GetSpecificsFieldNumberFromModelType(SYNCED_NOTIFICATIONS)); |
261 progress.set_token("token"); | 267 progress.set_token("token"); |
262 progress.mutable_gc_directive()->set_version_watermark(kDefaultVersion + 10); | 268 progress.mutable_gc_directive()->set_version_watermark(kDefaultVersion + 10); |
263 | 269 |
264 sync_pb::DataTypeContext context; | 270 sync_pb::DataTypeContext context; |
265 context.set_data_type_id( | 271 context.set_data_type_id( |
266 GetSpecificsFieldNumberFromModelType(SYNCED_NOTIFICATIONS)); | 272 GetSpecificsFieldNumberFromModelType(SYNCED_NOTIFICATIONS)); |
267 context.set_context("context"); | 273 context.set_context("context"); |
268 context.set_version(1); | 274 context.set_version(1); |
269 | 275 |
270 scoped_ptr<sync_pb::SyncEntity> type_root = | |
271 CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("root")), | |
272 Id::GetRoot().GetServerId(), SYNCED_NOTIFICATIONS); | |
273 type_root->set_server_defined_unique_tag( | |
274 ModelTypeToRootTag(SYNCED_NOTIFICATIONS)); | |
275 type_root->set_folder(true); | |
276 | |
277 scoped_ptr<sync_pb::SyncEntity> e1 = | 276 scoped_ptr<sync_pb::SyncEntity> e1 = |
278 CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e1")), | 277 CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e1")), "", |
279 type_root->id_string(), | |
280 SYNCED_NOTIFICATIONS); | 278 SYNCED_NOTIFICATIONS); |
281 | 279 |
282 scoped_ptr<sync_pb::SyncEntity> e2 = | 280 scoped_ptr<sync_pb::SyncEntity> e2 = |
283 CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e2")), | 281 CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e2")), "", |
284 type_root->id_string(), | |
285 SYNCED_NOTIFICATIONS); | 282 SYNCED_NOTIFICATIONS); |
286 e2->set_version(kDefaultVersion + 100); | 283 e2->set_version(kDefaultVersion + 100); |
287 | 284 |
288 // Add to the applicable updates list. | 285 // Add to the applicable updates list. |
289 SyncEntityList updates; | 286 SyncEntityList updates; |
290 updates.push_back(type_root.get()); | |
291 updates.push_back(e1.get()); | 287 updates.push_back(e1.get()); |
292 updates.push_back(e2.get()); | 288 updates.push_back(e2.get()); |
293 | 289 |
294 // Process and apply updates. | 290 // Process and apply updates. |
295 EXPECT_EQ( | 291 EXPECT_EQ( |
296 SYNCER_OK, | 292 SYNCER_OK, |
297 handler.ProcessGetUpdatesResponse(progress, context, updates, &status)); | 293 handler.ProcessGetUpdatesResponse(progress, context, updates, &status)); |
298 handler.ApplyUpdates(&status); | 294 handler.ApplyUpdates(&status); |
299 | 295 |
300 // Verify none is deleted because they are unapplied during GC. | 296 // Verify none is deleted because they are unapplied during GC. |
301 EXPECT_TRUE(EntryExists(type_root->id_string())); | 297 EXPECT_TRUE(TypeRootExists(SYNCED_NOTIFICATIONS)); |
302 EXPECT_TRUE(EntryExists(e1->id_string())); | 298 EXPECT_TRUE(EntryExists(e1->id_string())); |
303 EXPECT_TRUE(EntryExists(e2->id_string())); | 299 EXPECT_TRUE(EntryExists(e2->id_string())); |
304 | 300 |
305 // Process and apply again. Old entry is deleted but not root. | 301 // Process and apply again. Old entry is deleted but not root. |
306 progress.mutable_gc_directive()->set_version_watermark(kDefaultVersion + 20); | 302 progress.mutable_gc_directive()->set_version_watermark(kDefaultVersion + 20); |
307 EXPECT_EQ(SYNCER_OK, | 303 EXPECT_EQ(SYNCER_OK, |
308 handler.ProcessGetUpdatesResponse( | 304 handler.ProcessGetUpdatesResponse( |
309 progress, context, SyncEntityList(), &status)); | 305 progress, context, SyncEntityList(), &status)); |
310 handler.ApplyUpdates(&status); | 306 handler.ApplyUpdates(&status); |
311 EXPECT_TRUE(EntryExists(type_root->id_string())); | |
312 EXPECT_FALSE(EntryExists(e1->id_string())); | 307 EXPECT_FALSE(EntryExists(e1->id_string())); |
313 EXPECT_TRUE(EntryExists(e2->id_string())); | 308 EXPECT_TRUE(EntryExists(e2->id_string())); |
314 } | 309 } |
315 | 310 |
316 TEST_F(DirectoryUpdateHandlerProcessUpdateTest, ContextVersion) { | 311 TEST_F(DirectoryUpdateHandlerProcessUpdateTest, ContextVersion) { |
317 DirectoryTypeDebugInfoEmitter emitter(SYNCED_NOTIFICATIONS, &type_observers_); | 312 DirectoryTypeDebugInfoEmitter emitter(SYNCED_NOTIFICATIONS, &type_observers_); |
318 DirectoryUpdateHandler handler(dir(), SYNCED_NOTIFICATIONS, | 313 DirectoryUpdateHandler handler(dir(), SYNCED_NOTIFICATIONS, |
319 ui_worker(), &emitter); | 314 ui_worker(), &emitter); |
320 sessions::StatusController status; | 315 sessions::StatusController status; |
321 int field_number = GetSpecificsFieldNumberFromModelType(SYNCED_NOTIFICATIONS); | 316 int field_number = GetSpecificsFieldNumberFromModelType(SYNCED_NOTIFICATIONS); |
322 | 317 |
323 sync_pb::DataTypeProgressMarker progress; | 318 sync_pb::DataTypeProgressMarker progress; |
324 progress.set_data_type_id( | 319 progress.set_data_type_id( |
325 GetSpecificsFieldNumberFromModelType(SYNCED_NOTIFICATIONS)); | 320 GetSpecificsFieldNumberFromModelType(SYNCED_NOTIFICATIONS)); |
326 progress.set_token("token"); | 321 progress.set_token("token"); |
327 | 322 |
328 sync_pb::DataTypeContext old_context; | 323 sync_pb::DataTypeContext old_context; |
329 old_context.set_version(1); | 324 old_context.set_version(1); |
330 old_context.set_context("data"); | 325 old_context.set_context("data"); |
331 old_context.set_data_type_id(field_number); | 326 old_context.set_data_type_id(field_number); |
332 | 327 |
333 scoped_ptr<sync_pb::SyncEntity> type_root = | |
334 CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("root")), | |
335 Id::GetRoot().GetServerId(), SYNCED_NOTIFICATIONS); | |
336 type_root->set_server_defined_unique_tag( | |
337 ModelTypeToRootTag(SYNCED_NOTIFICATIONS)); | |
338 type_root->set_folder(true); | |
339 scoped_ptr<sync_pb::SyncEntity> e1 = | 328 scoped_ptr<sync_pb::SyncEntity> e1 = |
340 CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e1")), | 329 CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e1")), "", |
341 type_root->id_string(), | |
342 SYNCED_NOTIFICATIONS); | 330 SYNCED_NOTIFICATIONS); |
343 | 331 |
344 SyncEntityList updates; | 332 SyncEntityList updates; |
345 updates.push_back(type_root.get()); | |
346 updates.push_back(e1.get()); | 333 updates.push_back(e1.get()); |
347 | 334 |
348 // The first response should be processed fine. | 335 // The first response should be processed fine. |
349 EXPECT_EQ(SYNCER_OK, | 336 EXPECT_EQ(SYNCER_OK, |
350 handler.ProcessGetUpdatesResponse( | 337 handler.ProcessGetUpdatesResponse( |
351 progress, old_context, updates, &status)); | 338 progress, old_context, updates, &status)); |
352 handler.ApplyUpdates(&status); | 339 handler.ApplyUpdates(&status); |
353 | 340 |
354 EXPECT_TRUE(EntryExists(type_root->id_string())); | 341 // The PREFERENCES root should be auto-created. |
| 342 EXPECT_TRUE(TypeRootExists(SYNCED_NOTIFICATIONS)); |
| 343 |
355 EXPECT_TRUE(EntryExists(e1->id_string())); | 344 EXPECT_TRUE(EntryExists(e1->id_string())); |
356 | 345 |
357 { | 346 { |
358 sync_pb::DataTypeContext dir_context; | 347 sync_pb::DataTypeContext dir_context; |
359 syncable::ReadTransaction trans(FROM_HERE, dir()); | 348 syncable::ReadTransaction trans(FROM_HERE, dir()); |
360 trans.directory()->GetDataTypeContext( | 349 trans.directory()->GetDataTypeContext( |
361 &trans, SYNCED_NOTIFICATIONS, &dir_context); | 350 &trans, SYNCED_NOTIFICATIONS, &dir_context); |
362 EXPECT_EQ(old_context.SerializeAsString(), dir_context.SerializeAsString()); | 351 EXPECT_EQ(old_context.SerializeAsString(), dir_context.SerializeAsString()); |
363 } | 352 } |
364 | 353 |
365 sync_pb::DataTypeContext new_context; | 354 sync_pb::DataTypeContext new_context; |
366 new_context.set_version(0); | 355 new_context.set_version(0); |
367 new_context.set_context("old"); | 356 new_context.set_context("old"); |
368 new_context.set_data_type_id(field_number); | 357 new_context.set_data_type_id(field_number); |
369 | 358 |
370 scoped_ptr<sync_pb::SyncEntity> e2 = | 359 scoped_ptr<sync_pb::SyncEntity> e2 = |
371 CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e2")), | 360 CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e2")), "", |
372 type_root->id_string(), | |
373 SYNCED_NOTIFICATIONS); | 361 SYNCED_NOTIFICATIONS); |
374 updates.clear(); | 362 updates.clear(); |
375 updates.push_back(e2.get()); | 363 updates.push_back(e2.get()); |
376 | 364 |
377 // The second response, with an old context version, should result in an | 365 // The second response, with an old context version, should result in an |
378 // error and the updates should be dropped. | 366 // error and the updates should be dropped. |
379 EXPECT_EQ(DATATYPE_TRIGGERED_RETRY, | 367 EXPECT_EQ(DATATYPE_TRIGGERED_RETRY, |
380 handler.ProcessGetUpdatesResponse( | 368 handler.ProcessGetUpdatesResponse( |
381 progress, new_context, updates, &status)); | 369 progress, new_context, updates, &status)); |
382 handler.ApplyUpdates(&status); | 370 handler.ApplyUpdates(&status); |
(...skipping 20 matching lines...) Expand all Loading... |
403 sync_pb::DataTypeProgressMarker progress; | 391 sync_pb::DataTypeProgressMarker progress; |
404 progress.set_data_type_id(GetSpecificsFieldNumberFromModelType(ARTICLES)); | 392 progress.set_data_type_id(GetSpecificsFieldNumberFromModelType(ARTICLES)); |
405 progress.set_token("token"); | 393 progress.set_token("token"); |
406 progress.mutable_gc_directive()->set_version_watermark(kDefaultVersion + 10); | 394 progress.mutable_gc_directive()->set_version_watermark(kDefaultVersion + 10); |
407 | 395 |
408 sync_pb::DataTypeContext context; | 396 sync_pb::DataTypeContext context; |
409 context.set_data_type_id(GetSpecificsFieldNumberFromModelType(ARTICLES)); | 397 context.set_data_type_id(GetSpecificsFieldNumberFromModelType(ARTICLES)); |
410 context.set_context("context"); | 398 context.set_context("context"); |
411 context.set_version(1); | 399 context.set_version(1); |
412 | 400 |
413 scoped_ptr<sync_pb::SyncEntity> type_root = | 401 scoped_ptr<sync_pb::SyncEntity> e1 = CreateUpdate( |
414 CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("root")), | 402 SyncableIdToProto(Id::CreateFromServerId("e1")), "", ARTICLES); |
415 Id::GetRoot().GetServerId(), ARTICLES); | |
416 type_root->set_server_defined_unique_tag(ModelTypeToRootTag(ARTICLES)); | |
417 type_root->set_folder(true); | |
418 | |
419 scoped_ptr<sync_pb::SyncEntity> e1 = | |
420 CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e1")), | |
421 type_root->id_string(), | |
422 ARTICLES); | |
423 sync_pb::AttachmentIdProto* attachment_id = e1->add_attachment_id(); | 403 sync_pb::AttachmentIdProto* attachment_id = e1->add_attachment_id(); |
424 *attachment_id = CreateAttachmentIdProto(); | 404 *attachment_id = CreateAttachmentIdProto(); |
425 | 405 |
426 SyncEntityList updates; | 406 SyncEntityList updates; |
427 updates.push_back(type_root.get()); | |
428 updates.push_back(e1.get()); | 407 updates.push_back(e1.get()); |
429 | 408 |
430 // Process and apply updates. | 409 // Process and apply updates. |
431 EXPECT_EQ( | 410 EXPECT_EQ( |
432 SYNCER_OK, | 411 SYNCER_OK, |
433 handler.ProcessGetUpdatesResponse(progress, context, updates, &status)); | 412 handler.ProcessGetUpdatesResponse(progress, context, updates, &status)); |
434 handler.ApplyUpdates(&status); | 413 handler.ApplyUpdates(&status); |
435 | 414 |
436 ASSERT_TRUE(EntryExists(type_root->id_string())); | 415 ASSERT_TRUE(TypeRootExists(ARTICLES)); |
437 ASSERT_TRUE(EntryExists(e1->id_string())); | 416 ASSERT_TRUE(EntryExists(e1->id_string())); |
438 { | 417 { |
439 syncable::ReadTransaction trans(FROM_HERE, dir()); | 418 syncable::ReadTransaction trans(FROM_HERE, dir()); |
440 syncable::Entry e(&trans, | 419 syncable::Entry e(&trans, |
441 syncable::GET_BY_ID, | 420 syncable::GET_BY_ID, |
442 Id::CreateFromServerId(e1->id_string())); | 421 Id::CreateFromServerId(e1->id_string())); |
443 | 422 |
444 // See that the attachment_metadata is correct. | 423 // See that the attachment_metadata is correct. |
445 sync_pb::AttachmentMetadata attachment_metadata = e.GetAttachmentMetadata(); | 424 sync_pb::AttachmentMetadata attachment_metadata = e.GetAttachmentMetadata(); |
446 ASSERT_EQ(1, attachment_metadata.record_size()); | 425 ASSERT_EQ(1, attachment_metadata.record_size()); |
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1175 const UpdateCounters& counters = GetArticlesUpdateCounters(); | 1154 const UpdateCounters& counters = GetArticlesUpdateCounters(); |
1176 EXPECT_EQ(1, counters.num_updates_applied); | 1155 EXPECT_EQ(1, counters.num_updates_applied); |
1177 EXPECT_EQ(1, counters.num_local_overwrites); | 1156 EXPECT_EQ(1, counters.num_local_overwrites); |
1178 EXPECT_EQ(0, counters.num_server_overwrites); | 1157 EXPECT_EQ(0, counters.num_server_overwrites); |
1179 local_metadata = entry_factory()->GetLocalAttachmentMetadataForItem(handle); | 1158 local_metadata = entry_factory()->GetLocalAttachmentMetadataForItem(handle); |
1180 EXPECT_EQ(server_metadata.SerializeAsString(), | 1159 EXPECT_EQ(server_metadata.SerializeAsString(), |
1181 local_metadata.SerializeAsString()); | 1160 local_metadata.SerializeAsString()); |
1182 } | 1161 } |
1183 | 1162 |
1184 } // namespace syncer | 1163 } // namespace syncer |
OLD | NEW |