Index: chrome/browser/sync/engine/syncer_unittest.cc |
diff --git a/chrome/browser/sync/engine/syncer_unittest.cc b/chrome/browser/sync/engine/syncer_unittest.cc |
old mode 100644 |
new mode 100755 |
index 1d6c2095eab4ef248d58d090842606fb3c92a858..31840cda5b2454d46e60e588b6b5a7742a64c660 |
--- a/chrome/browser/sync/engine/syncer_unittest.cc |
+++ b/chrome/browser/sync/engine/syncer_unittest.cc |
@@ -27,10 +27,12 @@ |
#include "chrome/browser/sync/protocol/sync.pb.h" |
#include "chrome/browser/sync/syncable/directory_manager.h" |
#include "chrome/browser/sync/syncable/syncable.h" |
+#include "chrome/browser/sync/util/closure.h" |
#include "chrome/browser/sync/util/event_sys-inl.h" |
#include "chrome/test/sync/engine/mock_server_connection.h" |
#include "chrome/test/sync/engine/test_directory_setter_upper.h" |
#include "chrome/test/sync/engine/test_id_factory.h" |
+#include "chrome/test/sync/engine/test_syncable_utils.h" |
#include "testing/gtest/include/gtest/gtest.h" |
using std::map; |
@@ -42,10 +44,13 @@ namespace browser_sync { |
using syncable::BaseTransaction; |
using syncable::Blob; |
+using syncable::CountEntriesWithName; |
using syncable::Directory; |
using syncable::Entry; |
using syncable::ExtendedAttribute; |
using syncable::ExtendedAttributeKey; |
+using syncable::GetFirstEntryWithName; |
+using syncable::GetOnlyEntryWithName; |
using syncable::Id; |
using syncable::MutableEntry; |
using syncable::MutableExtendedAttribute; |
@@ -58,8 +63,6 @@ using syncable::CREATE; |
using syncable::CREATE_NEW_UPDATE_ITEM; |
using syncable::GET_BY_HANDLE; |
using syncable::GET_BY_ID; |
-using syncable::GET_BY_PARENTID_AND_NAME; |
-using syncable::GET_BY_PATH; |
using syncable::GET_BY_TAG; |
using syncable::ID; |
using syncable::IS_BOOKMARK_OBJECT; |
@@ -69,18 +72,17 @@ using syncable::IS_UNAPPLIED_UPDATE; |
using syncable::IS_UNSYNCED; |
using syncable::META_HANDLE; |
using syncable::MTIME; |
-using syncable::NAME; |
using syncable::NEXT_ID; |
+using syncable::NON_UNIQUE_NAME; |
using syncable::PARENT_ID; |
using syncable::PREV_ID; |
using syncable::SERVER_IS_DEL; |
-using syncable::SERVER_NAME; |
+using syncable::SERVER_NON_UNIQUE_NAME; |
using syncable::SERVER_PARENT_ID; |
using syncable::SERVER_POSITION_IN_PARENT; |
using syncable::SERVER_VERSION; |
using syncable::SINGLETON_TAG; |
using syncable::UNITTEST; |
-using syncable::UNSANITIZED_NAME; |
namespace { |
const char* kTestData = "Hello World!"; |
@@ -165,7 +167,7 @@ class SyncerTest : public testing::Test { |
dir->GetChildHandles(&trans, trans.root_id(), &children); |
ASSERT_TRUE(0 == children.size()); |
syncer_events_.clear(); |
- root_id_ = ids_.root(); |
+ root_id_ = TestIdFactory::root(); |
parent_id_ = ids_.MakeServer("parent id"); |
child_id_ = ids_.MakeServer("child id"); |
} |
@@ -341,6 +343,8 @@ class SyncerTest : public testing::Test { |
// Some ids to aid tests. Only the root one's value is specific. The rest |
// are named for test clarity. |
+ // TODO(chron): Get rid of these inbuilt IDs. They only make it |
+ // more confusing. |
syncable::Id root_id_; |
syncable::Id parent_id_; |
syncable::Id child_id_; |
@@ -815,9 +819,14 @@ TEST_F(SyncerTest, TestCommitListOrderingCounterexample) { |
TEST_F(SyncerTest, TestCommitListOrderingAndNewParent) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
ASSERT_TRUE(dir.good()); |
+ |
+ PathString parent1_name = PSTR("1"); |
+ PathString parent2_name = PSTR("A"); |
+ PathString child_name = PSTR("B"); |
+ |
{ |
WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry parent(&wtrans, syncable::CREATE, wtrans.root_id(), PSTR("1")); |
+ MutableEntry parent(&wtrans, syncable::CREATE, wtrans.root_id(), parent1_name); |
ASSERT_TRUE(parent.good()); |
parent.Put(syncable::IS_UNSYNCED, true); |
parent.Put(syncable::IS_DIR, true); |
@@ -826,19 +835,20 @@ TEST_F(SyncerTest, TestCommitListOrderingAndNewParent) { |
} |
syncable::Id parent2_id = ids_.NewLocalId(); |
- syncable::Id child2_id = ids_.NewServerId(); |
+ syncable::Id child_id = ids_.NewServerId(); |
{ |
WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry parent(&wtrans, syncable::CREATE, parent_id_, PSTR("A")); |
- ASSERT_TRUE(parent.good()); |
- parent.Put(syncable::IS_UNSYNCED, true); |
- parent.Put(syncable::IS_DIR, true); |
- parent.Put(syncable::ID, parent2_id); |
- MutableEntry child(&wtrans, syncable::CREATE, parent2_id, PSTR("B")); |
+ MutableEntry parent2(&wtrans, syncable::CREATE, parent_id_, parent2_name); |
+ ASSERT_TRUE(parent2.good()); |
+ parent2.Put(syncable::IS_UNSYNCED, true); |
+ parent2.Put(syncable::IS_DIR, true); |
+ parent2.Put(syncable::ID, parent2_id); |
+ |
+ MutableEntry child(&wtrans, syncable::CREATE, parent2_id, child_name); |
ASSERT_TRUE(child.good()); |
child.Put(syncable::IS_UNSYNCED, true); |
child.Put(syncable::IS_DIR, true); |
- child.Put(syncable::ID, child2_id); |
+ child.Put(syncable::ID, child_id); |
child.Put(syncable::BASE_VERSION, 1); |
} |
@@ -851,47 +861,69 @@ TEST_F(SyncerTest, TestCommitListOrderingAndNewParent) { |
// If this test starts failing, be aware other sort orders could be valid. |
EXPECT_TRUE(parent_id_ == mock_server_->committed_ids()[0]); |
EXPECT_TRUE(parent2_id == mock_server_->committed_ids()[1]); |
- EXPECT_TRUE(child2_id == mock_server_->committed_ids()[2]); |
+ EXPECT_TRUE(child_id == mock_server_->committed_ids()[2]); |
{ |
ReadTransaction rtrans(dir, __FILE__, __LINE__); |
- PathChar path[] = { '1', *kPathSeparator, 'A', 0}; |
- Entry entry_1A(&rtrans, syncable::GET_BY_PATH, path); |
- ASSERT_TRUE(entry_1A.good()); |
- Entry item_parent2(&rtrans, syncable::GET_BY_ID, parent2_id); |
- ASSERT_FALSE(item_parent2.good()); |
- Entry item_child2(&rtrans, syncable::GET_BY_ID, child2_id); |
- EXPECT_EQ(entry_1A.Get(syncable::ID), item_child2.Get(syncable::PARENT_ID)); |
- EXPECT_TRUE(entry_1A.Get(syncable::ID).ServerKnows()); |
+ // Check that things committed correctly. |
+ Entry entry_1(&rtrans, syncable::GET_BY_ID, parent_id_); |
+ EXPECT_EQ(entry_1.Get(NON_UNIQUE_NAME), parent1_name); |
+ // Check that parent2 is a subfolder of parent1. |
+ EXPECT_EQ(1, CountEntriesWithName(&rtrans, |
+ parent_id_, |
+ parent2_name)); |
+ |
+ // Parent2 was a local ID and thus should have changed on commit! |
+ Entry pre_commit_entry_parent2(&rtrans, syncable::GET_BY_ID, parent2_id); |
+ ASSERT_FALSE(pre_commit_entry_parent2.good()); |
+ |
+ // Look up the new ID. |
+ Id parent2_committed_id = |
+ GetOnlyEntryWithName(&rtrans, parent_id_, parent2_name); |
+ EXPECT_TRUE(parent2_committed_id.ServerKnows()); |
+ |
+ Entry child(&rtrans, syncable::GET_BY_ID, child_id); |
+ EXPECT_EQ(parent2_committed_id, child.Get(syncable::PARENT_ID)); |
} |
} |
TEST_F(SyncerTest, TestCommitListOrderingAndNewParentAndChild) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
ASSERT_TRUE(dir.good()); |
+ |
+ PathString parent_name = PSTR("1"); |
+ PathString parent2_name = PSTR("A"); |
+ PathString child_name = PSTR("B"); |
+ |
{ |
WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry parent(&wtrans, syncable::CREATE, wtrans.root_id(), PSTR("1")); |
+ MutableEntry parent(&wtrans, |
+ syncable::CREATE, |
+ wtrans.root_id(), |
+ parent_name); |
ASSERT_TRUE(parent.good()); |
parent.Put(syncable::IS_UNSYNCED, true); |
parent.Put(syncable::IS_DIR, true); |
parent.Put(syncable::ID, parent_id_); |
parent.Put(syncable::BASE_VERSION, 1); |
} |
+ |
int64 meta_handle_a, meta_handle_b; |
+ const Id parent2_local_id = ids_.NewLocalId(); |
+ const Id child_local_id = ids_.NewLocalId(); |
{ |
WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry parent(&wtrans, syncable::CREATE, parent_id_, PSTR("A")); |
- ASSERT_TRUE(parent.good()); |
- parent.Put(syncable::IS_UNSYNCED, true); |
- parent.Put(syncable::IS_DIR, true); |
- parent.Put(syncable::ID, ids_.FromNumber(-101)); |
- meta_handle_a = parent.Get(syncable::META_HANDLE); |
- MutableEntry child(&wtrans, syncable::CREATE, ids_.FromNumber(-101), |
- PSTR("B")); |
+ MutableEntry parent2(&wtrans, syncable::CREATE, parent_id_, parent2_name); |
+ ASSERT_TRUE(parent2.good()); |
+ parent2.Put(syncable::IS_UNSYNCED, true); |
+ parent2.Put(syncable::IS_DIR, true); |
+ |
+ parent2.Put(syncable::ID, parent2_local_id); |
+ meta_handle_a = parent2.Get(syncable::META_HANDLE); |
+ MutableEntry child(&wtrans, syncable::CREATE, parent2_local_id, child_name); |
ASSERT_TRUE(child.good()); |
child.Put(syncable::IS_UNSYNCED, true); |
child.Put(syncable::IS_DIR, true); |
- child.Put(syncable::ID, ids_.FromNumber(-102)); |
+ child.Put(syncable::ID, child_local_id); |
meta_handle_b = child.Get(syncable::META_HANDLE); |
} |
@@ -903,19 +935,30 @@ TEST_F(SyncerTest, TestCommitListOrderingAndNewParentAndChild) { |
ASSERT_TRUE(3 == mock_server_->committed_ids().size()); |
// If this test starts failing, be aware other sort orders could be valid. |
EXPECT_TRUE(parent_id_ == mock_server_->committed_ids()[0]); |
- EXPECT_TRUE(ids_.FromNumber(-101) == mock_server_->committed_ids()[1]); |
- EXPECT_TRUE(ids_.FromNumber(-102) == mock_server_->committed_ids()[2]); |
+ EXPECT_TRUE(parent2_local_id == mock_server_->committed_ids()[1]); |
+ EXPECT_TRUE(child_local_id == mock_server_->committed_ids()[2]); |
{ |
ReadTransaction rtrans(dir, __FILE__, __LINE__); |
- PathChar path[] = { '1', *kPathSeparator, 'A', 0}; |
- Entry entry_1A(&rtrans, syncable::GET_BY_PATH, path); |
- ASSERT_TRUE(entry_1A.good()); |
- Entry entry_id_minus_101(&rtrans, syncable::GET_BY_ID, |
- ids_.FromNumber(-101)); |
- ASSERT_FALSE(entry_id_minus_101.good()); |
+ |
+ Entry parent(&rtrans, syncable::GET_BY_ID, |
+ GetOnlyEntryWithName(&rtrans, rtrans.root_id(), parent_name)); |
+ ASSERT_TRUE(parent.good()); |
+ EXPECT_TRUE(parent.Get(syncable::ID).ServerKnows()); |
+ |
+ Entry parent2(&rtrans, syncable::GET_BY_ID, |
+ GetOnlyEntryWithName(&rtrans, parent.Get(ID), parent2_name)); |
+ ASSERT_TRUE(parent2.good()); |
+ EXPECT_TRUE(parent2.Get(syncable::ID).ServerKnows()); |
+ |
+ // Id changed on commit, so this should fail. |
+ Entry local_parent2_id_entry(&rtrans, |
+ syncable::GET_BY_ID, |
+ parent2_local_id); |
+ ASSERT_FALSE(local_parent2_id_entry.good()); |
+ |
Entry entry_b(&rtrans, syncable::GET_BY_HANDLE, meta_handle_b); |
- EXPECT_TRUE(entry_1A.Get(syncable::ID) == entry_b.Get(syncable::PARENT_ID)); |
- EXPECT_TRUE(entry_1A.Get(syncable::ID).ServerKnows()); |
+ EXPECT_TRUE(entry_b.Get(syncable::ID).ServerKnows()); |
+ EXPECT_TRUE(parent2.Get(syncable::ID) == entry_b.Get(syncable::PARENT_ID)); |
} |
} |
@@ -933,203 +976,19 @@ TEST_F(SyncerTest, UpdateWithZeroLengthName) { |
syncer_->SyncShare(); |
} |
-#if defined(OS_WIN) |
-TEST_F(SyncerTest, NameSanitizationWithClientRename) { |
- ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- ASSERT_TRUE(dir.good()); |
- mock_server_->AddUpdateDirectory(1, 0, "okay", 1, 10); |
- syncer_->SyncShare(); |
- { |
- ReadTransaction tr(dir, __FILE__, __LINE__); |
- Entry e(&tr, syncable::GET_BY_PARENTID_AND_NAME, tr.root_id(), |
- PSTR("okay")); |
- ASSERT_TRUE(e.good()); |
- } |
- mock_server_->AddUpdateDirectory(2, 0, "prn", 1, 20); |
- syncer_->SyncShare(); |
- { |
- WriteTransaction tr(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry e(&tr, syncable::GET_BY_PARENTID_AND_NAME, tr.root_id(), |
- PSTR("prn~1")); |
- ASSERT_TRUE(e.good()); |
- e.PutName(syncable::Name(PSTR("printer"))); |
- e.Put(syncable::IS_UNSYNCED, true); |
- } |
- syncer_->SyncShare(); |
- { |
- vector<CommitMessage*>::const_reverse_iterator it = |
- mock_server_->commit_messages().rbegin(); |
- ASSERT_TRUE(mock_server_->commit_messages().rend() != it); |
- const sync_pb::SyncEntity *const *s = (*it)->entries().data(); |
- int s_len = (*it)->entries_size(); |
- ASSERT_TRUE(1 == s_len); |
- ASSERT_TRUE("printer" == (*s)[0].name()); |
- } |
-} |
- |
-TEST_F(SyncerTest, NameSanitizationWithCascade) { |
- ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- ASSERT_TRUE(dir.good()); |
- mock_server_->AddUpdateDirectory(1, 0, "prn~1", 1, 10); |
- syncer_->SyncShare(); |
- { |
- ReadTransaction tr(dir, __FILE__, __LINE__); |
- Entry e(&tr, syncable::GET_BY_PARENTID_AND_NAME, tr.root_id(), |
- PSTR("prn~1")); |
- ASSERT_TRUE(e.good()); |
- } |
- mock_server_->AddUpdateDirectory(2, 0, "prn", 1, 20); |
- syncer_->SyncShare(); |
- { |
- ReadTransaction tr(dir, __FILE__, __LINE__); |
- Entry e(&tr, syncable::GET_BY_PARENTID_AND_NAME, tr.root_id(), |
- PSTR("prn~2")); |
- ASSERT_TRUE(e.good()); |
- } |
- mock_server_->AddUpdateDirectory(3, 0, "prn~2", 1, 30); |
- syncer_->SyncShare(); |
- { |
- ReadTransaction tr(dir, __FILE__, __LINE__); |
- Entry e(&tr, syncable::GET_BY_PARENTID_AND_NAME, tr.root_id(), |
- PSTR("prn~3")); |
- ASSERT_TRUE(e.good()); |
- } |
-} |
- |
-TEST_F(SyncerTest, GetStuckWithConflictingSanitizedNames) { |
- // We should get stuck here because we get two server updates with exactly the |
- // same name. |
+TEST_F(SyncerTest, DontGetStuckWithTwoSameNames) { |
+ // We should not get stuck here because we get |
+ // two server updates with exactly the same name. |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
ASSERT_TRUE(dir.good()); |
mock_server_->AddUpdateDirectory(1, 0, "foo:", 1, 10); |
syncer_->SyncShare(); |
mock_server_->AddUpdateDirectory(2, 0, "foo:", 1, 20); |
SyncRepeatedlyToTriggerStuckSignal(state_.get()); |
- EXPECT_TRUE(SyncerStuck(state_.get())); |
+ EXPECT_FALSE(SyncerStuck(state_.get())); |
syncer_events_.clear(); |
} |
-TEST_F(SyncerTest, MergeFolderWithSanitizedNameMatches) { |
- ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- CHECK(dir.good()); |
- { |
- WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry parent(&wtrans, CREATE, wtrans.root_id(), PSTR("Folder")); |
- ASSERT_TRUE(parent.good()); |
- parent.Put(IS_DIR, true); |
- parent.Put(IS_UNSYNCED, true); |
- parent.Put(UNSANITIZED_NAME, PSTR("Folder:")); |
- } |
- mock_server_->AddUpdateDirectory(100, 0, "Folder:", 10, 10); |
- syncer_->SyncShare(); |
- { |
- ReadTransaction trans(dir, __FILE__, __LINE__); |
- Directory::ChildHandles children; |
- dir->GetChildHandles(&trans, trans.root_id(), &children); |
- EXPECT_TRUE(1 == children.size()); |
- Directory::UnappliedUpdateMetaHandles unapplied; |
- dir->GetUnappliedUpdateMetaHandles(&trans, &unapplied); |
- EXPECT_TRUE(0 == unapplied.size()); |
- syncable::Directory::UnsyncedMetaHandles unsynced; |
- dir->GetUnsyncedMetaHandles(&trans, &unsynced); |
- EXPECT_TRUE(0 == unsynced.size()); |
- syncer_events_.clear(); |
- } |
-} |
- |
-// These two tests are the same as the two above, but they introduce case |
-// changes. |
-TEST_F(SyncerTest, GetStuckWithSanitizedNamesThatDifferOnlyByCase) { |
- // We should get stuck here because we get two server updates with exactly the |
- // same name. |
- ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- ASSERT_TRUE(dir.good()); |
- mock_server_->AddUpdateDirectory(1, 0, "FOO:", 1, 10); |
- syncer_->SyncShare(); |
- mock_server_->AddUpdateDirectory(2, 0, "foo:", 1, 20); |
- SyncRepeatedlyToTriggerStuckSignal(state_.get()); |
- EXPECT_TRUE(SyncerStuck(state_.get())); |
- syncer_events_.clear(); |
-} |
- |
-TEST_F(SyncerTest, MergeFolderWithSanitizedNameThatDiffersOnlyByCase) { |
- ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- CHECK(dir.good()); |
- { |
- WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry parent(&wtrans, CREATE, wtrans.root_id(), PSTR("FOLDER")); |
- ASSERT_TRUE(parent.good()); |
- parent.Put(IS_DIR, true); |
- parent.Put(IS_UNSYNCED, true); |
- parent.Put(UNSANITIZED_NAME, PSTR("FOLDER:")); |
- } |
- mock_server_->AddUpdateDirectory(100, 0, "Folder:", 10, 10); |
- mock_server_->set_conflict_all_commits(true); |
- syncer_->SyncShare(); |
- syncer_->SyncShare(); |
- syncer_->SyncShare(); // Good gracious, these tests are not so good. |
- { |
- ReadTransaction trans(dir, __FILE__, __LINE__); |
- Directory::ChildHandles children; |
- dir->GetChildHandles(&trans, trans.root_id(), &children); |
- EXPECT_TRUE(1 == children.size()); |
- Directory::UnappliedUpdateMetaHandles unapplied; |
- dir->GetUnappliedUpdateMetaHandles(&trans, &unapplied); |
- EXPECT_TRUE(0 == unapplied.size()); |
- syncable::Directory::UnsyncedMetaHandles unsynced; |
- dir->GetUnsyncedMetaHandles(&trans, &unsynced); |
- EXPECT_TRUE(0 == unsynced.size()); |
- syncer_events_.clear(); |
- } |
-} |
-#else // Mac / Linux ... |
- |
-TEST_F(SyncerTest, NameSanitizationWithClientRename) { |
- ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- ASSERT_TRUE(dir.good()); |
- mock_server_->AddUpdateDirectory(1, 0, "okay", 1, 10); |
- syncer_->SyncShare(); |
- { |
- ReadTransaction tr(dir, __FILE__, __LINE__); |
- Entry e(&tr, syncable::GET_BY_PARENTID_AND_NAME, tr.root_id(), |
- PSTR("okay")); |
- ASSERT_TRUE(e.good()); |
- } |
- mock_server_->AddUpdateDirectory(2, 0, "a/b", 1, 20); |
- syncer_->SyncShare(); |
- { |
- WriteTransaction tr(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry e(&tr, syncable::GET_BY_PARENTID_AND_NAME, tr.root_id(), |
- PSTR("a:b")); |
- ASSERT_TRUE(e.good()); |
- e.PutName(syncable::Name(PSTR("ab"))); |
- e.Put(syncable::IS_UNSYNCED, true); |
- } |
- syncer_->SyncShare(); |
- { |
- vector<CommitMessage*>::const_reverse_iterator it = |
- mock_server_->commit_messages().rbegin(); |
- ASSERT_TRUE(mock_server_->commit_messages().rend() != it); |
- const sync_pb::SyncEntity *const *s = (*it)->entries().data(); |
- int s_len = (*it)->entries_size(); |
- ASSERT_TRUE(1 == s_len); |
- ASSERT_TRUE("ab" == (*s)[0].name()); |
- } |
-} |
-#endif |
- |
-namespace { |
-void VerifyExistsWithNameInRoot(syncable::Directory* dir, |
- const PathString& name, |
- const string& entry, |
- int line) { |
- ReadTransaction tr(dir, __FILE__, __LINE__); |
- Entry e(&tr, syncable::GET_BY_PARENTID_AND_NAME, tr.root_id(), |
- name); |
- EXPECT_TRUE(e.good()) << "failed on call from " << entry << ":" << line; |
-} |
-} // namespace |
- |
TEST_F(SyncerTest, ExtendedAttributeWithNullCharacter) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
ASSERT_TRUE(dir.good()); |
@@ -1203,13 +1062,13 @@ TEST_F(SyncerTest, TestBasicUpdate) { |
} |
TEST_F(SyncerTest, IllegalAndLegalUpdates) { |
- Id root = ids_.root(); |
+ Id root = TestIdFactory::root(); |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
ASSERT_TRUE(dir.good()); |
// Should apply just fine. |
mock_server_->AddUpdateDirectory(1, 0, "in_root", 10, 10); |
- // Name clash: this is a conflict. |
+ // Same name. But this SHOULD work. |
mock_server_->AddUpdateDirectory(2, 0, "in_root", 10, 10); |
// Unknown parent: should never be applied. "-80" is a legal server ID, |
@@ -1223,8 +1082,8 @@ TEST_F(SyncerTest, IllegalAndLegalUpdates) { |
ConflictResolutionView conflict_view(state_.get()); |
SyncerStatus status(NULL, state_.get()); |
- // Ids 2 and 3 are expected to be in conflict now. |
- EXPECT_TRUE(2 == conflict_view.conflicting_updates()); |
+ // Id 3 should be in conflict now. |
+ EXPECT_TRUE(1 == conflict_view.conflicting_updates()); |
// These entries will be used in the second set of updates. |
mock_server_->AddUpdateDirectory(4, 0, "newer_version", 20, 10); |
@@ -1236,17 +1095,18 @@ TEST_F(SyncerTest, IllegalAndLegalUpdates) { |
syncer_->SyncShare(state_.get()); |
// The three items with an unresolved parent should be unapplied (3, 9, 100). |
- // The name clash should also still be in conflict. |
- EXPECT_TRUE(4 == conflict_view.conflicting_updates()); |
+ EXPECT_TRUE(3 == conflict_view.conflicting_updates()); |
{ |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
+ // Even though it has the same name, it should work. |
Entry name_clash(&trans, GET_BY_ID, ids_.FromNumber(2)); |
ASSERT_TRUE(name_clash.good()); |
- EXPECT_TRUE(name_clash.Get(IS_UNAPPLIED_UPDATE)); |
+ EXPECT_FALSE(name_clash.Get(IS_UNAPPLIED_UPDATE)) |
+ << "Duplicate name SHOULD be OK."; |
Entry bad_parent(&trans, GET_BY_ID, ids_.FromNumber(3)); |
ASSERT_TRUE(bad_parent.good()); |
- EXPECT_TRUE(name_clash.Get(IS_UNAPPLIED_UPDATE)) |
+ EXPECT_TRUE(bad_parent.Get(IS_UNAPPLIED_UPDATE)) |
<< "child of unknown parent should be in conflict"; |
Entry bad_parent_child(&trans, GET_BY_ID, ids_.FromNumber(9)); |
@@ -1260,7 +1120,7 @@ TEST_F(SyncerTest, IllegalAndLegalUpdates) { |
<< "great-grandchild of unknown parent should be in conflict"; |
} |
- // Updating 1 should unblock the clashing item 2. |
+ // Updating 1 should not affect item 2 of the same name. |
mock_server_->AddUpdateDirectory(1, 0, "new_name", 20, 20); |
// Moving 5 under 6 will create a cycle: a conflict. |
@@ -1275,6 +1135,7 @@ TEST_F(SyncerTest, IllegalAndLegalUpdates) { |
syncer_->SyncShare(state_.get()); |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
+ |
Entry still_a_dir(&trans, GET_BY_ID, ids_.FromNumber(10)); |
ASSERT_TRUE(still_a_dir.good()); |
EXPECT_FALSE(still_a_dir.Get(IS_UNAPPLIED_UPDATE)); |
@@ -1282,21 +1143,25 @@ TEST_F(SyncerTest, IllegalAndLegalUpdates) { |
EXPECT_TRUE(10 == still_a_dir.Get(SERVER_VERSION)); |
EXPECT_TRUE(still_a_dir.Get(IS_DIR)); |
- Entry rename(&trans, GET_BY_PARENTID_AND_NAME, root, PSTR("new_name")); |
+ Entry rename(&trans, GET_BY_ID, ids_.FromNumber(1)); |
ASSERT_TRUE(rename.good()); |
+ EXPECT_EQ(root, rename.Get(PARENT_ID)); |
+ EXPECT_EQ(PSTR("new_name"), rename.Get(NON_UNIQUE_NAME)); |
EXPECT_FALSE(rename.Get(IS_UNAPPLIED_UPDATE)); |
EXPECT_TRUE(ids_.FromNumber(1) == rename.Get(ID)); |
EXPECT_TRUE(20 == rename.Get(BASE_VERSION)); |
- Entry unblocked(&trans, GET_BY_PARENTID_AND_NAME, root, PSTR("in_root")); |
- ASSERT_TRUE(unblocked.good()); |
- EXPECT_FALSE(unblocked.Get(IS_UNAPPLIED_UPDATE)); |
- EXPECT_TRUE(ids_.FromNumber(2) == unblocked.Get(ID)); |
- EXPECT_TRUE(10 == unblocked.Get(BASE_VERSION)); |
+ Entry name_clash(&trans, GET_BY_ID, ids_.FromNumber(2)); |
+ ASSERT_TRUE(name_clash.good()); |
+ EXPECT_EQ(root, name_clash.Get(PARENT_ID)); |
+ EXPECT_TRUE(ids_.FromNumber(2) == name_clash.Get(ID)); |
+ EXPECT_TRUE(10 == name_clash.Get(BASE_VERSION)); |
+ EXPECT_EQ(PSTR("in_root"), name_clash.Get(NON_UNIQUE_NAME)); |
Entry ignored_old_version(&trans, GET_BY_ID, ids_.FromNumber(4)); |
ASSERT_TRUE(ignored_old_version.good()); |
- EXPECT_TRUE(ignored_old_version.Get(NAME) == PSTR("newer_version")); |
+ EXPECT_TRUE( |
+ ignored_old_version.Get(NON_UNIQUE_NAME) == PSTR("newer_version")); |
EXPECT_FALSE(ignored_old_version.Get(IS_UNAPPLIED_UPDATE)); |
EXPECT_TRUE(20 == ignored_old_version.Get(BASE_VERSION)); |
@@ -1324,6 +1189,9 @@ TEST_F(SyncerTest, IllegalAndLegalUpdates) { |
TEST_F(SyncerTest, CommitTimeRename) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
ASSERT_TRUE(dir.good()); |
+ int64 metahandle_folder; |
+ int64 metahandle_new_entry; |
+ |
// Create a folder and an entry. |
{ |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
@@ -1331,8 +1199,11 @@ TEST_F(SyncerTest, CommitTimeRename) { |
ASSERT_TRUE(parent.good()); |
parent.Put(IS_DIR, true); |
parent.Put(IS_UNSYNCED, true); |
+ metahandle_folder = parent.Get(META_HANDLE); |
+ |
MutableEntry entry(&trans, CREATE, parent.Get(ID), PSTR("new_entry")); |
ASSERT_TRUE(entry.good()); |
+ metahandle_new_entry = entry.Get(META_HANDLE); |
WriteTestDataToEntry(&trans, &entry); |
} |
@@ -1344,17 +1215,19 @@ TEST_F(SyncerTest, CommitTimeRename) { |
// Verify it was correctly renamed. |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry entry_folder(&trans, GET_BY_PATH, PSTR("renamed_Folder")); |
+ Entry entry_folder(&trans, GET_BY_HANDLE, metahandle_folder); |
ASSERT_TRUE(entry_folder.good()); |
+ EXPECT_EQ(PSTR("renamed_Folder"), entry_folder.Get(NON_UNIQUE_NAME)); |
- Entry entry_new(&trans, GET_BY_PATH, |
- PSTR("renamed_Folder") + PathString(kPathSeparator) |
- + PSTR("renamed_new_entry")); |
+ Entry entry_new(&trans, GET_BY_HANDLE, metahandle_new_entry); |
ASSERT_TRUE(entry_new.good()); |
+ EXPECT_EQ(entry_folder.Get(ID), entry_new.Get(PARENT_ID)); |
+ EXPECT_EQ(PSTR("renamed_new_entry"), entry_new.Get(NON_UNIQUE_NAME)); |
// And that the unrelated directory creation worked without a rename. |
- Entry new_dir(&trans, GET_BY_PATH, PSTR("dir_in_root")); |
+ Entry new_dir(&trans, GET_BY_ID, ids_.FromNumber(2)); |
EXPECT_TRUE(new_dir.good()); |
+ EXPECT_EQ(PSTR("dir_in_root"), new_dir.Get(NON_UNIQUE_NAME)); |
} |
} |
@@ -1367,109 +1240,56 @@ TEST_F(SyncerTest, CommitTimeRenameI18N) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
ASSERT_TRUE(dir.good()); |
- // Create a folder and entry. |
+ int64 metahandle; |
+ // Create a folder, expect a commit time rename. |
{ |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
MutableEntry parent(&trans, CREATE, root_id_, PSTR("Folder")); |
ASSERT_TRUE(parent.good()); |
parent.Put(IS_DIR, true); |
parent.Put(IS_UNSYNCED, true); |
- MutableEntry entry(&trans, CREATE, parent.Get(ID), PSTR("new_entry")); |
- ASSERT_TRUE(entry.good()); |
- WriteTestDataToEntry(&trans, &entry); |
+ metahandle = parent.Get(META_HANDLE); |
} |
- // Mix in a directory creation too for later. |
- mock_server_->AddUpdateDirectory(2, 0, "dir_in_root", 10, 10); |
mock_server_->SetCommitTimeRename(i18nString); |
syncer_->SyncShare(); |
// Verify it was correctly renamed. |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- PathString expectedFolder(i18nString); |
- expectedFolder.append("Folder"); |
- Entry entry_folder(&trans, GET_BY_PATH, expectedFolder); |
- ASSERT_TRUE(entry_folder.good()); |
- PathString expected = expectedFolder + PathString(kPathSeparator); |
- expected.append(i18nString); |
- expected.append("new_entry"); |
- |
- Entry entry_new(&trans, GET_BY_PATH, expected); |
- ASSERT_TRUE(entry_new.good()); |
- |
- // And that the unrelated directory creation worked without a rename. |
- Entry new_dir(&trans, GET_BY_PATH, PSTR("dir_in_root")); |
- EXPECT_TRUE(new_dir.good()); |
- } |
-} |
- |
-TEST_F(SyncerTest, CommitTimeRenameCollision) { |
- ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- ASSERT_TRUE(dir.good()); |
- // Create a folder to collide with. |
- { |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry collider(&trans, CREATE, root_id_, PSTR("renamed_Folder")); |
- ASSERT_TRUE(collider.good()); |
- collider.Put(IS_DIR, true); |
- collider.Put(IS_UNSYNCED, true); |
- } |
- syncer_->SyncShare(); // Now we have a folder. |
- |
- { |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry folder(&trans, CREATE, root_id_, PSTR("Folder")); |
- ASSERT_TRUE(folder.good()); |
- folder.Put(IS_DIR, true); |
- folder.Put(IS_UNSYNCED, true); |
- } |
+ PathString expected_folder_name(i18nString); |
+ expected_folder_name.append("Folder"); |
- mock_server_->set_next_new_id(30000); |
- mock_server_->SetCommitTimeRename("renamed_"); |
- syncer_->SyncShare(); // Should collide and rename aside. |
- // This case will only occur if we got a commit time rename aside |
- // and the server attempts to rename to an entry that we know about, but it |
- // does not. |
- // Verify it was correctly renamed; one of them should have a sanitized name. |
- { |
- ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry collider_folder(&trans, GET_BY_PARENTID_AND_NAME, root_id_, |
- PSTR("renamed_Folder")); |
- EXPECT_TRUE(collider_folder.Get(UNSANITIZED_NAME) == PSTR("")); |
- ASSERT_TRUE(collider_folder.good()); |
- |
- // ID is generated by next_new_id_ and server mock prepending of strings. |
- Entry entry_folder(&trans, GET_BY_ID, |
- syncable::Id::CreateFromServerId("mock_server:30000")); |
+ Entry entry_folder(&trans, GET_BY_HANDLE, metahandle); |
ASSERT_TRUE(entry_folder.good()); |
- // A little arbitrary but nothing we can do about that. |
- EXPECT_TRUE(entry_folder.Get(NAME) == PSTR("renamed_Folder~1")); |
- EXPECT_TRUE(entry_folder.Get(UNSANITIZED_NAME) == PSTR("renamed_Folder")); |
+ EXPECT_EQ(expected_folder_name, entry_folder.Get(NON_UNIQUE_NAME)); |
} |
} |
- |
// A commit with a lost response produces an update that has to be reunited with |
// its parent. |
TEST_F(SyncerTest, CommitReuniteUpdateAdjustsChildren) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
ASSERT_TRUE(dir.good()); |
+ |
// Create a folder in the root. |
+ int64 metahandle_folder; |
{ |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
MutableEntry entry(&trans, CREATE, trans.root_id(), PSTR("new_folder")); |
ASSERT_TRUE(entry.good()); |
entry.Put(IS_DIR, true); |
entry.Put(IS_UNSYNCED, true); |
+ metahandle_folder = entry.Get(META_HANDLE); |
} |
// Verify it and pull the ID out of the folder. |
syncable::Id folder_id; |
+ int64 metahandle_entry; |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry entry(&trans, GET_BY_PATH, PSTR("new_folder")); |
+ Entry entry(&trans, GET_BY_HANDLE, metahandle_folder); |
ASSERT_TRUE(entry.good()); |
folder_id = entry.Get(ID); |
ASSERT_TRUE(!folder_id.ServerKnows()); |
@@ -1480,6 +1300,7 @@ TEST_F(SyncerTest, CommitReuniteUpdateAdjustsChildren) { |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
MutableEntry entry(&trans, CREATE, folder_id, PSTR("new_entry")); |
ASSERT_TRUE(entry.good()); |
+ metahandle_entry = entry.Get(META_HANDLE); |
WriteTestDataToEntry(&trans, &entry); |
} |
@@ -1487,9 +1308,10 @@ TEST_F(SyncerTest, CommitReuniteUpdateAdjustsChildren) { |
syncable::Id entry_id; |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry entry(&trans, syncable::GET_BY_PARENTID_AND_NAME, folder_id, |
- PSTR("new_entry")); |
+ Entry entry(&trans, syncable::GET_BY_HANDLE, metahandle_entry); |
ASSERT_TRUE(entry.good()); |
+ EXPECT_EQ(folder_id, entry.Get(PARENT_ID)); |
+ EXPECT_EQ(PSTR("new_entry"), entry.Get(NON_UNIQUE_NAME)); |
entry_id = entry.Get(ID); |
EXPECT_TRUE(!entry_id.ServerKnows()); |
VerifyTestDataInEntry(&trans, &entry); |
@@ -1501,7 +1323,7 @@ TEST_F(SyncerTest, CommitReuniteUpdateAdjustsChildren) { |
syncable::Id new_folder_id = |
syncable::Id::CreateFromServerId("folder_server_id"); |
- // the following update should cause the folder to both apply the update, as |
+ // The following update should cause the folder to both apply the update, as |
// well as reassociate the id. |
mock_server_->AddUpdateDirectory(new_folder_id, root_id_, |
"new_folder", new_version, timestamp); |
@@ -1516,21 +1338,23 @@ TEST_F(SyncerTest, CommitReuniteUpdateAdjustsChildren) { |
{ |
// The folder's ID should have been updated. |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry folder(&trans, GET_BY_PATH, PSTR("new_folder")); |
+ Entry folder(&trans, GET_BY_HANDLE, metahandle_folder); |
ASSERT_TRUE(folder.good()); |
+ EXPECT_EQ(PSTR("new_folder"), folder.Get(NON_UNIQUE_NAME)); |
EXPECT_TRUE(new_version == folder.Get(BASE_VERSION)); |
EXPECT_TRUE(new_folder_id == folder.Get(ID)); |
EXPECT_TRUE(folder.Get(ID).ServerKnows()); |
+ EXPECT_EQ(trans.root_id(), folder.Get(PARENT_ID)); |
- // We changed the id of the parent, old lookups should fail. |
- Entry bad_entry(&trans, syncable::GET_BY_PARENTID_AND_NAME, folder_id, |
- PSTR("new_entry")); |
- EXPECT_FALSE(bad_entry.good()); |
+ // Since it was updated, the old folder should not exist. |
+ Entry old_dead_folder(&trans, GET_BY_ID, folder_id); |
+ EXPECT_FALSE(old_dead_folder.good()); |
- // The child's parent should have changed as well. |
- Entry entry(&trans, syncable::GET_BY_PARENTID_AND_NAME, new_folder_id, |
- PSTR("new_entry")); |
+ // The child's parent should have changed. |
+ Entry entry(&trans, syncable::GET_BY_HANDLE, metahandle_entry); |
ASSERT_TRUE(entry.good()); |
+ EXPECT_EQ(PSTR("new_entry"), entry.Get(NON_UNIQUE_NAME)); |
+ EXPECT_EQ(new_folder_id, entry.Get(PARENT_ID)); |
EXPECT_TRUE(!entry.Get(ID).ServerKnows()); |
VerifyTestDataInEntry(&trans, &entry); |
} |
@@ -1541,18 +1365,23 @@ TEST_F(SyncerTest, CommitReuniteUpdateAdjustsChildren) { |
TEST_F(SyncerTest, CommitReuniteUpdate) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
ASSERT_TRUE(dir.good()); |
+ |
// Create an entry in the root. |
+ int64 entry_metahandle; |
{ |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
MutableEntry entry(&trans, CREATE, trans.root_id(), PSTR("new_entry")); |
ASSERT_TRUE(entry.good()); |
+ entry_metahandle = entry.Get(META_HANDLE); |
WriteTestDataToEntry(&trans, &entry); |
} |
+ |
// Verify it and pull the ID out. |
syncable::Id entry_id; |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry entry(&trans, GET_BY_PATH, PSTR("new_entry")); |
+ |
+ Entry entry(&trans, GET_BY_HANDLE, entry_metahandle); |
ASSERT_TRUE(entry.good()); |
entry_id = entry.Get(ID); |
EXPECT_TRUE(!entry_id.ServerKnows()); |
@@ -1577,10 +1406,11 @@ TEST_F(SyncerTest, CommitReuniteUpdate) { |
syncer_->SyncShare(); |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry entry(&trans, GET_BY_PATH, PSTR("new_entry")); |
+ Entry entry(&trans, GET_BY_HANDLE, entry_metahandle); |
ASSERT_TRUE(entry.good()); |
EXPECT_TRUE(new_version == entry.Get(BASE_VERSION)); |
EXPECT_TRUE(new_entry_id == entry.Get(ID)); |
+ EXPECT_EQ(PSTR("new_entry"), entry.Get(NON_UNIQUE_NAME)); |
} |
} |
@@ -1592,18 +1422,21 @@ TEST_F(SyncerTest, CommitReuniteUpdate) { |
TEST_F(SyncerTest, CommitReuniteUpdateDoesNotChokeOnDeletedLocalEntry) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
ASSERT_TRUE(dir.good()); |
+ |
// Create a entry in the root. |
+ int64 entry_metahandle; |
{ |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
MutableEntry entry(&trans, CREATE, trans.root_id(), PSTR("new_entry")); |
ASSERT_TRUE(entry.good()); |
+ entry_metahandle = entry.Get(META_HANDLE); |
WriteTestDataToEntry(&trans, &entry); |
} |
// Verify it and pull the ID out. |
syncable::Id entry_id; |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry entry(&trans, GET_BY_PATH, PSTR("new_entry")); |
+ Entry entry(&trans, GET_BY_HANDLE, entry_metahandle); |
ASSERT_TRUE(entry.good()); |
entry_id = entry.Get(ID); |
EXPECT_TRUE(!entry_id.ServerKnows()); |
@@ -1628,7 +1461,9 @@ TEST_F(SyncerTest, CommitReuniteUpdateDoesNotChokeOnDeletedLocalEntry) { |
// Purposefully delete the entry now before the update application finishes. |
{ |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry entry(&trans, GET_BY_PATH, PSTR("new_entry")); |
+ Id new_entry_id = GetOnlyEntryWithName( |
+ &trans, trans.root_id(), PSTR("new_entry")); |
+ MutableEntry entry(&trans, GET_BY_ID, new_entry_id); |
ASSERT_TRUE(entry.good()); |
entry.Put(syncable::IS_DEL, true); |
} |
@@ -1637,7 +1472,9 @@ TEST_F(SyncerTest, CommitReuniteUpdateDoesNotChokeOnDeletedLocalEntry) { |
syncer_->SyncShare(); |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry entry(&trans, GET_BY_PATH, PSTR("new_entry")); |
+ Id new_entry_id = GetOnlyEntryWithName( |
+ &trans, trans.root_id(), PSTR("new_entry")); |
+ Entry entry(&trans, GET_BY_ID, new_entry_id); |
ASSERT_TRUE(entry.good()); |
EXPECT_FALSE(entry.Get(IS_DEL)); |
@@ -1742,62 +1579,64 @@ TEST_F(SyncerTest, ReverseFolderOrderingTest) { |
mock_server_->AddUpdateDirectory(1, 0, "parent", 10, 10); |
LoopSyncShare(syncer_); |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry child(&trans, syncable::GET_BY_PARENTID_AND_NAME, ids_.FromNumber(4), |
- PSTR("gggchild")); |
+ |
+ Id child_id = GetOnlyEntryWithName( |
+ &trans, ids_.FromNumber(4), PSTR("gggchild")); |
+ Entry child(&trans, GET_BY_ID, child_id); |
ASSERT_TRUE(child.good()); |
} |
-bool CreateFolderInBob(Directory* dir) { |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry bob(&trans, syncable::GET_BY_PARENTID_AND_NAME, trans.root_id(), |
- PSTR("bob")); |
- MutableEntry entry2(&trans, syncable::CREATE, bob.Get(syncable::ID), |
- PSTR("bob")); |
- CHECK(entry2.good()); |
- entry2.Put(syncable::IS_DIR, true); |
- entry2.Put(syncable::IS_UNSYNCED, true); |
- return true; |
-} |
+class EntryCreatedInNewFolderTest : public SyncerTest { |
+ public: |
+ void CreateFolderInBob() { |
+ ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
+ CHECK(dir.good()); |
-TEST_F(SyncerTest, EntryCreatedInNewFolderMidSync) { |
+ WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
+ MutableEntry bob(&trans, |
+ syncable::GET_BY_ID, |
+ GetOnlyEntryWithName(&trans, |
+ TestIdFactory::root(), |
+ PSTR("bob"))); |
+ CHECK(bob.good()); |
+ |
+ MutableEntry entry2(&trans, syncable::CREATE, bob.Get(syncable::ID), |
+ PSTR("bob")); |
+ CHECK(entry2.good()); |
+ entry2.Put(syncable::IS_DIR, true); |
+ entry2.Put(syncable::IS_UNSYNCED, true); |
+ } |
+}; |
+ |
+TEST_F(EntryCreatedInNewFolderTest, EntryCreatedInNewFolderMidSync) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
{ |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry entry(&trans, syncable::CREATE, trans.root_id(), PSTR("bob")); |
+ MutableEntry entry(&trans, syncable::CREATE, trans.root_id(), |
+ PSTR("bob")); |
ASSERT_TRUE(entry.good()); |
entry.Put(syncable::IS_DIR, true); |
entry.Put(syncable::IS_UNSYNCED, true); |
} |
- mock_server_->SetMidCommitCallbackFunction(CreateFolderInBob); |
+ |
+ mock_server_->SetMidCommitCallback( |
+ NewCallback<EntryCreatedInNewFolderTest>(this, |
+ &EntryCreatedInNewFolderTest::CreateFolderInBob)); |
syncer_->SyncShare(BUILD_COMMIT_REQUEST, SYNCER_END); |
EXPECT_TRUE(1 == mock_server_->committed_ids().size()); |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- PathChar path[] = {*kPathSeparator, 'b', 'o', 'b', 0}; |
- Entry entry(&trans, syncable::GET_BY_PATH, path); |
- ASSERT_TRUE(entry.good()); |
- PathChar path2[] = {*kPathSeparator, 'b', 'o', 'b', |
- *kPathSeparator, 'b', 'o', 'b', 0}; |
- Entry entry2(&trans, syncable::GET_BY_PATH, path2); |
- ASSERT_TRUE(entry2.good()); |
- } |
-} |
+ Entry parent_entry(&trans, syncable::GET_BY_ID, |
+ GetOnlyEntryWithName(&trans, TestIdFactory::root(), PSTR("bob"))); |
+ ASSERT_TRUE(parent_entry.good()); |
-bool TouchFredAndGingerInRoot(Directory* dir) { |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry fred(&trans, syncable::GET_BY_PARENTID_AND_NAME, trans.root_id(), |
- PSTR("fred")); |
- CHECK(fred.good()); |
- // Equivalent to touching the entry. |
- fred.Put(syncable::IS_UNSYNCED, true); |
- fred.Put(syncable::SYNCING, false); |
- MutableEntry ginger(&trans, syncable::GET_BY_PARENTID_AND_NAME, |
- trans.root_id(), PSTR("ginger")); |
- CHECK(ginger.good()); |
- ginger.Put(syncable::IS_UNSYNCED, true); |
- ginger.Put(syncable::SYNCING, false); |
- return true; |
+ Id child_id = |
+ GetOnlyEntryWithName(&trans, parent_entry.Get(ID), PSTR("bob")); |
+ Entry child(&trans, syncable::GET_BY_ID, child_id); |
+ ASSERT_TRUE(child.good()); |
+ EXPECT_EQ(parent_entry.Get(ID), child.Get(PARENT_ID)); |
+ } |
} |
TEST_F(SyncerTest, NegativeIDInUpdate) { |
@@ -1811,12 +1650,15 @@ TEST_F(SyncerTest, NegativeIDInUpdate) { |
TEST_F(SyncerTest, UnappliedUpdateOnCreatedItemItemDoesNotCrash) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
+ |
+ int64 metahandle_fred; |
{ |
// Create an item. |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
MutableEntry fred_match(&trans, CREATE, trans.root_id(), |
PSTR("fred_match")); |
ASSERT_TRUE(fred_match.good()); |
+ metahandle_fred = fred_match.Get(META_HANDLE); |
WriteTestDataToEntry(&trans, &fred_match); |
} |
// Commit it. |
@@ -1827,7 +1669,7 @@ TEST_F(SyncerTest, UnappliedUpdateOnCreatedItemItemDoesNotCrash) { |
{ |
// Now receive a change from outside. |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry fred_match(&trans, GET_BY_PATH, PSTR("fred_match")); |
+ MutableEntry fred_match(&trans, GET_BY_HANDLE, metahandle_fred); |
ASSERT_TRUE(fred_match.good()); |
EXPECT_TRUE(fred_match.Get(ID).ServerKnows()); |
fred_match_id = fred_match.Get(ID); |
@@ -1840,233 +1682,6 @@ TEST_F(SyncerTest, UnappliedUpdateOnCreatedItemItemDoesNotCrash) { |
} |
} |
-TEST_F(SyncerTest, NameClashWithResolverInconsistentUpdates) { |
- // I'm unsure what the client should really do when the scenario in this old |
- // test occurs. The set of updates we've received are not consistent. |
- ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- CHECK(dir.good()); |
- const char* base_name = "name_clash_with_resolver"; |
- const char* full_name = "name_clash_with_resolver.htm"; |
- const PathChar* base_name_p = PSTR("name_clash_with_resolver"); |
- mock_server_->AddUpdateBookmark(1, 0, full_name, 10, 10); |
- syncer_->SyncShare(); |
- { |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry entry(&trans, GET_BY_ID, ids_.FromNumber(1)); |
- ASSERT_TRUE(entry.good()); |
- WriteTestDataToEntry(&trans, &entry); |
- } |
- mock_server_->AddUpdateBookmark(2, 0, full_name, 10, 10); |
- mock_server_->set_conflict_n_commits(1); |
- syncer_->SyncShare(); |
- mock_server_->set_conflict_n_commits(1); |
- syncer_->SyncShare(); |
- EXPECT_TRUE(0 == syncer_events_.size()); |
- { |
- ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); |
- Entry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); |
- ASSERT_TRUE(id1.good()); |
- ASSERT_TRUE(id2.good()); |
- EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); |
- EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); |
- PathString id1name = id1.Get(NAME); |
- |
- EXPECT_TRUE(base_name_p == id1name.substr(0, strlen(base_name))); |
- EXPECT_TRUE(PSTR(".htm") == id1name.substr(id1name.length() - 4)); |
- EXPECT_LE(id1name.length(), 200ul); |
- EXPECT_TRUE(PSTR("name_clash_with_resolver.htm") == id2.Get(NAME)); |
- } |
-} |
- |
-TEST_F(SyncerTest, NameClashWithResolver) { |
- ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- CHECK(dir.good()); |
- const char* base_name = "name_clash_with_resolver"; |
- const char* full_name = "name_clash_with_resolver.htm"; |
- const PathChar* base_name_p = PSTR("name_clash_with_resolver"); |
- const PathChar* full_name_p = PSTR("name_clash_with_resolver.htm"); |
- mock_server_->AddUpdateBookmark(1, 0, "fred", 10, 10); |
- syncer_->SyncShare(); |
- { |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry entry(&trans, GET_BY_ID, ids_.FromNumber(1)); |
- ASSERT_TRUE(entry.good()); |
- entry.Put(NAME, full_name_p); |
- WriteTestDataToEntry(&trans, &entry); |
- } |
- mock_server_->AddUpdateBookmark(2, 0, full_name, 10, 10); |
- // We do NOT use LoopSyncShare here because of the way that |
- // mock_server_->conflict_n_commits works. |
- // It will only conflict the first n commits, so if we let the syncer loop, |
- // the second commit of the update will succeed even though it shouldn't. |
- mock_server_->set_conflict_n_commits(1); |
- syncer_->SyncShare(state_.get()); |
- mock_server_->set_conflict_n_commits(1); |
- syncer_->SyncShare(state_.get()); |
- EXPECT_TRUE(0 == syncer_events_.size()); |
- syncer_events_.clear(); |
- { |
- ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); |
- Entry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); |
- ASSERT_TRUE(id1.good()); |
- ASSERT_TRUE(id2.good()); |
- EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); |
- EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); |
- PathString id1name = id1.Get(NAME); |
- |
- EXPECT_TRUE(base_name_p == id1name.substr(0, strlen(base_name))); |
- EXPECT_TRUE(PSTR(".htm") == id1name.substr(id1name.length() - 4)); |
- EXPECT_LE(id1name.length(), 200ul); |
- EXPECT_TRUE(full_name_p == id2.Get(NAME)); |
- } |
-} |
- |
-TEST_F(SyncerTest, VeryLongNameClashWithResolver) { |
- ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- CHECK(dir.good()); |
- string name; |
- PathString name_w; |
- name.resize(250, 'X'); |
- name_w.resize(250, 'X'); |
- name.append(".htm"); |
- name_w.append(PSTR(".htm")); |
- mock_server_->AddUpdateBookmark(1, 0, "fred", 10, 10); |
- syncer_->SyncShare(); |
- { |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry entry(&trans, GET_BY_ID, ids_.FromNumber(1)); |
- ASSERT_TRUE(entry.good()); |
- entry.Put(NAME, name_w); |
- WriteTestDataToEntry(&trans, &entry); |
- } |
- mock_server_->AddUpdateBookmark(2, 0, name, 10, 10); |
- mock_server_->set_conflict_n_commits(1); |
- // We do NOT use LoopSyncShare here because of the way that |
- // mock_server_->conflict_n_commits works. |
- // It will only conflict the first n commits, so if we let the syncer loop, |
- // the second commit of the update will succeed even though it shouldn't. |
- syncer_->SyncShare(state_.get()); |
- mock_server_->set_conflict_n_commits(1); |
- syncer_->SyncShare(state_.get()); |
- EXPECT_TRUE(0 == syncer_events_.size()); |
- { |
- ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); |
- Entry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); |
- ASSERT_TRUE(id1.good()); |
- ASSERT_TRUE(id2.good()); |
- EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); |
- EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); |
- PathString id1name = id1.Get(NAME); |
- EXPECT_TRUE(PSTR(".htm") == id1name.substr(id1name.length() - 4)); |
- EXPECT_TRUE(name_w == id2.Get(NAME)); |
- } |
-} |
- |
-TEST_F(SyncerTest, NameClashWithResolverAndDotStartedName) { |
- ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- CHECK(dir.good()); |
- mock_server_->AddUpdateBookmark(1, 0, ".bob.htm", 10, 10); |
- syncer_->SyncShare(); |
- { |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry entry(&trans, GET_BY_ID, ids_.FromNumber(1)); |
- ASSERT_TRUE(entry.good()); |
- entry.Put(IS_UNSYNCED, true); |
- entry.Put(NAME, PSTR(".htm")); |
- WriteTestDataToEntry(&trans, &entry); |
- } |
- mock_server_->set_conflict_all_commits(true); |
- mock_server_->AddUpdateBookmark(2, 0, ".htm", 10, 10); |
- syncer_->SyncShare(); |
- syncer_->SyncShare(); |
- EXPECT_TRUE(0 == syncer_events_.size()); |
- { |
- ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); |
- Entry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); |
- ASSERT_TRUE(id1.good()); |
- ASSERT_TRUE(id2.good()); |
- EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); |
- EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); |
- PathString id1name = id1.Get(NAME); |
- EXPECT_TRUE(PSTR(".htm") == id1name.substr(0, 4)); |
- EXPECT_TRUE(PSTR(".htm") == id2.Get(NAME)); |
- } |
-} |
- |
-TEST_F(SyncerTest, ThreeNamesClashWithResolver) { |
- ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- CHECK(dir.good()); |
- mock_server_->set_conflict_all_commits(true); |
- mock_server_->AddUpdateBookmark(1, 0, "in_root.htm", 10, 10); |
- LoopSyncShare(syncer_); |
- { |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry entry(&trans, GET_BY_ID, ids_.FromNumber(1)); |
- ASSERT_TRUE(entry.good()); |
- ASSERT_FALSE(entry.Get(IS_DEL)); |
- entry.Put(IS_UNSYNCED, true); |
- } |
- mock_server_->AddUpdateBookmark(2, 0, "in_root.htm", 10, 10); |
- LoopSyncShare(syncer_); |
- LoopSyncShare(syncer_); |
- { |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry entry(&trans, GET_BY_ID, ids_.FromNumber(2)); |
- ASSERT_TRUE(entry.good()); |
- ASSERT_FALSE(entry.Get(IS_DEL)); |
- entry.Put(IS_UNSYNCED, true); |
- } |
- mock_server_->AddUpdateBookmark(3, 0, "in_root.htm", 10, 10); |
- LoopSyncShare(syncer_); |
- LoopSyncShare(syncer_); |
- { |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry entry(&trans, GET_BY_ID, ids_.FromNumber(3)); |
- ASSERT_TRUE(entry.good()); |
- ASSERT_FALSE(entry.Get(IS_DEL)); |
- entry.Put(IS_UNSYNCED, true); |
- } |
- mock_server_->AddUpdateBookmark(4, 0, "in_root.htm", 10, 10); |
- LoopSyncShare(syncer_); |
- LoopSyncShare(syncer_); |
- EXPECT_TRUE(0 == syncer_events_.size()); |
- { |
- ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); |
- Entry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); |
- Entry id3(&trans, GET_BY_ID, ids_.FromNumber(3)); |
- Entry id4(&trans, GET_BY_ID, ids_.FromNumber(4)); |
- ASSERT_TRUE(id1.good()); |
- ASSERT_TRUE(id2.good()); |
- ASSERT_TRUE(id3.good()); |
- ASSERT_TRUE(id4.good()); |
- EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); |
- EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); |
- EXPECT_TRUE(root_id_ == id3.Get(PARENT_ID)); |
- EXPECT_TRUE(root_id_ == id4.Get(PARENT_ID)); |
- PathString id1name = id1.Get(NAME); |
- ASSERT_GE(id1name.length(), 4ul); |
- EXPECT_TRUE(PSTR("in_root") == id1name.substr(0, 7)); |
- EXPECT_TRUE(PSTR(".htm") == id1name.substr(id1name.length() - 4)); |
- EXPECT_NE(PSTR("in_root.htm"), id1.Get(NAME)); |
- PathString id2name = id2.Get(NAME); |
- ASSERT_GE(id2name.length(), 4ul); |
- EXPECT_TRUE(PSTR("in_root") == id2name.substr(0, 7)); |
- EXPECT_TRUE(PSTR(".htm") == id2name.substr(id2name.length() - 4)); |
- EXPECT_NE(PSTR("in_root.htm"), id2.Get(NAME)); |
- PathString id3name = id3.Get(NAME); |
- ASSERT_GE(id3name.length(), 4ul); |
- EXPECT_TRUE(PSTR("in_root") == id3name.substr(0, 7)); |
- EXPECT_TRUE(PSTR(".htm") == id3name.substr(id3name.length() - 4)); |
- EXPECT_NE(PSTR("in_root.htm"), id3.Get(NAME)); |
- EXPECT_TRUE(PSTR("in_root.htm") == id4.Get(NAME)); |
- } |
-} |
- |
/** |
* In the event that we have a double changed entry, that is changed on both |
* the client and the server, the conflict resolver should just drop one of |
@@ -2107,12 +1722,13 @@ TEST_F(SyncerTest, DoublyChangedWithResolver) { |
syncer_events_.clear(); |
} |
-// We got this repro case when someone was editing entries while sync was |
+// We got this repro case when someone was editing bookmarks while sync was |
// occuring. The entry had changed out underneath the user. |
TEST_F(SyncerTest, CommitsUpdateDoesntAlterEntry) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
int64 test_time = 123456; |
+ int64 entry_metahandle; |
{ |
WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
MutableEntry entry(&wtrans, syncable::CREATE, root_id_, PSTR("Pete")); |
@@ -2121,6 +1737,7 @@ TEST_F(SyncerTest, CommitsUpdateDoesntAlterEntry) { |
entry.Put(syncable::IS_DIR, true); |
entry.Put(syncable::IS_UNSYNCED, true); |
entry.Put(syncable::MTIME, test_time); |
+ entry_metahandle = entry.Get(META_HANDLE); |
} |
syncer_->SyncShare(); |
syncable::Id id; |
@@ -2128,8 +1745,7 @@ TEST_F(SyncerTest, CommitsUpdateDoesntAlterEntry) { |
int64 server_position_in_parent; |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry entry(&trans, syncable::GET_BY_PARENTID_AND_NAME, trans.root_id(), |
- PSTR("Pete")); |
+ Entry entry(&trans, syncable::GET_BY_HANDLE, entry_metahandle); |
ASSERT_TRUE(entry.good()); |
id = entry.Get(ID); |
EXPECT_TRUE(id.ServerKnows()); |
@@ -2150,18 +1766,28 @@ TEST_F(SyncerTest, CommitsUpdateDoesntAlterEntry) { |
TEST_F(SyncerTest, ParentAndChildBothMatch) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
+ syncable::Id parent_id = ids_.NewServerId(); |
+ syncable::Id child_id = ids_.NewServerId(); |
+ |
{ |
WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
MutableEntry parent(&wtrans, CREATE, root_id_, PSTR("Folder")); |
ASSERT_TRUE(parent.good()); |
parent.Put(IS_DIR, true); |
parent.Put(IS_UNSYNCED, true); |
+ parent.Put(ID, parent_id); |
+ parent.Put(BASE_VERSION, 1); |
+ parent.Put(IS_BOOKMARK_OBJECT, true); |
+ |
MutableEntry child(&wtrans, CREATE, parent.Get(ID), PSTR("test.htm")); |
ASSERT_TRUE(child.good()); |
+ child.Put(ID, child_id); |
+ child.Put(BASE_VERSION, 1); |
+ child.Put(IS_BOOKMARK_OBJECT, true); |
WriteTestDataToEntry(&wtrans, &child); |
} |
- mock_server_->AddUpdateDirectory(parent_id_, root_id_, "Folder", 10, 10); |
- mock_server_->AddUpdateBookmark(child_id_, parent_id_, "test.htm", 10, 10); |
+ mock_server_->AddUpdateDirectory(parent_id, root_id_, "Folder", 10, 10); |
+ mock_server_->AddUpdateBookmark(child_id, parent_id, "test.htm", 10, 10); |
mock_server_->set_conflict_all_commits(true); |
syncer_->SyncShare(); |
syncer_->SyncShare(); |
@@ -2171,7 +1797,7 @@ TEST_F(SyncerTest, ParentAndChildBothMatch) { |
Directory::ChildHandles children; |
dir->GetChildHandles(&trans, root_id_, &children); |
EXPECT_TRUE(1 == children.size()); |
- dir->GetChildHandles(&trans, parent_id_, &children); |
+ dir->GetChildHandles(&trans, parent_id, &children); |
EXPECT_TRUE(1 == children.size()); |
Directory::UnappliedUpdateMetaHandles unapplied; |
dir->GetUnappliedUpdateMetaHandles(&trans, &unapplied); |
@@ -2241,12 +1867,15 @@ TEST_F(SyncerTest, DeletingEntryInFolder) { |
// This test is a little fake. |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
+ |
+ int64 existing_metahandle; |
{ |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
MutableEntry entry(&trans, CREATE, trans.root_id(), PSTR("existing")); |
ASSERT_TRUE(entry.good()); |
entry.Put(IS_DIR, true); |
entry.Put(IS_UNSYNCED, true); |
+ existing_metahandle = entry.Get(META_HANDLE); |
} |
syncer_->SyncShare(state_.get()); |
{ |
@@ -2256,7 +1885,7 @@ TEST_F(SyncerTest, DeletingEntryInFolder) { |
newfolder.Put(IS_DIR, true); |
newfolder.Put(IS_UNSYNCED, true); |
- MutableEntry existing(&trans, GET_BY_PATH, PSTR("existing")); |
+ MutableEntry existing(&trans, GET_BY_HANDLE, existing_metahandle); |
ASSERT_TRUE(existing.good()); |
existing.Put(PARENT_ID, newfolder.Get(ID)); |
existing.Put(IS_UNSYNCED, true); |
@@ -2270,10 +1899,11 @@ TEST_F(SyncerTest, DeletingEntryInFolder) { |
EXPECT_TRUE(0 == status.conflicting_commits()); |
} |
-// TODO(sync): Is this test useful anymore? |
TEST_F(SyncerTest, DeletingEntryWithLocalEdits) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
+ int64 newfolder_metahandle; |
+ |
mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); |
syncer_->SyncShare(); |
{ |
@@ -2281,15 +1911,15 @@ TEST_F(SyncerTest, DeletingEntryWithLocalEdits) { |
MutableEntry newfolder(&trans, CREATE, ids_.FromNumber(1), PSTR("local")); |
ASSERT_TRUE(newfolder.good()); |
newfolder.Put(IS_UNSYNCED, true); |
+ newfolder_metahandle = newfolder.Get(META_HANDLE); |
} |
mock_server_->AddUpdateDirectory(1, 0, "bob", 2, 20); |
mock_server_->SetLastUpdateDeleted(); |
syncer_->SyncShare(SYNCER_BEGIN, APPLY_UPDATES); |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry entry_by_path(&trans, syncable::GET_BY_PATH, |
- PathString(PSTR("bob")) + kPathSeparator + PSTR("local")); |
- ASSERT_TRUE(entry_by_path.good()); |
+ Entry entry(&trans, syncable::GET_BY_HANDLE, newfolder_metahandle); |
+ ASSERT_TRUE(entry.good()); |
} |
} |
@@ -2306,17 +1936,17 @@ TEST_F(SyncerTest, FolderSwapUpdate) { |
ReadTransaction trans(dir, __FILE__, __LINE__); |
Entry id1(&trans, GET_BY_ID, ids_.FromNumber(7801)); |
ASSERT_TRUE(id1.good()); |
- EXPECT_TRUE(PSTR("fred") == id1.Get(NAME)); |
+ EXPECT_TRUE(PSTR("fred") == id1.Get(NON_UNIQUE_NAME)); |
EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); |
Entry id2(&trans, GET_BY_ID, ids_.FromNumber(1024)); |
ASSERT_TRUE(id2.good()); |
- EXPECT_TRUE(PSTR("bob") == id2.Get(NAME)); |
+ EXPECT_TRUE(PSTR("bob") == id2.Get(NON_UNIQUE_NAME)); |
EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); |
} |
syncer_events_.clear(); |
} |
-TEST_F(SyncerTest, CorruptUpdateBadFolderSwapUpdate) { |
+TEST_F(SyncerTest, NameCollidingFolderSwapWorksFine) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
mock_server_->AddUpdateDirectory(7801, 0, "bob", 1, 10); |
@@ -2327,15 +1957,15 @@ TEST_F(SyncerTest, CorruptUpdateBadFolderSwapUpdate) { |
ReadTransaction trans(dir, __FILE__, __LINE__); |
Entry id1(&trans, GET_BY_ID, ids_.FromNumber(7801)); |
ASSERT_TRUE(id1.good()); |
- EXPECT_TRUE(PSTR("bob") == id1.Get(NAME)); |
+ EXPECT_TRUE(PSTR("bob") == id1.Get(NON_UNIQUE_NAME)); |
EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); |
Entry id2(&trans, GET_BY_ID, ids_.FromNumber(1024)); |
ASSERT_TRUE(id2.good()); |
- EXPECT_TRUE(PSTR("fred") == id2.Get(NAME)); |
+ EXPECT_TRUE(PSTR("fred") == id2.Get(NON_UNIQUE_NAME)); |
EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); |
Entry id3(&trans, GET_BY_ID, ids_.FromNumber(4096)); |
ASSERT_TRUE(id3.good()); |
- EXPECT_TRUE(PSTR("alice") == id3.Get(NAME)); |
+ EXPECT_TRUE(PSTR("alice") == id3.Get(NON_UNIQUE_NAME)); |
EXPECT_TRUE(root_id_ == id3.Get(PARENT_ID)); |
} |
mock_server_->AddUpdateDirectory(1024, 0, "bob", 2, 20); |
@@ -2346,226 +1976,20 @@ TEST_F(SyncerTest, CorruptUpdateBadFolderSwapUpdate) { |
ReadTransaction trans(dir, __FILE__, __LINE__); |
Entry id1(&trans, GET_BY_ID, ids_.FromNumber(7801)); |
ASSERT_TRUE(id1.good()); |
- EXPECT_TRUE(PSTR("bob") == id1.Get(NAME)); |
+ EXPECT_TRUE(PSTR("fred") == id1.Get(NON_UNIQUE_NAME)); |
EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); |
Entry id2(&trans, GET_BY_ID, ids_.FromNumber(1024)); |
ASSERT_TRUE(id2.good()); |
- EXPECT_TRUE(PSTR("fred") == id2.Get(NAME)); |
+ EXPECT_TRUE(PSTR("bob") == id2.Get(NON_UNIQUE_NAME)); |
EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); |
Entry id3(&trans, GET_BY_ID, ids_.FromNumber(4096)); |
ASSERT_TRUE(id3.good()); |
- EXPECT_TRUE(PSTR("alice") == id3.Get(NAME)); |
+ EXPECT_TRUE(PSTR("bob") == id3.Get(NON_UNIQUE_NAME)); |
EXPECT_TRUE(root_id_ == id3.Get(PARENT_ID)); |
} |
syncer_events_.clear(); |
} |
-// TODO(chron): New set of folder swap commit tests that don't rely on |
-// transactional commits. |
-TEST_F(SyncerTest, DISABLED_FolderSwapCommit) { |
- ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- CHECK(dir.good()); |
- mock_server_->AddUpdateDirectory(7801, 0, "bob", 1, 10); |
- mock_server_->AddUpdateDirectory(1024, 0, "fred", 1, 10); |
- syncer_->SyncShare(); |
- { |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry id1(&trans, GET_BY_ID, ids_.FromNumber(7801)); |
- MutableEntry id2(&trans, GET_BY_ID, ids_.FromNumber(1024)); |
- ASSERT_TRUE(id1.good()); |
- ASSERT_TRUE(id2.good()); |
- EXPECT_FALSE(id1.Put(NAME, PSTR("fred"))); |
- EXPECT_TRUE(id1.Put(NAME, PSTR("temp"))); |
- EXPECT_TRUE(id2.Put(NAME, PSTR("bob"))); |
- EXPECT_TRUE(id1.Put(NAME, PSTR("fred"))); |
- id1.Put(IS_UNSYNCED, true); |
- id2.Put(IS_UNSYNCED, true); |
- } |
- mock_server_->set_conflict_all_commits(true); |
- syncer_->SyncShare(); |
- ASSERT_TRUE(2 == mock_server_->commit_messages().size()); |
- { |
- ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry id1(&trans, GET_BY_ID, ids_.FromNumber(7801)); |
- ASSERT_TRUE(id1.good()); |
- EXPECT_TRUE(PSTR("fred") == id1.Get(NAME)); |
- EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); |
- EXPECT_FALSE(id1.Get(IS_UNSYNCED)); |
- Entry id2(&trans, GET_BY_ID, ids_.FromNumber(1024)); |
- ASSERT_TRUE(id2.good()); |
- EXPECT_TRUE(PSTR("bob") == id2.Get(NAME)); |
- EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); |
- EXPECT_FALSE(id2.Get(IS_UNSYNCED)); |
- } |
- syncer_events_.clear(); |
-} |
- |
-// TODO(chron): New set of folder swap commit tests that don't rely on |
-// transactional commits. |
-TEST_F(SyncerTest, DISABLED_DualFolderSwapCommit) { |
- ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- CHECK(dir.good()); |
- mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); |
- mock_server_->AddUpdateDirectory(2, 0, "fred", 1, 10); |
- mock_server_->AddUpdateDirectory(3, 0, "sue", 1, 10); |
- mock_server_->AddUpdateDirectory(4, 0, "greg", 1, 10); |
- syncer_->SyncShare(); |
- { |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); |
- MutableEntry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); |
- MutableEntry id3(&trans, GET_BY_ID, ids_.FromNumber(3)); |
- MutableEntry id4(&trans, GET_BY_ID, ids_.FromNumber(4)); |
- ASSERT_TRUE(id1.good()); |
- ASSERT_TRUE(id2.good()); |
- ASSERT_TRUE(id3.good()); |
- ASSERT_TRUE(id4.good()); |
- EXPECT_FALSE(id1.Put(NAME, PSTR("fred"))); |
- EXPECT_TRUE(id1.Put(NAME, PSTR("temp"))); |
- EXPECT_TRUE(id2.Put(NAME, PSTR("bob"))); |
- EXPECT_TRUE(id1.Put(NAME, PSTR("fred"))); |
- EXPECT_FALSE(id3.Put(NAME, PSTR("greg"))); |
- EXPECT_TRUE(id3.Put(NAME, PSTR("temp"))); |
- EXPECT_TRUE(id4.Put(NAME, PSTR("sue"))); |
- EXPECT_TRUE(id3.Put(NAME, PSTR("greg"))); |
- id1.Put(IS_UNSYNCED, true); |
- id2.Put(IS_UNSYNCED, true); |
- id3.Put(IS_UNSYNCED, true); |
- id4.Put(IS_UNSYNCED, true); |
- } |
- mock_server_->set_conflict_all_commits(true); |
- syncer_->SyncShare(); |
- ASSERT_TRUE(4 == mock_server_->commit_messages().size()); |
- { |
- ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); |
- ASSERT_TRUE(id1.good()); |
- EXPECT_TRUE(PSTR("fred") == id1.Get(NAME)); |
- EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); |
- EXPECT_FALSE(id1.Get(IS_UNSYNCED)); |
- Entry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); |
- ASSERT_TRUE(id2.good()); |
- EXPECT_TRUE(PSTR("bob") == id2.Get(NAME)); |
- EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); |
- EXPECT_FALSE(id2.Get(IS_UNSYNCED)); |
- Entry id3(&trans, GET_BY_ID, ids_.FromNumber(3)); |
- ASSERT_TRUE(id3.good()); |
- EXPECT_TRUE(PSTR("greg") == id3.Get(NAME)); |
- EXPECT_TRUE(root_id_ == id3.Get(PARENT_ID)); |
- EXPECT_FALSE(id3.Get(IS_UNSYNCED)); |
- Entry id4(&trans, GET_BY_ID, ids_.FromNumber(4)); |
- ASSERT_TRUE(id4.good()); |
- EXPECT_TRUE(PSTR("sue") == id4.Get(NAME)); |
- EXPECT_TRUE(root_id_ == id4.Get(PARENT_ID)); |
- EXPECT_FALSE(id4.Get(IS_UNSYNCED)); |
- } |
- syncer_events_.clear(); |
-} |
- |
-// TODO(chron): New set of folder swap commit tests that don't rely on |
-// transactional commits. |
-TEST_F(SyncerTest, DISABLED_TripleFolderRotateCommit) { |
- ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- CHECK(dir.good()); |
- mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); |
- mock_server_->AddUpdateDirectory(2, 0, "fred", 1, 10); |
- mock_server_->AddUpdateDirectory(3, 0, "sue", 1, 10); |
- syncer_->SyncShare(); |
- { |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); |
- MutableEntry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); |
- MutableEntry id3(&trans, GET_BY_ID, ids_.FromNumber(3)); |
- ASSERT_TRUE(id1.good()); |
- ASSERT_TRUE(id2.good()); |
- ASSERT_TRUE(id3.good()); |
- EXPECT_FALSE(id1.Put(NAME, PSTR("sue"))); |
- EXPECT_TRUE(id1.Put(NAME, PSTR("temp"))); |
- EXPECT_TRUE(id2.Put(NAME, PSTR("bob"))); |
- EXPECT_TRUE(id3.Put(NAME, PSTR("fred"))); |
- EXPECT_TRUE(id1.Put(NAME, PSTR("sue"))); |
- id1.Put(IS_UNSYNCED, true); |
- id2.Put(IS_UNSYNCED, true); |
- id3.Put(IS_UNSYNCED, true); |
- } |
- mock_server_->set_conflict_all_commits(true); |
- syncer_->SyncShare(); |
- ASSERT_TRUE(2 == mock_server_->commit_messages().size()); |
- { |
- ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); |
- ASSERT_TRUE(id1.good()); |
- EXPECT_TRUE(PSTR("sue") == id1.Get(NAME)); |
- EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); |
- EXPECT_FALSE(id1.Get(IS_UNSYNCED)); |
- Entry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); |
- ASSERT_TRUE(id2.good()); |
- EXPECT_TRUE(PSTR("bob") == id2.Get(NAME)); |
- EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); |
- EXPECT_FALSE(id2.Get(IS_UNSYNCED)); |
- Entry id3(&trans, GET_BY_ID, ids_.FromNumber(3)); |
- ASSERT_TRUE(id3.good()); |
- EXPECT_TRUE(PSTR("fred") == id3.Get(NAME)); |
- EXPECT_TRUE(root_id_ == id3.Get(PARENT_ID)); |
- EXPECT_FALSE(id3.Get(IS_UNSYNCED)); |
- } |
- syncer_events_.clear(); |
-} |
- |
-// TODO(chron): New set of folder swap commit tests that don't rely on |
-// transactional commits. |
-TEST_F(SyncerTest, DISABLED_ServerAndClientSwap) { |
- ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- CHECK(dir.good()); |
- mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); |
- mock_server_->AddUpdateDirectory(2, 0, "fred", 1, 10); |
- mock_server_->AddUpdateDirectory(3, 0, "sue", 1, 10); |
- mock_server_->AddUpdateDirectory(4, 0, "greg", 1, 10); |
- syncer_->SyncShare(); |
- { |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); |
- MutableEntry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); |
- ASSERT_TRUE(id1.good()); |
- ASSERT_TRUE(id2.good()); |
- EXPECT_FALSE(id1.Put(NAME, PSTR("fred"))); |
- EXPECT_TRUE(id1.Put(NAME, PSTR("temp"))); |
- EXPECT_TRUE(id2.Put(NAME, PSTR("bob"))); |
- EXPECT_TRUE(id1.Put(NAME, PSTR("fred"))); |
- id1.Put(IS_UNSYNCED, true); |
- id2.Put(IS_UNSYNCED, true); |
- } |
- mock_server_->set_conflict_all_commits(true); |
- mock_server_->AddUpdateDirectory(3, 0, "greg", 2, 20); |
- mock_server_->AddUpdateDirectory(4, 0, "sue", 2, 20); |
- syncer_->SyncShare(); |
- ASSERT_TRUE(2 == mock_server_->commit_messages().size()); |
- { |
- ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); |
- ASSERT_TRUE(id1.good()); |
- EXPECT_TRUE(PSTR("fred") == id1.Get(NAME)); |
- EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); |
- EXPECT_FALSE(id1.Get(IS_UNSYNCED)); |
- Entry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); |
- ASSERT_TRUE(id2.good()); |
- EXPECT_TRUE(PSTR("bob") == id2.Get(NAME)); |
- EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); |
- EXPECT_FALSE(id2.Get(IS_UNSYNCED)); |
- Entry id3(&trans, GET_BY_ID, ids_.FromNumber(3)); |
- ASSERT_TRUE(id3.good()); |
- EXPECT_TRUE(PSTR("greg") == id3.Get(NAME)); |
- EXPECT_TRUE(root_id_ == id3.Get(PARENT_ID)); |
- EXPECT_FALSE(id3.Get(IS_UNSYNCED)); |
- Entry id4(&trans, GET_BY_ID, ids_.FromNumber(4)); |
- ASSERT_TRUE(id4.good()); |
- EXPECT_TRUE(PSTR("sue") == id4.Get(NAME)); |
- EXPECT_TRUE(root_id_ == id4.Get(PARENT_ID)); |
- EXPECT_FALSE(id4.Get(IS_UNSYNCED)); |
- } |
- syncer_events_.clear(); |
-} |
- |
TEST_F(SyncerTest, CommitManyItemsInOneGo) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
uint32 max_batches = 3; |
@@ -2591,44 +2015,57 @@ TEST_F(SyncerTest, CommitManyItemsInOneGo) { |
TEST_F(SyncerTest, HugeConflict) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- PathString name = PSTR("f"); |
- int item_count = 30; // We should be able to do 300 or 3000 w/o issue. |
+ int item_count = 300; // We should be able to do 300 or 3000 w/o issue. |
CHECK(dir.good()); |
+ |
+ syncable::Id parent_id = ids_.NewServerId(); |
+ syncable::Id last_id = parent_id; |
+ vector<syncable::Id> tree_ids; |
+ |
+ // Create a lot of updates for which the parent does not exist yet. |
+ // Generate a huge deep tree which should all fail to apply at first. |
{ |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- syncable::Id last_id = trans.root_id(); |
- for (int i = 0; i < item_count ; i++) { |
- MutableEntry e(&trans, CREATE, last_id, name); |
- e.Put(IS_UNSYNCED, true); |
- e.Put(IS_DIR, true); |
- last_id = e.Get(ID); |
+ for (int i = 0; i < item_count; i++) { |
+ syncable::Id next_id = ids_.NewServerId(); |
+ tree_ids.push_back(next_id); |
+ mock_server_->AddUpdateDirectory(next_id, last_id, "BOB", 2, 20); |
+ last_id = next_id; |
} |
} |
+ |
syncer_->SyncShare(); |
- CHECK(dir.good()); |
+ |
+ // Check they're in the expected conflict state. |
{ |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry e(&trans, GET_BY_PARENTID_AND_NAME, root_id_, name); |
- syncable::Id in_root = e.Get(ID); |
- syncable::Id last_id = e.Get(ID); |
- for (int i = 0; i < item_count - 1 ; i++) { |
- MutableEntry e(&trans, GET_BY_PARENTID_AND_NAME, last_id, name); |
+ ReadTransaction trans(dir, __FILE__, __LINE__); |
+ for (int i = 0; i < item_count; i++) { |
+ Entry e(&trans, GET_BY_ID, tree_ids[i]); |
+ // They should all exist but none should be applied. |
ASSERT_TRUE(e.good()); |
- mock_server_->AddUpdateDirectory(in_root, root_id_, "BOB", 2, 20); |
- mock_server_->SetLastUpdateDeleted(); |
- if (0 == i) |
- e.Put(IS_UNSYNCED, true); |
- last_id = e.Get(ID); |
+ EXPECT_TRUE(e.Get(IS_DEL)); |
+ EXPECT_TRUE(e.Get(IS_UNAPPLIED_UPDATE)); |
} |
} |
- mock_server_->set_conflict_all_commits(true); |
- syncer_->SyncShare(); |
- syncer_->SyncShare(); |
+ |
+ // Add the missing parent directory. |
+ mock_server_->AddUpdateDirectory(parent_id, TestIdFactory::root(), |
+ "BOB", 2, 20); |
syncer_->SyncShare(); |
- CHECK(dir.good()); |
+ |
+ // Now they should all be OK. |
+ { |
+ ReadTransaction trans(dir, __FILE__, __LINE__); |
+ for (int i = 0; i < item_count; i++) { |
+ Entry e(&trans, GET_BY_ID, tree_ids[i]); |
+ ASSERT_TRUE(e.good()); |
+ EXPECT_FALSE(e.Get(IS_DEL)); |
+ EXPECT_FALSE(e.Get(IS_UNAPPLIED_UPDATE)); |
+ } |
+ } |
} |
-TEST_F(SyncerTest, CaseChangeNameClashConflict) { |
+TEST_F(SyncerTest, DontCrashOnCaseChange) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); |
@@ -2656,66 +2093,6 @@ TEST_F(SyncerTest, UnsyncedItemAndUpdate) { |
syncer_events_.clear(); |
} |
-TEST_F(SyncerTest, FolderMergeWithChildNameClash) { |
- ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- CHECK(dir.good()); |
- syncable::Id local_folder_id, root_id; |
- mock_server_->AddUpdateDirectory(parent_id_, root_id_, "Folder2", 10, 10); |
- mock_server_->AddUpdateBookmark(child_id_, parent_id_, "Bookmark", 10, 10); |
- syncer_->SyncShare(); |
- int64 local_folder_handle; |
- { |
- WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry parent(&wtrans, CREATE, root_id_, PSTR("Folder")); |
- ASSERT_TRUE(parent.good()); |
- local_folder_id = parent.Get(ID); |
- local_folder_handle = parent.Get(META_HANDLE); |
- parent.Put(IS_DIR, true); |
- parent.Put(IS_UNSYNCED, true); |
- MutableEntry child(&wtrans, CREATE, parent.Get(ID), PSTR("Bookmark")); |
- ASSERT_TRUE(child.good()); |
- WriteTestDataToEntry(&wtrans, &child); |
- } |
- mock_server_->AddUpdateDirectory(parent_id_, root_id_, "Folder", 20, 20); |
- mock_server_->set_conflict_all_commits(true); |
- LoopSyncShare(syncer_); |
- LoopSyncShare(syncer_); |
- { |
- ReadTransaction trans(dir, __FILE__, __LINE__); |
- Directory::ChildHandles children; |
- dir->GetChildHandles(&trans, root_id_, &children); |
- ASSERT_TRUE(2 == children.size()); |
- Entry parent(&trans, GET_BY_ID, parent_id_); |
- ASSERT_TRUE(parent.good()); |
- EXPECT_TRUE(parent.Get(NAME) == PSTR("Folder")); |
- if (local_folder_handle == children[0]) { |
- EXPECT_TRUE(children[1] == parent.Get(META_HANDLE)); |
- } else { |
- EXPECT_TRUE(children[0] == parent.Get(META_HANDLE)); |
- EXPECT_TRUE(children[1] == local_folder_handle); |
- } |
- dir->GetChildHandles(&trans, local_folder_id, &children); |
- EXPECT_TRUE(1 == children.size()); |
- dir->GetChildHandles(&trans, parent_id_, &children); |
- EXPECT_TRUE(1 == children.size()); |
- Directory::UnappliedUpdateMetaHandles unapplied; |
- dir->GetUnappliedUpdateMetaHandles(&trans, &unapplied); |
- EXPECT_TRUE(0 == unapplied.size()); |
- syncable::Directory::UnsyncedMetaHandles unsynced; |
- dir->GetUnsyncedMetaHandles(&trans, &unsynced); |
- EXPECT_TRUE(2 == unsynced.size()); |
- } |
- mock_server_->set_conflict_all_commits(false); |
- syncer_->SyncShare(); |
- { |
- ReadTransaction trans(dir, __FILE__, __LINE__); |
- syncable::Directory::UnsyncedMetaHandles unsynced; |
- dir->GetUnsyncedMetaHandles(&trans, &unsynced); |
- EXPECT_TRUE(0 == unsynced.size()); |
- } |
- syncer_events_.clear(); |
-} |
- |
TEST_F(SyncerTest, NewEntryAndAlteredServerEntrySharePath) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
@@ -2754,7 +2131,7 @@ TEST_F(SyncerTest, SiblingDirectoriesBecomeCircular) { |
ASSERT_TRUE(A.good()); |
A.Put(IS_UNSYNCED, true); |
ASSERT_TRUE(A.Put(PARENT_ID, ids_.FromNumber(2))); |
- ASSERT_TRUE(A.Put(NAME, PSTR("B"))); |
+ ASSERT_TRUE(A.Put(NON_UNIQUE_NAME, PSTR("B"))); |
} |
mock_server_->AddUpdateDirectory(2, 1, "A", 20, 20); |
mock_server_->set_conflict_all_commits(true); |
@@ -2766,8 +2143,8 @@ TEST_F(SyncerTest, SiblingDirectoriesBecomeCircular) { |
ASSERT_TRUE(A.good()); |
MutableEntry B(&wtrans, GET_BY_ID, ids_.FromNumber(2)); |
ASSERT_TRUE(B.good()); |
- EXPECT_TRUE(A.Get(NAME) == PSTR("B")); |
- EXPECT_TRUE(B.Get(NAME) == PSTR("B")); |
+ EXPECT_TRUE(A.Get(NON_UNIQUE_NAME) == PSTR("B")); |
+ EXPECT_TRUE(B.Get(NON_UNIQUE_NAME) == PSTR("B")); |
} |
} |
@@ -2786,11 +2163,11 @@ TEST_F(SyncerTest, ConflictSetClassificationError) { |
ASSERT_TRUE(A.good()); |
A.Put(IS_UNSYNCED, true); |
A.Put(IS_UNAPPLIED_UPDATE, true); |
- A.Put(SERVER_NAME, PSTR("B")); |
+ A.Put(SERVER_NON_UNIQUE_NAME, PSTR("B")); |
MutableEntry B(&wtrans, GET_BY_ID, ids_.FromNumber(2)); |
ASSERT_TRUE(B.good()); |
B.Put(IS_UNAPPLIED_UPDATE, true); |
- B.Put(SERVER_NAME, PSTR("A")); |
+ B.Put(SERVER_NON_UNIQUE_NAME, PSTR("A")); |
} |
syncer_->SyncShare(); |
syncer_events_.clear(); |
@@ -2812,9 +2189,9 @@ TEST_F(SyncerTest, SwapEntryNames) { |
MutableEntry B(&wtrans, GET_BY_ID, ids_.FromNumber(2)); |
ASSERT_TRUE(B.good()); |
B.Put(IS_UNSYNCED, true); |
- ASSERT_TRUE(A.Put(NAME, PSTR("C"))); |
- ASSERT_TRUE(B.Put(NAME, PSTR("A"))); |
- ASSERT_TRUE(A.Put(NAME, PSTR("B"))); |
+ ASSERT_TRUE(A.Put(NON_UNIQUE_NAME, PSTR("C"))); |
+ ASSERT_TRUE(B.Put(NON_UNIQUE_NAME, PSTR("A"))); |
+ ASSERT_TRUE(A.Put(NON_UNIQUE_NAME, PSTR("B"))); |
} |
syncer_->SyncShare(); |
syncer_events_.clear(); |
@@ -2881,12 +2258,16 @@ TEST_F(SyncerTest, FixDirectoryLoopConflict) { |
TEST_F(SyncerTest, ResolveWeWroteTheyDeleted) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
+ |
+ int64 bob_metahandle; |
+ |
mock_server_->AddUpdateBookmark(1, 0, "bob", 1, 10); |
syncer_->SyncShare(); |
{ |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); |
ASSERT_TRUE(bob.good()); |
+ bob_metahandle = bob.Get(META_HANDLE); |
WriteTestDataToEntry(&trans, &bob); |
} |
mock_server_->AddUpdateBookmark(1, 0, "bob", 2, 10); |
@@ -2896,7 +2277,7 @@ TEST_F(SyncerTest, ResolveWeWroteTheyDeleted) { |
syncer_->SyncShare(); |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry bob(&trans, GET_BY_PARENTID_AND_NAME, trans.root_id(), PSTR("bob")); |
+ Entry bob(&trans, GET_BY_HANDLE, bob_metahandle); |
ASSERT_TRUE(bob.good()); |
EXPECT_TRUE(bob.Get(IS_UNSYNCED)); |
EXPECT_FALSE(bob.Get(ID).ServerKnows()); |
@@ -2906,71 +2287,60 @@ TEST_F(SyncerTest, ResolveWeWroteTheyDeleted) { |
syncer_events_.clear(); |
} |
-// This test is disabled because we actually enforce the opposite behavior in: |
-// ConflictResolverMergesLocalDeleteAndServerUpdate for bookmarks. |
-TEST_F(SyncerTest, DISABLED_ResolveWeDeletedTheyWrote) { |
- ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- CHECK(dir.good()); |
- mock_server_->AddUpdateBookmark(1, 0, "bob", 1, 10); |
- syncer_->SyncShare(); |
- { |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); |
- ASSERT_TRUE(bob.good()); |
- bob.Put(IS_UNSYNCED, true); |
- bob.Put(IS_DEL, true); |
- } |
- mock_server_->AddUpdateBookmark(1, 0, "bob", 2, 10); |
- mock_server_->set_conflict_all_commits(true); |
- syncer_->SyncShare(); |
- syncer_->SyncShare(); |
- { |
- ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry bob(&trans, GET_BY_PARENTID_AND_NAME, trans.root_id(), PSTR("bob")); |
- ASSERT_TRUE(bob.good()); |
- EXPECT_TRUE(bob.Get(ID) == ids_.FromNumber(1)); |
- EXPECT_FALSE(bob.Get(IS_UNSYNCED)); |
- EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); |
- EXPECT_FALSE(bob.Get(IS_DEL)); |
- } |
- syncer_events_.clear(); |
-} |
- |
TEST_F(SyncerTest, ServerDeletingFolderWeHaveMovedSomethingInto) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
- mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); |
- mock_server_->AddUpdateDirectory(2, 0, "fred", 1, 10); |
+ |
+ syncable::Id bob_id = ids_.NewServerId(); |
+ syncable::Id fred_id = ids_.NewServerId(); |
+ |
+ mock_server_->AddUpdateDirectory(bob_id, TestIdFactory::root(), |
+ "bob", 1, 10); |
+ mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
+ "fred", 1, 10); |
syncer_->SyncShare(); |
{ |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); |
+ MutableEntry bob(&trans, GET_BY_ID, bob_id); |
ASSERT_TRUE(bob.good()); |
bob.Put(IS_UNSYNCED, true); |
- bob.Put(PARENT_ID, ids_.FromNumber(2)); |
+ bob.Put(PARENT_ID, fred_id); |
} |
- mock_server_->AddUpdateDirectory(2, 0, "fred", 2, 20); |
+ mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
+ "fred", 2, 20); |
mock_server_->SetLastUpdateDeleted(); |
mock_server_->set_conflict_all_commits(true); |
syncer_->SyncShare(); |
syncer_->SyncShare(); |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); |
+ |
+ Entry bob(&trans, GET_BY_ID, bob_id); |
ASSERT_TRUE(bob.good()); |
- Entry fred(&trans, GET_BY_PARENTID_AND_NAME, trans.root_id(), PSTR("fred")); |
+ EXPECT_TRUE(bob.Get(IS_UNSYNCED)); |
+ EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); |
+ EXPECT_TRUE(bob.Get(NON_UNIQUE_NAME) == PSTR("bob")); |
+ EXPECT_NE(bob.Get(PARENT_ID), fred_id); |
+ |
+ // Entry was deleted and reborn. |
+ Entry dead_fred(&trans, GET_BY_ID, fred_id); |
+ EXPECT_FALSE(dead_fred.good()); |
+ |
+ // Reborn fred |
+ Entry fred(&trans, GET_BY_ID, bob.Get(PARENT_ID)); |
ASSERT_TRUE(fred.good()); |
+ EXPECT_TRUE(fred.Get(PARENT_ID) == trans.root_id()); |
+ EXPECT_EQ(PSTR("fred"), fred.Get(NON_UNIQUE_NAME)); |
EXPECT_TRUE(fred.Get(IS_UNSYNCED)); |
- EXPECT_TRUE(bob.Get(IS_UNSYNCED)); |
- EXPECT_TRUE(bob.Get(PARENT_ID) == fred.Get(ID)); |
EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE)); |
- EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); |
} |
syncer_events_.clear(); |
} |
// TODO(ncarter): This test is bogus, but it actually seems to hit an |
// interesting case the 4th time SyncShare is called. |
+// TODO(chron): The fourth time that SyncShare is called it crashes. |
+// This seems to be due to a bug in the conflict set building logic. |
TEST_F(SyncerTest, DISABLED_ServerDeletingFolderWeHaveAnOpenEntryIn) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
@@ -3011,7 +2381,9 @@ TEST_F(SyncerTest, DISABLED_ServerDeletingFolderWeHaveAnOpenEntryIn) { |
ReadTransaction trans(dir, __FILE__, __LINE__); |
Entry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); |
ASSERT_TRUE(bob.good()); |
- Entry fred(&trans, GET_BY_PARENTID_AND_NAME, trans.root_id(), PSTR("fred")); |
+ Id fred_id = |
+ GetOnlyEntryWithName(&trans, TestIdFactory::root(), PSTR("fred")); |
+ Entry fred(&trans, GET_BY_ID, fred_id); |
ASSERT_TRUE(fred.good()); |
EXPECT_FALSE(fred.Get(IS_UNSYNCED)); |
EXPECT_TRUE(fred.Get(IS_UNAPPLIED_UPDATE)); |
@@ -3021,32 +2393,52 @@ TEST_F(SyncerTest, DISABLED_ServerDeletingFolderWeHaveAnOpenEntryIn) { |
syncer_events_.clear(); |
} |
+ |
TEST_F(SyncerTest, WeMovedSomethingIntoAFolderServerHasDeleted) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
- mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); |
- mock_server_->AddUpdateDirectory(2, 0, "fred", 1, 10); |
+ |
+ syncable::Id bob_id = ids_.NewServerId(); |
+ syncable::Id fred_id = ids_.NewServerId(); |
+ |
+ mock_server_->AddUpdateDirectory(bob_id, TestIdFactory::root(), |
+ "bob", 1, 10); |
+ mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
+ "fred", 1, 10); |
syncer_->SyncShare(); |
{ |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); |
+ Entry fred(&trans, GET_BY_ID, fred_id); |
+ ASSERT_TRUE(fred.good()); |
+ |
+ MutableEntry bob(&trans, GET_BY_ID, bob_id); |
ASSERT_TRUE(bob.good()); |
bob.Put(IS_UNSYNCED, true); |
- bob.Put(PARENT_ID, ids_.FromNumber(2)); |
+ bob.Put(PARENT_ID, fred_id); |
} |
- mock_server_->AddUpdateDirectory(2, 0, "fred", 2, 20); |
+ mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
+ "fred", 2, 20); |
mock_server_->SetLastUpdateDeleted(); |
mock_server_->set_conflict_all_commits(true); |
syncer_->SyncShare(); |
syncer_->SyncShare(); |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); |
+ Entry bob(&trans, GET_BY_ID, bob_id); |
ASSERT_TRUE(bob.good()); |
- Entry fred(&trans, GET_BY_PATH, PSTR("fred")); |
- ASSERT_TRUE(fred.good()); |
+ |
+ // Entry was deleted by server. We'll make a new one though with a new ID. |
+ Entry dead_fred(&trans, GET_BY_ID, fred_id); |
+ EXPECT_FALSE(dead_fred.good()); |
+ |
+ // Fred is reborn with a local ID. |
+ Entry fred(&trans, GET_BY_ID, bob.Get(PARENT_ID)); |
+ EXPECT_EQ(PSTR("fred"), fred.Get(NON_UNIQUE_NAME)); |
+ EXPECT_EQ(TestIdFactory::root(), fred.Get(PARENT_ID)); |
EXPECT_TRUE(fred.Get(IS_UNSYNCED)); |
EXPECT_FALSE(fred.Get(ID).ServerKnows()); |
+ |
+ // Bob needs to update his parent. |
EXPECT_TRUE(bob.Get(IS_UNSYNCED)); |
EXPECT_TRUE(bob.Get(PARENT_ID) == fred.Get(ID)); |
EXPECT_TRUE(fred.Get(PARENT_ID) == root_id_); |
@@ -3056,60 +2448,97 @@ TEST_F(SyncerTest, WeMovedSomethingIntoAFolderServerHasDeleted) { |
syncer_events_.clear(); |
} |
-namespace { |
+class FolderMoveDeleteRenameTest : public SyncerTest { |
+ public: |
+ FolderMoveDeleteRenameTest() : move_bob_count_(0), done_(false) {} |
-int move_bob_count; |
+ static const int64 bob_id_number = 1; |
+ static const int64 fred_id_number = 2; |
-bool MoveBobIntoID2(Directory* dir) { |
- if (--move_bob_count > 0) |
- return false; |
- if (move_bob_count == 0) { |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- Entry alice(&trans, GET_BY_ID, TestIdFactory::FromNumber(2)); |
- CHECK(alice.good()); |
- CHECK(!alice.Get(IS_DEL)); |
- MutableEntry bob(&trans, GET_BY_ID, TestIdFactory::FromNumber(1)); |
- CHECK(bob.good()); |
- bob.Put(IS_UNSYNCED, true); |
- bob.Put(PARENT_ID, alice.Get(ID)); |
- return true; |
+ void MoveBobIntoID2Runner() { |
+ if (!done_) { |
+ done_ = MoveBobIntoID2(); |
+ } |
} |
- return false; |
-} |
-} // namespace |
+ protected: |
+ int move_bob_count_; |
+ bool done_; |
-TEST_F(SyncerTest, |
+ bool MoveBobIntoID2() { |
+ ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
+ CHECK(dir.good()); |
+ |
+ if (--move_bob_count_ > 0) { |
+ return false; |
+ } |
+ |
+ if (move_bob_count_ == 0) { |
+ WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
+ Entry alice(&trans, GET_BY_ID, |
+ TestIdFactory::FromNumber(fred_id_number)); |
+ CHECK(alice.good()); |
+ CHECK(!alice.Get(IS_DEL)); |
+ MutableEntry bob(&trans, GET_BY_ID, |
+ TestIdFactory::FromNumber(bob_id_number)); |
+ CHECK(bob.good()); |
+ bob.Put(IS_UNSYNCED, true); |
+ bob.Put(PARENT_ID, alice.Get(ID)); |
+ return true; |
+ } |
+ return false; |
+ } |
+}; |
+ |
+TEST_F(FolderMoveDeleteRenameTest, |
WeMovedSomethingIntoAFolderServerHasDeletedAndWeRenamed) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
- mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); |
- mock_server_->AddUpdateDirectory(2, 0, "fred", 1, 10); |
+ |
+ const syncable::Id bob_id = TestIdFactory::FromNumber( |
+ FolderMoveDeleteRenameTest::bob_id_number); |
+ const syncable::Id fred_id = TestIdFactory::FromNumber( |
+ FolderMoveDeleteRenameTest::fred_id_number); |
+ |
+ mock_server_->AddUpdateDirectory(bob_id, TestIdFactory::root(), |
+ "bob", 1, 10); |
+ mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
+ "fred", 1, 10); |
syncer_->SyncShare(); |
{ |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry fred(&trans, GET_BY_ID, ids_.FromNumber(2)); |
+ MutableEntry fred(&trans, GET_BY_ID, fred_id); |
ASSERT_TRUE(fred.good()); |
fred.Put(IS_UNSYNCED, true); |
- fred.Put(NAME, PSTR("Alice")); |
+ fred.Put(NON_UNIQUE_NAME, PSTR("Alice")); |
} |
- mock_server_->AddUpdateDirectory(2, 0, "fred", 2, 20); |
+ mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
+ "fred", 2, 20); |
mock_server_->SetLastUpdateDeleted(); |
mock_server_->set_conflict_all_commits(true); |
// This test is a little brittle. We want to move the item into the folder |
// such that we think we're dealing with a simple conflict, but in reality |
// it's actually a conflict set. |
- move_bob_count = 2; |
- mock_server_->SetMidCommitCallbackFunction(MoveBobIntoID2); |
+ move_bob_count_ = 2; |
+ mock_server_->SetMidCommitCallback( |
+ NewCallback<FolderMoveDeleteRenameTest>(this, |
+ &FolderMoveDeleteRenameTest::MoveBobIntoID2Runner)); |
syncer_->SyncShare(); |
syncer_->SyncShare(); |
syncer_->SyncShare(); |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); |
+ Entry bob(&trans, GET_BY_ID, bob_id); |
ASSERT_TRUE(bob.good()); |
- Entry alice(&trans, GET_BY_PATH, PSTR("Alice")); |
+ |
+ // Old entry is dead |
+ Entry dead_fred(&trans, GET_BY_ID, fred_id); |
+ EXPECT_FALSE(dead_fred.good()); |
+ |
+ // New ID is created to fill parent folder, named correctly |
+ Entry alice(&trans, GET_BY_ID, bob.Get(PARENT_ID)); |
ASSERT_TRUE(alice.good()); |
+ EXPECT_EQ(PSTR("Alice"), alice.Get(NON_UNIQUE_NAME)); |
EXPECT_TRUE(alice.Get(IS_UNSYNCED)); |
EXPECT_FALSE(alice.Get(ID).ServerKnows()); |
EXPECT_TRUE(bob.Get(IS_UNSYNCED)); |
@@ -3126,42 +2555,56 @@ TEST_F(SyncerTest, |
WeMovedADirIntoAndCreatedAnEntryInAFolderServerHasDeleted) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
- mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); |
- mock_server_->AddUpdateDirectory(2, 0, "fred", 1, 10); |
+ |
+ syncable::Id bob_id = ids_.NewServerId(); |
+ syncable::Id fred_id = ids_.NewServerId(); |
+ |
+ mock_server_->AddUpdateDirectory(bob_id, TestIdFactory::root(), |
+ "bob", 1, 10); |
+ mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
+ "fred", 1, 10); |
syncer_->SyncShare(); |
syncable::Id new_item_id; |
{ |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); |
+ MutableEntry bob(&trans, GET_BY_ID, bob_id); |
ASSERT_TRUE(bob.good()); |
bob.Put(IS_UNSYNCED, true); |
- bob.Put(PARENT_ID, ids_.FromNumber(2)); |
- MutableEntry new_item(&trans, CREATE, ids_.FromNumber(2), PSTR("new_item")); |
+ bob.Put(PARENT_ID, fred_id); |
+ MutableEntry new_item(&trans, CREATE, fred_id, PSTR("new_item")); |
WriteTestDataToEntry(&trans, &new_item); |
new_item_id = new_item.Get(ID); |
} |
- mock_server_->AddUpdateDirectory(2, 0, "fred", 2, 20); |
+ mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
+ "fred", 2, 20); |
mock_server_->SetLastUpdateDeleted(); |
mock_server_->set_conflict_all_commits(true); |
syncer_->SyncShare(); |
syncer_->SyncShare(); |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); |
+ |
+ Entry bob(&trans, GET_BY_ID, bob_id); |
ASSERT_TRUE(bob.good()); |
- Entry fred(&trans, GET_BY_PATH, PSTR("fred")); |
+ EXPECT_TRUE(bob.Get(IS_UNSYNCED)); |
+ EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); |
+ EXPECT_NE(bob.Get(PARENT_ID), fred_id); |
+ |
+ // Was recreated. Old one shouldn't exist. |
+ Entry dead_fred(&trans, GET_BY_ID, fred_id); |
+ EXPECT_FALSE(dead_fred.good()); |
+ |
+ Entry fred(&trans, GET_BY_ID, bob.Get(PARENT_ID)); |
ASSERT_TRUE(fred.good()); |
- PathChar path[] = {'f', 'r', 'e', 'd', *kPathSeparator, |
- 'n', 'e', 'w', '_', 'i', 't', 'e', 'm', 0}; |
- Entry new_item(&trans, GET_BY_PATH, path); |
- EXPECT_TRUE(new_item.good()); |
EXPECT_TRUE(fred.Get(IS_UNSYNCED)); |
EXPECT_FALSE(fred.Get(ID).ServerKnows()); |
- EXPECT_TRUE(bob.Get(IS_UNSYNCED)); |
- EXPECT_TRUE(bob.Get(PARENT_ID) == fred.Get(ID)); |
- EXPECT_TRUE(fred.Get(PARENT_ID) == root_id_); |
+ EXPECT_EQ(PSTR("fred"), fred.Get(NON_UNIQUE_NAME)); |
EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE)); |
- EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); |
+ EXPECT_TRUE(fred.Get(PARENT_ID) == root_id_); |
+ |
+ Entry new_item(&trans, GET_BY_ID, new_item_id); |
+ ASSERT_TRUE(new_item.good()); |
+ EXPECT_EQ(new_item.Get(PARENT_ID), fred.Get(ID)); |
} |
syncer_events_.clear(); |
} |
@@ -3359,60 +2802,80 @@ TEST_F(SyncerTest, NewServerItemInAFolderHierarchyWeHaveDeleted2) { |
syncer_events_.clear(); |
} |
-namespace { |
-int countown_till_delete = 0; |
- |
-void DeleteSusanInRoot(Directory* dir) { |
- ASSERT_GT(countown_till_delete, 0); |
- if (0 != --countown_till_delete) |
- return; |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry susan(&trans, GET_BY_PATH, PSTR("susan")); |
- Directory::ChildHandles children; |
- dir->GetChildHandles(&trans, susan.Get(ID), &children); |
- ASSERT_TRUE(0 == children.size()); |
- susan.Put(IS_DEL, true); |
- susan.Put(IS_UNSYNCED, true); |
-} |
+class SusanDeletingTest : public SyncerTest { |
+ public: |
+ SusanDeletingTest() : countdown_till_delete_(0) {} |
-} // namespace |
+ static const int64 susan_int_id_ = 4; |
-TEST_F(SyncerTest, NewServerItemInAFolderHierarchyWeHaveDeleted3) { |
+ void DeleteSusanInRoot() { |
+ ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
+ ASSERT_TRUE(dir.good()); |
+ |
+ const syncable::Id susan_id = TestIdFactory::FromNumber(susan_int_id_); |
+ ASSERT_GT(countdown_till_delete_, 0); |
+ if (0 != --countdown_till_delete_) |
+ return; |
+ WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
+ MutableEntry susan(&trans, GET_BY_ID, susan_id); |
+ Directory::ChildHandles children; |
+ dir->GetChildHandles(&trans, susan.Get(ID), &children); |
+ ASSERT_TRUE(0 == children.size()); |
+ susan.Put(IS_DEL, true); |
+ susan.Put(IS_UNSYNCED, true); |
+ } |
+ |
+ protected: |
+ int countdown_till_delete_; |
+}; |
+ |
+TEST_F(SusanDeletingTest, |
+ NewServerItemInAFolderHierarchyWeHaveDeleted3) { |
// Same as 2, except we deleted the folder the set is in between set building |
// and conflict resolution. |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
- mock_server_->AddUpdateDirectory(4, 0, "susan", 1, 10); |
- mock_server_->AddUpdateDirectory(1, 4, "bob", 1, 10); |
- mock_server_->AddUpdateDirectory(2, 1, "joe", 1, 10); |
+ |
+ const syncable::Id bob_id = TestIdFactory::FromNumber(1); |
+ const syncable::Id joe_id = TestIdFactory::FromNumber(2); |
+ const syncable::Id fred_id = TestIdFactory::FromNumber(3); |
+ const syncable::Id susan_id = TestIdFactory::FromNumber(susan_int_id_); |
+ |
+ mock_server_->AddUpdateDirectory(susan_id, TestIdFactory::root(), |
+ "susan", 1, 10); |
+ mock_server_->AddUpdateDirectory(bob_id, susan_id, "bob", 1, 10); |
+ mock_server_->AddUpdateDirectory(joe_id, bob_id, "joe", 1, 10); |
LoopSyncShare(syncer_); |
{ |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); |
+ MutableEntry bob(&trans, GET_BY_ID, bob_id); |
ASSERT_TRUE(bob.good()); |
bob.Put(IS_UNSYNCED, true); |
bob.Put(IS_DEL, true); |
- MutableEntry joe(&trans, GET_BY_ID, ids_.FromNumber(2)); |
+ |
+ MutableEntry joe(&trans, GET_BY_ID, joe_id); |
ASSERT_TRUE(joe.good()); |
joe.Put(IS_UNSYNCED, true); |
joe.Put(IS_DEL, true); |
} |
- mock_server_->AddUpdateDirectory(3, 2, "fred", 2, 20); |
+ mock_server_->AddUpdateDirectory(fred_id, joe_id, "fred", 2, 20); |
mock_server_->set_conflict_all_commits(true); |
- countown_till_delete = 2; |
- syncer_->pre_conflict_resolution_function_ = DeleteSusanInRoot; |
+ countdown_till_delete_ = 2; |
+ syncer_->pre_conflict_resolution_closure_ = |
+ NewCallback<SusanDeletingTest>(this, |
+ &SusanDeletingTest::DeleteSusanInRoot); |
syncer_->SyncShare(); |
syncer_->SyncShare(); |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); |
+ Entry bob(&trans, GET_BY_ID, bob_id); |
ASSERT_TRUE(bob.good()); |
- Entry joe(&trans, GET_BY_ID, ids_.FromNumber(2)); |
+ Entry joe(&trans, GET_BY_ID, joe_id); |
ASSERT_TRUE(joe.good()); |
- Entry fred(&trans, GET_BY_ID, ids_.FromNumber(3)); |
+ Entry fred(&trans, GET_BY_ID, fred_id); |
ASSERT_TRUE(fred.good()); |
- Entry susan(&trans, GET_BY_ID, ids_.FromNumber(4)); |
+ Entry susan(&trans, GET_BY_ID, susan_id); |
ASSERT_TRUE(susan.good()); |
EXPECT_FALSE(susan.Get(IS_UNAPPLIED_UPDATE)); |
EXPECT_TRUE(fred.Get(IS_UNAPPLIED_UPDATE)); |
@@ -3423,19 +2886,19 @@ TEST_F(SyncerTest, NewServerItemInAFolderHierarchyWeHaveDeleted3) { |
EXPECT_TRUE(bob.Get(IS_UNSYNCED)); |
EXPECT_TRUE(joe.Get(IS_UNSYNCED)); |
} |
- EXPECT_TRUE(0 == countown_till_delete); |
- syncer_->pre_conflict_resolution_function_ = 0; |
+ EXPECT_TRUE(0 == countdown_till_delete_); |
+ syncer_->pre_conflict_resolution_closure_ = NULL; |
LoopSyncShare(syncer_); |
LoopSyncShare(syncer_); |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); |
+ Entry bob(&trans, GET_BY_ID, bob_id); |
ASSERT_TRUE(bob.good()); |
- Entry joe(&trans, GET_BY_ID, ids_.FromNumber(2)); |
+ Entry joe(&trans, GET_BY_ID, joe_id); |
ASSERT_TRUE(joe.good()); |
- Entry fred(&trans, GET_BY_ID, ids_.FromNumber(3)); |
+ Entry fred(&trans, GET_BY_ID, fred_id); |
ASSERT_TRUE(fred.good()); |
- Entry susan(&trans, GET_BY_ID, ids_.FromNumber(4)); |
+ Entry susan(&trans, GET_BY_ID, susan_id); |
ASSERT_TRUE(susan.good()); |
EXPECT_TRUE(susan.Get(IS_UNSYNCED)); |
EXPECT_FALSE(fred.Get(IS_UNSYNCED)); |
@@ -3456,103 +2919,146 @@ TEST_F(SyncerTest, NewServerItemInAFolderHierarchyWeHaveDeleted3) { |
TEST_F(SyncerTest, WeMovedSomethingIntoAFolderHierarchyServerHasDeleted) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
- mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); |
- mock_server_->AddUpdateDirectory(2, 0, "fred", 1, 10); |
- mock_server_->AddUpdateDirectory(3, 2, "alice", 1, 10); |
+ |
+ const syncable::Id bob_id = ids_.NewServerId(); |
+ const syncable::Id fred_id = ids_.NewServerId(); |
+ const syncable::Id alice_id = ids_.NewServerId(); |
+ |
+ mock_server_->AddUpdateDirectory(bob_id, TestIdFactory::root(), |
+ "bob", 1, 10); |
+ mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
+ "fred", 1, 10); |
+ mock_server_->AddUpdateDirectory(alice_id, fred_id, "alice", 1, 10); |
syncer_->SyncShare(); |
{ |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); |
+ MutableEntry bob(&trans, GET_BY_ID, bob_id); |
ASSERT_TRUE(bob.good()); |
bob.Put(IS_UNSYNCED, true); |
- bob.Put(PARENT_ID, ids_.FromNumber(3)); // Move into alice. |
+ bob.Put(PARENT_ID, alice_id); // Move into alice. |
} |
- mock_server_->AddUpdateDirectory(2, 0, "fred", 2, 20); |
+ mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
+ "fred", 2, 20); |
mock_server_->SetLastUpdateDeleted(); |
- mock_server_->AddUpdateDirectory(3, 0, "alice", 2, 20); |
+ mock_server_->AddUpdateDirectory(alice_id, TestIdFactory::root(), |
+ "alice", 2, 20); |
mock_server_->SetLastUpdateDeleted(); |
mock_server_->set_conflict_all_commits(true); |
syncer_->SyncShare(); |
syncer_->SyncShare(); |
{ |
+ // Bob is the entry at the bottom of the tree. |
+ // The tree should be regenerated and old IDs removed. |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); |
+ Entry bob(&trans, GET_BY_ID, bob_id); |
ASSERT_TRUE(bob.good()); |
- Entry fred(&trans, GET_BY_PATH, PSTR("fred")); |
- ASSERT_TRUE(fred.good()); |
- PathChar path[] = {'f', 'r', 'e', 'd', *kPathSeparator, |
- 'a', 'l', 'i', 'c', 'e', 0}; |
- Entry alice(&trans, GET_BY_PATH, path); |
+ EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); |
+ EXPECT_TRUE(bob.Get(IS_UNSYNCED)); |
+ |
+ // Old one should be deleted, but new one should have been made. |
+ Entry dead_alice(&trans, GET_BY_ID, alice_id); |
+ EXPECT_FALSE(dead_alice.good()); |
+ EXPECT_NE(bob.Get(PARENT_ID), alice_id); |
+ |
+ // Newly born alice |
+ Entry alice(&trans, GET_BY_ID, bob.Get(PARENT_ID)); |
ASSERT_TRUE(alice.good()); |
- EXPECT_TRUE(fred.Get(IS_UNSYNCED)); |
+ EXPECT_FALSE(alice.Get(IS_UNAPPLIED_UPDATE)); |
EXPECT_TRUE(alice.Get(IS_UNSYNCED)); |
- EXPECT_TRUE(bob.Get(IS_UNSYNCED)); |
- EXPECT_FALSE(fred.Get(ID).ServerKnows()); |
EXPECT_FALSE(alice.Get(ID).ServerKnows()); |
- EXPECT_TRUE(alice.Get(PARENT_ID) == fred.Get(ID)); |
- EXPECT_TRUE(bob.Get(PARENT_ID) == alice.Get(ID)); |
- EXPECT_TRUE(fred.Get(PARENT_ID) == root_id_); |
+ EXPECT_TRUE(alice.Get(NON_UNIQUE_NAME) == PSTR("alice")); |
+ |
+ // Alice needs a parent as well. Old parent should have been erased. |
+ Entry dead_fred(&trans, GET_BY_ID, fred_id); |
+ EXPECT_FALSE(dead_fred.good()); |
+ EXPECT_NE(alice.Get(PARENT_ID), fred_id); |
+ |
+ Entry fred(&trans, GET_BY_ID, alice.Get(PARENT_ID)); |
+ ASSERT_TRUE(fred.good()); |
+ EXPECT_EQ(fred.Get(PARENT_ID), TestIdFactory::root()); |
+ EXPECT_TRUE(fred.Get(IS_UNSYNCED)); |
+ EXPECT_FALSE(fred.Get(ID).ServerKnows()); |
EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE)); |
- EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); |
- EXPECT_FALSE(alice.Get(IS_UNAPPLIED_UPDATE)); |
+ EXPECT_TRUE(fred.Get(NON_UNIQUE_NAME) == PSTR("fred")); |
} |
syncer_events_.clear(); |
} |
TEST_F(SyncerTest, WeMovedSomethingIntoAFolderHierarchyServerHasDeleted2) { |
- // The difference here is that the hierarchy's not in the root. We have |
+ // The difference here is that the hierarchy is not in the root. We have |
// another entry that shouldn't be touched. |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
- mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); |
- mock_server_->AddUpdateDirectory(4, 0, "susan", 1, 10); |
- mock_server_->AddUpdateDirectory(2, 4, "fred", 1, 10); |
- mock_server_->AddUpdateDirectory(3, 2, "alice", 1, 10); |
+ |
+ const syncable::Id bob_id = ids_.NewServerId(); |
+ const syncable::Id fred_id = ids_.NewServerId(); |
+ const syncable::Id alice_id = ids_.NewServerId(); |
+ const syncable::Id susan_id = ids_.NewServerId(); |
+ |
+ mock_server_->AddUpdateDirectory(bob_id, TestIdFactory::root(), |
+ "bob", 1, 10); |
+ mock_server_->AddUpdateDirectory(susan_id, TestIdFactory::root(), |
+ "susan", 1, 10); |
+ mock_server_->AddUpdateDirectory(fred_id, susan_id, "fred", 1, 10); |
+ mock_server_->AddUpdateDirectory(alice_id, fred_id, "alice", 1, 10); |
syncer_->SyncShare(); |
{ |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); |
+ MutableEntry bob(&trans, GET_BY_ID, bob_id); |
ASSERT_TRUE(bob.good()); |
bob.Put(IS_UNSYNCED, true); |
- bob.Put(PARENT_ID, ids_.FromNumber(3)); // Move into alice. |
+ bob.Put(PARENT_ID, alice_id); // Move into alice. |
} |
- mock_server_->AddUpdateDirectory(2, 0, "fred", 2, 20); |
+ mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
+ "fred", 2, 20); |
mock_server_->SetLastUpdateDeleted(); |
- mock_server_->AddUpdateDirectory(3, 0, "alice", 2, 20); |
+ mock_server_->AddUpdateDirectory(alice_id, TestIdFactory::root(), |
+ "alice", 2, 20); |
mock_server_->SetLastUpdateDeleted(); |
mock_server_->set_conflict_all_commits(true); |
syncer_->SyncShare(); |
syncer_->SyncShare(); |
{ |
+ // Root |
+ // |- Susan |
+ // |- Fred |
+ // |- Alice |
+ // |- Bob |
+ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); |
+ Entry bob(&trans, GET_BY_ID, bob_id); |
ASSERT_TRUE(bob.good()); |
- PathChar path[] = {'s', 'u', 's', 'a', 'n', *kPathSeparator, |
- 'f', 'r', 'e', 'd', 0}; |
- Entry fred(&trans, GET_BY_PATH, path); |
- ASSERT_TRUE(fred.good()); |
- PathChar path2[] = {'s', 'u', 's', 'a', 'n', *kPathSeparator, |
- 'f', 'r', 'e', 'd', *kPathSeparator, |
- 'a', 'l', 'i', 'c', 'e', 0}; |
- Entry alice(&trans, GET_BY_PATH, path2); |
- ASSERT_TRUE(alice.good()); |
- Entry susan(&trans, GET_BY_ID, ids_.FromNumber(4)); |
- ASSERT_TRUE(susan.good()); |
- Entry susan_by_path(&trans, GET_BY_PATH, PSTR("susan")); |
- ASSERT_TRUE(susan.good()); |
- EXPECT_FALSE(susan.Get(IS_UNSYNCED)); |
- EXPECT_TRUE(fred.Get(IS_UNSYNCED)); |
+ EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); |
+ EXPECT_TRUE(bob.Get(IS_UNSYNCED)); // Parent changed |
+ EXPECT_NE(bob.Get(PARENT_ID), alice_id); |
+ |
+ // New one was born, this is the old one |
+ Entry dead_alice(&trans, GET_BY_ID, alice_id); |
+ EXPECT_FALSE(dead_alice.good()); |
+ |
+ // Newly born |
+ Entry alice(&trans, GET_BY_ID, bob.Get(PARENT_ID)); |
EXPECT_TRUE(alice.Get(IS_UNSYNCED)); |
- EXPECT_TRUE(bob.Get(IS_UNSYNCED)); |
- EXPECT_FALSE(fred.Get(ID).ServerKnows()); |
+ EXPECT_FALSE(alice.Get(IS_UNAPPLIED_UPDATE)); |
EXPECT_FALSE(alice.Get(ID).ServerKnows()); |
- EXPECT_TRUE(alice.Get(PARENT_ID) == fred.Get(ID)); |
- EXPECT_TRUE(bob.Get(PARENT_ID) == alice.Get(ID)); |
- EXPECT_TRUE(fred.Get(PARENT_ID) == susan.Get(ID)); |
- EXPECT_TRUE(susan.Get(PARENT_ID) == root_id_); |
+ EXPECT_NE(alice.Get(PARENT_ID), fred_id); // This fred was deleted |
+ |
+ // New one was born, this is the old one |
+ Entry dead_fred(&trans, GET_BY_ID, fred_id); |
+ EXPECT_FALSE(dead_fred.good()); |
+ |
+ // Newly born |
+ Entry fred(&trans, GET_BY_ID, alice.Get(PARENT_ID)); |
+ EXPECT_TRUE(fred.Get(IS_UNSYNCED)); |
EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE)); |
- EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); |
- EXPECT_FALSE(alice.Get(IS_UNAPPLIED_UPDATE)); |
+ EXPECT_FALSE(fred.Get(ID).ServerKnows()); |
+ EXPECT_TRUE(fred.Get(PARENT_ID) == susan_id); |
+ |
+ // Unchanged |
+ Entry susan(&trans, GET_BY_ID, susan_id); |
+ ASSERT_TRUE(susan.good()); |
+ EXPECT_FALSE(susan.Get(IS_UNSYNCED)); |
+ EXPECT_TRUE(susan.Get(PARENT_ID) == root_id_); |
EXPECT_FALSE(susan.Get(IS_UNAPPLIED_UPDATE)); |
} |
syncer_events_.clear(); |
@@ -3585,34 +3091,6 @@ TEST_F(SyncerTest, DuplicateIDReturn) { |
syncer_events_.clear(); |
} |
-// This test is not very useful anymore. It used to trigger a more interesting |
-// condition. |
-TEST_F(SyncerTest, SimpleConflictOnAnEntry) { |
- ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- CHECK(dir.good()); |
- { |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry bob(&trans, CREATE, trans.root_id(), PSTR("bob")); |
- ASSERT_TRUE(bob.good()); |
- bob.Put(IS_UNSYNCED, true); |
- WriteTestDataToEntry(&trans, &bob); |
- } |
- syncer_->SyncShare(); |
- syncable::Id bobid; |
- { |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry bob(&trans, GET_BY_PATH, PSTR("bob")); |
- ASSERT_TRUE(bob.good()); |
- EXPECT_FALSE(bob.Get(IS_UNSYNCED)); |
- bob.Put(IS_UNSYNCED, true); |
- bobid = bob.Get(ID); |
- } |
- mock_server_->AddUpdateBookmark(1, 0, "jim", 2, 20); |
- mock_server_->set_conflict_all_commits(true); |
- SyncRepeatedlyToTriggerConflictResolution(state_.get()); |
- syncer_events_.clear(); |
-} |
- |
TEST_F(SyncerTest, DeletedEntryWithBadParentInLoopCalculation) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
ASSERT_TRUE(dir.good()); |
@@ -3654,7 +3132,7 @@ TEST_F(SyncerTest, ConflictResolverMergeOverwritesLocalEntry) { |
MutableEntry update(&trans, CREATE_NEW_UPDATE_ITEM, ids_.FromNumber(3)); |
update.Put(BASE_VERSION, 1); |
- update.Put(SERVER_NAME, PSTR("name")); |
+ update.Put(SERVER_NON_UNIQUE_NAME, PSTR("name")); |
update.Put(PARENT_ID, ids_.FromNumber(0)); |
update.Put(IS_UNAPPLIED_UPDATE, true); |
@@ -3792,13 +3270,17 @@ TEST_F(SyncerTest, MergingExistingItems) { |
// In this test a long changelog contains a child at the start of the changelog |
// and a parent at the end. While these updates are in progress the client would |
// appear stuck. |
-TEST_F(SyncerTest, LongChangelistCreatesFakeOrphanedEntries) { |
+TEST_F(SyncerTest, LongChangelistWithApplicationConflict) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
const int DEPTH = 400; |
+ syncable::Id folder_id = ids_.FromNumber(1); |
+ |
// First we an item in a folder in the root. However the folder won't come |
// till much later. |
- mock_server_->AddUpdateDirectory(99999, 1, "stuck", 1, 1); |
+ syncable::Id stuck_entry_id = TestIdFactory::FromNumber(99999); |
+ mock_server_->AddUpdateDirectory(stuck_entry_id, |
+ folder_id, "stuck", 1, 1); |
mock_server_->SetChangesRemaining(DEPTH - 1); |
syncer_->SyncShare(state_.get()); |
@@ -3808,18 +3290,30 @@ TEST_F(SyncerTest, LongChangelistCreatesFakeOrphanedEntries) { |
mock_server_->SetChangesRemaining(DEPTH - i); |
syncer_->SyncShare(state_.get()); |
EXPECT_FALSE(SyncerStuck(state_.get())); |
+ |
+ // Ensure our folder hasn't somehow applied. |
+ ReadTransaction trans(dir, __FILE__, __LINE__); |
+ Entry child(&trans, GET_BY_ID, stuck_entry_id); |
+ EXPECT_TRUE(child.good()); |
+ EXPECT_TRUE(child.Get(IS_UNAPPLIED_UPDATE)); |
+ EXPECT_TRUE(child.Get(IS_DEL)); |
+ EXPECT_FALSE(child.Get(IS_UNSYNCED)); |
} |
+ |
// And finally the folder. |
- mock_server_->AddUpdateDirectory(1, 0, "folder", 1, 1); |
+ mock_server_->AddUpdateDirectory(folder_id, |
+ TestIdFactory::root(), "folder", 1, 1); |
mock_server_->SetChangesRemaining(0); |
LoopSyncShare(syncer_); |
LoopSyncShare(syncer_); |
- // Check that everything's as expected after the commit. |
+ // Check that everything is as expected after the commit. |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry entry(&trans, GET_BY_PATH, PSTR("folder")); |
+ Entry entry(&trans, GET_BY_ID, folder_id); |
ASSERT_TRUE(entry.good()); |
- Entry child(&trans, GET_BY_PARENTID_AND_NAME, entry.Get(ID), PSTR("stuck")); |
+ Entry child(&trans, GET_BY_ID, stuck_entry_id); |
+ EXPECT_EQ(entry.Get(ID), child.Get(PARENT_ID)); |
+ EXPECT_EQ(PSTR("stuck"), child.Get(NON_UNIQUE_NAME)); |
EXPECT_TRUE(child.good()); |
} |
} |
@@ -3835,7 +3329,7 @@ TEST_F(SyncerTest, DontMergeTwoExistingItems) { |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
MutableEntry entry(&trans, GET_BY_ID, ids_.FromNumber(2)); |
ASSERT_TRUE(entry.good()); |
- EXPECT_TRUE(entry.Put(NAME, PSTR("Copy of base"))); |
+ EXPECT_TRUE(entry.Put(NON_UNIQUE_NAME, PSTR("Copy of base"))); |
entry.Put(IS_UNSYNCED, true); |
} |
mock_server_->AddUpdateBookmark(1, 0, "Copy of base", 50, 50); |
@@ -3850,7 +3344,7 @@ TEST_F(SyncerTest, DontMergeTwoExistingItems) { |
EXPECT_FALSE(entry2.Get(IS_UNAPPLIED_UPDATE)); |
EXPECT_TRUE(entry2.Get(IS_UNSYNCED)); |
EXPECT_FALSE(entry2.Get(IS_DEL)); |
- EXPECT_NE(entry1.Get(NAME), entry2.Get(NAME)); |
+ EXPECT_EQ(entry1.Get(NON_UNIQUE_NAME), entry2.Get(NON_UNIQUE_NAME)); |
} |
} |
@@ -3906,31 +3400,6 @@ TEST_F(SyncerTest, TestMoveSanitizedNamedFolder) { |
syncer_->SyncShare(); |
} |
-TEST_F(SyncerTest, QuicklyMergeDualCreatedHierarchy) { |
- ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- EXPECT_TRUE(dir.good()); |
- mock_server_->set_conflict_all_commits(true); |
- int depth = 10; |
- { |
- WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- syncable::Id parent = root_id_; |
- for (int i = 0 ; i < depth ; ++i) { |
- MutableEntry entry(&trans, CREATE, parent, PSTR("folder")); |
- entry.Put(IS_DIR, true); |
- entry.Put(IS_UNSYNCED, true); |
- parent = entry.Get(ID); |
- } |
- } |
- for (int i = 0 ; i < depth ; ++i) { |
- mock_server_->AddUpdateDirectory(i + 1, i, "folder", 1, 1); |
- } |
- syncer_->SyncShare(state_.get()); |
- syncer_->SyncShare(state_.get()); |
- SyncerStatus status(NULL, state_.get()); |
- EXPECT_LT(status.consecutive_problem_commits(), 5); |
- EXPECT_TRUE(0 == dir->unsynced_entity_count()); |
-} |
- |
TEST(SortedCollectionsIntersect, SortedCollectionsIntersectTest) { |
int negative[] = {-3, -2, -1}; |
int straddle[] = {-1, 0, 1}; |
@@ -3973,77 +3442,86 @@ const char kRootId[] = "0"; |
TEST_F(SyncerTest, DirectoryUpdateTest) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
- mock_server_->AddUpdateDirectory("in_root_id", kRootId, |
+ |
+ Id in_root_id = ids_.NewServerId(); |
+ Id in_in_root_id = ids_.NewServerId(); |
+ |
+ mock_server_->AddUpdateDirectory(in_root_id, TestIdFactory::root(), |
"in_root_name", 2, 2); |
- mock_server_->AddUpdateDirectory("in_in_root_id", "in_root_id", |
+ mock_server_->AddUpdateDirectory(in_in_root_id, in_root_id, |
"in_in_root_name", 3, 3); |
syncer_->SyncShare(); |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- // Entry will have been dropped. |
- Entry by_path(&trans, GET_BY_PATH, PSTR("in_root_name")); |
- EXPECT_TRUE(by_path.good()); |
- Entry by_path2(&trans, GET_BY_PATH, PSTR("in_root_name") + |
- PathString(kPathSeparator) + |
- PSTR("in_in_root_name")); |
- EXPECT_TRUE(by_path2.good()); |
+ Entry in_root(&trans, GET_BY_ID, in_root_id); |
+ ASSERT_TRUE(in_root.good()); |
+ EXPECT_EQ(PSTR("in_root_name"), in_root.Get(NON_UNIQUE_NAME)); |
+ EXPECT_EQ(TestIdFactory::root(), in_root.Get(PARENT_ID)); |
+ |
+ Entry in_in_root(&trans, GET_BY_ID, in_in_root_id); |
+ ASSERT_TRUE(in_in_root.good()); |
+ EXPECT_EQ(PSTR("in_in_root_name"), in_in_root.Get(NON_UNIQUE_NAME)); |
+ EXPECT_EQ(in_root_id, in_in_root.Get(PARENT_ID)); |
} |
} |
TEST_F(SyncerTest, DirectoryCommitTest) { |
- syncable::Id in_root, in_dir; |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
+ |
+ syncable::Id in_root_id, in_dir_id; |
+ int64 foo_metahandle; |
+ int64 bar_metahandle; |
+ |
{ |
WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
MutableEntry parent(&wtrans, syncable::CREATE, root_id_, PSTR("foo")); |
ASSERT_TRUE(parent.good()); |
parent.Put(syncable::IS_UNSYNCED, true); |
parent.Put(syncable::IS_DIR, true); |
- in_root = parent.Get(syncable::ID); |
+ in_root_id = parent.Get(syncable::ID); |
+ foo_metahandle = parent.Get(META_HANDLE); |
+ |
MutableEntry child(&wtrans, syncable::CREATE, parent.Get(ID), PSTR("bar")); |
ASSERT_TRUE(child.good()); |
child.Put(syncable::IS_UNSYNCED, true); |
child.Put(syncable::IS_DIR, true); |
- in_dir = parent.Get(syncable::ID); |
+ bar_metahandle = child.Get(META_HANDLE); |
+ in_dir_id = parent.Get(syncable::ID); |
} |
syncer_->SyncShare(); |
{ |
ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry by_path(&trans, GET_BY_PATH, PSTR("foo")); |
- ASSERT_TRUE(by_path.good()); |
- EXPECT_NE(by_path.Get(syncable::ID), in_root); |
- Entry by_path2(&trans, GET_BY_PATH, PSTR("foo") + |
- PathString(kPathSeparator) + |
- PSTR("bar")); |
- ASSERT_TRUE(by_path2.good()); |
- EXPECT_NE(by_path2.Get(syncable::ID), in_dir); |
- } |
-} |
+ Entry fail_by_old_id_entry(&trans, GET_BY_ID, in_root_id); |
+ ASSERT_FALSE(fail_by_old_id_entry.good()); |
-namespace { |
+ Entry foo_entry(&trans, GET_BY_HANDLE, foo_metahandle); |
+ ASSERT_TRUE(foo_entry.good()); |
+ EXPECT_EQ(PSTR("foo"), foo_entry.Get(NON_UNIQUE_NAME)); |
+ EXPECT_NE(foo_entry.Get(syncable::ID), in_root_id); |
-void CheckEntryVersion(syncable::DirectoryManager* dirmgr, PathString name) { |
- ScopedDirLookup dir(dirmgr, name); |
- ASSERT_TRUE(dir.good()); |
- ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry entry(&trans, GET_BY_PATH, PSTR("foo")); |
- ASSERT_TRUE(entry.good()); |
- EXPECT_TRUE(entry.Get(BASE_VERSION) == 1); |
+ Entry bar_entry(&trans, GET_BY_HANDLE, bar_metahandle); |
+ ASSERT_TRUE(bar_entry.good()); |
+ EXPECT_EQ(PSTR("bar"), bar_entry.Get(NON_UNIQUE_NAME)); |
+ EXPECT_NE(bar_entry.Get(syncable::ID), in_dir_id); |
+ EXPECT_EQ(foo_entry.Get(syncable::ID), bar_entry.Get(PARENT_ID)); |
+ } |
} |
-} // namespace |
- |
TEST_F(SyncerTest, ConflictSetSizeReducedToOne) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
- mock_server_->AddUpdateBookmark(2, 0, "in_root", 1, 1); |
+ |
+ syncable::Id in_root_id = ids_.NewServerId(); |
+ |
+ mock_server_->AddUpdateBookmark(in_root_id, TestIdFactory::root(), |
+ "in_root", 1, 1); |
syncer_->SyncShare(); |
{ |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry oentry(&trans, GET_BY_PATH, PSTR("in_root")); |
+ MutableEntry oentry(&trans, GET_BY_ID, in_root_id); |
ASSERT_TRUE(oentry.good()); |
- oentry.Put(NAME, PSTR("old_in_root")); |
+ oentry.Put(NON_UNIQUE_NAME, PSTR("old_in_root")); |
WriteTestDataToEntry(&trans, &oentry); |
MutableEntry entry(&trans, CREATE, trans.root_id(), PSTR("in_root")); |
ASSERT_TRUE(entry.good()); |
@@ -4086,15 +3564,21 @@ TEST_F(SyncerTest, TestClientCommand) { |
TEST_F(SyncerTest, EnsureWeSendUpOldParent) { |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
CHECK(dir.good()); |
- mock_server_->AddUpdateDirectory(1, 0, "folder_one", 1, 1); |
- mock_server_->AddUpdateDirectory(2, 0, "folder_two", 1, 1); |
+ |
+ syncable::Id folder_one_id = ids_.FromNumber(1); |
+ syncable::Id folder_two_id = ids_.FromNumber(2); |
+ |
+ mock_server_->AddUpdateDirectory(folder_one_id, TestIdFactory::root(), |
+ "folder_one", 1, 1); |
+ mock_server_->AddUpdateDirectory(folder_two_id, TestIdFactory::root(), |
+ "folder_two", 1, 1); |
syncer_->SyncShare(); |
{ |
// A moved entry should send an old parent. |
WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
- MutableEntry entry(&trans, GET_BY_PATH, PSTR("folder_one")); |
+ MutableEntry entry(&trans, GET_BY_ID, folder_one_id); |
ASSERT_TRUE(entry.good()); |
- entry.Put(PARENT_ID, ids_.FromNumber(2)); |
+ entry.Put(PARENT_ID, folder_two_id); |
entry.Put(IS_UNSYNCED, true); |
// A new entry should send no parent. |
MutableEntry create(&trans, CREATE, trans.root_id(), PSTR("new_folder")); |
@@ -4113,6 +3597,7 @@ TEST_F(SyncerTest, Test64BitVersionSupport) { |
CHECK(dir.good()); |
int64 really_big_int = std::numeric_limits<int64>::max() - 12; |
const PathString name(PSTR("ringo's dang orang ran rings around my o-ring")); |
+ int64 item_metahandle; |
// Try writing max int64 to the version fields of a meta entry. |
{ |
@@ -4121,29 +3606,18 @@ TEST_F(SyncerTest, Test64BitVersionSupport) { |
ASSERT_TRUE(entry.good()); |
entry.Put(syncable::BASE_VERSION, really_big_int); |
entry.Put(syncable::SERVER_VERSION, really_big_int); |
- entry.Put(syncable::ID, syncable::Id::CreateFromServerId("ID")); |
+ entry.Put(syncable::ID, ids_.NewServerId()); |
+ item_metahandle = entry.Get(META_HANDLE); |
} |
// Now read it back out and make sure the value is max int64. |
ReadTransaction rtrans(dir, __FILE__, __LINE__); |
- Entry entry(&rtrans, syncable::GET_BY_PATH, name); |
+ Entry entry(&rtrans, syncable::GET_BY_HANDLE, item_metahandle); |
ASSERT_TRUE(entry.good()); |
EXPECT_TRUE(really_big_int == entry.Get(syncable::BASE_VERSION)); |
} |
-TEST_F(SyncerTest, TestDSStoreDirectorySyncsNormally) { |
- syncable::Id item_id = parent_id_; |
- mock_server_->AddUpdateDirectory(item_id, |
- root_id_, ".DS_Store", 1, 1); |
- syncer_->SyncShare(); |
- ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
- CHECK(dir.good()); |
- ReadTransaction trans(dir, __FILE__, __LINE__); |
- Entry ds_dir(&trans, GET_BY_PATH, PSTR(".DS_Store")); |
- ASSERT_TRUE(ds_dir.good()); |
-} |
- |
TEST_F(SyncerTest, TestSimpleUndelete) { |
- Id id = ids_.MakeServer("undeletion item"), root = ids_.root(); |
+ Id id = ids_.MakeServer("undeletion item"), root = TestIdFactory::root(); |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
EXPECT_TRUE(dir.good()); |
mock_server_->set_conflict_all_commits(true); |
@@ -4203,7 +3677,7 @@ TEST_F(SyncerTest, TestSimpleUndelete) { |
} |
TEST_F(SyncerTest, TestUndeleteWithMissingDeleteUpdate) { |
- Id id = ids_.MakeServer("undeletion item"), root = ids_.root(); |
+ Id id = ids_.MakeServer("undeletion item"), root = TestIdFactory::root(); |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
EXPECT_TRUE(dir.good()); |
// Let there be a entry, from the server. |
@@ -4251,7 +3725,7 @@ TEST_F(SyncerTest, TestUndeleteWithMissingDeleteUpdate) { |
TEST_F(SyncerTest, TestUndeleteIgnoreCorrectlyUnappliedUpdate) { |
Id id1 = ids_.MakeServer("first"), id2 = ids_.MakeServer("second"); |
- Id root = ids_.root(); |
+ Id root = TestIdFactory::root(); |
ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
EXPECT_TRUE(dir.good()); |
// Duplicate! expect path clashing! |
@@ -4296,7 +3770,7 @@ TEST_F(SyncerTest, SingletonTagUpdates) { |
ASSERT_TRUE(hurdle.good()); |
ASSERT_TRUE(!hurdle.Get(IS_DEL)); |
ASSERT_TRUE(hurdle.Get(SINGLETON_TAG).empty()); |
- ASSERT_TRUE(hurdle.GetName().value() == PSTR("bob")); |
+ ASSERT_TRUE(hurdle.Get(NON_UNIQUE_NAME) == PSTR("bob")); |
// Try to lookup by the tagname. These should fail. |
Entry tag_alpha(&trans, GET_BY_TAG, PSTR("alpha")); |
@@ -4321,18 +3795,18 @@ TEST_F(SyncerTest, SingletonTagUpdates) { |
ASSERT_TRUE(tag_alpha.good()); |
ASSERT_TRUE(!tag_alpha.Get(IS_DEL)); |
ASSERT_TRUE(tag_alpha.Get(SINGLETON_TAG) == PSTR("alpha")); |
- ASSERT_TRUE(tag_alpha.GetName().value() == PSTR("update1")); |
+ ASSERT_TRUE(tag_alpha.Get(NON_UNIQUE_NAME) == PSTR("update1")); |
Entry tag_bob(&trans, GET_BY_TAG, PSTR("bob")); |
ASSERT_TRUE(tag_bob.good()); |
ASSERT_TRUE(!tag_bob.Get(IS_DEL)); |
ASSERT_TRUE(tag_bob.Get(SINGLETON_TAG) == PSTR("bob")); |
- ASSERT_TRUE(tag_bob.GetName().value() == PSTR("update2")); |
+ ASSERT_TRUE(tag_bob.Get(NON_UNIQUE_NAME) == PSTR("update2")); |
// The old item should be unchanged. |
Entry hurdle(&trans, GET_BY_HANDLE, hurdle_handle); |
ASSERT_TRUE(hurdle.good()); |
ASSERT_TRUE(!hurdle.Get(IS_DEL)); |
ASSERT_TRUE(hurdle.Get(SINGLETON_TAG).empty()); |
- ASSERT_TRUE(hurdle.GetName().value() == PSTR("bob")); |
+ ASSERT_TRUE(hurdle.Get(NON_UNIQUE_NAME) == PSTR("bob")); |
} |
} |