| 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 |