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

Unified Diff: sync/syncable/directory_unittest.cc

Issue 247983002: Keep track of which attachments are referenced by which sync entries. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: FakeAttachmentService::StoreAttachments now calls AttachmentStore::Write. Created 6 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: sync/syncable/directory_unittest.cc
diff --git a/sync/syncable/directory_unittest.cc b/sync/syncable/directory_unittest.cc
index b2bff36aa56131e62f75b098876ee1d6d69fbb92..ef11d3ba6e8da021876e1d95e5399910c89e836c 100644
--- a/sync/syncable/directory_unittest.cc
+++ b/sync/syncable/directory_unittest.cc
@@ -6,6 +6,11 @@
#include "base/strings/stringprintf.h"
#include "base/test/values_test_util.h"
+#include "sync/api/attachments/attachment.h"
+#include "sync/internal_api/public/read_node.h"
+#include "sync/internal_api/public/read_transaction.h"
+#include "sync/internal_api/public/write_node.h"
+#include "sync/internal_api/public/write_transaction.h"
#include "sync/syncable/syncable_proto_util.h"
#include "sync/syncable/syncable_util.h"
#include "sync/syncable/syncable_write_transaction.h"
@@ -62,24 +67,24 @@ void SyncableDirectoryTest::SetUp() {
}
void SyncableDirectoryTest::TearDown() {
- if (dir_)
- dir_->SaveChanges();
- dir_.reset();
+ if (user_share_.directory)
+ user_share_.directory->SaveChanges();
+ user_share_.directory.reset();
}
DirOpenResult SyncableDirectoryTest::ReopenDirectory() {
// Use a TestDirectoryBackingStore and sql::Connection so we can have test
// data persist across Directory object lifetimes while getting the
// performance benefits of not writing to disk.
- dir_.reset(
+ user_share_.directory.reset(
new Directory(new TestDirectoryBackingStore(kDirectoryName, &connection_),
&handler_,
NULL,
NULL,
NULL));
- DirOpenResult open_result =
- dir_->Open(kDirectoryName, &delegate_, NullTransactionObserver());
+ DirOpenResult open_result = user_share_.directory->Open(
+ kDirectoryName, &delegate_, NullTransactionObserver());
return open_result;
}
@@ -93,16 +98,30 @@ void SyncableDirectoryTest::CreateEntry(const std::string& entryname,
const int id) {
CreateEntry(entryname, TestIdFactory::FromNumber(id));
}
+
void SyncableDirectoryTest::CreateEntry(const std::string& entryname, Id id) {
- WriteTransaction wtrans(FROM_HERE, UNITTEST, dir_.get());
+ WriteTransaction wtrans(FROM_HERE, UNITTEST, user_share_.directory.get());
MutableEntry me(&wtrans, CREATE, BOOKMARKS, wtrans.root_id(), entryname);
ASSERT_TRUE(me.good());
me.PutId(id);
me.PutIsUnsynced(true);
}
+void SyncableDirectoryTest::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);
+}
+
DirOpenResult SyncableDirectoryTest::SimulateSaveAndReloadDir() {
- if (!dir_->SaveChanges())
+ if (!user_share_.directory->SaveChanges())
return FAILED_IN_UNITTEST;
return ReopenDirectory();
@@ -114,7 +133,7 @@ DirOpenResult SyncableDirectoryTest::SimulateCrashAndReloadDir() {
void SyncableDirectoryTest::GetAllMetaHandles(BaseTransaction* trans,
MetahandleSet* result) {
- dir_->GetAllMetaHandles(trans, result);
+ user_share_.directory->GetAllMetaHandles(trans, result);
}
void SyncableDirectoryTest::CheckPurgeEntriesWithTypeInSucceeded(
@@ -122,12 +141,13 @@ void SyncableDirectoryTest::CheckPurgeEntriesWithTypeInSucceeded(
bool before_reload) {
SCOPED_TRACE(testing::Message("Before reload: ") << before_reload);
{
- ReadTransaction trans(FROM_HERE, dir_.get());
+ ReadTransaction trans(FROM_HERE, user_share_.directory.get());
MetahandleSet all_set;
- dir_->GetAllMetaHandles(&trans, &all_set);
+ user_share_.directory->GetAllMetaHandles(&trans, &all_set);
EXPECT_EQ(4U, all_set.size());
if (before_reload)
- EXPECT_EQ(6U, dir_->kernel_->metahandles_to_purge.size());
+ EXPECT_EQ(6U,
+ user_share_.directory->kernel_->metahandles_to_purge.size());
for (MetahandleSet::iterator iter = all_set.begin(); iter != all_set.end();
++iter) {
Entry e(&trans, GET_BY_HANDLE, *iter);
@@ -144,30 +164,54 @@ void SyncableDirectoryTest::CheckPurgeEntriesWithTypeInSucceeded(
for (ModelTypeSet::Iterator it = types_to_purge.First(); it.Good();
it.Inc()) {
- EXPECT_FALSE(dir_->InitialSyncEndedForType(it.Get()));
+ EXPECT_FALSE(user_share_.directory->InitialSyncEndedForType(it.Get()));
sync_pb::DataTypeProgressMarker progress;
- dir_->GetDownloadProgress(it.Get(), &progress);
+ user_share_.directory->GetDownloadProgress(it.Get(), &progress);
EXPECT_EQ("", progress.token());
- ReadTransaction trans(FROM_HERE, dir_.get());
+ ReadTransaction trans(FROM_HERE, user_share_.directory.get());
sync_pb::DataTypeContext context;
- dir_->GetDataTypeContext(&trans, it.Get(), &context);
+ user_share_.directory->GetDataTypeContext(&trans, it.Get(), &context);
EXPECT_TRUE(context.SerializeAsString().empty());
}
EXPECT_FALSE(types_to_purge.Has(BOOKMARKS));
- EXPECT_TRUE(dir_->InitialSyncEndedForType(BOOKMARKS));
+ EXPECT_TRUE(user_share_.directory->InitialSyncEndedForType(BOOKMARKS));
}
bool SyncableDirectoryTest::IsInDirtyMetahandles(int64 metahandle) {
- return 1 == dir_->kernel_->dirty_metahandles.count(metahandle);
+ return 1 ==
+ user_share_.directory->kernel_->dirty_metahandles.count(metahandle);
}
bool SyncableDirectoryTest::IsInMetahandlesToPurge(int64 metahandle) {
- return 1 == dir_->kernel_->metahandles_to_purge.count(metahandle);
+ return 1 ==
+ user_share_.directory->kernel_->metahandles_to_purge.count(metahandle);
+}
+
+BaseNode::InitByLookupResult SyncableDirectoryTest::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 SyncableDirectoryTest::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();
}
scoped_ptr<Directory>& SyncableDirectoryTest::dir() {
- return dir_;
+ return user_share_.directory;
+}
+
+UserShare* SyncableDirectoryTest::user_share() {
+ return &user_share_;
}
DirectoryChangeDelegate* SyncableDirectoryTest::directory_change_delegate() {
@@ -1521,6 +1565,58 @@ TEST_F(SyncableDirectoryTest, StressTransactions) {
}
}
+// Verify that Directory keeps track of which attachments are referenced by
+// which entries.
+TEST_F(SyncableDirectoryTest, 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));
+ CreateEntryWithAttachmentMetadata(PREFERENCES, tag1, attachment_metadata);
+
+ // See that the directory knows it's linked.
+ ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id));
+
+ // 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));
+
+ // 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));
+
+ // 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));
+
+ // Save, destroy, and recreate the directory. See that it's still linked.
+ ASSERT_TRUE(dir()->SaveChanges());
+ ASSERT_EQ(syncable::OPENED, ReopenDirectory());
+ ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id));
+
+ // 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));
+}
+
} // namespace syncable
} // namespace syncer

Powered by Google App Engine
This is Rietveld 408576698