Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(114)

Side by Side Diff: sync/engine/directory_update_handler_unittest.cc

Issue 393083004: Update Commit and GetUpdatesResponse messages to include attachment ids. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Update SyncManagerImpl to detect attachment metadata changes. Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sync/engine/directory_commit_contribution_unittest.cc ('k') | sync/engine/get_commit_ids.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "sync/internal_api/public/base/attachment_id_proto.h"
11 #include "sync/internal_api/public/base/model_type.h" 12 #include "sync/internal_api/public/base/model_type.h"
12 #include "sync/internal_api/public/test/test_entry_factory.h" 13 #include "sync/internal_api/public/test/test_entry_factory.h"
13 #include "sync/protocol/sync.pb.h" 14 #include "sync/protocol/sync.pb.h"
14 #include "sync/sessions/directory_type_debug_info_emitter.h" 15 #include "sync/sessions/directory_type_debug_info_emitter.h"
15 #include "sync/sessions/status_controller.h" 16 #include "sync/sessions/status_controller.h"
16 #include "sync/syncable/directory.h" 17 #include "sync/syncable/directory.h"
17 #include "sync/syncable/entry.h" 18 #include "sync/syncable/entry.h"
18 #include "sync/syncable/mutable_entry.h" 19 #include "sync/syncable/mutable_entry.h"
19 #include "sync/syncable/syncable_model_neutral_write_transaction.h" 20 #include "sync/syncable/syncable_model_neutral_write_transaction.h"
20 #include "sync/syncable/syncable_proto_util.h" 21 #include "sync/syncable/syncable_proto_util.h"
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 390
390 { 391 {
391 sync_pb::DataTypeContext dir_context; 392 sync_pb::DataTypeContext dir_context;
392 syncable::ReadTransaction trans(FROM_HERE, dir()); 393 syncable::ReadTransaction trans(FROM_HERE, dir());
393 trans.directory()->GetDataTypeContext( 394 trans.directory()->GetDataTypeContext(
394 &trans, SYNCED_NOTIFICATIONS, &dir_context); 395 &trans, SYNCED_NOTIFICATIONS, &dir_context);
395 EXPECT_EQ(old_context.SerializeAsString(), dir_context.SerializeAsString()); 396 EXPECT_EQ(old_context.SerializeAsString(), dir_context.SerializeAsString());
396 } 397 }
397 } 398 }
398 399
400 // See that updates containing attachment metadata are applied
401 // (i.e. server_attachment_metadata is copied to attachment_metadata).
402 TEST_F(DirectoryUpdateHandlerProcessUpdateTest,
403 ProcessAndApplyUpdatesWithAttachments) {
404 DirectoryTypeDebugInfoEmitter emitter(ARTICLES, &type_observers_);
405 DirectoryUpdateHandler handler(dir(), ARTICLES, ui_worker(), &emitter);
406 sessions::StatusController status;
407
408 sync_pb::DataTypeProgressMarker progress;
409 progress.set_data_type_id(GetSpecificsFieldNumberFromModelType(ARTICLES));
410 progress.set_token("token");
411 progress.mutable_gc_directive()->set_version_watermark(kDefaultVersion + 10);
412
413 sync_pb::DataTypeContext context;
414 context.set_data_type_id(GetSpecificsFieldNumberFromModelType(ARTICLES));
415 context.set_context("context");
416 context.set_version(1);
417
418 scoped_ptr<sync_pb::SyncEntity> type_root =
419 CreateUpdate(SyncableIdToProto(syncable::Id::CreateFromServerId("root")),
420 syncable::GetNullId().GetServerId(),
421 ARTICLES);
422 type_root->set_server_defined_unique_tag(ModelTypeToRootTag(ARTICLES));
423 type_root->set_folder(true);
424
425 scoped_ptr<sync_pb::SyncEntity> e1 =
426 CreateUpdate(SyncableIdToProto(syncable::Id::CreateFromServerId("e1")),
427 type_root->id_string(),
428 ARTICLES);
429 sync_pb::AttachmentIdProto* attachment_id = e1->add_attachment_id();
430 *attachment_id = CreateAttachmentIdProto();
431
432 SyncEntityList updates;
433 updates.push_back(type_root.get());
434 updates.push_back(e1.get());
435
436 // Process and apply updates.
437 EXPECT_EQ(
438 SYNCER_OK,
439 handler.ProcessGetUpdatesResponse(progress, context, updates, &status));
440 handler.ApplyUpdates(&status);
441
442 ASSERT_TRUE(EntryExists(type_root->id_string()));
443 ASSERT_TRUE(EntryExists(e1->id_string()));
444 {
445 syncable::ReadTransaction trans(FROM_HERE, dir());
446 syncable::Entry e(&trans,
447 syncable::GET_BY_ID,
448 syncable::Id::CreateFromServerId(e1->id_string()));
449
450 // See that the attachment_metadata is correct.
451 sync_pb::AttachmentMetadata attachment_metadata = e.GetAttachmentMetadata();
452 ASSERT_EQ(1, attachment_metadata.record_size());
453 ASSERT_EQ(attachment_id->SerializeAsString(),
454 attachment_metadata.record(0).id().SerializeAsString());
455 ASSERT_TRUE(attachment_metadata.record(0).is_on_server());
456
457 // See that attachment_metadata and server_attachment_metadata are equal.
458 ASSERT_EQ(attachment_metadata.SerializeAsString(),
459 e.GetServerAttachmentMetadata().SerializeAsString());
460 }
461 }
462
399 // A test harness for tests that focus on applying updates. 463 // A test harness for tests that focus on applying updates.
400 // 464 //
401 // Update application is performed when we want to take updates that were 465 // Update application is performed when we want to take updates that were
402 // previously downloaded, processed, and stored in our syncable::Directory 466 // previously downloaded, processed, and stored in our syncable::Directory
403 // and use them to update our local state (both the Directory's local state 467 // and use them to update our local state (both the Directory's local state
404 // and the model's local state, though these tests focus only on the Directory's 468 // and the model's local state, though these tests focus only on the Directory's
405 // local state). 469 // local state).
406 // 470 //
407 // This is kept separate from the update processing test in part for historical 471 // This is kept separate from the update processing test in part for historical
408 // reasons, and in part because these tests may require a bit more infrastrcture 472 // reasons, and in part because these tests may require a bit more infrastrcture
409 // in the future. Update application should happen on a different thread a lot 473 // in the future. Update application should happen on a different thread a lot
410 // of the time so these tests may end up requiring more infrastructure than the 474 // of the time so these tests may end up requiring more infrastructure than the
411 // update processing tests. Currently, we're bypassing most of those issues by 475 // update processing tests. Currently, we're bypassing most of those issues by
412 // using FakeModelWorkers, so there's not much difference between the two test 476 // using FakeModelWorkers, so there's not much difference between the two test
413 // harnesses. 477 // harnesses.
414 class DirectoryUpdateHandlerApplyUpdateTest : public ::testing::Test { 478 class DirectoryUpdateHandlerApplyUpdateTest : public ::testing::Test {
415 public: 479 public:
416 DirectoryUpdateHandlerApplyUpdateTest() 480 DirectoryUpdateHandlerApplyUpdateTest()
417 : ui_worker_(new FakeModelWorker(GROUP_UI)), 481 : ui_worker_(new FakeModelWorker(GROUP_UI)),
418 password_worker_(new FakeModelWorker(GROUP_PASSWORD)), 482 password_worker_(new FakeModelWorker(GROUP_PASSWORD)),
419 passive_worker_(new FakeModelWorker(GROUP_PASSIVE)), 483 passive_worker_(new FakeModelWorker(GROUP_PASSIVE)),
420 bookmarks_emitter_(BOOKMARKS, &type_observers_), 484 bookmarks_emitter_(BOOKMARKS, &type_observers_),
421 passwords_emitter_(PASSWORDS, &type_observers_), 485 passwords_emitter_(PASSWORDS, &type_observers_),
486 articles_emitter_(ARTICLES, &type_observers_),
422 update_handler_map_deleter_(&update_handler_map_) {} 487 update_handler_map_deleter_(&update_handler_map_) {}
423 488
424 virtual void SetUp() OVERRIDE { 489 virtual void SetUp() OVERRIDE {
425 dir_maker_.SetUp(); 490 dir_maker_.SetUp();
426 entry_factory_.reset(new TestEntryFactory(directory())); 491 entry_factory_.reset(new TestEntryFactory(directory()));
427 492
428 update_handler_map_.insert(std::make_pair( 493 update_handler_map_.insert(std::make_pair(
429 BOOKMARKS, 494 BOOKMARKS,
430 new DirectoryUpdateHandler(directory(), BOOKMARKS, 495 new DirectoryUpdateHandler(directory(), BOOKMARKS,
431 ui_worker_, &bookmarks_emitter_))); 496 ui_worker_, &bookmarks_emitter_)));
432 update_handler_map_.insert(std::make_pair( 497 update_handler_map_.insert(std::make_pair(
433 PASSWORDS, 498 PASSWORDS,
434 new DirectoryUpdateHandler(directory(), 499 new DirectoryUpdateHandler(directory(),
435 PASSWORDS, 500 PASSWORDS,
436 password_worker_, 501 password_worker_,
437 &passwords_emitter_))); 502 &passwords_emitter_)));
503 update_handler_map_.insert(std::make_pair(
504 ARTICLES,
505 new DirectoryUpdateHandler(
506 directory(), ARTICLES, ui_worker_, &articles_emitter_)));
438 } 507 }
439 508
440 virtual void TearDown() OVERRIDE { 509 virtual void TearDown() OVERRIDE {
441 dir_maker_.TearDown(); 510 dir_maker_.TearDown();
442 } 511 }
443 512
444 const UpdateCounters& GetBookmarksUpdateCounters() { 513 const UpdateCounters& GetBookmarksUpdateCounters() {
445 return bookmarks_emitter_.GetUpdateCounters(); 514 return bookmarks_emitter_.GetUpdateCounters();
446 } 515 }
447 516
448 const UpdateCounters& GetPasswordsUpdateCounters() { 517 const UpdateCounters& GetPasswordsUpdateCounters() {
449 return passwords_emitter_.GetUpdateCounters(); 518 return passwords_emitter_.GetUpdateCounters();
450 } 519 }
451 520
521 const UpdateCounters& GetArticlesUpdateCounters() {
522 return articles_emitter_.GetUpdateCounters();
523 }
524
452 protected: 525 protected:
453 void ApplyBookmarkUpdates(sessions::StatusController* status) { 526 void ApplyBookmarkUpdates(sessions::StatusController* status) {
454 update_handler_map_[BOOKMARKS]->ApplyUpdates(status); 527 update_handler_map_[BOOKMARKS]->ApplyUpdates(status);
455 } 528 }
456 529
457 void ApplyPasswordUpdates(sessions::StatusController* status) { 530 void ApplyPasswordUpdates(sessions::StatusController* status) {
458 update_handler_map_[PASSWORDS]->ApplyUpdates(status); 531 update_handler_map_[PASSWORDS]->ApplyUpdates(status);
459 } 532 }
460 533
534 void ApplyArticlesUpdates(sessions::StatusController* status) {
535 update_handler_map_[ARTICLES]->ApplyUpdates(status);
536 }
537
461 TestEntryFactory* entry_factory() { 538 TestEntryFactory* entry_factory() {
462 return entry_factory_.get(); 539 return entry_factory_.get();
463 } 540 }
464 541
465 syncable::Directory* directory() { 542 syncable::Directory* directory() {
466 return dir_maker_.directory(); 543 return dir_maker_.directory();
467 } 544 }
468 545
469 private: 546 private:
470 typedef std::map<ModelType, UpdateHandler*> UpdateHandlerMap; 547 typedef std::map<ModelType, UpdateHandler*> UpdateHandlerMap;
471 548
472 base::MessageLoop loop_; // Needed to initialize the directory. 549 base::MessageLoop loop_; // Needed to initialize the directory.
473 TestDirectorySetterUpper dir_maker_; 550 TestDirectorySetterUpper dir_maker_;
474 scoped_ptr<TestEntryFactory> entry_factory_; 551 scoped_ptr<TestEntryFactory> entry_factory_;
475 552
476 scoped_refptr<FakeModelWorker> ui_worker_; 553 scoped_refptr<FakeModelWorker> ui_worker_;
477 scoped_refptr<FakeModelWorker> password_worker_; 554 scoped_refptr<FakeModelWorker> password_worker_;
478 scoped_refptr<FakeModelWorker> passive_worker_; 555 scoped_refptr<FakeModelWorker> passive_worker_;
479 556
480 ObserverList<TypeDebugInfoObserver> type_observers_; 557 ObserverList<TypeDebugInfoObserver> type_observers_;
481 DirectoryTypeDebugInfoEmitter bookmarks_emitter_; 558 DirectoryTypeDebugInfoEmitter bookmarks_emitter_;
482 DirectoryTypeDebugInfoEmitter passwords_emitter_; 559 DirectoryTypeDebugInfoEmitter passwords_emitter_;
560 DirectoryTypeDebugInfoEmitter articles_emitter_;
483 561
484 UpdateHandlerMap update_handler_map_; 562 UpdateHandlerMap update_handler_map_;
485 STLValueDeleter<UpdateHandlerMap> update_handler_map_deleter_; 563 STLValueDeleter<UpdateHandlerMap> update_handler_map_deleter_;
486 }; 564 };
487 565
488 namespace { 566 namespace {
489 sync_pb::EntitySpecifics DefaultBookmarkSpecifics() { 567 sync_pb::EntitySpecifics DefaultBookmarkSpecifics() {
490 sync_pb::EntitySpecifics result; 568 sync_pb::EntitySpecifics result;
491 AddDefaultFieldValue(BOOKMARKS, &result); 569 AddDefaultFieldValue(BOOKMARKS, &result);
492 return result; 570 return result;
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
1017 syncable::ReadTransaction trans(FROM_HERE, directory()); 1095 syncable::ReadTransaction trans(FROM_HERE, directory());
1018 syncable::Entry e1(&trans, syncable::GET_BY_HANDLE, decryptable_handle); 1096 syncable::Entry e1(&trans, syncable::GET_BY_HANDLE, decryptable_handle);
1019 syncable::Entry e2(&trans, syncable::GET_BY_HANDLE, undecryptable_handle); 1097 syncable::Entry e2(&trans, syncable::GET_BY_HANDLE, undecryptable_handle);
1020 ASSERT_TRUE(e1.good()); 1098 ASSERT_TRUE(e1.good());
1021 ASSERT_TRUE(e2.good()); 1099 ASSERT_TRUE(e2.good());
1022 EXPECT_FALSE(e1.GetIsUnappliedUpdate()); 1100 EXPECT_FALSE(e1.GetIsUnappliedUpdate());
1023 EXPECT_TRUE(e2.GetIsUnappliedUpdate()); 1101 EXPECT_TRUE(e2.GetIsUnappliedUpdate());
1024 } 1102 }
1025 } 1103 }
1026 1104
1105 TEST_F(DirectoryUpdateHandlerApplyUpdateTest,
1106 SimpleConflictDifferentAttachmentMetadata) {
1107 const bool is_folder = false;
1108 sync_pb::EntitySpecifics specifics;
1109 *specifics.mutable_article() = sync_pb::ArticleSpecifics();
1110 int64 handle = entry_factory()->CreateSyncedItem("art1", ARTICLES, is_folder);
1111
1112 sync_pb::AttachmentIdProto local_attachment_id = CreateAttachmentIdProto();
1113 sync_pb::AttachmentIdProto server_attachment_id = CreateAttachmentIdProto();
1114
1115 // Add an attachment to the local attachment metadata.
1116 sync_pb::AttachmentMetadata local_metadata;
1117 sync_pb::AttachmentMetadataRecord* local_record = local_metadata.add_record();
1118 *local_record->mutable_id() = local_attachment_id;
1119 local_record->set_is_on_server(true);
1120 entry_factory()->SetLocalAttachmentMetadataForItem(handle, local_metadata);
1121
1122 // Add a different attachment to the server attachment metadata.
1123 sync_pb::AttachmentMetadata server_metadata;
1124 sync_pb::AttachmentMetadataRecord* server_record =
1125 server_metadata.add_record();
1126 *server_record->mutable_id() = server_attachment_id;
1127 server_record->set_is_on_server(true);
1128 entry_factory()->SetServerAttachmentMetadataForItem(handle, server_metadata);
1129
1130 // At this point we have a simple conflict. The server says art1 should have
1131 // server_attachment_id, but the local sync engine says it should have
1132 // local_attachment_id.
1133
1134 sessions::StatusController status;
1135 ApplyArticlesUpdates(&status);
1136
1137 // See that the server won.
1138 const UpdateCounters& counters = GetArticlesUpdateCounters();
1139 EXPECT_EQ(1, counters.num_updates_applied);
1140 EXPECT_EQ(1, counters.num_local_overwrites);
1141 EXPECT_EQ(0, counters.num_server_overwrites);
1142 local_metadata = entry_factory()->GetLocalAttachmentMetadataForItem(handle);
1143 EXPECT_EQ(server_metadata.SerializeAsString(),
1144 local_metadata.SerializeAsString());
1145 }
1146
1147 TEST_F(DirectoryUpdateHandlerApplyUpdateTest,
1148 SimpleConflictSameAttachmentMetadataDifferentOrder) {
1149 const bool is_folder = false;
1150 sync_pb::EntitySpecifics specifics;
1151 *specifics.mutable_article() = sync_pb::ArticleSpecifics();
1152 int64 handle = entry_factory()->CreateSyncedItem("art1", ARTICLES, is_folder);
1153
1154 sync_pb::AttachmentIdProto id1 = CreateAttachmentIdProto();
1155 sync_pb::AttachmentIdProto id2 = CreateAttachmentIdProto();
1156
1157 // Add id1, then id2 to the local attachment metadata.
1158 sync_pb::AttachmentMetadata local_metadata;
1159 sync_pb::AttachmentMetadataRecord* record = local_metadata.add_record();
1160 *record->mutable_id() = id1;
1161 record->set_is_on_server(true);
1162 record = local_metadata.add_record();
1163 *record->mutable_id() = id2;
1164 record->set_is_on_server(true);
1165 entry_factory()->SetLocalAttachmentMetadataForItem(handle, local_metadata);
1166
1167 // Add id1 and id2 to the server attachment metadata, but in reverse order.
1168 sync_pb::AttachmentMetadata server_metadata;
1169 record = server_metadata.add_record();
1170 *record->mutable_id() = id2;
1171 record->set_is_on_server(true);
1172 record = local_metadata.add_record();
1173 *record->mutable_id() = id1;
1174 record->set_is_on_server(true);
1175 entry_factory()->SetServerAttachmentMetadataForItem(handle, server_metadata);
1176
1177 // At this point we have a (false) conflict.
1178
1179 sessions::StatusController status;
1180 ApplyArticlesUpdates(&status);
1181
1182 // See that the server won.
1183 const UpdateCounters& counters = GetArticlesUpdateCounters();
1184 EXPECT_EQ(1, counters.num_updates_applied);
1185 EXPECT_EQ(1, counters.num_local_overwrites);
1186 EXPECT_EQ(0, counters.num_server_overwrites);
1187 local_metadata = entry_factory()->GetLocalAttachmentMetadataForItem(handle);
1188 EXPECT_EQ(server_metadata.SerializeAsString(),
1189 local_metadata.SerializeAsString());
1190 }
1191
1027 } // namespace syncer 1192 } // namespace syncer
OLDNEW
« no previous file with comments | « sync/engine/directory_commit_contribution_unittest.cc ('k') | sync/engine/get_commit_ids.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698