sync_session_unittest.cc revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1// Copyright (c) 2009 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/sync/sessions/sync_session.h" 6 7#include "chrome/browser/sync/engine/conflict_resolver.h" 8#include "chrome/browser/sync/engine/syncer_types.h" 9#include "chrome/browser/sync/engine/syncer_util.h" 10#include "chrome/browser/sync/syncable/directory_manager.h" 11#include "chrome/browser/sync/syncable/syncable.h" 12#include "chrome/test/sync/engine/test_directory_setter_upper.h" 13#include "testing/gtest/include/gtest/gtest.h" 14 15using syncable::MultiTypeTimeStamp; 16using syncable::WriteTransaction; 17 18namespace browser_sync { 19namespace sessions { 20namespace { 21 22class SyncSessionTest : public testing::Test, 23 public SyncSession::Delegate, 24 public ModelSafeWorkerRegistrar { 25 public: 26 SyncSessionTest() : controller_invocations_allowed_(false) { 27 GetModelSafeRoutingInfo(&routes_); 28 } 29 virtual void SetUp() { 30 context_.reset(new SyncSessionContext(NULL, NULL, NULL, this)); 31 session_.reset(new SyncSession(context_.get(), this)); 32 } 33 virtual void TearDown() { 34 session_.reset(); 35 context_.reset(); 36 } 37 38 virtual void OnSilencedUntil(const base::TimeTicks& silenced_until) { 39 FailControllerInvocationIfDisabled("OnSilencedUntil"); 40 } 41 virtual bool IsSyncingCurrentlySilenced() { 42 FailControllerInvocationIfDisabled("IsSyncingCurrentlySilenced"); 43 return false; 44 } 45 virtual void OnReceivedLongPollIntervalUpdate( 46 const base::TimeDelta& new_interval) { 47 FailControllerInvocationIfDisabled("OnReceivedLongPollIntervalUpdate"); 48 } 49 virtual void OnReceivedShortPollIntervalUpdate( 50 const base::TimeDelta& new_interval) { 51 FailControllerInvocationIfDisabled("OnReceivedShortPollIntervalUpdate"); 52 } 53 virtual void OnShouldStopSyncingPermanently() { 54 FailControllerInvocationIfDisabled("OnShouldStopSyncingPermanently"); 55 } 56 57 // ModelSafeWorkerRegistrar implementation. 58 virtual void GetWorkers(std::vector<ModelSafeWorker*>* out) {} 59 virtual void GetModelSafeRoutingInfo(ModelSafeRoutingInfo* out) { 60 (*out)[syncable::BOOKMARKS] = GROUP_UI; 61 (*out)[syncable::AUTOFILL] = GROUP_UI; 62 } 63 64 StatusController* status() { return session_->status_controller(); } 65 protected: 66 void FailControllerInvocationIfDisabled(const std::string& msg) { 67 if (!controller_invocations_allowed_) 68 FAIL() << msg; 69 } 70 71 MultiTypeTimeStamp ParamsMeaningAllEnabledTypes() { 72 MultiTypeTimeStamp request_params; 73 request_params.timestamp = 2000; 74 request_params.data_types[syncable::BOOKMARKS] = true; 75 request_params.data_types[syncable::AUTOFILL] = true; 76 return request_params; 77 } 78 79 MultiTypeTimeStamp ParamsMeaningJustOneEnabledType() { 80 MultiTypeTimeStamp request_params; 81 request_params.timestamp = 5000; 82 request_params.data_types[syncable::AUTOFILL] = true; 83 return request_params; 84 } 85 86 bool controller_invocations_allowed_; 87 scoped_ptr<SyncSession> session_; 88 scoped_ptr<SyncSessionContext> context_; 89 ModelSafeRoutingInfo routes_; 90}; 91 92TEST_F(SyncSessionTest, ScopedContextHelpers) { 93 ConflictResolver resolver; 94 SyncerEventChannel* channel = new SyncerEventChannel(); 95 EXPECT_FALSE(context_->resolver()); 96 EXPECT_FALSE(context_->syncer_event_channel()); 97 { 98 ScopedSessionContextConflictResolver s_resolver(context_.get(), &resolver); 99 ScopedSessionContextSyncerEventChannel s_channel(context_.get(), channel); 100 EXPECT_EQ(&resolver, context_->resolver()); 101 EXPECT_EQ(channel, context_->syncer_event_channel()); 102 } 103 EXPECT_FALSE(context_->resolver()); 104 EXPECT_FALSE(context_->syncer_event_channel()); 105 channel->Notify(SyncerEvent(SyncerEvent::SHUTDOWN_USE_WITH_CARE)); 106 delete channel; 107} 108 109TEST_F(SyncSessionTest, SetWriteTransaction) { 110 TestDirectorySetterUpper db; 111 db.SetUp(); 112 session_.reset(NULL); 113 context_.reset(new SyncSessionContext(NULL, NULL, db.manager(), this)); 114 session_.reset(new SyncSession(context_.get(), this)); 115 context_->set_account_name(db.name()); 116 syncable::ScopedDirLookup dir(context_->directory_manager(), 117 context_->account_name()); 118 ASSERT_TRUE(dir.good()); 119 120 SyncSession session(context_.get(), this); 121 EXPECT_TRUE(NULL == session.write_transaction()); 122 { 123 WriteTransaction trans(dir, syncable::UNITTEST, __FILE__, __LINE__); 124 sessions::ScopedSetSessionWriteTransaction set_trans(&session, &trans); 125 EXPECT_TRUE(&trans == session.write_transaction()); 126 } 127 db.TearDown(); 128} 129 130TEST_F(SyncSessionTest, MoreToSyncIfUnsyncedGreaterThanCommitted) { 131 // If any forward progress was made during the session, and the number of 132 // unsynced handles still exceeds the number of commit ids we added, there is 133 // more to sync. For example, this occurs if we had more commit ids 134 // than could fit in a single commit batch. 135 EXPECT_FALSE(session_->HasMoreToSync()); 136 OrderedCommitSet commit_set(routes_); 137 commit_set.AddCommitItem(0, syncable::Id(), syncable::BOOKMARKS); 138 status()->set_commit_set(commit_set); 139 EXPECT_FALSE(session_->HasMoreToSync()); 140 141 std::vector<int64> unsynced_handles; 142 unsynced_handles.push_back(1); 143 unsynced_handles.push_back(2); 144 status()->set_unsynced_handles(unsynced_handles); 145 EXPECT_FALSE(session_->HasMoreToSync()); 146 status()->increment_num_successful_commits(); 147 EXPECT_TRUE(session_->HasMoreToSync()); 148} 149 150TEST_F(SyncSessionTest, MoreToSyncIfConflictSetsBuilt) { 151 // If we built conflict sets, then we need to loop back and try 152 // to get updates & commit again. 153 status()->update_conflict_sets_built(true); 154 EXPECT_TRUE(session_->HasMoreToSync()); 155} 156 157TEST_F(SyncSessionTest, MoreToDownloadIfDownloadFailed) { 158 status()->set_updates_request_parameters(ParamsMeaningAllEnabledTypes()); 159 160 // When DownloadUpdatesCommand fails, these should be false. 161 EXPECT_FALSE(status()->ServerSaysNothingMoreToDownload()); 162 EXPECT_FALSE(status()->download_updates_succeeded()); 163 164 // Download updates has its own loop in the syncer; it shouldn't factor 165 // into HasMoreToSync. 166 EXPECT_FALSE(session_->HasMoreToSync()); 167} 168 169TEST_F(SyncSessionTest, MoreToDownloadIfGotTimestamp) { 170 status()->set_updates_request_parameters(ParamsMeaningAllEnabledTypes()); 171 172 // When the server returns a timestamp, that means there's more to download. 173 status()->mutable_updates_response()->mutable_get_updates() 174 ->set_new_timestamp(1000000L); 175 EXPECT_FALSE(status()->ServerSaysNothingMoreToDownload()); 176 EXPECT_TRUE(status()->download_updates_succeeded()); 177 178 // Download updates has its own loop in the syncer; it shouldn't factor 179 // into HasMoreToSync. 180 EXPECT_FALSE(session_->HasMoreToSync()); 181} 182 183TEST_F(SyncSessionTest, MoreToDownloadIfGotNoTimestamp) { 184 status()->set_updates_request_parameters(ParamsMeaningAllEnabledTypes()); 185 186 // When the server returns a timestamp, that means we're up to date. 187 status()->mutable_updates_response()->mutable_get_updates() 188 ->clear_new_timestamp(); 189 EXPECT_TRUE(status()->ServerSaysNothingMoreToDownload()); 190 EXPECT_TRUE(status()->download_updates_succeeded()); 191 192 // Download updates has its own loop in the syncer; it shouldn't factor 193 // into HasMoreToSync. 194 EXPECT_FALSE(session_->HasMoreToSync()); 195} 196 197TEST_F(SyncSessionTest, MoreToDownloadIfGotNoTimestampForSubset) { 198 status()->set_updates_request_parameters(ParamsMeaningJustOneEnabledType()); 199 200 // When the server returns a timestamp, that means we're up to date for that 201 // type. But there may still be more to download if there are other 202 // datatypes that we didn't request on this go-round. 203 status()->mutable_updates_response()->mutable_get_updates() 204 ->clear_new_timestamp(); 205 EXPECT_FALSE(status()->ServerSaysNothingMoreToDownload()); 206 EXPECT_TRUE(status()->download_updates_succeeded()); 207 208 // Download updates has its own loop in the syncer; it shouldn't factor 209 // into HasMoreToSync. 210 EXPECT_FALSE(session_->HasMoreToSync()); 211} 212 213TEST_F(SyncSessionTest, MoreToDownloadIfGotTimestampAndEntries) { 214 status()->set_updates_request_parameters(ParamsMeaningAllEnabledTypes()); 215 // The actual entry count should not factor into the HasMoreToSync 216 // determination. 217 status()->mutable_updates_response()->mutable_get_updates()->add_entries(); 218 status()->mutable_updates_response()->mutable_get_updates() 219 ->set_new_timestamp(1000000L);; 220 EXPECT_FALSE(status()->ServerSaysNothingMoreToDownload()); 221 EXPECT_TRUE(status()->download_updates_succeeded()); 222 223 // Download updates has its own loop in the syncer; it shouldn't factor 224 // into HasMoreToSync. 225 EXPECT_FALSE(session_->HasMoreToSync()); 226} 227 228 229TEST_F(SyncSessionTest, MoreToSyncIfConflictsResolved) { 230 // Conflict resolution happens after get updates and commit, 231 // so we need to loop back and get updates / commit again now 232 // that we have made forward progress. 233 status()->update_conflicts_resolved(true); 234 EXPECT_TRUE(session_->HasMoreToSync()); 235} 236 237} // namespace 238} // namespace sessions 239} // namespace browser_sync 240