Index: sync/engine/directory_update_handler_unittest.cc |
diff --git a/sync/engine/directory_update_handler_unittest.cc b/sync/engine/directory_update_handler_unittest.cc |
index 837e9f418c4e912e43d62bca5f4384069b468f2a..6052da19735233a995b73544fb68c717c7e97f4b 100644 |
--- a/sync/engine/directory_update_handler_unittest.cc |
+++ b/sync/engine/directory_update_handler_unittest.cc |
@@ -8,6 +8,7 @@ |
#include "base/message_loop/message_loop.h" |
#include "base/stl_util.h" |
#include "sync/engine/syncer_proto_util.h" |
+#include "sync/internal_api/public/base/attachment_id_proto.h" |
#include "sync/internal_api/public/base/model_type.h" |
#include "sync/internal_api/public/test/test_entry_factory.h" |
#include "sync/protocol/sync.pb.h" |
@@ -396,6 +397,69 @@ TEST_F(DirectoryUpdateHandlerProcessUpdateTest, ContextVersion) { |
} |
} |
+// See that updates containing attachment metadata are applied |
+// (i.e. server_attachment_metadata is copied to attachment_metadata). |
+TEST_F(DirectoryUpdateHandlerProcessUpdateTest, |
+ ProcessAndApplyUpdatesWithAttachments) { |
+ DirectoryTypeDebugInfoEmitter emitter(ARTICLES, &type_observers_); |
+ DirectoryUpdateHandler handler(dir(), ARTICLES, ui_worker(), &emitter); |
+ sessions::StatusController status; |
+ |
+ sync_pb::DataTypeProgressMarker progress; |
+ progress.set_data_type_id(GetSpecificsFieldNumberFromModelType(ARTICLES)); |
+ progress.set_token("token"); |
+ progress.mutable_gc_directive()->set_version_watermark(kDefaultVersion + 10); |
+ |
+ sync_pb::DataTypeContext context; |
+ context.set_data_type_id(GetSpecificsFieldNumberFromModelType(ARTICLES)); |
+ context.set_context("context"); |
+ context.set_version(1); |
+ |
+ scoped_ptr<sync_pb::SyncEntity> type_root = |
+ CreateUpdate(SyncableIdToProto(syncable::Id::CreateFromServerId("root")), |
+ syncable::GetNullId().GetServerId(), |
+ ARTICLES); |
+ type_root->set_server_defined_unique_tag(ModelTypeToRootTag(ARTICLES)); |
+ type_root->set_folder(true); |
+ |
+ scoped_ptr<sync_pb::SyncEntity> e1 = |
+ CreateUpdate(SyncableIdToProto(syncable::Id::CreateFromServerId("e1")), |
+ type_root->id_string(), |
+ ARTICLES); |
+ sync_pb::AttachmentIdProto* attachment_id = e1->add_attachment_id(); |
+ *attachment_id = CreateAttachmentIdProto(); |
+ |
+ SyncEntityList updates; |
+ updates.push_back(type_root.get()); |
+ updates.push_back(e1.get()); |
+ |
+ // Process and apply updates. |
+ EXPECT_EQ( |
+ SYNCER_OK, |
+ handler.ProcessGetUpdatesResponse(progress, context, updates, &status)); |
+ handler.ApplyUpdates(&status); |
+ |
+ ASSERT_TRUE(EntryExists(type_root->id_string())); |
+ ASSERT_TRUE(EntryExists(e1->id_string())); |
+ { |
+ syncable::ReadTransaction trans(FROM_HERE, dir()); |
+ syncable::Entry e(&trans, |
+ syncable::GET_BY_ID, |
+ syncable::Id::CreateFromServerId(e1->id_string())); |
+ |
+ // See that the attachment_metadata is correct. |
+ sync_pb::AttachmentMetadata attachment_metadata = e.GetAttachmentMetadata(); |
+ ASSERT_EQ(1, attachment_metadata.record_size()); |
+ ASSERT_EQ(attachment_id->SerializeAsString(), |
+ attachment_metadata.record(0).id().SerializeAsString()); |
+ ASSERT_TRUE(attachment_metadata.record(0).is_on_server()); |
+ |
+ // See that attachment_metadata and server_attachment_metadata are equal. |
+ ASSERT_EQ(attachment_metadata.SerializeAsString(), |
+ e.GetServerAttachmentMetadata().SerializeAsString()); |
+ } |
+} |
+ |
// A test harness for tests that focus on applying updates. |
// |
// Update application is performed when we want to take updates that were |
@@ -419,6 +483,7 @@ class DirectoryUpdateHandlerApplyUpdateTest : public ::testing::Test { |
passive_worker_(new FakeModelWorker(GROUP_PASSIVE)), |
bookmarks_emitter_(BOOKMARKS, &type_observers_), |
passwords_emitter_(PASSWORDS, &type_observers_), |
+ articles_emitter_(ARTICLES, &type_observers_), |
update_handler_map_deleter_(&update_handler_map_) {} |
virtual void SetUp() OVERRIDE { |
@@ -435,6 +500,10 @@ class DirectoryUpdateHandlerApplyUpdateTest : public ::testing::Test { |
PASSWORDS, |
password_worker_, |
&passwords_emitter_))); |
+ update_handler_map_.insert(std::make_pair( |
+ ARTICLES, |
+ new DirectoryUpdateHandler( |
+ directory(), ARTICLES, ui_worker_, &articles_emitter_))); |
} |
virtual void TearDown() OVERRIDE { |
@@ -449,6 +518,10 @@ class DirectoryUpdateHandlerApplyUpdateTest : public ::testing::Test { |
return passwords_emitter_.GetUpdateCounters(); |
} |
+ const UpdateCounters& GetArticlesUpdateCounters() { |
+ return articles_emitter_.GetUpdateCounters(); |
+ } |
+ |
protected: |
void ApplyBookmarkUpdates(sessions::StatusController* status) { |
update_handler_map_[BOOKMARKS]->ApplyUpdates(status); |
@@ -458,6 +531,10 @@ class DirectoryUpdateHandlerApplyUpdateTest : public ::testing::Test { |
update_handler_map_[PASSWORDS]->ApplyUpdates(status); |
} |
+ void ApplyArticlesUpdates(sessions::StatusController* status) { |
+ update_handler_map_[ARTICLES]->ApplyUpdates(status); |
+ } |
+ |
TestEntryFactory* entry_factory() { |
return entry_factory_.get(); |
} |
@@ -480,6 +557,7 @@ class DirectoryUpdateHandlerApplyUpdateTest : public ::testing::Test { |
ObserverList<TypeDebugInfoObserver> type_observers_; |
DirectoryTypeDebugInfoEmitter bookmarks_emitter_; |
DirectoryTypeDebugInfoEmitter passwords_emitter_; |
+ DirectoryTypeDebugInfoEmitter articles_emitter_; |
UpdateHandlerMap update_handler_map_; |
STLValueDeleter<UpdateHandlerMap> update_handler_map_deleter_; |
@@ -1024,4 +1102,91 @@ TEST_F(DirectoryUpdateHandlerApplyUpdateTest, SomeUndecryptablePassword) { |
} |
} |
+TEST_F(DirectoryUpdateHandlerApplyUpdateTest, |
+ SimpleConflictDifferentAttachmentMetadata) { |
+ const bool is_folder = false; |
+ sync_pb::EntitySpecifics specifics; |
+ *specifics.mutable_article() = sync_pb::ArticleSpecifics(); |
+ int64 handle = entry_factory()->CreateSyncedItem("art1", ARTICLES, is_folder); |
+ |
+ sync_pb::AttachmentIdProto local_attachment_id = CreateAttachmentIdProto(); |
+ sync_pb::AttachmentIdProto server_attachment_id = CreateAttachmentIdProto(); |
+ |
+ // Add an attachment to the local attachment metadata. |
+ sync_pb::AttachmentMetadata local_metadata; |
+ sync_pb::AttachmentMetadataRecord* local_record = local_metadata.add_record(); |
+ *local_record->mutable_id() = local_attachment_id; |
+ local_record->set_is_on_server(true); |
+ entry_factory()->SetLocalAttachmentMetadataForItem(handle, local_metadata); |
+ |
+ // Add a different attachment to the server attachment metadata. |
+ sync_pb::AttachmentMetadata server_metadata; |
+ sync_pb::AttachmentMetadataRecord* server_record = |
+ server_metadata.add_record(); |
+ *server_record->mutable_id() = server_attachment_id; |
+ server_record->set_is_on_server(true); |
+ entry_factory()->SetServerAttachmentMetadataForItem(handle, server_metadata); |
+ |
+ // At this point we have a simple conflict. The server says art1 should have |
+ // server_attachment_id, but the local sync engine says it should have |
+ // local_attachment_id. |
+ |
+ sessions::StatusController status; |
+ ApplyArticlesUpdates(&status); |
+ |
+ // See that the server won. |
+ const UpdateCounters& counters = GetArticlesUpdateCounters(); |
+ EXPECT_EQ(1, counters.num_updates_applied); |
+ EXPECT_EQ(1, counters.num_local_overwrites); |
+ EXPECT_EQ(0, counters.num_server_overwrites); |
+ local_metadata = entry_factory()->GetLocalAttachmentMetadataForItem(handle); |
+ EXPECT_EQ(server_metadata.SerializeAsString(), |
+ local_metadata.SerializeAsString()); |
+} |
+ |
+TEST_F(DirectoryUpdateHandlerApplyUpdateTest, |
+ SimpleConflictSameAttachmentMetadataDifferentOrder) { |
+ const bool is_folder = false; |
+ sync_pb::EntitySpecifics specifics; |
+ *specifics.mutable_article() = sync_pb::ArticleSpecifics(); |
+ int64 handle = entry_factory()->CreateSyncedItem("art1", ARTICLES, is_folder); |
+ |
+ sync_pb::AttachmentIdProto id1 = CreateAttachmentIdProto(); |
+ sync_pb::AttachmentIdProto id2 = CreateAttachmentIdProto(); |
+ |
+ // Add id1, then id2 to the local attachment metadata. |
+ sync_pb::AttachmentMetadata local_metadata; |
+ sync_pb::AttachmentMetadataRecord* record = local_metadata.add_record(); |
+ *record->mutable_id() = id1; |
+ record->set_is_on_server(true); |
+ record = local_metadata.add_record(); |
+ *record->mutable_id() = id2; |
+ record->set_is_on_server(true); |
+ entry_factory()->SetLocalAttachmentMetadataForItem(handle, local_metadata); |
+ |
+ // Add id1 and id2 to the server attachment metadata, but in reverse order. |
+ sync_pb::AttachmentMetadata server_metadata; |
+ record = server_metadata.add_record(); |
+ *record->mutable_id() = id2; |
+ record->set_is_on_server(true); |
+ record = local_metadata.add_record(); |
+ *record->mutable_id() = id1; |
+ record->set_is_on_server(true); |
+ entry_factory()->SetServerAttachmentMetadataForItem(handle, server_metadata); |
+ |
+ // At this point we have a (false) conflict. |
+ |
+ sessions::StatusController status; |
+ ApplyArticlesUpdates(&status); |
+ |
+ // See that the server won. |
+ const UpdateCounters& counters = GetArticlesUpdateCounters(); |
+ EXPECT_EQ(1, counters.num_updates_applied); |
+ EXPECT_EQ(1, counters.num_local_overwrites); |
+ EXPECT_EQ(0, counters.num_server_overwrites); |
+ local_metadata = entry_factory()->GetLocalAttachmentMetadataForItem(handle); |
+ EXPECT_EQ(server_metadata.SerializeAsString(), |
+ local_metadata.SerializeAsString()); |
+} |
+ |
} // namespace syncer |