diff options
Diffstat (limited to 'sync')
-rw-r--r-- | sync/engine/sync_scheduler.cc | 61 | ||||
-rw-r--r-- | sync/engine/sync_scheduler.h | 13 | ||||
-rw-r--r-- | sync/engine/syncer.cc | 42 | ||||
-rw-r--r-- | sync/engine/syncer_unittest.cc | 503 | ||||
-rw-r--r-- | sync/sessions/status_controller.h | 3 | ||||
-rw-r--r-- | sync/sessions/sync_session_unittest.cc | 52 | ||||
-rw-r--r-- | sync/test/engine/mock_connection_manager.cc | 31 | ||||
-rw-r--r-- | sync/test/engine/mock_connection_manager.h | 28 |
8 files changed, 406 insertions, 327 deletions
diff --git a/sync/engine/sync_scheduler.cc b/sync/engine/sync_scheduler.cc index 8baee7c..9ddd26c 100644 --- a/sync/engine/sync_scheduler.cc +++ b/sync/engine/sync_scheduler.cc @@ -682,6 +682,37 @@ const char* SyncScheduler::GetDecisionString( return ""; } +// static +void SyncScheduler::SetSyncerStepsForPurpose( + SyncSessionJob::SyncSessionJobPurpose purpose, + SyncerStep* start, + SyncerStep* end) { + switch (purpose) { + case SyncSessionJob::CONFIGURATION: + *start = DOWNLOAD_UPDATES; + *end = APPLY_UPDATES; + return; + case SyncSessionJob::CLEAR_USER_DATA: + *start = CLEAR_PRIVATE_DATA; + *end = CLEAR_PRIVATE_DATA; + return; + case SyncSessionJob::NUDGE: + case SyncSessionJob::POLL: + *start = SYNCER_BEGIN; + *end = SYNCER_END; + return; + case SyncSessionJob::CLEANUP_DISABLED_TYPES: + *start = CLEANUP_DISABLED_TYPES; + *end = CLEANUP_DISABLED_TYPES; + return; + default: + NOTREACHED(); + *start = SYNCER_END; + *end = SYNCER_END; + return; + } +} + void SyncScheduler::PostTask( const tracked_objects::Location& from_here, const char* name, const base::Closure& task) { @@ -730,36 +761,6 @@ void SyncScheduler::ScheduleSyncSessionJob(const SyncSessionJob& job) { delay); } -void SyncScheduler::SetSyncerStepsForPurpose( - SyncSessionJob::SyncSessionJobPurpose purpose, - SyncerStep* start, SyncerStep* end) { - DCHECK_EQ(MessageLoop::current(), sync_loop_); - switch (purpose) { - case SyncSessionJob::CONFIGURATION: - *start = DOWNLOAD_UPDATES; - *end = APPLY_UPDATES; - return; - case SyncSessionJob::CLEAR_USER_DATA: - *start = CLEAR_PRIVATE_DATA; - *end = CLEAR_PRIVATE_DATA; - return; - case SyncSessionJob::NUDGE: - case SyncSessionJob::POLL: - *start = SYNCER_BEGIN; - *end = SYNCER_END; - return; - case SyncSessionJob::CLEANUP_DISABLED_TYPES: - *start = CLEANUP_DISABLED_TYPES; - *end = CLEANUP_DISABLED_TYPES; - return; - default: - NOTREACHED(); - *start = SYNCER_END; - *end = SYNCER_END; - return; - } -} - void SyncScheduler::DoSyncSessionJob(const SyncSessionJob& job) { DCHECK_EQ(MessageLoop::current(), sync_loop_); if (!ShouldRunJob(job)) { diff --git a/sync/engine/sync_scheduler.h b/sync/engine/sync_scheduler.h index d5ff4c0..4ec621d 100644 --- a/sync/engine/sync_scheduler.h +++ b/sync/engine/sync_scheduler.h @@ -179,6 +179,7 @@ class SyncScheduler : public sessions::SyncSession::Delegate { }; friend class SyncSchedulerTest; friend class SyncSchedulerWhiteboxTest; + friend class SyncerTest; FRIEND_TEST_ALL_PREFIXES(SyncSchedulerWhiteboxTest, DropNudgeWhileExponentialBackOff); @@ -247,6 +248,12 @@ class SyncScheduler : public sessions::SyncSession::Delegate { static const char* GetDecisionString(JobProcessDecision decision); + // Assign |start| and |end| to appropriate SyncerStep values for the + // specified |purpose|. + static void SetSyncerStepsForPurpose( + SyncSessionJob::SyncSessionJobPurpose purpose, + SyncerStep* start, SyncerStep* end); + // Helpers that log before posting to |sync_loop_|. These will only post // the task in between calls to Start/Stop. void PostTask(const tracked_objects::Location& from_here, @@ -340,12 +347,6 @@ class SyncScheduler : public sessions::SyncSession::Delegate { // Creates a session for a poll and performs the sync. void PollTimerCallback(); - // Assign |start| and |end| to appropriate SyncerStep values for the - // specified |purpose|. - void SetSyncerStepsForPurpose(SyncSessionJob::SyncSessionJobPurpose purpose, - SyncerStep* start, - SyncerStep* end); - // Used to update |connection_code_|, see below. void UpdateServerConnectionManagerStatus( HttpResponse::ServerConnectionCode code); diff --git a/sync/engine/syncer.cc b/sync/engine/syncer.cc index 62c7af8..5de4ae5 100644 --- a/sync/engine/syncer.cc +++ b/sync/engine/syncer.cc @@ -110,17 +110,6 @@ void Syncer::SyncShare(sessions::SyncSession* session, switch (current_step) { case SYNCER_BEGIN: - // This isn't perfect, as we can end up bundling extensions activity - // intended for the next session into the current one. We could do a - // test-and-reset as with the source, but note that also falls short if - // the commit request fails (e.g. due to lost connection), as we will - // fall all the way back to the syncer thread main loop in that case, - // creating a new session when a connection is established, losing the - // records set here on the original attempt. This should provide us - // with the right data "most of the time", and we're only using this - // for analysis purposes, so Law of Large Numbers FTW. - session->context()->extensions_monitor()->GetAndClearRecords( - session->mutable_extensions_activity()); session->context()->PruneUnthrottledTypes(base::TimeTicks::Now()); session->SendEventNotification(SyncEngineEvent::SYNC_CYCLE_BEGIN); @@ -166,13 +155,19 @@ void Syncer::SyncShare(sessions::SyncSession* session, case STORE_TIMESTAMPS: { StoreTimestampsCommand store_timestamps; store_timestamps.Execute(session); - // We should download all of the updates before attempting to process - // them. - if (session->status_controller().ServerSaysNothingMoreToDownload() || - !session->status_controller().download_updates_succeeded()) { - next_step = APPLY_UPDATES; - } else { + // We download all of the updates before attempting to apply them. + if (!session->status_controller().download_updates_succeeded()) { + // We may have downloaded some updates, but if the latest download + // attempt failed then we don't have all the updates. We'll leave + // it to a retry job to pick up where we left off. + last_step = SYNCER_END; // Necessary for CONFIGURATION mode. + next_step = SYNCER_END; + DVLOG(1) << "Aborting sync cycle due to download updates failure"; + } else if (!session->status_controller() + .ServerSaysNothingMoreToDownload()) { next_step = DOWNLOAD_UPDATES; + } else { + next_step = APPLY_UPDATES; } break; } @@ -203,6 +198,19 @@ void Syncer::SyncShare(sessions::SyncSession* session, if (!session->status_controller().commit_ids().empty()) { DVLOG(1) << "Building a commit message"; + + // This isn't perfect, since the set of extensions activity may not + // correlate exactly with the items being committed. That's OK as + // long as we're looking for a rough estimate of extensions activity, + // not an precise mapping of which commits were triggered by which + // extension. + // + // We will push this list of extensions activity back into the + // ExtensionsActivityMonitor if this commit turns out to not contain + // any bookmarks, or if the commit fails. + session->context()->extensions_monitor()->GetAndClearRecords( + session->mutable_extensions_activity()); + BuildCommitCommand build_commit_command; build_commit_command.Execute(session); diff --git a/sync/engine/syncer_unittest.cc b/sync/engine/syncer_unittest.cc index 1d8cbb0..e063243 100644 --- a/sync/engine/syncer_unittest.cc +++ b/sync/engine/syncer_unittest.cc @@ -33,6 +33,7 @@ #include "sync/engine/syncer_util.h" #include "sync/engine/syncproto.h" #include "sync/engine/traffic_recorder.h" +#include "sync/engine/sync_scheduler.h" #include "sync/protocol/bookmark_specifics.pb.h" #include "sync/protocol/nigori_specifics.pb.h" #include "sync/protocol/preference_specifics.pb.h" @@ -186,18 +187,33 @@ class SyncerTest : public testing::Test, info, workers); } - bool SyncShareAsDelegate() { + bool SyncShareAsDelegate( + SyncScheduler::SyncSessionJob::SyncSessionJobPurpose purpose) { + SyncerStep start; + SyncerStep end; + SyncScheduler::SetSyncerStepsForPurpose(purpose, &start, &end); + session_.reset(MakeSession()); - syncer_->SyncShare(session_.get(), SYNCER_BEGIN, SYNCER_END); + syncer_->SyncShare(session_.get(), start, end); return session_->HasMoreToSync(); } + bool SyncShareNudge() { + session_.reset(MakeSession()); + return SyncShareAsDelegate(SyncScheduler::SyncSessionJob::NUDGE); + } + + bool SyncShareConfigure() { + session_.reset(MakeSession()); + return SyncShareAsDelegate(SyncScheduler::SyncSessionJob::CONFIGURATION); + } + void LoopSyncShare() { bool should_loop = false; int loop_iterations = 0; do { ASSERT_LT(++loop_iterations, 100) << "infinite loop detected. please fix"; - should_loop = SyncShareAsDelegate(); + should_loop = SyncShareNudge(); } while (should_loop); } @@ -257,6 +273,10 @@ class SyncerTest : public testing::Test, EXPECT_EQ("http://demo/", specifics.bookmark().url()); } + bool initial_sync_ended_for_type(syncable::ModelType type) { + return directory()->initial_sync_ended_for_type(type); + } + void SyncRepeatedlyToTriggerConflictResolution(SyncSession* session) { // We should trigger after less than 6 syncs, but extra does no harm. for (int i = 0 ; i < 6 ; ++i) @@ -542,7 +562,7 @@ TEST_F(SyncerTest, GetCommitIdsCommandTruncates) { // Create two server entries. mock_server_->AddUpdateDirectory(ids_.MakeServer("x"), root, "X", 10, 10); mock_server_->AddUpdateDirectory(ids_.MakeServer("w"), root, "W", 10, 10); - SyncShareAsDelegate(); + SyncShareNudge(); // Create some new client entries. CreateUnsyncedDirectory("C", ids_.MakeLocal("c")); @@ -596,7 +616,7 @@ TEST_F(SyncerTest, GetCommitIdsFiltersThrottledEntries) { AddDefaultFieldValue(syncable::BOOKMARKS, &bookmark_data); mock_server_->AddUpdateDirectory(1, 0, "A", 10, 10); - SyncShareAsDelegate(); + SyncShareNudge(); { WriteTransaction wtrans(FROM_HERE, UNITTEST, directory()); @@ -611,7 +631,7 @@ TEST_F(SyncerTest, GetCommitIdsFiltersThrottledEntries) { context_->SetUnthrottleTime( throttled_types, base::TimeTicks::Now() + base::TimeDelta::FromSeconds(1200)); - SyncShareAsDelegate(); + SyncShareNudge(); { // Nothing should have been committed as bookmarks is throttled. @@ -625,7 +645,7 @@ TEST_F(SyncerTest, GetCommitIdsFiltersThrottledEntries) { context_->SetUnthrottleTime( throttled_types, base::TimeTicks::Now() - base::TimeDelta::FromSeconds(1200)); - SyncShareAsDelegate(); + SyncShareNudge(); { // It should have been committed. ReadTransaction rtrans(FROM_HERE, directory()); @@ -665,7 +685,7 @@ TEST_F(SyncerTest, GetCommitIdsFiltersUnreadyEntries) { mock_server_->AddUpdateDirectory(2, 0, "B", 10, 10); mock_server_->AddUpdateDirectory(3, 0, "C", 10, 10); mock_server_->AddUpdateDirectory(4, 0, "D", 10, 10); - SyncShareAsDelegate(); + SyncShareNudge(); // Server side change will put A in conflict. mock_server_->AddUpdateDirectory(1, 0, "A", 20, 20); { @@ -708,7 +728,7 @@ TEST_F(SyncerTest, GetCommitIdsFiltersUnreadyEntries) { D.Put(SPECIFICS, encrypted_bookmark); D.Put(NON_UNIQUE_NAME, "not encrypted"); } - SyncShareAsDelegate(); + SyncShareNudge(); { // We remove any unready entries from the status controller's unsynced // handles, so this should remain 0 even though the entries didn't commit. @@ -725,7 +745,7 @@ TEST_F(SyncerTest, GetCommitIdsFiltersUnreadyEntries) { // Resolve the pending keys. cryptographer(&rtrans)->DecryptPendingKeys(other_params); } - SyncShareAsDelegate(); + SyncShareNudge(); { // 2 unsynced handles to reflect the items that committed succesfully. EXPECT_EQ(2U, session_->status_controller().unsynced_handles().size()); @@ -754,7 +774,7 @@ TEST_F(SyncerTest, GetCommitIdsFiltersUnreadyEntries) { D.Put(SPECIFICS, encrypted_bookmark); D.Put(NON_UNIQUE_NAME, kEncryptedString); } - SyncShareAsDelegate(); + SyncShareNudge(); { // We attempted to commit two items. EXPECT_EQ(2U, session_->status_controller().unsynced_handles().size()); @@ -805,7 +825,7 @@ TEST_F(SyncerTest, EncryptionAwareConflicts) { mock_server_->AddUpdateSpecifics(2, 1, "B", 10, 10, false, 2, bookmark); mock_server_->AddUpdateSpecifics(3, 1, "C", 10, 10, false, 1, bookmark); mock_server_->AddUpdateSpecifics(4, 0, "D", 10, 10, false, 0, pref); - SyncShareAsDelegate(); + SyncShareNudge(); { EXPECT_EQ(0U, session_->status_controller().unsynced_handles().size()); // Initial state. Everything is normal. @@ -826,7 +846,7 @@ TEST_F(SyncerTest, EncryptionAwareConflicts) { encrypted_bookmark); mock_server_->AddUpdateSpecifics(4, 0, kEncryptedString, 20, 20, false, 0, encrypted_pref); - SyncShareAsDelegate(); + SyncShareNudge(); { EXPECT_EQ(0U, session_->status_controller().unsynced_handles().size()); // All should be unapplied due to being undecryptable and have a valid @@ -847,7 +867,7 @@ TEST_F(SyncerTest, EncryptionAwareConflicts) { // Item 3 doesn't change. mock_server_->AddUpdateSpecifics(4, 0, kEncryptedString, 30, 30, false, 0, encrypted_pref); - SyncShareAsDelegate(); + SyncShareNudge(); { EXPECT_EQ(0U, session_->status_controller().unsynced_handles().size()); // Items 1, 2, and 4 should have newer server versions, 3 remains the same. @@ -866,7 +886,7 @@ TEST_F(SyncerTest, EncryptionAwareConflicts) { // Reordered to after item 2. mock_server_->AddUpdateSpecifics(3, 1, kEncryptedString, 30, 30, false, 3, encrypted_bookmark); - SyncShareAsDelegate(); + SyncShareNudge(); { EXPECT_EQ(0U, session_->status_controller().unsynced_handles().size()); // Items 2 and 4 should be the only ones with BASE_SERVER_SPECIFICS set. @@ -902,7 +922,7 @@ TEST_F(SyncerTest, EncryptionAwareConflicts) { D.Put(NON_UNIQUE_NAME, kEncryptedString); D.Put(IS_UNSYNCED, true); } - SyncShareAsDelegate(); + SyncShareNudge(); { EXPECT_EQ(0U, session_->status_controller().unsynced_handles().size()); // Item 1 remains unsynced due to there being pending keys. @@ -920,7 +940,7 @@ TEST_F(SyncerTest, EncryptionAwareConflicts) { cryptographer(&rtrans)->DecryptPendingKeys(key_params); } // First cycle resolves conflicts, second cycle commits changes. - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(2, session_->status_controller().syncer_status(). num_server_overwrites); EXPECT_EQ(1, session_->status_controller().syncer_status(). @@ -928,7 +948,7 @@ TEST_F(SyncerTest, EncryptionAwareConflicts) { // We attempted to commit item 1. EXPECT_EQ(1U, session_->status_controller().unsynced_handles().size()); EXPECT_TRUE(session_->status_controller().did_commit_items()); - SyncShareAsDelegate(); + SyncShareNudge(); { // Everything should be resolved now. The local changes should have // overwritten the server changes for 2 and 4, while the server changes @@ -973,7 +993,7 @@ TEST_F(SyncerTest, ReceiveOldNigori) { sync_pb::EntitySpecifics initial_nigori_specifics; initial_nigori_specifics.mutable_nigori(); mock_server_->SetNigori(1, 10, 10, initial_nigori_specifics); - SyncShareAsDelegate(); + SyncShareNudge(); { // Set up the current nigori node (containing both keys and encrypt @@ -1000,7 +1020,7 @@ TEST_F(SyncerTest, ReceiveOldNigori) { cryptographer(&wtrans)->GetEncryptedTypes())); } - SyncShareAsDelegate(); // Commit it. + SyncShareNudge(); // Commit it. // Now set up the old nigori node and add it as a server update. sync_pb::EntitySpecifics old_nigori_specifics; @@ -1009,7 +1029,7 @@ TEST_F(SyncerTest, ReceiveOldNigori) { other_cryptographer.UpdateNigoriFromEncryptedTypes(old_nigori); mock_server_->SetNigori(1, 30, 30, old_nigori_specifics); - SyncShareAsDelegate(); // Download the old nigori and apply it. + SyncShareNudge(); // Download the old nigori and apply it. { // Ensure everything is committed and stable now. The cryptographer @@ -1058,7 +1078,7 @@ TEST_F(SyncerTest, NigoriConflicts) { our_encrypted_specifics.mutable_bookmark()->set_title("title2"); // Receive the initial nigori node. - SyncShareAsDelegate(); + SyncShareNudge(); encrypted_types = syncable::ModelTypeSet::All(); { // Local changes with different passphrase, different types, and sync_tabs. @@ -1099,8 +1119,8 @@ TEST_F(SyncerTest, NigoriConflicts) { // data (with priority given to the server's encryption keys if they are // undecryptable), which we then commit. The cryptographer should have pending // keys and merge the set of encrypted types. - SyncShareAsDelegate(); // Resolve conflict in this cycle. - SyncShareAsDelegate(); // Commit local change in this cycle. + SyncShareNudge(); // Resolve conflict in this cycle. + SyncShareNudge(); // Commit local change in this cycle. { // Ensure the nigori data merged (encrypted types, sync_tabs). WriteTransaction wtrans(FROM_HERE, UNITTEST, directory()); @@ -1130,7 +1150,7 @@ TEST_F(SyncerTest, NigoriConflicts) { nigori_entry.Put(IS_UNSYNCED, true); } - SyncShareAsDelegate(); + SyncShareNudge(); { // Ensure everything is committed and stable now. The cryptographer // should be able to decrypt both sets of keys, sync_tabs should be true, @@ -1174,7 +1194,7 @@ TEST_F(SyncerTest, TestGetUnsyncedAndSimpleCommit) { } const StatusController& status = session_->status_controller(); - syncer_->SyncShare(session_.get(), SYNCER_BEGIN, SYNCER_END); + SyncShareNudge(); EXPECT_EQ(2u, status.unsynced_handles().size()); ASSERT_EQ(2u, mock_server_->committed_ids().size()); // If this test starts failing, be aware other sort orders could be valid. @@ -1219,7 +1239,7 @@ TEST_F(SyncerTest, TestPurgeWhileUnsynced) { syncable::ModelTypeSet(syncable::PREFERENCES)); const StatusController& status = session_->status_controller(); - syncer_->SyncShare(session_.get(), SYNCER_BEGIN, SYNCER_END); + SyncShareNudge(); EXPECT_EQ(2U, status.unsynced_handles().size()); ASSERT_EQ(2U, mock_server_->committed_ids().size()); // If this test starts failing, be aware other sort orders could be valid. @@ -1255,7 +1275,7 @@ TEST_F(SyncerTest, TestPurgeWhileUnapplied) { directory()->PurgeEntriesWithTypeIn( syncable::ModelTypeSet(syncable::BOOKMARKS)); - syncer_->SyncShare(session_.get(), SYNCER_BEGIN, SYNCER_END); + SyncShareNudge(); directory()->SaveChanges(); { ReadTransaction rt(FROM_HERE, directory()); @@ -1458,7 +1478,7 @@ TEST_F(SyncerTest, TestCommitListOrderingWithNesting) { } } - syncer_->SyncShare(session_.get(), SYNCER_BEGIN, SYNCER_END); + SyncShareNudge(); EXPECT_EQ(6u, session_->status_controller().unsynced_handles().size()); ASSERT_EQ(6u, mock_server_->committed_ids().size()); // This test will NOT unroll deletes because SERVER_PARENT_ID is not set. @@ -1526,7 +1546,7 @@ TEST_F(SyncerTest, TestCommitListOrderingWithNewItems) { child.Put(syncable::BASE_VERSION, 1); } - syncer_->SyncShare(session_.get(), SYNCER_BEGIN, SYNCER_END); + SyncShareNudge(); EXPECT_EQ(6u, session_->status_controller().unsynced_handles().size()); ASSERT_EQ(6u, mock_server_->committed_ids().size()); // If this test starts failing, be aware other sort orders could be valid. @@ -1565,7 +1585,7 @@ TEST_F(SyncerTest, TestCommitListOrderingCounterexample) { child2.Put(syncable::BASE_VERSION, 1); } - syncer_->SyncShare(session_.get(), SYNCER_BEGIN, SYNCER_END); + SyncShareNudge(); EXPECT_EQ(3u, session_->status_controller().unsynced_handles().size()); ASSERT_EQ(3u, mock_server_->committed_ids().size()); // If this test starts failing, be aware other sort orders could be valid. @@ -1611,7 +1631,7 @@ TEST_F(SyncerTest, TestCommitListOrderingAndNewParent) { child.Put(syncable::BASE_VERSION, 1); } - syncer_->SyncShare(session_.get(), SYNCER_BEGIN, SYNCER_END); + SyncShareNudge(); EXPECT_EQ(3u, session_->status_controller().unsynced_handles().size()); ASSERT_EQ(3u, mock_server_->committed_ids().size()); // If this test starts failing, be aware other sort orders could be valid. @@ -1682,7 +1702,7 @@ TEST_F(SyncerTest, TestCommitListOrderingAndNewParentAndChild) { meta_handle_b = child.Get(syncable::META_HANDLE); } - syncer_->SyncShare(session_.get(), SYNCER_BEGIN, SYNCER_END); + SyncShareNudge(); EXPECT_EQ(3u, session_->status_controller().unsynced_handles().size()); ASSERT_EQ(3u, mock_server_->committed_ids().size()); // If this test starts failing, be aware other sort orders could be valid. @@ -1719,11 +1739,11 @@ TEST_F(SyncerTest, UpdateWithZeroLengthName) { mock_server_->AddUpdateDirectory(1, 0, "", 1, 10); // And one legal one that we're going to delete. mock_server_->AddUpdateDirectory(2, 0, "FOO", 1, 10); - SyncShareAsDelegate(); + SyncShareNudge(); // Delete the legal one. The new update has a null name. mock_server_->AddUpdateDirectory(2, 0, "", 2, 20); mock_server_->SetLastUpdateDeleted(); - SyncShareAsDelegate(); + SyncShareNudge(); } TEST_F(SyncerTest, TestBasicUpdate) { @@ -1734,7 +1754,7 @@ TEST_F(SyncerTest, TestBasicUpdate) { int64 timestamp = 10; mock_server_->AddUpdateDirectory(id, parent_id, name, version, timestamp); - SyncShareAsDelegate(); + SyncShareNudge(); { WriteTransaction trans(FROM_HERE, UNITTEST, directory()); Entry entry(&trans, GET_BY_ID, @@ -1765,7 +1785,7 @@ TEST_F(SyncerTest, IllegalAndLegalUpdates) { // until an item with the server ID "-80" arrives. mock_server_->AddUpdateDirectory(3, -80, "bad_parent", 10, 10); - syncer_->SyncShare(session_.get(), SYNCER_BEGIN, SYNCER_END); + SyncShareNudge(); StatusController* status = session_->mutable_status_controller(); // Id 3 should be in conflict now. @@ -1784,7 +1804,7 @@ TEST_F(SyncerTest, IllegalAndLegalUpdates) { mock_server_->AddUpdateDirectory(100, 9, "bad_parent_child2", 10, 10); mock_server_->AddUpdateDirectory(10, 0, "dir_to_bookmark", 10, 10); - syncer_->SyncShare(session_.get(), SYNCER_BEGIN, SYNCER_END); + SyncShareNudge(); // The three items with an unresolved parent should be unapplied (3, 9, 100). // The name clash should also still be in conflict. EXPECT_EQ(3, status->TotalNumConflictingItems()); @@ -1826,11 +1846,11 @@ TEST_F(SyncerTest, IllegalAndLegalUpdates) { // Flip the is_dir bit: should fail verify & be dropped. mock_server_->AddUpdateBookmark(10, 0, "dir_to_bookmark", 20, 20); - syncer_->SyncShare(session_.get(), SYNCER_BEGIN, SYNCER_END); + SyncShareNudge(); // Version number older than last known: should fail verify & be dropped. mock_server_->AddUpdateDirectory(4, 0, "old_version", 10, 10); - syncer_->SyncShare(session_.get(), SYNCER_BEGIN, SYNCER_END); + SyncShareNudge(); { ReadTransaction trans(FROM_HERE, directory()); @@ -1912,7 +1932,7 @@ TEST_F(SyncerTest, CommitTimeRename) { // Mix in a directory creation too for later. mock_server_->AddUpdateDirectory(2, 0, "dir_in_root", 10, 10); mock_server_->SetCommitTimeRename("renamed_"); - SyncShareAsDelegate(); + SyncShareNudge(); // Verify it was correctly renamed. { @@ -1953,7 +1973,7 @@ TEST_F(SyncerTest, CommitTimeRenameI18N) { } mock_server_->SetCommitTimeRename(i18nString); - SyncShareAsDelegate(); + SyncShareNudge(); // Verify it was correctly renamed. { @@ -2033,7 +2053,7 @@ TEST_F(SyncerTest, CommitReuniteUpdateAdjustsChildren) { mock_server_->set_conflict_all_commits(true); // Alright! Apply that update! - SyncShareAsDelegate(); + SyncShareNudge(); { // The folder's ID should have been updated. ReadTransaction trans(FROM_HERE, directory()); @@ -2099,7 +2119,7 @@ TEST_F(SyncerTest, CommitReuniteUpdate) { mock_server_->set_conflict_all_commits(true); // Alright! Apply that update! - SyncShareAsDelegate(); + SyncShareNudge(); { ReadTransaction trans(FROM_HERE, directory()); Entry entry(&trans, GET_BY_HANDLE, entry_metahandle); @@ -2162,7 +2182,7 @@ TEST_F(SyncerTest, CommitReuniteUpdateDoesNotChokeOnDeletedLocalEntry) { } // Just don't CHECK fail in sync, have the update split. - SyncShareAsDelegate(); + SyncShareNudge(); { ReadTransaction trans(FROM_HERE, directory()); Id new_entry_id = GetOnlyEntryWithName( @@ -2182,7 +2202,7 @@ TEST_F(SyncerTest, ConflictMatchingEntryHandlesUnsanitizedNames) { mock_server_->AddUpdateDirectory(1, 0, "A/A", 10, 10); mock_server_->AddUpdateDirectory(2, 0, "B/B", 10, 10); mock_server_->set_conflict_all_commits(true); - SyncShareAsDelegate(); + SyncShareNudge(); { WriteTransaction wtrans(FROM_HERE, UNITTEST, directory()); @@ -2222,7 +2242,7 @@ TEST_F(SyncerTest, ConflictMatchingEntryHandlesNormalNames) { mock_server_->AddUpdateDirectory(1, 0, "A", 10, 10); mock_server_->AddUpdateDirectory(2, 0, "B", 10, 10); mock_server_->set_conflict_all_commits(true); - SyncShareAsDelegate(); + SyncShareNudge(); { WriteTransaction wtrans(FROM_HERE, UNITTEST, directory()); @@ -2326,7 +2346,7 @@ TEST_F(EntryCreatedInNewFolderTest, EntryCreatedInNewFolderMidSync) { TEST_F(SyncerTest, NegativeIDInUpdate) { mock_server_->AddUpdateBookmark(-10, 0, "bad", 40, 40); - SyncShareAsDelegate(); + SyncShareNudge(); // The negative id would make us CHECK! } @@ -2342,7 +2362,7 @@ TEST_F(SyncerTest, UnappliedUpdateOnCreatedItemItemDoesNotCrash) { WriteTestDataToEntry(&trans, &fred_match); } // Commit it. - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(1u, mock_server_->committed_ids().size()); mock_server_->set_conflict_all_commits(true); syncable::Id fred_match_id; @@ -2358,7 +2378,7 @@ TEST_F(SyncerTest, UnappliedUpdateOnCreatedItemItemDoesNotCrash) { } // Run the syncer. for (int i = 0 ; i < 30 ; ++i) { - SyncShareAsDelegate(); + SyncShareNudge(); } } @@ -2421,7 +2441,7 @@ TEST_F(SyncerTest, CommitsUpdateDoesntAlterEntry) { entry.Put(syncable::MTIME, test_time); entry_metahandle = entry.Get(META_HANDLE); } - SyncShareAsDelegate(); + SyncShareNudge(); syncable::Id id; int64 version; int64 server_position_in_parent; @@ -2440,7 +2460,7 @@ TEST_F(SyncerTest, CommitsUpdateDoesntAlterEntry) { EXPECT_EQ(root_id_.GetServerId(), update->parent_id_string()); EXPECT_EQ(version, update->version()); EXPECT_EQ(server_position_in_parent, update->position_in_parent()); - SyncShareAsDelegate(); + SyncShareNudge(); { ReadTransaction trans(FROM_HERE, directory()); Entry entry(&trans, syncable::GET_BY_ID, id); @@ -2475,9 +2495,9 @@ TEST_F(SyncerTest, ParentAndChildBothMatch) { 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); - SyncShareAsDelegate(); - SyncShareAsDelegate(); - SyncShareAsDelegate(); + SyncShareNudge(); + SyncShareNudge(); + SyncShareNudge(); { ReadTransaction trans(FROM_HERE, directory()); Directory::ChildHandles children; @@ -2502,7 +2522,7 @@ TEST_F(SyncerTest, CommittingNewDeleted) { entry.Put(IS_UNSYNCED, true); entry.Put(IS_DEL, true); } - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(0u, mock_server_->committed_ids().size()); } @@ -2585,7 +2605,7 @@ TEST_F(SyncerTest, DeletingEntryWithLocalEdits) { int64 newfolder_metahandle; mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); - SyncShareAsDelegate(); + SyncShareNudge(); { WriteTransaction trans(FROM_HERE, UNITTEST, directory()); MutableEntry newfolder(&trans, CREATE, ids_.FromNumber(1), "local"); @@ -2608,10 +2628,10 @@ TEST_F(SyncerTest, DeletingEntryWithLocalEdits) { TEST_F(SyncerTest, FolderSwapUpdate) { mock_server_->AddUpdateDirectory(7801, 0, "bob", 1, 10); mock_server_->AddUpdateDirectory(1024, 0, "fred", 1, 10); - SyncShareAsDelegate(); + SyncShareNudge(); mock_server_->AddUpdateDirectory(1024, 0, "bob", 2, 20); mock_server_->AddUpdateDirectory(7801, 0, "fred", 2, 20); - SyncShareAsDelegate(); + SyncShareNudge(); { ReadTransaction trans(FROM_HERE, directory()); Entry id1(&trans, GET_BY_ID, ids_.FromNumber(7801)); @@ -2630,7 +2650,7 @@ TEST_F(SyncerTest, NameCollidingFolderSwapWorksFine) { mock_server_->AddUpdateDirectory(7801, 0, "bob", 1, 10); mock_server_->AddUpdateDirectory(1024, 0, "fred", 1, 10); mock_server_->AddUpdateDirectory(4096, 0, "alice", 1, 10); - SyncShareAsDelegate(); + SyncShareNudge(); { ReadTransaction trans(FROM_HERE, directory()); Entry id1(&trans, GET_BY_ID, ids_.FromNumber(7801)); @@ -2649,7 +2669,7 @@ TEST_F(SyncerTest, NameCollidingFolderSwapWorksFine) { mock_server_->AddUpdateDirectory(1024, 0, "bob", 2, 20); mock_server_->AddUpdateDirectory(7801, 0, "fred", 2, 20); mock_server_->AddUpdateDirectory(4096, 0, "bob", 2, 20); - SyncShareAsDelegate(); + SyncShareNudge(); { ReadTransaction trans(FROM_HERE, directory()); Entry id1(&trans, GET_BY_ID, ids_.FromNumber(7801)); @@ -2683,7 +2703,7 @@ TEST_F(SyncerTest, CommitManyItemsInOneGo) { } } uint32 num_loops = 0; - while (SyncShareAsDelegate()) { + while (SyncShareNudge()) { num_loops++; ASSERT_LT(num_loops, max_batches * 2); } @@ -2708,7 +2728,7 @@ TEST_F(SyncerTest, HugeConflict) { last_id = next_id; } } - SyncShareAsDelegate(); + SyncShareNudge(); // Check they're in the expected conflict state. { @@ -2725,7 +2745,7 @@ TEST_F(SyncerTest, HugeConflict) { // Add the missing parent directory. mock_server_->AddUpdateDirectory(parent_id, TestIdFactory::root(), "BOB", 2, 20); - SyncShareAsDelegate(); + SyncShareNudge(); // Now they should all be OK. { @@ -2741,7 +2761,7 @@ TEST_F(SyncerTest, HugeConflict) { TEST_F(SyncerTest, DontCrashOnCaseChange) { mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); - SyncShareAsDelegate(); + SyncShareNudge(); { WriteTransaction trans(FROM_HERE, UNITTEST, directory()); MutableEntry e(&trans, GET_BY_ID, ids_.FromNumber(1)); @@ -2750,22 +2770,22 @@ TEST_F(SyncerTest, DontCrashOnCaseChange) { } mock_server_->set_conflict_all_commits(true); mock_server_->AddUpdateDirectory(1, 0, "BOB", 2, 20); - SyncShareAsDelegate(); // USED TO CAUSE AN ASSERT + SyncShareNudge(); // USED TO CAUSE AN ASSERT saw_syncer_event_ = false; } TEST_F(SyncerTest, UnsyncedItemAndUpdate) { mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); - SyncShareAsDelegate(); + SyncShareNudge(); mock_server_->set_conflict_all_commits(true); mock_server_->AddUpdateDirectory(2, 0, "bob", 2, 20); - SyncShareAsDelegate(); // USED TO CAUSE AN ASSERT + SyncShareNudge(); // USED TO CAUSE AN ASSERT saw_syncer_event_ = false; } TEST_F(SyncerTest, NewEntryAndAlteredServerEntrySharePath) { mock_server_->AddUpdateBookmark(1, 0, "Foo.htm", 10, 10); - SyncShareAsDelegate(); + SyncShareNudge(); int64 local_folder_handle; syncable::Id local_folder_id; { @@ -2782,7 +2802,7 @@ TEST_F(SyncerTest, NewEntryAndAlteredServerEntrySharePath) { } mock_server_->AddUpdateBookmark(1, 0, "Bar.htm", 20, 20); mock_server_->set_conflict_all_commits(true); - SyncShareAsDelegate(); + SyncShareNudge(); saw_syncer_event_ = false; { // Update #20 should have been dropped in favor of the local version. @@ -2801,13 +2821,13 @@ TEST_F(SyncerTest, NewEntryAndAlteredServerEntrySharePath) { } // Allow local changes to commit. mock_server_->set_conflict_all_commits(false); - SyncShareAsDelegate(); + SyncShareNudge(); saw_syncer_event_ = false; // Now add a server change to make the two names equal. There should // be no conflict with that, since names are not unique. mock_server_->AddUpdateBookmark(1, 0, "Bar.htm", 30, 30); - SyncShareAsDelegate(); + SyncShareNudge(); saw_syncer_event_ = false; { WriteTransaction wtrans(FROM_HERE, UNITTEST, directory()); @@ -2831,7 +2851,7 @@ TEST_F(SyncerTest, NewEntryAndAlteredServerEntrySharePath) { TEST_F(SyncerTest, NewEntryAndAlteredServerEntrySharePath_OldBookmarksProto) { mock_server_->set_use_legacy_bookmarks_protocol(true); mock_server_->AddUpdateBookmark(1, 0, "Foo.htm", 10, 10); - SyncShareAsDelegate(); + SyncShareNudge(); int64 local_folder_handle; syncable::Id local_folder_id; { @@ -2848,7 +2868,7 @@ TEST_F(SyncerTest, NewEntryAndAlteredServerEntrySharePath_OldBookmarksProto) { } mock_server_->AddUpdateBookmark(1, 0, "Bar.htm", 20, 20); mock_server_->set_conflict_all_commits(true); - SyncShareAsDelegate(); + SyncShareNudge(); saw_syncer_event_ = false; { // Update #20 should have been dropped in favor of the local version. @@ -2867,13 +2887,13 @@ TEST_F(SyncerTest, NewEntryAndAlteredServerEntrySharePath_OldBookmarksProto) { } // Allow local changes to commit. mock_server_->set_conflict_all_commits(false); - SyncShareAsDelegate(); + SyncShareNudge(); saw_syncer_event_ = false; // Now add a server change to make the two names equal. There should // be no conflict with that, since names are not unique. mock_server_->AddUpdateBookmark(1, 0, "Bar.htm", 30, 30); - SyncShareAsDelegate(); + SyncShareNudge(); saw_syncer_event_ = false; { WriteTransaction wtrans(FROM_HERE, UNITTEST, directory()); @@ -2898,7 +2918,7 @@ TEST_F(SyncerTest, SiblingDirectoriesBecomeCircular) { // we don't currently resolve this. This test ensures we don't. mock_server_->AddUpdateDirectory(1, 0, "A", 10, 10); mock_server_->AddUpdateDirectory(2, 0, "B", 10, 10); - SyncShareAsDelegate(); + SyncShareNudge(); { WriteTransaction wtrans(FROM_HERE, UNITTEST, directory()); MutableEntry A(&wtrans, GET_BY_ID, ids_.FromNumber(1)); @@ -2909,7 +2929,7 @@ TEST_F(SyncerTest, SiblingDirectoriesBecomeCircular) { } mock_server_->AddUpdateDirectory(2, 1, "A", 20, 20); mock_server_->set_conflict_all_commits(true); - SyncShareAsDelegate(); + SyncShareNudge(); saw_syncer_event_ = false; { WriteTransaction wtrans(FROM_HERE, UNITTEST, directory()); @@ -2927,7 +2947,7 @@ TEST_F(SyncerTest, SwapEntryNames) { mock_server_->AddUpdateDirectory(1, 0, "A", 10, 10); mock_server_->AddUpdateDirectory(2, 0, "B", 10, 10); mock_server_->set_conflict_all_commits(true); - SyncShareAsDelegate(); + SyncShareNudge(); { WriteTransaction wtrans(FROM_HERE, UNITTEST, directory()); MutableEntry A(&wtrans, GET_BY_ID, ids_.FromNumber(1)); @@ -2940,7 +2960,7 @@ TEST_F(SyncerTest, SwapEntryNames) { ASSERT_TRUE(B.Put(NON_UNIQUE_NAME, "A")); ASSERT_TRUE(A.Put(NON_UNIQUE_NAME, "B")); } - SyncShareAsDelegate(); + SyncShareNudge(); saw_syncer_event_ = false; } @@ -2948,7 +2968,7 @@ TEST_F(SyncerTest, DualDeletionWithNewItemNameClash) { mock_server_->AddUpdateDirectory(1, 0, "A", 10, 10); mock_server_->AddUpdateBookmark(2, 0, "B", 10, 10); mock_server_->set_conflict_all_commits(true); - SyncShareAsDelegate(); + SyncShareNudge(); { WriteTransaction trans(FROM_HERE, UNITTEST, directory()); MutableEntry B(&trans, GET_BY_ID, ids_.FromNumber(2)); @@ -2958,7 +2978,7 @@ TEST_F(SyncerTest, DualDeletionWithNewItemNameClash) { } mock_server_->AddUpdateBookmark(2, 0, "A", 11, 11); mock_server_->SetLastUpdateDeleted(); - SyncShareAsDelegate(); + SyncShareNudge(); { ReadTransaction trans(FROM_HERE, directory()); Entry B(&trans, GET_BY_ID, ids_.FromNumber(2)); @@ -2973,7 +2993,7 @@ TEST_F(SyncerTest, ResolveWeWroteTheyDeleted) { int64 bob_metahandle; mock_server_->AddUpdateBookmark(1, 0, "bob", 1, 10); - SyncShareAsDelegate(); + SyncShareNudge(); { WriteTransaction trans(FROM_HERE, UNITTEST, directory()); MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); @@ -2984,8 +3004,8 @@ TEST_F(SyncerTest, ResolveWeWroteTheyDeleted) { mock_server_->AddUpdateBookmark(1, 0, "bob", 2, 10); mock_server_->SetLastUpdateDeleted(); mock_server_->set_conflict_all_commits(true); - SyncShareAsDelegate(); - SyncShareAsDelegate(); + SyncShareNudge(); + SyncShareNudge(); { ReadTransaction trans(FROM_HERE, directory()); Entry bob(&trans, GET_BY_HANDLE, bob_metahandle); @@ -3019,16 +3039,16 @@ TEST_F(SyncerTest, DuplicateIDReturn) { mock_server_->set_next_new_id(10000); EXPECT_EQ(1u, directory()->unsynced_entity_count()); // we get back a bad id in here (should never happen). - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(1u, directory()->unsynced_entity_count()); - SyncShareAsDelegate(); // another bad id in here. + SyncShareNudge(); // another bad id in here. EXPECT_EQ(0u, directory()->unsynced_entity_count()); saw_syncer_event_ = false; } TEST_F(SyncerTest, DeletedEntryWithBadParentInLoopCalculation) { mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); - SyncShareAsDelegate(); + SyncShareNudge(); { WriteTransaction trans(FROM_HERE, UNITTEST, directory()); MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); @@ -3039,8 +3059,8 @@ TEST_F(SyncerTest, DeletedEntryWithBadParentInLoopCalculation) { bob.Put(IS_UNSYNCED, true); } mock_server_->AddUpdateDirectory(2, 1, "fred", 1, 10); - SyncShareAsDelegate(); - SyncShareAsDelegate(); + SyncShareNudge(); + SyncShareNudge(); } TEST_F(SyncerTest, ConflictResolverMergesLocalDeleteAndServerUpdate) { @@ -3060,7 +3080,7 @@ TEST_F(SyncerTest, ConflictResolverMergesLocalDeleteAndServerUpdate) { // We don't care about actually committing, just the resolution. mock_server_->set_conflict_all_commits(true); - SyncShareAsDelegate(); + SyncShareNudge(); { ReadTransaction trans(FROM_HERE, directory()); @@ -3096,7 +3116,7 @@ TEST_F(SyncerTest, UpdateFlipsTheFolderBit) { mock_server_->set_conflict_all_commits(true); // The syncer should not attempt to apply the invalid update. - SyncShareAsDelegate(); + SyncShareNudge(); { ReadTransaction trans(FROM_HERE, directory()); @@ -3115,7 +3135,7 @@ TEST_F(SyncerTest, UpdateFlipsTheFolderBit) { TEST_F(SyncerTest, MergingExistingItems) { mock_server_->set_conflict_all_commits(true); mock_server_->AddUpdateBookmark(1, 0, "base", 10, 10); - SyncShareAsDelegate(); + SyncShareNudge(); { WriteTransaction trans(FROM_HERE, UNITTEST, directory()); MutableEntry entry(&trans, CREATE, trans.root_id(), "Copy of base"); @@ -3183,7 +3203,7 @@ TEST_F(SyncerTest, DontMergeTwoExistingItems) { mock_server_->set_conflict_all_commits(true); mock_server_->AddUpdateBookmark(1, 0, "base", 10, 10); mock_server_->AddUpdateBookmark(2, 0, "base2", 10, 10); - SyncShareAsDelegate(); + SyncShareNudge(); { WriteTransaction trans(FROM_HERE, UNITTEST, directory()); MutableEntry entry(&trans, GET_BY_ID, ids_.FromNumber(2)); @@ -3211,10 +3231,10 @@ TEST_F(SyncerTest, TestUndeleteUpdate) { mock_server_->set_conflict_all_commits(true); mock_server_->AddUpdateDirectory(1, 0, "foo", 1, 1); mock_server_->AddUpdateDirectory(2, 1, "bar", 1, 2); - SyncShareAsDelegate(); + SyncShareNudge(); mock_server_->AddUpdateDirectory(2, 1, "bar", 2, 3); mock_server_->SetLastUpdateDeleted(); - SyncShareAsDelegate(); + SyncShareNudge(); int64 metahandle; { @@ -3226,11 +3246,11 @@ TEST_F(SyncerTest, TestUndeleteUpdate) { } mock_server_->AddUpdateDirectory(1, 0, "foo", 2, 4); mock_server_->SetLastUpdateDeleted(); - SyncShareAsDelegate(); + SyncShareNudge(); // This used to be rejected as it's an undeletion. Now, it results in moving // the delete path aside. mock_server_->AddUpdateDirectory(2, 1, "bar", 3, 5); - SyncShareAsDelegate(); + SyncShareNudge(); { ReadTransaction trans(FROM_HERE, directory()); Entry entry(&trans, GET_BY_ID, ids_.FromNumber(2)); @@ -3245,7 +3265,7 @@ TEST_F(SyncerTest, TestUndeleteUpdate) { TEST_F(SyncerTest, TestMoveSanitizedNamedFolder) { mock_server_->AddUpdateDirectory(1, 0, "foo", 1, 1); mock_server_->AddUpdateDirectory(2, 0, ":::", 1, 2); - SyncShareAsDelegate(); + SyncShareNudge(); { WriteTransaction trans(FROM_HERE, UNITTEST, directory()); MutableEntry entry(&trans, GET_BY_ID, ids_.FromNumber(2)); @@ -3253,10 +3273,10 @@ TEST_F(SyncerTest, TestMoveSanitizedNamedFolder) { EXPECT_TRUE(entry.Put(PARENT_ID, ids_.FromNumber(1))); EXPECT_TRUE(entry.Put(IS_UNSYNCED, true)); } - SyncShareAsDelegate(); + SyncShareNudge(); // We use the same sync ts as before so our times match up. mock_server_->AddUpdateDirectory(2, 1, ":::", 2, 2); - SyncShareAsDelegate(); + SyncShareNudge(); } // Don't crash when this occurs. @@ -3264,7 +3284,7 @@ TEST_F(SyncerTest, UpdateWhereParentIsNotAFolder) { mock_server_->AddUpdateBookmark(1, 0, "B", 10, 10); mock_server_->AddUpdateDirectory(2, 1, "BookmarkParent", 10, 10); // Used to cause a CHECK - SyncShareAsDelegate(); + SyncShareNudge(); { ReadTransaction rtrans(FROM_HERE, directory()); Entry good_entry(&rtrans, syncable::GET_BY_ID, ids_.FromNumber(1)); @@ -3286,7 +3306,7 @@ TEST_F(SyncerTest, DirectoryUpdateTest) { "in_root_name", 2, 2); mock_server_->AddUpdateDirectory(in_in_root_id, in_root_id, "in_in_root_name", 3, 3); - SyncShareAsDelegate(); + SyncShareNudge(); { ReadTransaction trans(FROM_HERE, directory()); Entry in_root(&trans, GET_BY_ID, in_root_id); @@ -3324,7 +3344,7 @@ TEST_F(SyncerTest, DirectoryCommitTest) { bar_metahandle = child.Get(META_HANDLE); in_dir_id = parent.Get(syncable::ID); } - SyncShareAsDelegate(); + SyncShareNudge(); { ReadTransaction trans(FROM_HERE, directory()); Entry fail_by_old_id_entry(&trans, GET_BY_ID, in_root_id); @@ -3351,7 +3371,7 @@ TEST_F(SyncerTest, TestClientCommand) { command->set_set_sync_long_poll_interval(800); command->set_sessions_commit_delay_seconds(3141); mock_server_->AddUpdateDirectory(1, 0, "in_root", 1, 1); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_TRUE(TimeDelta::FromSeconds(8) == last_short_poll_interval_received_); @@ -3365,7 +3385,7 @@ TEST_F(SyncerTest, TestClientCommand) { command->set_set_sync_long_poll_interval(190); command->set_sessions_commit_delay_seconds(2718); mock_server_->AddUpdateDirectory(1, 0, "in_root", 1, 1); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_TRUE(TimeDelta::FromSeconds(180) == last_short_poll_interval_received_); @@ -3383,7 +3403,7 @@ TEST_F(SyncerTest, EnsureWeSendUpOldParent) { "folder_one", 1, 1); mock_server_->AddUpdateDirectory(folder_two_id, TestIdFactory::root(), "folder_two", 1, 1); - SyncShareAsDelegate(); + SyncShareNudge(); { // A moved entry should send an "old parent." WriteTransaction trans(FROM_HERE, UNITTEST, directory()); @@ -3396,7 +3416,7 @@ TEST_F(SyncerTest, EnsureWeSendUpOldParent) { create.Put(IS_UNSYNCED, true); create.Put(SPECIFICS, DefaultBookmarkSpecifics()); } - SyncShareAsDelegate(); + SyncShareNudge(); const sync_pb::CommitMessage& commit = mock_server_->last_sent_commit(); ASSERT_EQ(2, commit.entries_size()); EXPECT_TRUE(commit.entries(0).parent_id_string() == "2"); @@ -3431,7 +3451,7 @@ TEST_F(SyncerTest, TestSimpleUndelete) { mock_server_->set_conflict_all_commits(true); // Let there be an entry from the server. mock_server_->AddUpdateBookmark(id, root, "foo", 1, 10); - SyncShareAsDelegate(); + SyncShareNudge(); // Check it out and delete it. { WriteTransaction wtrans(FROM_HERE, UNITTEST, directory()); @@ -3443,7 +3463,7 @@ TEST_F(SyncerTest, TestSimpleUndelete) { // Delete it locally. entry.Put(IS_DEL, true); } - SyncShareAsDelegate(); + SyncShareNudge(); // Confirm we see IS_DEL and not SERVER_IS_DEL. { ReadTransaction trans(FROM_HERE, directory()); @@ -3454,11 +3474,11 @@ TEST_F(SyncerTest, TestSimpleUndelete) { EXPECT_TRUE(entry.Get(IS_DEL)); EXPECT_FALSE(entry.Get(SERVER_IS_DEL)); } - SyncShareAsDelegate(); + SyncShareNudge(); // Update from server confirming deletion. mock_server_->AddUpdateBookmark(id, root, "foo", 2, 11); mock_server_->SetLastUpdateDeleted(); - SyncShareAsDelegate(); + SyncShareNudge(); // IS_DEL AND SERVER_IS_DEL now both true. { ReadTransaction trans(FROM_HERE, directory()); @@ -3471,7 +3491,7 @@ TEST_F(SyncerTest, TestSimpleUndelete) { } // Undelete from server. mock_server_->AddUpdateBookmark(id, root, "foo", 2, 12); - SyncShareAsDelegate(); + SyncShareNudge(); // IS_DEL and SERVER_IS_DEL now both false. { ReadTransaction trans(FROM_HERE, directory()); @@ -3489,7 +3509,7 @@ TEST_F(SyncerTest, TestUndeleteWithMissingDeleteUpdate) { // Let there be a entry, from the server. mock_server_->set_conflict_all_commits(true); mock_server_->AddUpdateBookmark(id, root, "foo", 1, 10); - SyncShareAsDelegate(); + SyncShareNudge(); // Check it out and delete it. { WriteTransaction wtrans(FROM_HERE, UNITTEST, directory()); @@ -3501,7 +3521,7 @@ TEST_F(SyncerTest, TestUndeleteWithMissingDeleteUpdate) { // Delete it locally. entry.Put(IS_DEL, true); } - SyncShareAsDelegate(); + SyncShareNudge(); // Confirm we see IS_DEL and not SERVER_IS_DEL. { ReadTransaction trans(FROM_HERE, directory()); @@ -3512,11 +3532,11 @@ TEST_F(SyncerTest, TestUndeleteWithMissingDeleteUpdate) { EXPECT_TRUE(entry.Get(IS_DEL)); EXPECT_FALSE(entry.Get(SERVER_IS_DEL)); } - SyncShareAsDelegate(); + SyncShareNudge(); // Say we do not get an update from server confirming deletion. Undelete // from server mock_server_->AddUpdateBookmark(id, root, "foo", 2, 12); - SyncShareAsDelegate(); + SyncShareNudge(); // IS_DEL and SERVER_IS_DEL now both false. { ReadTransaction trans(FROM_HERE, directory()); @@ -3536,16 +3556,16 @@ TEST_F(SyncerTest, TestUndeleteIgnoreCorrectlyUnappliedUpdate) { mock_server_->set_conflict_all_commits(true); mock_server_->AddUpdateBookmark(id1, root, "foo", 1, 10); mock_server_->AddUpdateBookmark(id2, root, "foo", 1, 10); - SyncShareAsDelegate(); + SyncShareNudge(); mock_server_->AddUpdateBookmark(id2, root, "foo2", 2, 20); - SyncShareAsDelegate(); // Now just don't explode. + SyncShareNudge(); // Now just don't explode. } TEST_F(SyncerTest, ClientTagServerCreatedUpdatesWork) { mock_server_->AddUpdateDirectory(1, 0, "permitem1", 1, 10); mock_server_->SetLastUpdateClientTag("permfolder"); - SyncShareAsDelegate(); + SyncShareNudge(); { ReadTransaction trans(FROM_HERE, directory()); @@ -3560,7 +3580,7 @@ TEST_F(SyncerTest, ClientTagServerCreatedUpdatesWork) { mock_server_->AddUpdateDirectory(1, 0, "permitem_renamed", 10, 100); mock_server_->SetLastUpdateClientTag("permfolder"); - SyncShareAsDelegate(); + SyncShareNudge(); { ReadTransaction trans(FROM_HERE, directory()); @@ -3579,7 +3599,7 @@ TEST_F(SyncerTest, ClientTagIllegalUpdateIgnored) { mock_server_->AddUpdateDirectory(1, 0, "permitem1", 1, 10); mock_server_->SetLastUpdateClientTag("permfolder"); - SyncShareAsDelegate(); + SyncShareNudge(); { ReadTransaction trans(FROM_HERE, directory()); @@ -3594,7 +3614,7 @@ TEST_F(SyncerTest, ClientTagIllegalUpdateIgnored) { mock_server_->AddUpdateDirectory(1, 0, "permitem_renamed", 10, 100); mock_server_->SetLastUpdateClientTag("wrongtag"); - SyncShareAsDelegate(); + SyncShareNudge(); { ReadTransaction trans(FROM_HERE, directory()); @@ -3639,7 +3659,7 @@ TEST_F(SyncerTest, ClientTagUncommittedTagMatchesUpdate) { CopyFrom(server_bookmark); mock_server_->set_conflict_all_commits(true); - SyncShareAsDelegate(); + SyncShareNudge(); // This should cause client tag reunion, preserving the metahandle. { ReadTransaction trans(FROM_HERE, directory()); @@ -3661,7 +3681,7 @@ TEST_F(SyncerTest, ClientTagUncommittedTagMatchesUpdate) { } mock_server_->set_conflict_all_commits(false); - SyncShareAsDelegate(); + SyncShareNudge(); // The resolved entry ought to commit cleanly. { @@ -3700,7 +3720,7 @@ TEST_F(SyncerTest, ClientTagConflictWithDeletedLocalEntry) { mock_server_->SetLastUpdateClientTag("clientperm"); mock_server_->set_conflict_all_commits(true); - SyncShareAsDelegate(); + SyncShareNudge(); // This should cause client tag overwrite. { ReadTransaction trans(FROM_HERE, directory()); @@ -3729,7 +3749,7 @@ TEST_F(SyncerTest, ClientTagUpdateClashesWithLocalEntry) { mock_server_->set_conflict_all_commits(true); - SyncShareAsDelegate(); + SyncShareNudge(); int64 tag1_metahandle = syncable::kInvalidMetaHandle; int64 tag2_metahandle = syncable::kInvalidMetaHandle; // This should cause client tag overwrite. @@ -3769,7 +3789,7 @@ TEST_F(SyncerTest, ClientTagUpdateClashesWithLocalEntry) { mock_server_->SetLastUpdateClientTag("tag1"); mock_server_->AddUpdateBookmark(3, 0, "Three", 13, 130); mock_server_->SetLastUpdateClientTag("tag2"); - SyncShareAsDelegate(); + SyncShareNudge(); { ReadTransaction trans(FROM_HERE, directory()); @@ -3841,7 +3861,7 @@ TEST_F(SyncerTest, ClientTagClashWithinBatchOfUpdates) { mock_server_->set_conflict_all_commits(true); - SyncShareAsDelegate(); + SyncShareNudge(); // This should cause client tag overwrite. { ReadTransaction trans(FROM_HERE, directory()); @@ -3909,7 +3929,7 @@ TEST_F(SyncerTest, UniqueServerTagUpdates) { mock_server_->SetLastUpdateServerTag("alpha"); mock_server_->AddUpdateDirectory(2, 0, "update2", 2, 20); mock_server_->SetLastUpdateServerTag("bob"); - SyncShareAsDelegate(); + SyncShareNudge(); { ReadTransaction trans(FROM_HERE, directory()); @@ -3940,31 +3960,154 @@ TEST_F(SyncerTest, GetUpdatesSetsRequestedTypes) { // GetUpdates handler. EnableDatatype sets the expectation value from our // set of enabled/disabled datatypes. EnableDatatype(syncable::BOOKMARKS); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); EnableDatatype(syncable::AUTOFILL); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); EnableDatatype(syncable::PREFERENCES); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); DisableDatatype(syncable::BOOKMARKS); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); DisableDatatype(syncable::AUTOFILL); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); DisableDatatype(syncable::PREFERENCES); EnableDatatype(syncable::AUTOFILL); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); } +// A typical scenario: server and client each have one update for the other. +// This is the "happy path" alternative to UpdateFailsThenDontCommit. +TEST_F(SyncerTest, UpdateThenCommit) { + syncable::Id to_receive = ids_.NewServerId(); + syncable::Id to_commit = ids_.NewLocalId(); + + mock_server_->AddUpdateDirectory(to_receive, ids_.root(), "x", 1, 10); + int64 commit_handle = CreateUnsyncedDirectory("y", to_commit); + SyncShareNudge(); + + ReadTransaction trans(FROM_HERE, directory()); + + Entry received(&trans, GET_BY_ID, to_receive); + ASSERT_TRUE(received.good()); + EXPECT_FALSE(received.Get(IS_UNSYNCED)); + EXPECT_FALSE(received.Get(IS_UNAPPLIED_UPDATE)); + + Entry committed(&trans, GET_BY_HANDLE, commit_handle); + ASSERT_TRUE(committed.good()); + EXPECT_FALSE(committed.Get(IS_UNSYNCED)); + EXPECT_FALSE(committed.Get(IS_UNAPPLIED_UPDATE)); +} + +// Same as above, but this time we fail to download updates. +// We should not attempt to commit anything unless we successfully downloaded +// updates, otherwise we risk causing a server-side conflict. +TEST_F(SyncerTest, UpdateFailsThenDontCommit) { + syncable::Id to_receive = ids_.NewServerId(); + syncable::Id to_commit = ids_.NewLocalId(); + + mock_server_->AddUpdateDirectory(to_receive, ids_.root(), "x", 1, 10); + int64 commit_handle = CreateUnsyncedDirectory("y", to_commit); + mock_server_->FailNextPostBufferToPathCall(); + SyncShareNudge(); + + ReadTransaction trans(FROM_HERE, directory()); + + // We did not receive this update. + Entry received(&trans, GET_BY_ID, to_receive); + ASSERT_FALSE(received.good()); + + // And our local update remains unapplied. + Entry committed(&trans, GET_BY_HANDLE, commit_handle); + ASSERT_TRUE(committed.good()); + EXPECT_TRUE(committed.Get(IS_UNSYNCED)); + EXPECT_FALSE(committed.Get(IS_UNAPPLIED_UPDATE)); + + // Inform the Mock we won't be fetching all updates. + mock_server_->ClearUpdatesQueue(); +} + +// Downloads two updates and applies them successfully. +// This is the "happy path" alternative to ConfigureFailsDontApplyUpdates. +TEST_F(SyncerTest, ConfigureDownloadsTwoBatchesSuccess) { + EXPECT_FALSE(initial_sync_ended_for_type(syncable::BOOKMARKS)); + + syncable::Id node1 = ids_.NewServerId(); + syncable::Id node2 = ids_.NewServerId(); + + // Construct the first GetUpdates response. + mock_server_->AddUpdateDirectory(node1, ids_.root(), "one", 1, 10); + mock_server_->SetChangesRemaining(1); + mock_server_->NextUpdateBatch(); + + // Construct the second GetUpdates response. + mock_server_->AddUpdateDirectory(node2, ids_.root(), "two", 1, 20); + + SyncShareConfigure(); + + ReadTransaction trans(FROM_HERE, directory()); + // Both nodes should be downloaded and applied. + + Entry n1(&trans, GET_BY_ID, node1); + ASSERT_TRUE(n1.good()); + EXPECT_FALSE(n1.Get(IS_UNAPPLIED_UPDATE)); + + Entry n2(&trans, GET_BY_ID, node2); + ASSERT_TRUE(n2.good()); + EXPECT_FALSE(n2.Get(IS_UNAPPLIED_UPDATE)); + + EXPECT_TRUE(initial_sync_ended_for_type(syncable::BOOKMARKS)); +} + +// Same as the above case, but this time the second batch fails to download. +TEST_F(SyncerTest, ConfigureFailsDontApplyUpdates) { + EXPECT_FALSE(initial_sync_ended_for_type(syncable::BOOKMARKS)); + + syncable::Id node1 = ids_.NewServerId(); + syncable::Id node2 = ids_.NewServerId(); + + // The scenario: we have two batches of updates with one update each. A + // normal confgure step would download all the updates one batch at a time and + // apply them. This configure will succeed in downloading the first batch + // then fail when downloading the second. + mock_server_->FailNthPostBufferToPathCall(2); + + // Construct the first GetUpdates response. + mock_server_->AddUpdateDirectory(node1, ids_.root(), "one", 1, 10); + mock_server_->SetChangesRemaining(1); + mock_server_->NextUpdateBatch(); + + // Consutrct the second GetUpdates response. + mock_server_->AddUpdateDirectory(node2, ids_.root(), "two", 1, 20); + + SyncShareConfigure(); + + ReadTransaction trans(FROM_HERE, directory()); + + // The first node was downloaded, but not applied. + Entry n1(&trans, GET_BY_ID, node1); + ASSERT_TRUE(n1.good()); + EXPECT_TRUE(n1.Get(IS_UNAPPLIED_UPDATE)); + + // The second node was not downloaded. + Entry n2(&trans, GET_BY_ID, node2); + EXPECT_FALSE(n2.good()); + + // One update remains undownloaded. + mock_server_->ClearUpdatesQueue(); + + EXPECT_FALSE(initial_sync_ended_for_type(syncable::BOOKMARKS)); +} + // Test what happens if a client deletes, then recreates, an object very // quickly. It is possible that the deletion gets sent as a commit, and // the undelete happens during the commit request. The principle here @@ -4102,7 +4245,7 @@ class SyncerUndeletionTest : public SyncerTest { TEST_F(SyncerUndeletionTest, UndeleteDuringCommit) { Create(); ExpectUnsyncedCreation(); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); @@ -4113,7 +4256,7 @@ TEST_F(SyncerUndeletionTest, UndeleteDuringCommit) { ExpectUnsyncedDeletion(); mock_server_->SetMidCommitCallback( base::Bind(&SyncerUndeletionTest::Undelete, base::Unretained(this))); - SyncShareAsDelegate(); + SyncShareNudge(); // The item ought to exist as an unsynced undeletion (meaning, // we think that the next commit ought to be a recreation commit). @@ -4127,7 +4270,7 @@ TEST_F(SyncerUndeletionTest, UndeleteDuringCommit) { // normal to recieve updates from our own commits. mock_server_->SetMidCommitCallback(base::Closure()); mock_server_->AddUpdateTombstone(Get(metahandle_, ID)); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); ExpectSyncedAndCreated(); @@ -4136,7 +4279,7 @@ TEST_F(SyncerUndeletionTest, UndeleteDuringCommit) { TEST_F(SyncerUndeletionTest, UndeleteBeforeCommit) { Create(); ExpectUnsyncedCreation(); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); @@ -4147,7 +4290,7 @@ TEST_F(SyncerUndeletionTest, UndeleteBeforeCommit) { ExpectUnsyncedDeletion(); Undelete(); ExpectUnsyncedEdit(); // Edit, not undelete: server thinks it exists. - SyncShareAsDelegate(); + SyncShareNudge(); // The item ought to have committed successfully. EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); @@ -4158,7 +4301,7 @@ TEST_F(SyncerUndeletionTest, UndeleteBeforeCommit) { // Now, encounter a GetUpdates corresponding to the just-committed // update. mock_server_->AddUpdateFromLastCommit(); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); ExpectSyncedAndCreated(); @@ -4167,7 +4310,7 @@ TEST_F(SyncerUndeletionTest, UndeleteBeforeCommit) { TEST_F(SyncerUndeletionTest, UndeleteAfterCommitButBeforeGetUpdates) { Create(); ExpectUnsyncedCreation(); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); @@ -4176,7 +4319,7 @@ TEST_F(SyncerUndeletionTest, UndeleteAfterCommitButBeforeGetUpdates) { // Delete and commit. Delete(); ExpectUnsyncedDeletion(); - SyncShareAsDelegate(); + SyncShareNudge(); // The item ought to have committed successfully. EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); @@ -4190,7 +4333,7 @@ TEST_F(SyncerUndeletionTest, UndeleteAfterCommitButBeforeGetUpdates) { // Now, encounter a GetUpdates corresponding to the just-committed // deletion update. The undeletion should prevail. mock_server_->AddUpdateFromLastCommit(); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); ExpectSyncedAndCreated(); @@ -4199,14 +4342,14 @@ TEST_F(SyncerUndeletionTest, UndeleteAfterCommitButBeforeGetUpdates) { TEST_F(SyncerUndeletionTest, UndeleteAfterDeleteAndGetUpdates) { Create(); ExpectUnsyncedCreation(); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); ExpectSyncedAndCreated(); mock_server_->AddUpdateFromLastCommit(); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); ExpectSyncedAndCreated(); @@ -4214,7 +4357,7 @@ TEST_F(SyncerUndeletionTest, UndeleteAfterDeleteAndGetUpdates) { // Delete and commit. Delete(); ExpectUnsyncedDeletion(); - SyncShareAsDelegate(); + SyncShareNudge(); // The item ought to have committed successfully. EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); @@ -4224,7 +4367,7 @@ TEST_F(SyncerUndeletionTest, UndeleteAfterDeleteAndGetUpdates) { // Now, encounter a GetUpdates corresponding to the just-committed // deletion update. Should be consistent. mock_server_->AddUpdateFromLastCommit(); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); ExpectSyncedAndDeleted(); @@ -4235,7 +4378,7 @@ TEST_F(SyncerUndeletionTest, UndeleteAfterDeleteAndGetUpdates) { // Now, encounter a GetUpdates corresponding to the just-committed // deletion update. The undeletion should prevail. - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); ExpectSyncedAndCreated(); @@ -4245,7 +4388,7 @@ TEST_F(SyncerUndeletionTest, UndeleteAfterDeleteAndGetUpdates) { TEST_F(SyncerUndeletionTest, UndeleteAfterOtherClientDeletes) { Create(); ExpectUnsyncedCreation(); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); @@ -4253,14 +4396,14 @@ TEST_F(SyncerUndeletionTest, UndeleteAfterOtherClientDeletes) { // Add a delete from the server. mock_server_->AddUpdateFromLastCommit(); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); ExpectSyncedAndCreated(); // Some other client deletes the item. mock_server_->AddUpdateTombstone(Get(metahandle_, ID)); - SyncShareAsDelegate(); + SyncShareNudge(); // The update ought to have applied successfully. EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); @@ -4270,7 +4413,7 @@ TEST_F(SyncerUndeletionTest, UndeleteAfterOtherClientDeletes) { // Undelete it locally. Undelete(); ExpectUnsyncedUndeletion(); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); ExpectSyncedAndCreated(); @@ -4278,7 +4421,7 @@ TEST_F(SyncerUndeletionTest, UndeleteAfterOtherClientDeletes) { // Now, encounter a GetUpdates corresponding to the just-committed // deletion update. The undeletion should prevail. mock_server_->AddUpdateFromLastCommit(); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); ExpectSyncedAndCreated(); @@ -4287,7 +4430,7 @@ TEST_F(SyncerUndeletionTest, UndeleteAfterOtherClientDeletes) { TEST_F(SyncerUndeletionTest, UndeleteAfterOtherClientDeletesImmediately) { Create(); ExpectUnsyncedCreation(); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); @@ -4296,7 +4439,7 @@ TEST_F(SyncerUndeletionTest, UndeleteAfterOtherClientDeletesImmediately) { // Some other client deletes the item before we get a chance // to GetUpdates our original request. mock_server_->AddUpdateTombstone(Get(metahandle_, ID)); - SyncShareAsDelegate(); + SyncShareNudge(); // The update ought to have applied successfully. EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); @@ -4306,7 +4449,7 @@ TEST_F(SyncerUndeletionTest, UndeleteAfterOtherClientDeletesImmediately) { // Undelete it locally. Undelete(); ExpectUnsyncedUndeletion(); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); ExpectSyncedAndCreated(); @@ -4314,7 +4457,7 @@ TEST_F(SyncerUndeletionTest, UndeleteAfterOtherClientDeletesImmediately) { // Now, encounter a GetUpdates corresponding to the just-committed // deletion update. The undeletion should prevail. mock_server_->AddUpdateFromLastCommit(); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); ExpectSyncedAndCreated(); @@ -4323,7 +4466,7 @@ TEST_F(SyncerUndeletionTest, UndeleteAfterOtherClientDeletesImmediately) { TEST_F(SyncerUndeletionTest, OtherClientUndeletes) { Create(); ExpectUnsyncedCreation(); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); @@ -4331,7 +4474,7 @@ TEST_F(SyncerUndeletionTest, OtherClientUndeletes) { // Get the updates of our just-committed entry. mock_server_->AddUpdateFromLastCommit(); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); ExpectSyncedAndCreated(); @@ -4339,7 +4482,7 @@ TEST_F(SyncerUndeletionTest, OtherClientUndeletes) { // We delete the item. Delete(); ExpectUnsyncedDeletion(); - SyncShareAsDelegate(); + SyncShareNudge(); // The update ought to have applied successfully. EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); @@ -4349,7 +4492,7 @@ TEST_F(SyncerUndeletionTest, OtherClientUndeletes) { // Now, encounter a GetUpdates corresponding to the just-committed // deletion update. mock_server_->AddUpdateFromLastCommit(); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); ExpectSyncedAndDeleted(); @@ -4359,7 +4502,7 @@ TEST_F(SyncerUndeletionTest, OtherClientUndeletes) { Get(metahandle_, PARENT_ID), "Thadeusz", 100, 1000); mock_server_->SetLastUpdateClientTag(client_tag_); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); ExpectSyncedAndCreated(); @@ -4369,7 +4512,7 @@ TEST_F(SyncerUndeletionTest, OtherClientUndeletes) { TEST_F(SyncerUndeletionTest, OtherClientUndeletesImmediately) { Create(); ExpectUnsyncedCreation(); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); @@ -4377,7 +4520,7 @@ TEST_F(SyncerUndeletionTest, OtherClientUndeletesImmediately) { // Get the updates of our just-committed entry. mock_server_->AddUpdateFromLastCommit(); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); ExpectSyncedAndCreated(); @@ -4385,7 +4528,7 @@ TEST_F(SyncerUndeletionTest, OtherClientUndeletesImmediately) { // We delete the item. Delete(); ExpectUnsyncedDeletion(); - SyncShareAsDelegate(); + SyncShareNudge(); // The update ought to have applied successfully. EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); @@ -4398,7 +4541,7 @@ TEST_F(SyncerUndeletionTest, OtherClientUndeletesImmediately) { Get(metahandle_, PARENT_ID), "Thadeusz", 100, 1000); mock_server_->SetLastUpdateClientTag(client_tag_); - SyncShareAsDelegate(); + SyncShareNudge(); EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems()); EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); ExpectSyncedAndCreated(); @@ -4463,7 +4606,7 @@ TEST_F(SyncerPositionUpdateTest, InOrderPositive) { AddRootItemWithPosition(201); AddRootItemWithPosition(400); - SyncShareAsDelegate(); + SyncShareNudge(); ExpectLocalItemsInServerOrder(); } @@ -4475,7 +4618,7 @@ TEST_F(SyncerPositionUpdateTest, InOrderNegative) { AddRootItemWithPosition(-150); AddRootItemWithPosition(100); - SyncShareAsDelegate(); + SyncShareNudge(); ExpectLocalItemsInServerOrder(); } @@ -4490,7 +4633,7 @@ TEST_F(SyncerPositionUpdateTest, ReverseOrder) { AddRootItemWithPosition(-200); AddRootItemWithPosition(-400); - SyncShareAsDelegate(); + SyncShareNudge(); ExpectLocalItemsInServerOrder(); } @@ -4502,7 +4645,7 @@ TEST_F(SyncerPositionUpdateTest, RandomOrderInBatches) { AddRootItemWithPosition(-400); AddRootItemWithPosition(100); - SyncShareAsDelegate(); + SyncShareNudge(); ExpectLocalItemsInServerOrder(); AddRootItemWithPosition(-150); @@ -4510,12 +4653,12 @@ TEST_F(SyncerPositionUpdateTest, RandomOrderInBatches) { AddRootItemWithPosition(200); AddRootItemWithPosition(-201); - SyncShareAsDelegate(); + SyncShareNudge(); ExpectLocalItemsInServerOrder(); AddRootItemWithPosition(-144); - SyncShareAsDelegate(); + SyncShareNudge(); ExpectLocalItemsInServerOrder(); } @@ -4575,7 +4718,7 @@ TEST_F(SyncerPositionTiebreakingTest, LowMidHigh) { Add(low_id_); Add(mid_id_); Add(high_id_); - SyncShareAsDelegate(); + SyncShareNudge(); ExpectLocalOrderIsByServerId(); } @@ -4583,7 +4726,7 @@ TEST_F(SyncerPositionTiebreakingTest, LowHighMid) { Add(low_id_); Add(high_id_); Add(mid_id_); - SyncShareAsDelegate(); + SyncShareNudge(); ExpectLocalOrderIsByServerId(); } @@ -4591,7 +4734,7 @@ TEST_F(SyncerPositionTiebreakingTest, HighMidLow) { Add(high_id_); Add(mid_id_); Add(low_id_); - SyncShareAsDelegate(); + SyncShareNudge(); ExpectLocalOrderIsByServerId(); } @@ -4599,7 +4742,7 @@ TEST_F(SyncerPositionTiebreakingTest, HighLowMid) { Add(high_id_); Add(low_id_); Add(mid_id_); - SyncShareAsDelegate(); + SyncShareNudge(); ExpectLocalOrderIsByServerId(); } @@ -4607,7 +4750,7 @@ TEST_F(SyncerPositionTiebreakingTest, MidHighLow) { Add(mid_id_); Add(high_id_); Add(low_id_); - SyncShareAsDelegate(); + SyncShareNudge(); ExpectLocalOrderIsByServerId(); } @@ -4615,7 +4758,7 @@ TEST_F(SyncerPositionTiebreakingTest, MidLowHigh) { Add(mid_id_); Add(low_id_); Add(high_id_); - SyncShareAsDelegate(); + SyncShareNudge(); ExpectLocalOrderIsByServerId(); } diff --git a/sync/sessions/status_controller.h b/sync/sessions/status_controller.h index c2a3cfc..7e2f258 100644 --- a/sync/sessions/status_controller.h +++ b/sync/sessions/status_controller.h @@ -175,7 +175,8 @@ class StatusController { // Returns true if the last download_updates_command received a valid // server response. bool download_updates_succeeded() const { - return updates_response().has_get_updates(); + return shared_.error.value().last_download_updates_result + == SYNCER_OK; } // Returns true if the last updates response indicated that we were fully diff --git a/sync/sessions/sync_session_unittest.cc b/sync/sessions/sync_session_unittest.cc index 48524a4..d5ce46a 100644 --- a/sync/sessions/sync_session_unittest.cc +++ b/sync/sessions/sync_session_unittest.cc @@ -215,6 +215,8 @@ TEST_F(SyncSessionTest, MoreToSyncIfUnsyncedGreaterThanCommitted) { TEST_F(SyncSessionTest, MoreToDownloadIfDownloadFailed) { status()->set_updates_request_types(ParamsMeaningAllEnabledTypes()); + status()->set_last_download_updates_result(NETWORK_IO_ERROR); + // When DownloadUpdatesCommand fails, these should be false. EXPECT_FALSE(status()->ServerSaysNothingMoreToDownload()); EXPECT_FALSE(status()->download_updates_succeeded()); @@ -229,6 +231,7 @@ TEST_F(SyncSessionTest, MoreToDownloadIfGotChangesRemaining) { // When the server returns changes_remaining, that means there's // more to download. + status()->set_last_download_updates_result(SYNCER_OK); status()->mutable_updates_response()->mutable_get_updates() ->set_changes_remaining(1000L); EXPECT_FALSE(status()->ServerSaysNothingMoreToDownload()); @@ -242,54 +245,7 @@ TEST_F(SyncSessionTest, MoreToDownloadIfGotChangesRemaining) { TEST_F(SyncSessionTest, MoreToDownloadIfGotNoChangesRemaining) { status()->set_updates_request_types(ParamsMeaningAllEnabledTypes()); - // When the server returns a timestamp, that means we're up to date. - status()->mutable_updates_response()->mutable_get_updates() - ->set_changes_remaining(0); - EXPECT_TRUE(status()->ServerSaysNothingMoreToDownload()); - EXPECT_TRUE(status()->download_updates_succeeded()); - - // Download updates has its own loop in the syncer; it shouldn't factor - // into HasMoreToSync. - EXPECT_FALSE(session_->HasMoreToSync()); -} - -TEST_F(SyncSessionTest, MoreToDownloadIfGotNoChangesRemainingForSubset) { - status()->set_updates_request_types(ParamsMeaningJustOneEnabledType()); - - // When the server returns a timestamp, that means we're up to date for that - // type. But there may still be more to download if there are other - // datatypes that we didn't request on this go-round. - status()->mutable_updates_response()->mutable_get_updates() - ->set_changes_remaining(0); - - EXPECT_TRUE(status()->ServerSaysNothingMoreToDownload()); - EXPECT_TRUE(status()->download_updates_succeeded()); - - // Download updates has its own loop in the syncer; it shouldn't factor - // into HasMoreToSync. - EXPECT_FALSE(session_->HasMoreToSync()); -} - -TEST_F(SyncSessionTest, MoreToDownloadIfGotChangesRemainingAndEntries) { - status()->set_updates_request_types(ParamsMeaningAllEnabledTypes()); - // The actual entry count should not factor into the HasMoreToSync - // determination. - status()->mutable_updates_response()->mutable_get_updates()->add_entries(); - status()->mutable_updates_response()->mutable_get_updates() - ->set_changes_remaining(1000000L);; - EXPECT_FALSE(status()->ServerSaysNothingMoreToDownload()); - EXPECT_TRUE(status()->download_updates_succeeded()); - - // Download updates has its own loop in the syncer; it shouldn't factor - // into HasMoreToSync. - EXPECT_FALSE(session_->HasMoreToSync()); -} - -TEST_F(SyncSessionTest, MoreToDownloadIfGotNoChangesRemainingAndEntries) { - status()->set_updates_request_types(ParamsMeaningAllEnabledTypes()); - // The actual entry count should not factor into the HasMoreToSync - // determination. - status()->mutable_updates_response()->mutable_get_updates()->add_entries(); + status()->set_last_download_updates_result(SYNCER_OK); status()->mutable_updates_response()->mutable_get_updates() ->set_changes_remaining(0); EXPECT_TRUE(status()->ServerSaysNothingMoreToDownload()); diff --git a/sync/test/engine/mock_connection_manager.cc b/sync/test/engine/mock_connection_manager.cc index ab95bce..166b27a 100644 --- a/sync/test/engine/mock_connection_manager.cc +++ b/sync/test/engine/mock_connection_manager.cc @@ -48,7 +48,7 @@ MockConnectionManager::MockConnectionManager(syncable::Directory* directory) store_birthday_sent_(false), client_stuck_(false), commit_time_rename_prepended_string_(""), - fail_next_postbuffer_(false), + countdown_to_postbuffer_fail_(0), directory_(directory), mid_commit_observer_(NULL), throttling_(false), @@ -111,8 +111,9 @@ bool MockConnectionManager::PostBufferToPath(PostBufferParams* params, InvalidateAndClearAuthToken(); } - if (fail_next_postbuffer_) { - fail_next_postbuffer_ = false; + if (--countdown_to_postbuffer_fail_ == 0) { + // Fail as countdown hits zero. + params->response.server_status = HttpResponse::SYNC_SERVER_ERROR; return false; } @@ -564,30 +565,6 @@ const CommitResponse& MockConnectionManager::last_commit_response() const { return *commit_responses_->back(); } -void MockConnectionManager::ThrottleNextRequest( - ResponseCodeOverrideRequestor* visitor) { - base::AutoLock lock(response_code_override_lock_); - throttling_ = true; - if (visitor) - visitor->OnOverrideComplete(); -} - -void MockConnectionManager::FailWithAuthInvalid( - ResponseCodeOverrideRequestor* visitor) { - base::AutoLock lock(response_code_override_lock_); - fail_with_auth_invalid_ = true; - if (visitor) - visitor->OnOverrideComplete(); -} - -void MockConnectionManager::StopFailingWithAuthInvalid( - ResponseCodeOverrideRequestor* visitor) { - base::AutoLock lock(response_code_override_lock_); - fail_with_auth_invalid_ = false; - if (visitor) - visitor->OnOverrideComplete(); -} - bool MockConnectionManager::IsModelTypePresentInSpecifics( const google::protobuf::RepeatedPtrField< sync_pb::DataTypeProgressMarker>& filter, diff --git a/sync/test/engine/mock_connection_manager.h b/sync/test/engine/mock_connection_manager.h index a2b5060..f603de1 100644 --- a/sync/test/engine/mock_connection_manager.h +++ b/sync/test/engine/mock_connection_manager.h @@ -117,25 +117,11 @@ class MockConnectionManager : public browser_sync::ServerConnectionManager { // issue multiple requests during a sync cycle. void NextUpdateBatch(); - void FailNextPostBufferToPathCall() { fail_next_postbuffer_ = true; } + void FailNextPostBufferToPathCall() { countdown_to_postbuffer_fail_ = 1; } + void FailNthPostBufferToPathCall(int n) { countdown_to_postbuffer_fail_ = n; } void SetClearUserDataResponseStatus(sync_pb::SyncEnums::ErrorType errortype); - // A visitor class to allow a test to change some monitoring state atomically - // with the action of overriding the response codes sent back to the Syncer - // (for example, so you can say "ThrottleNextRequest, and assert no more - // requests are made once throttling is in effect" in one step. - class ResponseCodeOverrideRequestor { - public: - // Called with response_code_override_lock_ acquired. - virtual void OnOverrideComplete() = 0; - - protected: - virtual ~ResponseCodeOverrideRequestor() {} - }; - void ThrottleNextRequest(ResponseCodeOverrideRequestor* visitor); - void FailWithAuthInvalid(ResponseCodeOverrideRequestor* visitor); - void StopFailingWithAuthInvalid(ResponseCodeOverrideRequestor* visitor); void FailNonPeriodicGetUpdates() { fail_non_periodic_get_updates_ = true; } // Simple inspectors. @@ -222,6 +208,11 @@ class MockConnectionManager : public browser_sync::ServerConnectionManager { return store_birthday_; } + // Explicitly indicate that we will not be fetching some updates. + void ClearUpdatesQueue() { + update_queue_.clear(); + } + // Locate the most recent update message for purpose of alteration. sync_pb::SyncEntity* GetMutableLastUpdate(); @@ -299,8 +290,9 @@ class MockConnectionManager : public browser_sync::ServerConnectionManager { bool client_stuck_; std::string commit_time_rename_prepended_string_; - // Fail on the next call to PostBufferToPath(). - bool fail_next_postbuffer_; + // On each PostBufferToPath() call, we decrement this counter. The call fails + // iff we hit zero at that call. + int countdown_to_postbuffer_fail_; // Our directory. Used only to ensure that we are not holding the transaction // lock when performing network I/O. Can be NULL if the test author is |