| Index: sync/internal_api/sync_manager_impl_unittest.cc
|
| diff --git a/sync/internal_api/sync_manager_impl_unittest.cc b/sync/internal_api/sync_manager_impl_unittest.cc
|
| index a5c0c81001d94974ae23b68f2105faacdb902c9c..20b768529b11a03044b63152fd2ab3363b306f04 100644
|
| --- a/sync/internal_api/sync_manager_impl_unittest.cc
|
| +++ b/sync/internal_api/sync_manager_impl_unittest.cc
|
| @@ -210,22 +210,94 @@ class SyncApiTest : public testing::Test {
|
| }
|
|
|
| protected:
|
| + // Create an entry with the given |model_type|, |client_tag| and
|
| + // |attachment_metadata|.
|
| + void CreateEntryWithAttachmentMetadata(
|
| + const ModelType& model_type,
|
| + const std::string& client_tag,
|
| + const sync_pb::AttachmentMetadata& attachment_metadata);
|
| +
|
| + // Attempts to load the entry specified by |model_type| and |client_tag| and
|
| + // returns the lookup result code.
|
| + BaseNode::InitByLookupResult LookupEntryByClientTag(
|
| + const ModelType& model_type,
|
| + const std::string& client_tag);
|
| +
|
| + // Replace the entry specified by |model_type| and |client_tag| with a
|
| + // tombstone.
|
| + void ReplaceWithTombstone(const ModelType& model_type,
|
| + const std::string& client_tag);
|
| +
|
| + // Save changes to the Directory, destroy it then reload it.
|
| + bool ReloadDir();
|
| +
|
| + UserShare* user_share();
|
| + syncable::Directory* dir();
|
| + SyncEncryptionHandler* encryption_handler();
|
| +
|
| + private:
|
| base::MessageLoop message_loop_;
|
| TestUserShare test_user_share_;
|
| };
|
|
|
| +UserShare* SyncApiTest::user_share() {
|
| + return test_user_share_.user_share();
|
| +}
|
| +
|
| +syncable::Directory* SyncApiTest::dir() {
|
| + return test_user_share_.user_share()->directory.get();
|
| +}
|
| +
|
| +SyncEncryptionHandler* SyncApiTest::encryption_handler() {
|
| + return test_user_share_.encryption_handler();
|
| +}
|
| +
|
| +bool SyncApiTest::ReloadDir() {
|
| + return test_user_share_.Reload();
|
| +}
|
| +
|
| +void SyncApiTest::CreateEntryWithAttachmentMetadata(
|
| + const ModelType& model_type,
|
| + const std::string& client_tag,
|
| + const sync_pb::AttachmentMetadata& attachment_metadata) {
|
| + syncer::WriteTransaction trans(FROM_HERE, user_share());
|
| + syncer::ReadNode root_node(&trans);
|
| + root_node.InitByRootLookup();
|
| + syncer::WriteNode node(&trans);
|
| + ASSERT_EQ(node.InitUniqueByCreation(model_type, root_node, client_tag),
|
| + syncer::WriteNode::INIT_SUCCESS);
|
| + node.SetAttachmentMetadata(attachment_metadata);
|
| +}
|
| +
|
| +BaseNode::InitByLookupResult SyncApiTest::LookupEntryByClientTag(
|
| + const ModelType& model_type,
|
| + const std::string& client_tag) {
|
| + syncer::ReadTransaction trans(FROM_HERE, user_share());
|
| + syncer::ReadNode node(&trans);
|
| + return node.InitByClientTagLookup(model_type, client_tag);
|
| +}
|
| +
|
| +void SyncApiTest::ReplaceWithTombstone(const ModelType& model_type,
|
| + const std::string& client_tag) {
|
| + syncer::WriteTransaction trans(FROM_HERE, user_share());
|
| + syncer::WriteNode node(&trans);
|
| + ASSERT_EQ(node.InitByClientTagLookup(model_type, client_tag),
|
| + syncer::WriteNode::INIT_OK);
|
| + node.Tombstone();
|
| +}
|
| +
|
| TEST_F(SyncApiTest, SanityCheckTest) {
|
| {
|
| - ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + ReadTransaction trans(FROM_HERE, user_share());
|
| EXPECT_TRUE(trans.GetWrappedTrans());
|
| }
|
| {
|
| - WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + WriteTransaction trans(FROM_HERE, user_share());
|
| EXPECT_TRUE(trans.GetWrappedTrans());
|
| }
|
| {
|
| // No entries but root should exist
|
| - ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + ReadTransaction trans(FROM_HERE, user_share());
|
| ReadNode node(&trans);
|
| // Metahandle 1 can be root, sanity check 2
|
| EXPECT_EQ(BaseNode::INIT_FAILED_ENTRY_NOT_GOOD, node.InitByIdLookup(2));
|
| @@ -234,17 +306,16 @@ TEST_F(SyncApiTest, SanityCheckTest) {
|
|
|
| TEST_F(SyncApiTest, BasicTagWrite) {
|
| {
|
| - ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + ReadTransaction trans(FROM_HERE, user_share());
|
| ReadNode root_node(&trans);
|
| root_node.InitByRootLookup();
|
| EXPECT_EQ(root_node.GetFirstChildId(), 0);
|
| }
|
|
|
| - ignore_result(MakeNode(test_user_share_.user_share(),
|
| - BOOKMARKS, "testtag"));
|
| + ignore_result(MakeNode(user_share(), BOOKMARKS, "testtag"));
|
|
|
| {
|
| - ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + ReadTransaction trans(FROM_HERE, user_share());
|
| ReadNode node(&trans);
|
| EXPECT_EQ(BaseNode::INIT_OK,
|
| node.InitByClientTagLookup(BOOKMARKS, "testtag"));
|
| @@ -258,21 +329,18 @@ TEST_F(SyncApiTest, BasicTagWrite) {
|
|
|
| TEST_F(SyncApiTest, ModelTypesSiloed) {
|
| {
|
| - WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + WriteTransaction trans(FROM_HERE, user_share());
|
| ReadNode root_node(&trans);
|
| root_node.InitByRootLookup();
|
| EXPECT_EQ(root_node.GetFirstChildId(), 0);
|
| }
|
|
|
| - ignore_result(MakeNode(test_user_share_.user_share(),
|
| - BOOKMARKS, "collideme"));
|
| - ignore_result(MakeNode(test_user_share_.user_share(),
|
| - PREFERENCES, "collideme"));
|
| - ignore_result(MakeNode(test_user_share_.user_share(),
|
| - AUTOFILL, "collideme"));
|
| + ignore_result(MakeNode(user_share(), BOOKMARKS, "collideme"));
|
| + ignore_result(MakeNode(user_share(), PREFERENCES, "collideme"));
|
| + ignore_result(MakeNode(user_share(), AUTOFILL, "collideme"));
|
|
|
| {
|
| - ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + ReadTransaction trans(FROM_HERE, user_share());
|
|
|
| ReadNode bookmarknode(&trans);
|
| EXPECT_EQ(BaseNode::INIT_OK,
|
| @@ -297,14 +365,14 @@ TEST_F(SyncApiTest, ModelTypesSiloed) {
|
|
|
| TEST_F(SyncApiTest, ReadMissingTagsFails) {
|
| {
|
| - ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + ReadTransaction trans(FROM_HERE, user_share());
|
| ReadNode node(&trans);
|
| EXPECT_EQ(BaseNode::INIT_FAILED_ENTRY_NOT_GOOD,
|
| node.InitByClientTagLookup(BOOKMARKS,
|
| "testtag"));
|
| }
|
| {
|
| - WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + WriteTransaction trans(FROM_HERE, user_share());
|
| WriteNode node(&trans);
|
| EXPECT_EQ(BaseNode::INIT_FAILED_ENTRY_NOT_GOOD,
|
| node.InitByClientTagLookup(BOOKMARKS,
|
| @@ -320,7 +388,7 @@ TEST_F(SyncApiTest, TestDeleteBehavior) {
|
| std::string test_title("test1");
|
|
|
| {
|
| - WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + WriteTransaction trans(FROM_HERE, user_share());
|
| ReadNode root_node(&trans);
|
| root_node.InitByRootLookup();
|
|
|
| @@ -341,7 +409,7 @@ TEST_F(SyncApiTest, TestDeleteBehavior) {
|
|
|
| // Ensure we can delete something with a tag.
|
| {
|
| - WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + WriteTransaction trans(FROM_HERE, user_share());
|
| WriteNode wnode(&trans);
|
| EXPECT_EQ(BaseNode::INIT_OK,
|
| wnode.InitByClientTagLookup(BOOKMARKS,
|
| @@ -355,7 +423,7 @@ TEST_F(SyncApiTest, TestDeleteBehavior) {
|
| // Lookup of a node which was deleted should return failure,
|
| // but have found some data about the node.
|
| {
|
| - ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + ReadTransaction trans(FROM_HERE, user_share());
|
| ReadNode node(&trans);
|
| EXPECT_EQ(BaseNode::INIT_FAILED_ENTRY_IS_DEL,
|
| node.InitByClientTagLookup(BOOKMARKS,
|
| @@ -366,7 +434,7 @@ TEST_F(SyncApiTest, TestDeleteBehavior) {
|
| }
|
|
|
| {
|
| - WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + WriteTransaction trans(FROM_HERE, user_share());
|
| ReadNode folder_node(&trans);
|
| EXPECT_EQ(BaseNode::INIT_OK, folder_node.InitByIdLookup(folder_id));
|
|
|
| @@ -384,7 +452,7 @@ TEST_F(SyncApiTest, TestDeleteBehavior) {
|
|
|
| // Now look up should work.
|
| {
|
| - ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + ReadTransaction trans(FROM_HERE, user_share());
|
| ReadNode node(&trans);
|
| EXPECT_EQ(BaseNode::INIT_OK,
|
| node.InitByClientTagLookup(BOOKMARKS,
|
| @@ -397,11 +465,11 @@ TEST_F(SyncApiTest, TestDeleteBehavior) {
|
| TEST_F(SyncApiTest, WriteAndReadPassword) {
|
| KeyParams params = {"localhost", "username", "passphrase"};
|
| {
|
| - ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + ReadTransaction trans(FROM_HERE, user_share());
|
| trans.GetCryptographer()->AddKey(params);
|
| }
|
| {
|
| - WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + WriteTransaction trans(FROM_HERE, user_share());
|
| ReadNode root_node(&trans);
|
| root_node.InitByRootLookup();
|
|
|
| @@ -415,7 +483,7 @@ TEST_F(SyncApiTest, WriteAndReadPassword) {
|
| password_node.SetPasswordSpecifics(data);
|
| }
|
| {
|
| - ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + ReadTransaction trans(FROM_HERE, user_share());
|
| ReadNode root_node(&trans);
|
| root_node.InitByRootLookup();
|
|
|
| @@ -431,13 +499,13 @@ TEST_F(SyncApiTest, WriteAndReadPassword) {
|
| TEST_F(SyncApiTest, WriteEncryptedTitle) {
|
| KeyParams params = {"localhost", "username", "passphrase"};
|
| {
|
| - ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + ReadTransaction trans(FROM_HERE, user_share());
|
| trans.GetCryptographer()->AddKey(params);
|
| }
|
| - test_user_share_.encryption_handler()->EnableEncryptEverything();
|
| + encryption_handler()->EnableEncryptEverything();
|
| int bookmark_id;
|
| {
|
| - WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + WriteTransaction trans(FROM_HERE, user_share());
|
| ReadNode root_node(&trans);
|
| root_node.InitByRootLookup();
|
|
|
| @@ -453,7 +521,7 @@ TEST_F(SyncApiTest, WriteEncryptedTitle) {
|
| pref_node.SetTitle("bar");
|
| }
|
| {
|
| - ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + ReadTransaction trans(FROM_HERE, user_share());
|
| ReadNode root_node(&trans);
|
| root_node.InitByRootLookup();
|
|
|
| @@ -472,9 +540,8 @@ TEST_F(SyncApiTest, WriteEncryptedTitle) {
|
| }
|
|
|
| TEST_F(SyncApiTest, BaseNodeSetSpecifics) {
|
| - int64 child_id = MakeNode(test_user_share_.user_share(),
|
| - BOOKMARKS, "testtag");
|
| - WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + int64 child_id = MakeNode(user_share(), BOOKMARKS, "testtag");
|
| + WriteTransaction trans(FROM_HERE, user_share());
|
| WriteNode node(&trans);
|
| EXPECT_EQ(BaseNode::INIT_OK, node.InitByIdLookup(child_id));
|
|
|
| @@ -489,9 +556,8 @@ TEST_F(SyncApiTest, BaseNodeSetSpecifics) {
|
| }
|
|
|
| TEST_F(SyncApiTest, BaseNodeSetSpecificsPreservesUnknownFields) {
|
| - int64 child_id = MakeNode(test_user_share_.user_share(),
|
| - BOOKMARKS, "testtag");
|
| - WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + int64 child_id = MakeNode(user_share(), BOOKMARKS, "testtag");
|
| + WriteTransaction trans(FROM_HERE, user_share());
|
| WriteNode node(&trans);
|
| EXPECT_EQ(BaseNode::INIT_OK, node.InitByIdLookup(child_id));
|
| EXPECT_TRUE(node.GetEntitySpecifics().unknown_fields().empty());
|
| @@ -508,7 +574,7 @@ TEST_F(SyncApiTest, BaseNodeSetSpecificsPreservesUnknownFields) {
|
| }
|
|
|
| TEST_F(SyncApiTest, EmptyTags) {
|
| - WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + WriteTransaction trans(FROM_HERE, user_share());
|
| ReadNode root_node(&trans);
|
| root_node.InitByRootLookup();
|
| WriteNode node(&trans);
|
| @@ -522,10 +588,9 @@ TEST_F(SyncApiTest, EmptyTags) {
|
|
|
| // Test counting nodes when the type's root node has no children.
|
| TEST_F(SyncApiTest, GetTotalNodeCountEmpty) {
|
| - int64 type_root = MakeServerNodeForType(test_user_share_.user_share(),
|
| - BOOKMARKS);
|
| + int64 type_root = MakeServerNodeForType(user_share(), BOOKMARKS);
|
| {
|
| - ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + ReadTransaction trans(FROM_HERE, user_share());
|
| ReadNode type_root_node(&trans);
|
| EXPECT_EQ(BaseNode::INIT_OK,
|
| type_root_node.InitByIdLookup(type_root));
|
| @@ -535,14 +600,10 @@ TEST_F(SyncApiTest, GetTotalNodeCountEmpty) {
|
|
|
| // Test counting nodes when there is one child beneath the type's root.
|
| TEST_F(SyncApiTest, GetTotalNodeCountOneChild) {
|
| - int64 type_root = MakeServerNodeForType(test_user_share_.user_share(),
|
| - BOOKMARKS);
|
| - int64 parent = MakeFolderWithParent(test_user_share_.user_share(),
|
| - BOOKMARKS,
|
| - type_root,
|
| - NULL);
|
| + int64 type_root = MakeServerNodeForType(user_share(), BOOKMARKS);
|
| + int64 parent = MakeFolderWithParent(user_share(), BOOKMARKS, type_root, NULL);
|
| {
|
| - ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + ReadTransaction trans(FROM_HERE, user_share());
|
| ReadNode type_root_node(&trans);
|
| EXPECT_EQ(BaseNode::INIT_OK,
|
| type_root_node.InitByIdLookup(type_root));
|
| @@ -557,32 +618,15 @@ TEST_F(SyncApiTest, GetTotalNodeCountOneChild) {
|
| // Test counting nodes when there are multiple children beneath the type root,
|
| // and one of those children has children of its own.
|
| TEST_F(SyncApiTest, GetTotalNodeCountMultipleChildren) {
|
| - int64 type_root = MakeServerNodeForType(test_user_share_.user_share(),
|
| - BOOKMARKS);
|
| - int64 parent = MakeFolderWithParent(test_user_share_.user_share(),
|
| - BOOKMARKS,
|
| - type_root,
|
| - NULL);
|
| - ignore_result(MakeFolderWithParent(test_user_share_.user_share(),
|
| - BOOKMARKS,
|
| - type_root,
|
| - NULL));
|
| - int64 child1 = MakeFolderWithParent(
|
| - test_user_share_.user_share(),
|
| - BOOKMARKS,
|
| - parent,
|
| - NULL);
|
| - ignore_result(MakeBookmarkWithParent(
|
| - test_user_share_.user_share(),
|
| - parent,
|
| - NULL));
|
| - ignore_result(MakeBookmarkWithParent(
|
| - test_user_share_.user_share(),
|
| - child1,
|
| - NULL));
|
| -
|
| - {
|
| - ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
|
| + int64 type_root = MakeServerNodeForType(user_share(), BOOKMARKS);
|
| + int64 parent = MakeFolderWithParent(user_share(), BOOKMARKS, type_root, NULL);
|
| + ignore_result(MakeFolderWithParent(user_share(), BOOKMARKS, type_root, NULL));
|
| + int64 child1 = MakeFolderWithParent(user_share(), BOOKMARKS, parent, NULL);
|
| + ignore_result(MakeBookmarkWithParent(user_share(), parent, NULL));
|
| + ignore_result(MakeBookmarkWithParent(user_share(), child1, NULL));
|
| +
|
| + {
|
| + ReadTransaction trans(FROM_HERE, user_share());
|
| ReadNode type_root_node(&trans);
|
| EXPECT_EQ(BaseNode::INIT_OK,
|
| type_root_node.InitByIdLookup(type_root));
|
| @@ -594,6 +638,57 @@ TEST_F(SyncApiTest, GetTotalNodeCountMultipleChildren) {
|
| }
|
| }
|
|
|
| +// Verify that Directory keeps track of which attachments are referenced by
|
| +// which entries.
|
| +TEST_F(SyncApiTest, AttachmentLinking) {
|
| + // Add an entry with an attachment.
|
| + std::string tag1("some tag");
|
| + syncer::AttachmentId attachment_id(syncer::AttachmentId::Create());
|
| + sync_pb::AttachmentMetadata attachment_metadata;
|
| + sync_pb::AttachmentMetadataRecord* record = attachment_metadata.add_record();
|
| + *record->mutable_id() = attachment_id.GetProto();
|
| + ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id.GetProto()));
|
| + CreateEntryWithAttachmentMetadata(PREFERENCES, tag1, attachment_metadata);
|
| +
|
| + // See that the directory knows it's linked.
|
| + ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id.GetProto()));
|
| +
|
| + // Add a second entry referencing the same attachment.
|
| + std::string tag2("some other tag");
|
| + CreateEntryWithAttachmentMetadata(PREFERENCES, tag2, attachment_metadata);
|
| +
|
| + // See that the directory knows it's still linked.
|
| + ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id.GetProto()));
|
| +
|
| + // Tombstone the first entry.
|
| + ReplaceWithTombstone(syncer::PREFERENCES, tag1);
|
| +
|
| + // See that the attachment is still considered linked because the entry hasn't
|
| + // been purged from the Directory.
|
| + ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id.GetProto()));
|
| +
|
| + // Save changes and see that the entry is truly gone.
|
| + ASSERT_TRUE(dir()->SaveChanges());
|
| + ASSERT_EQ(LookupEntryByClientTag(PREFERENCES, tag1),
|
| + syncer::WriteNode::INIT_FAILED_ENTRY_NOT_GOOD);
|
| +
|
| + // However, the attachment is still linked.
|
| + ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id.GetProto()));
|
| +
|
| + // Save, destroy, and recreate the directory. See that it's still linked.
|
| + ASSERT_TRUE(ReloadDir());
|
| + ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id.GetProto()));
|
| +
|
| + // Tombstone the second entry, save changes, see that it's truly gone.
|
| + ReplaceWithTombstone(syncer::PREFERENCES, tag2);
|
| + ASSERT_TRUE(dir()->SaveChanges());
|
| + ASSERT_EQ(LookupEntryByClientTag(PREFERENCES, tag2),
|
| + syncer::WriteNode::INIT_FAILED_ENTRY_NOT_GOOD);
|
| +
|
| + // Finally, the attachment is no longer linked.
|
| + ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id.GetProto()));
|
| +}
|
| +
|
| namespace {
|
|
|
| class TestHttpPostProviderInterface : public HttpPostProviderInterface {
|
|
|