| Index: sync/syncable/directory_unittest.cc
|
| diff --git a/sync/syncable/directory_unittest.cc b/sync/syncable/directory_unittest.cc
|
| index b2bff36aa56131e62f75b098876ee1d6d69fbb92..f58f54f9b9ba09ed0b57cab55d0b2612c3449f81 100644
|
| --- a/sync/syncable/directory_unittest.cc
|
| +++ b/sync/syncable/directory_unittest.cc
|
| @@ -6,6 +6,7 @@
|
|
|
| #include "base/strings/stringprintf.h"
|
| #include "base/test/values_test_util.h"
|
| +#include "sync/internal_api/public/base/attachment_id_proto.h"
|
| #include "sync/syncable/syncable_proto_util.h"
|
| #include "sync/syncable/syncable_util.h"
|
| #include "sync/syncable/syncable_write_transaction.h"
|
| @@ -84,23 +85,45 @@ DirOpenResult SyncableDirectoryTest::ReopenDirectory() {
|
| }
|
|
|
| // Creates an empty entry and sets the ID field to a default one.
|
| -void SyncableDirectoryTest::CreateEntry(const std::string& entryname) {
|
| - CreateEntry(entryname, TestIdFactory::FromNumber(-99));
|
| +void SyncableDirectoryTest::CreateEntry(const ModelType& model_type,
|
| + const std::string& entryname) {
|
| + CreateEntry(model_type, entryname, TestIdFactory::FromNumber(-99));
|
| }
|
|
|
| // Creates an empty entry and sets the ID field to id.
|
| -void SyncableDirectoryTest::CreateEntry(const std::string& entryname,
|
| +void SyncableDirectoryTest::CreateEntry(const ModelType& model_type,
|
| + const std::string& entryname,
|
| const int id) {
|
| - CreateEntry(entryname, TestIdFactory::FromNumber(id));
|
| + CreateEntry(model_type, entryname, TestIdFactory::FromNumber(id));
|
| }
|
| -void SyncableDirectoryTest::CreateEntry(const std::string& entryname, Id id) {
|
| +
|
| +void SyncableDirectoryTest::CreateEntry(const ModelType& model_type,
|
| + const std::string& entryname,
|
| + const Id& id) {
|
| + CreateEntryWithAttachmentMetadata(
|
| + model_type, entryname, id, sync_pb::AttachmentMetadata());
|
| +}
|
| +
|
| +void SyncableDirectoryTest::CreateEntryWithAttachmentMetadata(
|
| + const ModelType& model_type,
|
| + const std::string& entryname,
|
| + const Id& id,
|
| + const sync_pb::AttachmentMetadata& attachment_metadata) {
|
| WriteTransaction wtrans(FROM_HERE, UNITTEST, dir_.get());
|
| - MutableEntry me(&wtrans, CREATE, BOOKMARKS, wtrans.root_id(), entryname);
|
| + MutableEntry me(&wtrans, CREATE, model_type, wtrans.root_id(), entryname);
|
| ASSERT_TRUE(me.good());
|
| me.PutId(id);
|
| + me.PutAttachmentMetadata(attachment_metadata);
|
| me.PutIsUnsynced(true);
|
| }
|
|
|
| +void SyncableDirectoryTest::DeleteEntry(const Id& id) {
|
| + WriteTransaction trans(FROM_HERE, UNITTEST, dir().get());
|
| + MutableEntry entry(&trans, GET_BY_ID, id);
|
| + ASSERT_TRUE(entry.good());
|
| + entry.PutIsDel(true);
|
| +}
|
| +
|
| DirOpenResult SyncableDirectoryTest::SimulateSaveAndReloadDir() {
|
| if (!dir_->SaveChanges())
|
| return FAILED_IN_UNITTEST;
|
| @@ -411,8 +434,8 @@ TEST_F(SyncableDirectoryTest, ManageDeleteJournals) {
|
| int64 handle2 = 0;
|
| {
|
| // Create two bookmark entries and save in database.
|
| - CreateEntry("item1", id1);
|
| - CreateEntry("item2", id2);
|
| + CreateEntry(BOOKMARKS, "item1", id1);
|
| + CreateEntry(BOOKMARKS, "item2", id2);
|
| {
|
| WriteTransaction trans(FROM_HERE, UNITTEST, dir().get());
|
| MutableEntry item1(&trans, GET_BY_ID, id1);
|
| @@ -529,7 +552,7 @@ TEST_F(SyncableDirectoryTest, TestBasicLookupNonExistantID) {
|
| }
|
|
|
| TEST_F(SyncableDirectoryTest, TestBasicLookupValidID) {
|
| - CreateEntry("rtc");
|
| + CreateEntry(BOOKMARKS, "rtc");
|
| ReadTransaction rtrans(FROM_HERE, dir().get());
|
| Entry e(&rtrans, GET_BY_ID, TestIdFactory::FromNumber(-99));
|
| ASSERT_TRUE(e.good());
|
| @@ -1521,6 +1544,100 @@ TEST_F(SyncableDirectoryTest, StressTransactions) {
|
| }
|
| }
|
|
|
| +// Verify that Directory is notifed when a MutableEntry's AttachmentMetadata
|
| +// changes.
|
| +TEST_F(SyncableDirectoryTest, MutableEntry_PutAttachmentMetadata) {
|
| + sync_pb::AttachmentMetadata attachment_metadata;
|
| + sync_pb::AttachmentMetadataRecord* record = attachment_metadata.add_record();
|
| + sync_pb::AttachmentIdProto attachment_id_proto =
|
| + syncer::CreateAttachmentIdProto();
|
| + *record->mutable_id() = attachment_id_proto;
|
| + ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id_proto));
|
| + {
|
| + WriteTransaction trans(FROM_HERE, UNITTEST, dir().get());
|
| +
|
| + // Create an entry with attachment metadata and see that the attachment id
|
| + // is not linked.
|
| + MutableEntry entry(
|
| + &trans, CREATE, PREFERENCES, trans.root_id(), "some entry");
|
| + entry.PutId(TestIdFactory::FromNumber(-1));
|
| + entry.PutIsUnsynced(true);
|
| + ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id_proto));
|
| +
|
| + // Now add the attachment metadata and see that Directory believes it is
|
| + // linked.
|
| + entry.PutAttachmentMetadata(attachment_metadata);
|
| + ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id_proto));
|
| +
|
| + // Clear out the attachment metadata and see that it's no longer linked.
|
| + sync_pb::AttachmentMetadata empty_attachment_metadata;
|
| + entry.PutAttachmentMetadata(empty_attachment_metadata);
|
| + ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id_proto));
|
| + }
|
| + ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id_proto));
|
| +}
|
| +
|
| +// Verify that deleted entries with attachments will retain the attachments.
|
| +TEST_F(SyncableDirectoryTest, Directory_DeleteDoesNotUnlinkAttachments) {
|
| + sync_pb::AttachmentMetadata attachment_metadata;
|
| + sync_pb::AttachmentMetadataRecord* record = attachment_metadata.add_record();
|
| + sync_pb::AttachmentIdProto attachment_id_proto =
|
| + syncer::CreateAttachmentIdProto();
|
| + *record->mutable_id() = attachment_id_proto;
|
| + ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id_proto));
|
| + const Id id = TestIdFactory::FromNumber(-1);
|
| +
|
| + // Create an entry with attachment metadata and see that the attachment id
|
| + // is linked.
|
| + CreateEntryWithAttachmentMetadata(
|
| + PREFERENCES, "some entry", id, attachment_metadata);
|
| + ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id_proto));
|
| +
|
| + // Delete the entry and see that it's still linked because the entry hasn't
|
| + // yet been purged.
|
| + DeleteEntry(id);
|
| + ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id_proto));
|
| +
|
| + // Reload the Directory, purging the deleted entry, and see that the
|
| + // attachment is no longer linked.
|
| + SimulateSaveAndReloadDir();
|
| + ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id_proto));
|
| +}
|
| +
|
| +// Verify that a given attachment can be referenced by multiple entries and that
|
| +// any one of the references is sufficient to ensure it remains linked.
|
| +TEST_F(SyncableDirectoryTest, Directory_LastReferenceUnlinksAttachments) {
|
| + // Create one attachment.
|
| + sync_pb::AttachmentMetadata attachment_metadata;
|
| + sync_pb::AttachmentMetadataRecord* record = attachment_metadata.add_record();
|
| + sync_pb::AttachmentIdProto attachment_id_proto =
|
| + syncer::CreateAttachmentIdProto();
|
| + *record->mutable_id() = attachment_id_proto;
|
| +
|
| + // Create two entries, each referencing the attachment.
|
| + const Id id1 = TestIdFactory::FromNumber(-1);
|
| + const Id id2 = TestIdFactory::FromNumber(-2);
|
| + CreateEntryWithAttachmentMetadata(
|
| + PREFERENCES, "some entry", id1, attachment_metadata);
|
| + CreateEntryWithAttachmentMetadata(
|
| + PREFERENCES, "some other entry", id2, attachment_metadata);
|
| +
|
| + // See that the attachment is considered linked.
|
| + ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id_proto));
|
| +
|
| + // Delete the first entry, reload the Directory, see that the attachment is
|
| + // still linked.
|
| + DeleteEntry(id1);
|
| + SimulateSaveAndReloadDir();
|
| + ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id_proto));
|
| +
|
| + // Delete the second entry, reload the Directory, see that the attachment is
|
| + // no loner linked.
|
| + DeleteEntry(id2);
|
| + SimulateSaveAndReloadDir();
|
| + ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id_proto));
|
| +}
|
| +
|
| } // namespace syncable
|
|
|
| } // namespace syncer
|
|
|