Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/bind.h" | 5 #include "base/bind.h" |
| 6 #include "base/callback.h" | 6 #include "base/callback.h" |
| 7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "base/memory/weak_ptr.h" | 8 #include "base/memory/weak_ptr.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/test/test_timeouts.h" | 10 #include "base/test/test_timeouts.h" |
| 11 #include "sync/engine/backoff_delay_provider.h" | 11 #include "sync/engine/backoff_delay_provider.h" |
| 12 #include "sync/engine/sync_scheduler_impl.h" | 12 #include "sync/engine/sync_scheduler_impl.h" |
| 13 #include "sync/engine/syncer.h" | 13 #include "sync/engine/syncer.h" |
| 14 #include "sync/internal_api/public/base/model_type_invalidation_map_test_util.h" | |
| 15 #include "sync/sessions/test_util.h" | 14 #include "sync/sessions/test_util.h" |
| 16 #include "sync/test/callback_counter.h" | 15 #include "sync/test/callback_counter.h" |
| 17 #include "sync/test/engine/fake_model_worker.h" | 16 #include "sync/test/engine/fake_model_worker.h" |
| 18 #include "sync/test/engine/mock_connection_manager.h" | 17 #include "sync/test/engine/mock_connection_manager.h" |
| 19 #include "sync/test/engine/test_directory_setter_upper.h" | 18 #include "sync/test/engine/test_directory_setter_upper.h" |
| 20 #include "sync/test/fake_extensions_activity_monitor.h" | 19 #include "sync/test/fake_extensions_activity_monitor.h" |
| 21 #include "testing/gmock/include/gmock/gmock.h" | 20 #include "testing/gmock/include/gmock/gmock.h" |
| 22 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 23 | 22 |
| 24 using base::TimeDelta; | 23 using base::TimeDelta; |
| 25 using base::TimeTicks; | 24 using base::TimeTicks; |
| 26 using testing::_; | 25 using testing::_; |
| 27 using testing::AtLeast; | 26 using testing::AtLeast; |
| 28 using testing::DoAll; | 27 using testing::DoAll; |
| 29 using testing::Eq; | |
| 30 using testing::Invoke; | 28 using testing::Invoke; |
| 31 using testing::Mock; | 29 using testing::Mock; |
| 32 using testing::Not; | |
| 33 using testing::Return; | 30 using testing::Return; |
| 34 using testing::WithArg; | 31 using testing::WithArg; |
| 35 using testing::WithArgs; | 32 using testing::WithArgs; |
| 36 | 33 |
| 37 namespace syncer { | 34 namespace syncer { |
| 38 using sessions::SyncSession; | 35 using sessions::SyncSession; |
| 39 using sessions::SyncSessionContext; | 36 using sessions::SyncSessionContext; |
| 40 using sessions::SyncSessionSnapshot; | |
| 41 using sync_pb::GetUpdatesCallerInfo; | 37 using sync_pb::GetUpdatesCallerInfo; |
| 42 | 38 |
| 43 class MockSyncer : public Syncer { | 39 class MockSyncer : public Syncer { |
| 44 public: | 40 public: |
| 45 MOCK_METHOD3(NormalSyncShare, bool(ModelTypeSet, | 41 MOCK_METHOD3(NormalSyncShare, bool(ModelTypeSet, |
| 46 const sessions::NudgeTracker&, | 42 const sessions::NudgeTracker&, |
| 47 sessions::SyncSession*)); | 43 sessions::SyncSession*)); |
| 48 MOCK_METHOD2(ConfigureSyncShare, bool(ModelTypeSet, sessions::SyncSession*)); | 44 MOCK_METHOD3(ConfigureSyncShare, |
| 45 bool(ModelTypeSet, | |
| 46 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource, | |
| 47 SyncSession*)); | |
| 49 MOCK_METHOD2(PollSyncShare, bool(ModelTypeSet, sessions::SyncSession*)); | 48 MOCK_METHOD2(PollSyncShare, bool(ModelTypeSet, sessions::SyncSession*)); |
| 50 }; | 49 }; |
| 51 | 50 |
| 52 // Used when tests want to record syncing activity to examine later. | |
| 53 struct SyncShareRecords { | 51 struct SyncShareRecords { |
| 54 std::vector<TimeTicks> times; | 52 std::vector<TimeTicks> times; |
|
tim (not reviewing)
2013/08/02 22:49:39
This could just be made a typedef.
| |
| 55 std::vector<SyncSessionSnapshot> snapshots; | |
| 56 }; | 53 }; |
| 57 | 54 |
| 58 void QuitLoopNow() { | 55 void QuitLoopNow() { |
| 59 // We use QuitNow() instead of Quit() as the latter may get stalled | 56 // We use QuitNow() instead of Quit() as the latter may get stalled |
| 60 // indefinitely in the presence of repeated timers with low delays | 57 // indefinitely in the presence of repeated timers with low delays |
| 61 // and a slow test (e.g., ThrottlingDoesThrottle [which has a poll | 58 // and a slow test (e.g., ThrottlingDoesThrottle [which has a poll |
| 62 // delay of 5ms] run under TSAN on the trybots). | 59 // delay of 5ms] run under TSAN on the trybots). |
| 63 base::MessageLoop::current()->QuitNow(); | 60 base::MessageLoop::current()->QuitNow(); |
| 64 } | 61 } |
| 65 | 62 |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 83 } | 80 } |
| 84 | 81 |
| 85 ModelSafeRoutingInfo TypesToRoutingInfo(ModelTypeSet types) { | 82 ModelSafeRoutingInfo TypesToRoutingInfo(ModelTypeSet types) { |
| 86 ModelSafeRoutingInfo routes; | 83 ModelSafeRoutingInfo routes; |
| 87 for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) { | 84 for (ModelTypeSet::Iterator iter = types.First(); iter.Good(); iter.Inc()) { |
| 88 routes[iter.Get()] = GROUP_PASSIVE; | 85 routes[iter.Get()] = GROUP_PASSIVE; |
| 89 } | 86 } |
| 90 return routes; | 87 return routes; |
| 91 } | 88 } |
| 92 | 89 |
| 93 // Compare a ModelTypeSet to a ModelTypeInvalidationMap, ignoring | |
| 94 // state values. | |
| 95 testing::AssertionResult ModelTypeSetMatchesInvalidationMap( | |
| 96 ModelTypeSet lhs, const ModelTypeInvalidationMap& rhs) { | |
| 97 ModelTypeSet rhs_set = ModelTypeInvalidationMapToSet(rhs); | |
| 98 | |
| 99 if (!rhs_set.Equals(rhs_set)) { | |
| 100 return testing::AssertionFailure() | |
| 101 << "ModelTypeSet: " << ModelTypeSetToString(lhs) | |
| 102 << " does not match ModelTypeInvalidationMap: " | |
| 103 << ModelTypeSetToString(rhs_set); | |
| 104 } else { | |
| 105 return testing::AssertionSuccess(); | |
| 106 } | |
| 107 } | |
| 108 | |
| 109 // Convenient to use in tests wishing to analyze SyncShare calls over time. | 90 // Convenient to use in tests wishing to analyze SyncShare calls over time. |
| 110 static const size_t kMinNumSamples = 5; | 91 static const size_t kMinNumSamples = 5; |
| 111 class SyncSchedulerTest : public testing::Test { | 92 class SyncSchedulerTest : public testing::Test { |
| 112 public: | 93 public: |
| 113 SyncSchedulerTest() : weak_ptr_factory_(this), syncer_(NULL), delay_(NULL) {} | 94 SyncSchedulerTest() : weak_ptr_factory_(this), syncer_(NULL), delay_(NULL) {} |
| 114 | 95 |
| 115 class MockDelayProvider : public BackoffDelayProvider { | 96 class MockDelayProvider : public BackoffDelayProvider { |
| 116 public: | 97 public: |
| 117 MockDelayProvider() : BackoffDelayProvider( | 98 MockDelayProvider() : BackoffDelayProvider( |
| 118 TimeDelta::FromSeconds(kInitialBackoffRetrySeconds), | 99 TimeDelta::FromSeconds(kInitialBackoffRetrySeconds), |
| 119 TimeDelta::FromSeconds(kInitialBackoffImmediateRetrySeconds)) { | 100 TimeDelta::FromSeconds(kInitialBackoffImmediateRetrySeconds)) { |
| 120 } | 101 } |
| 121 | 102 |
| 122 MOCK_METHOD1(GetDelay, TimeDelta(const TimeDelta&)); | 103 MOCK_METHOD1(GetDelay, TimeDelta(const TimeDelta&)); |
| 123 }; | 104 }; |
| 124 | 105 |
| 125 virtual void SetUp() { | 106 virtual void SetUp() { |
| 126 dir_maker_.SetUp(); | 107 dir_maker_.SetUp(); |
| 127 syncer_ = new MockSyncer(); | 108 syncer_ = new testing::StrictMock<MockSyncer>(); |
| 128 delay_ = NULL; | 109 delay_ = NULL; |
| 129 | 110 |
| 130 routing_info_[BOOKMARKS] = GROUP_UI; | 111 routing_info_[BOOKMARKS] = GROUP_UI; |
| 131 routing_info_[AUTOFILL] = GROUP_DB; | 112 routing_info_[AUTOFILL] = GROUP_DB; |
| 132 routing_info_[THEMES] = GROUP_UI; | 113 routing_info_[THEMES] = GROUP_UI; |
| 133 routing_info_[NIGORI] = GROUP_PASSIVE; | 114 routing_info_[NIGORI] = GROUP_PASSIVE; |
| 134 | 115 |
| 135 workers_.clear(); | 116 workers_.clear(); |
| 136 workers_.push_back(make_scoped_refptr(new FakeModelWorker(GROUP_UI))); | 117 workers_.push_back(make_scoped_refptr(new FakeModelWorker(GROUP_UI))); |
| 137 workers_.push_back(make_scoped_refptr(new FakeModelWorker(GROUP_DB))); | 118 workers_.push_back(make_scoped_refptr(new FakeModelWorker(GROUP_DB))); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 180 } | 161 } |
| 181 | 162 |
| 182 void AnalyzePollRun(const SyncShareRecords& records, size_t min_num_samples, | 163 void AnalyzePollRun(const SyncShareRecords& records, size_t min_num_samples, |
| 183 const TimeTicks& optimal_start, const TimeDelta& poll_interval) { | 164 const TimeTicks& optimal_start, const TimeDelta& poll_interval) { |
| 184 const std::vector<TimeTicks>& data(records.times); | 165 const std::vector<TimeTicks>& data(records.times); |
| 185 EXPECT_GE(data.size(), min_num_samples); | 166 EXPECT_GE(data.size(), min_num_samples); |
| 186 for (size_t i = 0; i < data.size(); i++) { | 167 for (size_t i = 0; i < data.size(); i++) { |
| 187 SCOPED_TRACE(testing::Message() << "SyncShare # (" << i << ")"); | 168 SCOPED_TRACE(testing::Message() << "SyncShare # (" << i << ")"); |
| 188 TimeTicks optimal_next_sync = optimal_start + poll_interval * i; | 169 TimeTicks optimal_next_sync = optimal_start + poll_interval * i; |
| 189 EXPECT_GE(data[i], optimal_next_sync); | 170 EXPECT_GE(data[i], optimal_next_sync); |
| 190 EXPECT_EQ(GetUpdatesCallerInfo::PERIODIC, | |
| 191 records.snapshots[i].source().updates_source); | |
| 192 } | 171 } |
| 193 } | 172 } |
| 194 | 173 |
| 195 void DoQuitLoopNow() { | 174 void DoQuitLoopNow() { |
| 196 QuitLoopNow(); | 175 QuitLoopNow(); |
| 197 } | 176 } |
| 198 | 177 |
| 199 void StartSyncScheduler(SyncScheduler::Mode mode) { | 178 void StartSyncScheduler(SyncScheduler::Mode mode) { |
| 200 scheduler()->Start(mode); | 179 scheduler()->Start(mode); |
| 201 } | 180 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 239 scoped_ptr<MockConnectionManager> connection_; | 218 scoped_ptr<MockConnectionManager> connection_; |
| 240 scoped_ptr<SyncSessionContext> context_; | 219 scoped_ptr<SyncSessionContext> context_; |
| 241 scoped_ptr<SyncSchedulerImpl> scheduler_; | 220 scoped_ptr<SyncSchedulerImpl> scheduler_; |
| 242 MockSyncer* syncer_; | 221 MockSyncer* syncer_; |
| 243 MockDelayProvider* delay_; | 222 MockDelayProvider* delay_; |
| 244 std::vector<scoped_refptr<FakeModelWorker> > workers_; | 223 std::vector<scoped_refptr<FakeModelWorker> > workers_; |
| 245 FakeExtensionsActivityMonitor extensions_activity_monitor_; | 224 FakeExtensionsActivityMonitor extensions_activity_monitor_; |
| 246 ModelSafeRoutingInfo routing_info_; | 225 ModelSafeRoutingInfo routing_info_; |
| 247 }; | 226 }; |
| 248 | 227 |
| 249 void RecordSyncShareImpl(SyncSession* s, SyncShareRecords* record) { | 228 void RecordSyncShareImpl(SyncShareRecords* record) { |
| 250 record->times.push_back(TimeTicks::Now()); | 229 record->times.push_back(TimeTicks::Now()); |
| 251 record->snapshots.push_back(s->TakeSnapshot()); | |
| 252 } | 230 } |
| 253 | 231 |
| 254 ACTION_P(RecordSyncShare, record) { | 232 ACTION_P(RecordSyncShare, record) { |
| 255 RecordSyncShareImpl(arg0, record); | 233 RecordSyncShareImpl(record); |
| 256 if (base::MessageLoop::current()->is_running()) | 234 if (base::MessageLoop::current()->is_running()) |
| 257 QuitLoopNow(); | 235 QuitLoopNow(); |
| 258 return true; | 236 return true; |
| 259 } | 237 } |
| 260 | 238 |
| 261 ACTION_P2(RecordSyncShareMultiple, record, quit_after) { | 239 ACTION_P2(RecordSyncShareMultiple, record, quit_after) { |
| 262 RecordSyncShareImpl(arg0, record); | 240 RecordSyncShareImpl(record); |
| 263 EXPECT_LE(record->times.size(), quit_after); | 241 EXPECT_LE(record->times.size(), quit_after); |
| 264 if (record->times.size() >= quit_after && | 242 if (record->times.size() >= quit_after && |
| 265 base::MessageLoop::current()->is_running()) { | 243 base::MessageLoop::current()->is_running()) { |
| 266 QuitLoopNow(); | 244 QuitLoopNow(); |
| 267 } | 245 } |
| 268 return true; | 246 return true; |
| 269 } | 247 } |
| 270 | 248 |
| 271 ACTION(AddFailureAndQuitLoopNow) { | 249 ACTION(AddFailureAndQuitLoopNow) { |
| 272 ADD_FAILURE(); | 250 ADD_FAILURE(); |
| 273 QuitLoopNow(); | 251 QuitLoopNow(); |
| 274 return true; | 252 return true; |
| 275 } | 253 } |
| 276 | 254 |
| 277 ACTION(QuitLoopNowAction) { | 255 ACTION(QuitLoopNowAction) { |
| 278 QuitLoopNow(); | 256 QuitLoopNow(); |
| 279 return true; | 257 return true; |
| 280 } | 258 } |
| 281 | 259 |
| 282 // Test nudge scheduling. | 260 // Test nudge scheduling. |
| 283 TEST_F(SyncSchedulerTest, Nudge) { | 261 TEST_F(SyncSchedulerTest, Nudge) { |
| 284 SyncShareRecords records; | 262 SyncShareRecords records; |
| 285 ModelTypeSet model_types(BOOKMARKS); | 263 ModelTypeSet model_types(BOOKMARKS); |
| 286 | 264 |
| 287 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 265 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 288 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 266 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 289 WithArg<2>(RecordSyncShare(&records)))) | 267 RecordSyncShare(&records))) |
| 290 .RetiresOnSaturation(); | 268 .RetiresOnSaturation(); |
| 291 | 269 |
| 292 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 270 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 293 | 271 |
| 294 scheduler()->ScheduleLocalNudge(zero(), model_types, FROM_HERE); | 272 scheduler()->ScheduleLocalNudge(zero(), model_types, FROM_HERE); |
| 295 RunLoop(); | 273 RunLoop(); |
| 296 | 274 |
| 297 ASSERT_EQ(1U, records.snapshots.size()); | |
| 298 EXPECT_TRUE(ModelTypeSetMatchesInvalidationMap( | |
| 299 model_types, | |
| 300 records.snapshots[0].source().types)); | |
| 301 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, | |
| 302 records.snapshots[0].source().updates_source); | |
| 303 | |
| 304 Mock::VerifyAndClearExpectations(syncer()); | 275 Mock::VerifyAndClearExpectations(syncer()); |
| 305 | 276 |
| 306 // Make sure a second, later, nudge is unaffected by first (no coalescing). | 277 // Make sure a second, later, nudge is unaffected by first (no coalescing). |
| 307 SyncShareRecords records2; | 278 SyncShareRecords records2; |
| 308 model_types.Remove(BOOKMARKS); | 279 model_types.Remove(BOOKMARKS); |
| 309 model_types.Put(AUTOFILL); | 280 model_types.Put(AUTOFILL); |
| 310 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 281 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 311 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 282 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 312 WithArg<2>(RecordSyncShare(&records2)))); | 283 RecordSyncShare(&records2))); |
| 313 scheduler()->ScheduleLocalNudge(zero(), model_types, FROM_HERE); | 284 scheduler()->ScheduleLocalNudge(zero(), model_types, FROM_HERE); |
| 314 RunLoop(); | 285 RunLoop(); |
| 315 | |
| 316 ASSERT_EQ(1U, records2.snapshots.size()); | |
| 317 EXPECT_TRUE(ModelTypeSetMatchesInvalidationMap( | |
| 318 model_types, | |
| 319 records2.snapshots[0].source().types)); | |
| 320 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, | |
| 321 records2.snapshots[0].source().updates_source); | |
| 322 } | 286 } |
| 323 | 287 |
| 324 // Make sure a regular config command is scheduled fine in the absence of any | 288 // Make sure a regular config command is scheduled fine in the absence of any |
| 325 // errors. | 289 // errors. |
| 326 TEST_F(SyncSchedulerTest, Config) { | 290 TEST_F(SyncSchedulerTest, Config) { |
| 327 SyncShareRecords records; | 291 SyncShareRecords records; |
| 328 const ModelTypeSet model_types(BOOKMARKS); | 292 const ModelTypeSet model_types(BOOKMARKS); |
| 329 | 293 |
| 330 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_)) | 294 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) |
| 331 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess), | 295 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess), |
| 332 WithArg<1>(RecordSyncShare(&records)))); | 296 RecordSyncShare(&records))); |
| 333 | 297 |
| 334 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); | 298 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 335 | 299 |
| 336 CallbackCounter counter; | 300 CallbackCounter counter; |
| 337 ConfigurationParams params( | 301 ConfigurationParams params( |
| 338 GetUpdatesCallerInfo::RECONFIGURATION, | 302 GetUpdatesCallerInfo::RECONFIGURATION, |
| 339 model_types, | 303 model_types, |
| 340 TypesToRoutingInfo(model_types), | 304 TypesToRoutingInfo(model_types), |
| 341 base::Bind(&CallbackCounter::Callback, base::Unretained(&counter))); | 305 base::Bind(&CallbackCounter::Callback, base::Unretained(&counter))); |
| 342 ASSERT_TRUE(scheduler()->ScheduleConfiguration(params)); | 306 ASSERT_TRUE(scheduler()->ScheduleConfiguration(params)); |
| 343 ASSERT_EQ(1, counter.times_called()); | 307 ASSERT_EQ(1, counter.times_called()); |
| 344 | |
| 345 ASSERT_EQ(1U, records.snapshots.size()); | |
| 346 EXPECT_TRUE(ModelTypeSetMatchesInvalidationMap( | |
| 347 model_types, | |
| 348 records.snapshots[0].source().types)); | |
| 349 EXPECT_EQ(GetUpdatesCallerInfo::RECONFIGURATION, | |
| 350 records.snapshots[0].source().updates_source); | |
| 351 } | 308 } |
| 352 | 309 |
| 353 // Simulate a failure and make sure the config request is retried. | 310 // Simulate a failure and make sure the config request is retried. |
| 354 TEST_F(SyncSchedulerTest, ConfigWithBackingOff) { | 311 TEST_F(SyncSchedulerTest, ConfigWithBackingOff) { |
| 355 UseMockDelayProvider(); | 312 UseMockDelayProvider(); |
| 356 EXPECT_CALL(*delay(), GetDelay(_)) | 313 EXPECT_CALL(*delay(), GetDelay(_)) |
| 357 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(1))); | 314 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(1))); |
| 358 SyncShareRecords records; | 315 SyncShareRecords records; |
| 359 const ModelTypeSet model_types(BOOKMARKS); | 316 const ModelTypeSet model_types(BOOKMARKS); |
| 360 | 317 |
| 361 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_)) | |
| 362 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed), | |
| 363 WithArg<1>(RecordSyncShare(&records)))) | |
| 364 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess), | |
| 365 WithArg<1>(RecordSyncShare(&records)))); | |
| 366 | |
| 367 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); | 318 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 368 | 319 |
| 369 ASSERT_EQ(0U, records.snapshots.size()); | 320 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) |
| 321 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed), | |
| 322 RecordSyncShare(&records))); | |
| 323 | |
| 370 CallbackCounter counter; | 324 CallbackCounter counter; |
| 371 ConfigurationParams params( | 325 ConfigurationParams params( |
| 372 GetUpdatesCallerInfo::RECONFIGURATION, | 326 GetUpdatesCallerInfo::RECONFIGURATION, |
| 373 model_types, | 327 model_types, |
| 374 TypesToRoutingInfo(model_types), | 328 TypesToRoutingInfo(model_types), |
| 375 base::Bind(&CallbackCounter::Callback, base::Unretained(&counter))); | 329 base::Bind(&CallbackCounter::Callback, base::Unretained(&counter))); |
| 376 ASSERT_FALSE(scheduler()->ScheduleConfiguration(params)); | 330 ASSERT_FALSE(scheduler()->ScheduleConfiguration(params)); |
| 377 ASSERT_EQ(0, counter.times_called()); | 331 ASSERT_EQ(0, counter.times_called()); |
| 378 | 332 |
| 379 ASSERT_EQ(1U, records.snapshots.size()); | 333 Mock::VerifyAndClearExpectations(syncer()); |
| 334 | |
| 335 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) | |
| 336 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess), | |
| 337 RecordSyncShare(&records))); | |
| 380 RunLoop(); | 338 RunLoop(); |
| 381 | 339 |
| 382 ASSERT_EQ(2U, records.snapshots.size()); | |
| 383 ASSERT_EQ(1, counter.times_called()); | 340 ASSERT_EQ(1, counter.times_called()); |
| 384 EXPECT_TRUE(ModelTypeSetMatchesInvalidationMap( | |
| 385 model_types, | |
| 386 records.snapshots[1].source().types)); | |
| 387 EXPECT_EQ(GetUpdatesCallerInfo::RECONFIGURATION, | |
| 388 records.snapshots[1].source().updates_source); | |
| 389 } | 341 } |
| 390 | 342 |
| 391 // Issue a nudge when the config has failed. Make sure both the config and | 343 // Issue a nudge when the config has failed. Make sure both the config and |
| 392 // nudge are executed. | 344 // nudge are executed. |
| 393 TEST_F(SyncSchedulerTest, NudgeWithConfigWithBackingOff) { | 345 TEST_F(SyncSchedulerTest, NudgeWithConfigWithBackingOff) { |
| 394 const ModelTypeSet model_types(BOOKMARKS); | 346 const ModelTypeSet model_types(BOOKMARKS); |
| 395 UseMockDelayProvider(); | 347 UseMockDelayProvider(); |
| 396 EXPECT_CALL(*delay(), GetDelay(_)) | 348 EXPECT_CALL(*delay(), GetDelay(_)) |
| 397 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(50))); | 349 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(50))); |
| 398 SyncShareRecords records; | 350 SyncShareRecords records; |
| 399 | 351 |
| 400 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_)) | |
| 401 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed), | |
| 402 WithArg<1>(RecordSyncShare(&records)))) | |
| 403 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed), | |
| 404 WithArg<1>(RecordSyncShare(&records)))) | |
| 405 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess), | |
| 406 WithArg<1>(RecordSyncShare(&records)))); | |
| 407 | |
| 408 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | |
| 409 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | |
| 410 WithArg<2>(RecordSyncShare(&records)))); | |
| 411 | |
| 412 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); | 352 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 413 | 353 |
| 414 ASSERT_EQ(0U, records.snapshots.size()); | 354 // Request a configure and make sure it fails. |
| 355 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) | |
| 356 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed), | |
| 357 RecordSyncShare(&records))); | |
| 415 CallbackCounter counter; | 358 CallbackCounter counter; |
| 416 ConfigurationParams params( | 359 ConfigurationParams params( |
| 417 GetUpdatesCallerInfo::RECONFIGURATION, | 360 GetUpdatesCallerInfo::RECONFIGURATION, |
| 418 model_types, | 361 model_types, |
| 419 TypesToRoutingInfo(model_types), | 362 TypesToRoutingInfo(model_types), |
| 420 base::Bind(&CallbackCounter::Callback, base::Unretained(&counter))); | 363 base::Bind(&CallbackCounter::Callback, base::Unretained(&counter))); |
| 421 ASSERT_FALSE(scheduler()->ScheduleConfiguration(params)); | 364 ASSERT_FALSE(scheduler()->ScheduleConfiguration(params)); |
| 422 ASSERT_EQ(0, counter.times_called()); | 365 ASSERT_EQ(0, counter.times_called()); |
| 423 ASSERT_EQ(1U, records.snapshots.size()); | 366 Mock::VerifyAndClearExpectations(syncer()); |
| 424 | 367 |
| 368 // Ask for a nudge while dealing with repeated configure failure. | |
| 369 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) | |
| 370 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed), | |
| 371 RecordSyncShare(&records))); | |
| 425 scheduler()->ScheduleLocalNudge(zero(), model_types, FROM_HERE); | 372 scheduler()->ScheduleLocalNudge(zero(), model_types, FROM_HERE); |
| 426 RunLoop(); | 373 RunLoop(); |
| 427 // Note that we're not RunLoop()ing for the NUDGE we just scheduled, but | 374 // Note that we're not RunLoop()ing for the NUDGE we just scheduled, but |
| 428 // for the first retry attempt from the config job (after | 375 // for the first retry attempt from the config job (after |
| 429 // waiting ~+/- 50ms). | 376 // waiting ~+/- 50ms). |
| 430 ASSERT_EQ(2U, records.snapshots.size()); | 377 Mock::VerifyAndClearExpectations(syncer()); |
| 431 ASSERT_EQ(0, counter.times_called()); | 378 ASSERT_EQ(0, counter.times_called()); |
| 432 EXPECT_EQ(GetUpdatesCallerInfo::RECONFIGURATION, | |
| 433 records.snapshots[1].source().updates_source); | |
| 434 | 379 |
| 380 // Let the next configure retry succeed. | |
| 381 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) | |
| 382 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess), | |
| 383 RecordSyncShare(&records))); | |
| 435 RunLoop(); | 384 RunLoop(); |
| 436 // This is the 3rd attempt, which we've set up to SimulateSuccess. | |
| 437 ASSERT_EQ(3U, records.snapshots.size()); | |
| 438 ASSERT_EQ(1, counter.times_called()); | |
| 439 | 385 |
| 440 // Now change the mode so nudge can execute. | 386 // Now change the mode so nudge can execute. |
| 387 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | |
| 388 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | |
| 389 RecordSyncShare(&records))); | |
| 441 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 390 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 442 | |
| 443 ASSERT_EQ(4U, records.snapshots.size()); | |
| 444 | |
| 445 EXPECT_TRUE(ModelTypeSetMatchesInvalidationMap( | |
| 446 model_types, | |
| 447 records.snapshots[2].source().types)); | |
| 448 EXPECT_EQ(GetUpdatesCallerInfo::RECONFIGURATION, | |
| 449 records.snapshots[2].source().updates_source); | |
| 450 | |
| 451 EXPECT_TRUE(ModelTypeSetMatchesInvalidationMap( | |
| 452 model_types, | |
| 453 records.snapshots[3].source().types)); | |
| 454 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, | |
| 455 records.snapshots[3].source().updates_source); | |
| 456 | |
| 457 } | 391 } |
| 458 | 392 |
| 459 // Test that nudges are coalesced. | 393 // Test that nudges are coalesced. |
| 460 TEST_F(SyncSchedulerTest, NudgeCoalescing) { | 394 TEST_F(SyncSchedulerTest, NudgeCoalescing) { |
| 461 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 395 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 462 | 396 |
| 463 SyncShareRecords r; | 397 SyncShareRecords r; |
| 464 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 398 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 465 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 399 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 466 WithArg<2>(RecordSyncShare(&r)))); | 400 RecordSyncShare(&r))); |
| 467 const ModelTypeSet types1(BOOKMARKS), types2(AUTOFILL), types3(THEMES); | 401 const ModelTypeSet types1(BOOKMARKS), types2(AUTOFILL), types3(THEMES); |
| 468 TimeDelta delay = zero(); | 402 TimeDelta delay = zero(); |
| 469 TimeTicks optimal_time = TimeTicks::Now() + delay; | 403 TimeTicks optimal_time = TimeTicks::Now() + delay; |
| 470 scheduler()->ScheduleLocalNudge(delay, types1, FROM_HERE); | 404 scheduler()->ScheduleLocalNudge(delay, types1, FROM_HERE); |
| 471 scheduler()->ScheduleLocalNudge(zero(), types2, FROM_HERE); | 405 scheduler()->ScheduleLocalNudge(zero(), types2, FROM_HERE); |
| 472 RunLoop(); | 406 RunLoop(); |
| 473 | 407 |
| 474 ASSERT_EQ(1U, r.snapshots.size()); | 408 ASSERT_EQ(1U, r.times.size()); |
| 475 EXPECT_GE(r.times[0], optimal_time); | 409 EXPECT_GE(r.times[0], optimal_time); |
| 476 EXPECT_TRUE(ModelTypeSetMatchesInvalidationMap( | |
| 477 Union(types1, types2), | |
| 478 r.snapshots[0].source().types)); | |
| 479 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, | |
| 480 r.snapshots[0].source().updates_source); | |
| 481 | 410 |
| 482 Mock::VerifyAndClearExpectations(syncer()); | 411 Mock::VerifyAndClearExpectations(syncer()); |
| 483 | 412 |
| 484 SyncShareRecords r2; | 413 SyncShareRecords r2; |
| 485 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 414 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 486 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 415 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 487 WithArg<2>(RecordSyncShare(&r2)))); | 416 RecordSyncShare(&r2))); |
| 488 scheduler()->ScheduleLocalNudge(zero(), types3, FROM_HERE); | 417 scheduler()->ScheduleLocalNudge(zero(), types3, FROM_HERE); |
| 489 RunLoop(); | 418 RunLoop(); |
| 490 | |
| 491 ASSERT_EQ(1U, r2.snapshots.size()); | |
| 492 EXPECT_TRUE(ModelTypeSetMatchesInvalidationMap( | |
| 493 types3, | |
| 494 r2.snapshots[0].source().types)); | |
| 495 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, | |
| 496 r2.snapshots[0].source().updates_source); | |
| 497 } | 419 } |
| 498 | 420 |
| 499 // Test that nudges are coalesced. | 421 // Test that nudges are coalesced. |
| 500 TEST_F(SyncSchedulerTest, NudgeCoalescingWithDifferentTimings) { | 422 TEST_F(SyncSchedulerTest, NudgeCoalescingWithDifferentTimings) { |
| 501 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 423 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 502 | 424 |
| 503 SyncShareRecords r; | 425 SyncShareRecords r; |
| 504 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 426 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 505 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 427 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 506 WithArg<2>(RecordSyncShare(&r)))); | 428 RecordSyncShare(&r))); |
| 507 ModelTypeSet types1(BOOKMARKS), types2(AUTOFILL), types3; | 429 ModelTypeSet types1(BOOKMARKS), types2(AUTOFILL), types3; |
| 508 | 430 |
| 509 // Create a huge time delay. | 431 // Create a huge time delay. |
| 510 TimeDelta delay = TimeDelta::FromDays(1); | 432 TimeDelta delay = TimeDelta::FromDays(1); |
| 511 | 433 |
| 512 scheduler()->ScheduleLocalNudge(delay, types1, FROM_HERE); | 434 scheduler()->ScheduleLocalNudge(delay, types1, FROM_HERE); |
| 513 scheduler()->ScheduleLocalNudge(zero(), types2, FROM_HERE); | 435 scheduler()->ScheduleLocalNudge(zero(), types2, FROM_HERE); |
| 514 | 436 |
| 515 TimeTicks min_time = TimeTicks::Now(); | 437 TimeTicks min_time = TimeTicks::Now(); |
| 516 TimeTicks max_time = TimeTicks::Now() + delay; | 438 TimeTicks max_time = TimeTicks::Now() + delay; |
| 517 | 439 |
| 518 RunLoop(); | 440 RunLoop(); |
| 519 | 441 Mock::VerifyAndClearExpectations(syncer()); |
| 520 // Make sure the sync has happened. | |
| 521 ASSERT_EQ(1U, r.snapshots.size()); | |
| 522 EXPECT_TRUE(ModelTypeSetMatchesInvalidationMap( | |
| 523 Union(types1, types2), | |
| 524 r.snapshots[0].source().types)); | |
| 525 | 442 |
| 526 // Make sure the sync happened at the right time. | 443 // Make sure the sync happened at the right time. |
| 444 ASSERT_EQ(1U, r.times.size()); | |
| 527 EXPECT_GE(r.times[0], min_time); | 445 EXPECT_GE(r.times[0], min_time); |
| 528 EXPECT_LE(r.times[0], max_time); | 446 EXPECT_LE(r.times[0], max_time); |
| 529 } | 447 } |
| 530 | 448 |
| 531 // Test nudge scheduling. | 449 // Test nudge scheduling. |
| 532 TEST_F(SyncSchedulerTest, NudgeWithStates) { | 450 TEST_F(SyncSchedulerTest, NudgeWithStates) { |
| 533 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 451 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 534 | 452 |
| 535 SyncShareRecords records; | 453 SyncShareRecords records; |
| 536 const ModelTypeSet types(BOOKMARKS); | 454 const ModelTypeSet types(BOOKMARKS); |
| 537 ModelTypeInvalidationMap invalidation_map = | 455 ModelTypeInvalidationMap invalidation_map = |
| 538 ModelTypeSetToInvalidationMap(types, "test"); | 456 ModelTypeSetToInvalidationMap(types, "test"); |
| 539 | 457 |
| 540 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 458 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 541 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 459 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 542 WithArg<2>(RecordSyncShare(&records)))) | 460 RecordSyncShare(&records))) |
| 543 .RetiresOnSaturation(); | 461 .RetiresOnSaturation(); |
| 544 scheduler()->ScheduleInvalidationNudge(zero(), invalidation_map, FROM_HERE); | 462 scheduler()->ScheduleInvalidationNudge(zero(), invalidation_map, FROM_HERE); |
| 545 RunLoop(); | 463 RunLoop(); |
| 546 | 464 |
| 547 ASSERT_EQ(1U, records.snapshots.size()); | |
| 548 EXPECT_THAT(invalidation_map, Eq(records.snapshots[0].source().types)); | |
| 549 EXPECT_EQ(GetUpdatesCallerInfo::NOTIFICATION, | |
| 550 records.snapshots[0].source().updates_source); | |
| 551 | |
| 552 Mock::VerifyAndClearExpectations(syncer()); | 465 Mock::VerifyAndClearExpectations(syncer()); |
| 553 | 466 |
| 554 // Make sure a second, later, nudge is unaffected by first (no coalescing). | 467 // Make sure a second, later, nudge is unaffected by first (no coalescing). |
| 555 SyncShareRecords records2; | 468 SyncShareRecords records2; |
| 556 invalidation_map.erase(BOOKMARKS); | 469 invalidation_map.erase(BOOKMARKS); |
| 557 invalidation_map[AUTOFILL].payload = "test2"; | 470 invalidation_map[AUTOFILL].payload = "test2"; |
| 558 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 471 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 559 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 472 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 560 WithArg<2>(RecordSyncShare(&records2)))); | 473 RecordSyncShare(&records2))); |
| 561 scheduler()->ScheduleInvalidationNudge(zero(), invalidation_map, FROM_HERE); | 474 scheduler()->ScheduleInvalidationNudge(zero(), invalidation_map, FROM_HERE); |
| 562 RunLoop(); | 475 RunLoop(); |
| 563 | |
| 564 ASSERT_EQ(1U, records2.snapshots.size()); | |
| 565 EXPECT_THAT(invalidation_map, Eq(records2.snapshots[0].source().types)); | |
| 566 EXPECT_EQ(GetUpdatesCallerInfo::NOTIFICATION, | |
| 567 records2.snapshots[0].source().updates_source); | |
| 568 } | 476 } |
| 569 | 477 |
| 570 // Test that polling works as expected. | 478 // Test that polling works as expected. |
| 571 TEST_F(SyncSchedulerTest, Polling) { | 479 TEST_F(SyncSchedulerTest, Polling) { |
| 572 SyncShareRecords records; | 480 SyncShareRecords records; |
| 573 TimeDelta poll_interval(TimeDelta::FromMilliseconds(30)); | 481 TimeDelta poll_interval(TimeDelta::FromMilliseconds(30)); |
| 574 EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples)) | 482 EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples)) |
| 575 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), | 483 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), |
| 576 WithArg<1>(RecordSyncShareMultiple(&records, kMinNumSamples)))); | 484 RecordSyncShareMultiple(&records, kMinNumSamples))); |
| 577 | 485 |
| 578 scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval); | 486 scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval); |
| 579 | 487 |
| 580 TimeTicks optimal_start = TimeTicks::Now() + poll_interval; | 488 TimeTicks optimal_start = TimeTicks::Now() + poll_interval; |
| 581 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 489 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 582 | 490 |
| 583 // Run again to wait for polling. | 491 // Run again to wait for polling. |
| 584 RunLoop(); | 492 RunLoop(); |
| 585 | 493 |
| 586 StopSyncScheduler(); | 494 StopSyncScheduler(); |
| 587 AnalyzePollRun(records, kMinNumSamples, optimal_start, poll_interval); | 495 AnalyzePollRun(records, kMinNumSamples, optimal_start, poll_interval); |
| 588 } | 496 } |
| 589 | 497 |
| 590 // Test that the short poll interval is used. | 498 // Test that the short poll interval is used. |
| 591 TEST_F(SyncSchedulerTest, PollNotificationsDisabled) { | 499 TEST_F(SyncSchedulerTest, PollNotificationsDisabled) { |
| 592 SyncShareRecords records; | 500 SyncShareRecords records; |
| 593 TimeDelta poll_interval(TimeDelta::FromMilliseconds(30)); | 501 TimeDelta poll_interval(TimeDelta::FromMilliseconds(30)); |
| 594 EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples)) | 502 EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples)) |
| 595 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), | 503 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), |
| 596 WithArg<1>(RecordSyncShareMultiple(&records, kMinNumSamples)))); | 504 RecordSyncShareMultiple(&records, kMinNumSamples))); |
| 597 | 505 |
| 598 scheduler()->OnReceivedShortPollIntervalUpdate(poll_interval); | 506 scheduler()->OnReceivedShortPollIntervalUpdate(poll_interval); |
| 599 scheduler()->SetNotificationsEnabled(false); | 507 scheduler()->SetNotificationsEnabled(false); |
| 600 | 508 |
| 601 TimeTicks optimal_start = TimeTicks::Now() + poll_interval; | 509 TimeTicks optimal_start = TimeTicks::Now() + poll_interval; |
| 602 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 510 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 603 | 511 |
| 604 // Run again to wait for polling. | 512 // Run again to wait for polling. |
| 605 RunLoop(); | 513 RunLoop(); |
| 606 | 514 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 662 StopSyncScheduler(); | 570 StopSyncScheduler(); |
| 663 } | 571 } |
| 664 | 572 |
| 665 // Test that no syncing occurs when throttled. | 573 // Test that no syncing occurs when throttled. |
| 666 TEST_F(SyncSchedulerTest, ThrottlingDoesThrottle) { | 574 TEST_F(SyncSchedulerTest, ThrottlingDoesThrottle) { |
| 667 const ModelTypeSet types(BOOKMARKS); | 575 const ModelTypeSet types(BOOKMARKS); |
| 668 TimeDelta poll(TimeDelta::FromMilliseconds(5)); | 576 TimeDelta poll(TimeDelta::FromMilliseconds(5)); |
| 669 TimeDelta throttle(TimeDelta::FromMinutes(10)); | 577 TimeDelta throttle(TimeDelta::FromMinutes(10)); |
| 670 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | 578 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 671 | 579 |
| 672 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_)) | 580 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) |
| 673 .WillOnce(DoAll( | 581 .WillOnce(DoAll( |
| 674 WithArg<1>(sessions::test_util::SimulateThrottled(throttle)), | 582 WithArg<2>(sessions::test_util::SimulateThrottled(throttle)), |
| 675 Return(true))) | 583 Return(true))) |
| 676 .WillRepeatedly(AddFailureAndQuitLoopNow()); | 584 .WillRepeatedly(AddFailureAndQuitLoopNow()); |
| 677 | 585 |
| 678 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 586 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 679 | 587 |
| 680 scheduler()->ScheduleLocalNudge( | 588 scheduler()->ScheduleLocalNudge( |
| 681 TimeDelta::FromMicroseconds(1), types, FROM_HERE); | 589 TimeDelta::FromMicroseconds(1), types, FROM_HERE); |
| 682 PumpLoop(); | 590 PumpLoop(); |
| 683 | 591 |
| 684 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); | 592 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 700 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | 608 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 701 | 609 |
| 702 ::testing::InSequence seq; | 610 ::testing::InSequence seq; |
| 703 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) | 611 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) |
| 704 .WillOnce(DoAll( | 612 .WillOnce(DoAll( |
| 705 WithArg<1>(sessions::test_util::SimulateThrottled(throttle1)), | 613 WithArg<1>(sessions::test_util::SimulateThrottled(throttle1)), |
| 706 Return(true))) | 614 Return(true))) |
| 707 .RetiresOnSaturation(); | 615 .RetiresOnSaturation(); |
| 708 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) | 616 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) |
| 709 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), | 617 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), |
| 710 WithArg<1>(RecordSyncShareMultiple(&records, kMinNumSamples)))); | 618 RecordSyncShareMultiple(&records, kMinNumSamples))); |
| 711 | 619 |
| 712 TimeTicks optimal_start = TimeTicks::Now() + poll + throttle1; | 620 TimeTicks optimal_start = TimeTicks::Now() + poll + throttle1; |
| 713 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 621 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 714 | 622 |
| 715 // Run again to wait for polling. | 623 // Run again to wait for polling. |
| 716 RunLoop(); | 624 RunLoop(); |
| 717 | 625 |
| 718 StopSyncScheduler(); | 626 StopSyncScheduler(); |
| 719 AnalyzePollRun(records, kMinNumSamples, optimal_start, poll); | 627 AnalyzePollRun(records, kMinNumSamples, optimal_start, poll); |
| 720 } | 628 } |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 747 StopSyncScheduler(); | 655 StopSyncScheduler(); |
| 748 } | 656 } |
| 749 | 657 |
| 750 TEST_F(SyncSchedulerTest, ThrottlingExpiresFromConfigure) { | 658 TEST_F(SyncSchedulerTest, ThrottlingExpiresFromConfigure) { |
| 751 SyncShareRecords records; | 659 SyncShareRecords records; |
| 752 TimeDelta poll(TimeDelta::FromDays(1)); | 660 TimeDelta poll(TimeDelta::FromDays(1)); |
| 753 TimeDelta throttle1(TimeDelta::FromMilliseconds(150)); | 661 TimeDelta throttle1(TimeDelta::FromMilliseconds(150)); |
| 754 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | 662 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 755 | 663 |
| 756 ::testing::InSequence seq; | 664 ::testing::InSequence seq; |
| 757 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_)) | 665 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) |
| 758 .WillOnce(DoAll( | 666 .WillOnce(DoAll( |
| 759 WithArg<1>(sessions::test_util::SimulateThrottled(throttle1)), | 667 WithArg<2>(sessions::test_util::SimulateThrottled(throttle1)), |
| 760 Return(true))) | 668 Return(true))) |
| 761 .RetiresOnSaturation(); | 669 .RetiresOnSaturation(); |
| 762 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_)) | 670 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) |
| 763 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess), | 671 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess), |
| 764 QuitLoopNowAction())); | 672 QuitLoopNowAction())); |
| 765 | 673 |
| 766 const ModelTypeSet types(BOOKMARKS); | 674 const ModelTypeSet types(BOOKMARKS); |
| 767 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); | 675 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 768 | 676 |
| 769 CallbackCounter counter; | 677 CallbackCounter counter; |
| 770 ConfigurationParams params( | 678 ConfigurationParams params( |
| 771 GetUpdatesCallerInfo::RECONFIGURATION, | 679 GetUpdatesCallerInfo::RECONFIGURATION, |
| 772 types, | 680 types, |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 827 const ModelTypeSet unthrottled_types(PREFERENCES); | 735 const ModelTypeSet unthrottled_types(PREFERENCES); |
| 828 | 736 |
| 829 ::testing::InSequence seq; | 737 ::testing::InSequence seq; |
| 830 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 738 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 831 .WillOnce(DoAll( | 739 .WillOnce(DoAll( |
| 832 WithArg<2>( | 740 WithArg<2>( |
| 833 sessions::test_util::SimulateTypesThrottled( | 741 sessions::test_util::SimulateTypesThrottled( |
| 834 throttled_types, throttle1)), | 742 throttled_types, throttle1)), |
| 835 Return(true))) | 743 Return(true))) |
| 836 .RetiresOnSaturation(); | 744 .RetiresOnSaturation(); |
| 837 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | |
| 838 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | |
| 839 WithArg<2>(RecordSyncShare(&records)))); | |
| 840 | 745 |
| 841 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 746 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 842 scheduler()->ScheduleLocalNudge(zero(), throttled_types, FROM_HERE); | 747 scheduler()->ScheduleLocalNudge(zero(), throttled_types, FROM_HERE); |
| 843 PumpLoop(); | 748 PumpLoop(); |
| 844 EXPECT_EQ(0U, records.snapshots.size()); | |
| 845 EXPECT_TRUE(GetThrottledTypes().HasAll(throttled_types)); | 749 EXPECT_TRUE(GetThrottledTypes().HasAll(throttled_types)); |
| 846 | 750 |
| 847 // Ignore invalidations for throttled types. | 751 // Ignore invalidations for throttled types. |
| 848 ModelTypeInvalidationMap invalidation_map = | 752 ModelTypeInvalidationMap invalidation_map = |
| 849 ModelTypeSetToInvalidationMap(throttled_types, "test"); | 753 ModelTypeSetToInvalidationMap(throttled_types, "test"); |
| 850 scheduler()->ScheduleInvalidationNudge(zero(), invalidation_map, FROM_HERE); | 754 scheduler()->ScheduleInvalidationNudge(zero(), invalidation_map, FROM_HERE); |
| 851 PumpLoop(); | 755 PumpLoop(); |
| 852 EXPECT_EQ(0U, records.snapshots.size()); | |
| 853 | 756 |
| 854 // Ignore refresh requests for throttled types. | 757 // Ignore refresh requests for throttled types. |
| 855 scheduler()->ScheduleLocalRefreshRequest(zero(), throttled_types, FROM_HERE); | 758 scheduler()->ScheduleLocalRefreshRequest(zero(), throttled_types, FROM_HERE); |
| 856 PumpLoop(); | 759 PumpLoop(); |
| 857 EXPECT_EQ(0U, records.snapshots.size()); | 760 |
| 761 Mock::VerifyAndClearExpectations(syncer()); | |
| 858 | 762 |
| 859 // Local nudges for non-throttled types will trigger a sync. | 763 // Local nudges for non-throttled types will trigger a sync. |
| 764 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | |
| 765 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | |
| 766 RecordSyncShare(&records))); | |
| 860 scheduler()->ScheduleLocalNudge(zero(), unthrottled_types, FROM_HERE); | 767 scheduler()->ScheduleLocalNudge(zero(), unthrottled_types, FROM_HERE); |
| 861 RunLoop(); | 768 RunLoop(); |
| 862 EXPECT_EQ(1U, records.snapshots.size()); | 769 Mock::VerifyAndClearExpectations(syncer()); |
| 863 | 770 |
| 864 StopSyncScheduler(); | 771 StopSyncScheduler(); |
| 865 } | 772 } |
| 866 | 773 |
| 867 // Test nudges / polls don't run in config mode and config tasks do. | 774 // Test nudges / polls don't run in config mode and config tasks do. |
| 868 TEST_F(SyncSchedulerTest, ConfigurationMode) { | 775 TEST_F(SyncSchedulerTest, ConfigurationMode) { |
| 869 TimeDelta poll(TimeDelta::FromMilliseconds(15)); | 776 TimeDelta poll(TimeDelta::FromMilliseconds(15)); |
| 870 SyncShareRecords records; | 777 SyncShareRecords records; |
| 871 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | 778 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 872 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_)) | |
| 873 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess), | |
| 874 WithArg<1>(RecordSyncShare(&records)))) | |
| 875 .RetiresOnSaturation(); | |
| 876 | 779 |
| 877 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); | 780 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 878 | 781 |
| 879 const ModelTypeSet nudge_types(AUTOFILL); | 782 const ModelTypeSet nudge_types(AUTOFILL); |
| 880 scheduler()->ScheduleLocalNudge(zero(), nudge_types, FROM_HERE); | 783 scheduler()->ScheduleLocalNudge(zero(), nudge_types, FROM_HERE); |
| 881 scheduler()->ScheduleLocalNudge(zero(), nudge_types, FROM_HERE); | 784 scheduler()->ScheduleLocalNudge(zero(), nudge_types, FROM_HERE); |
| 882 | 785 |
| 883 const ModelTypeSet config_types(BOOKMARKS); | 786 const ModelTypeSet config_types(BOOKMARKS); |
| 884 | 787 |
| 788 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) | |
| 789 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess), | |
| 790 RecordSyncShare(&records))) | |
| 791 .RetiresOnSaturation(); | |
| 885 CallbackCounter counter; | 792 CallbackCounter counter; |
| 886 ConfigurationParams params( | 793 ConfigurationParams params( |
| 887 GetUpdatesCallerInfo::RECONFIGURATION, | 794 GetUpdatesCallerInfo::RECONFIGURATION, |
| 888 config_types, | 795 config_types, |
| 889 TypesToRoutingInfo(config_types), | 796 TypesToRoutingInfo(config_types), |
| 890 base::Bind(&CallbackCounter::Callback, base::Unretained(&counter))); | 797 base::Bind(&CallbackCounter::Callback, base::Unretained(&counter))); |
| 891 ASSERT_TRUE(scheduler()->ScheduleConfiguration(params)); | 798 ASSERT_TRUE(scheduler()->ScheduleConfiguration(params)); |
| 892 ASSERT_EQ(1, counter.times_called()); | 799 ASSERT_EQ(1, counter.times_called()); |
| 893 | 800 Mock::VerifyAndClearExpectations(syncer()); |
| 894 ASSERT_EQ(1U, records.snapshots.size()); | |
| 895 EXPECT_TRUE(ModelTypeSetMatchesInvalidationMap( | |
| 896 config_types, | |
| 897 records.snapshots[0].source().types)); | |
| 898 | 801 |
| 899 // Switch to NORMAL_MODE to ensure NUDGES were properly saved and run. | 802 // Switch to NORMAL_MODE to ensure NUDGES were properly saved and run. |
| 900 // SyncSchedulerWhiteboxTest also provides coverage for this, but much | |
| 901 // more targeted ('whitebox' style). | |
| 902 scheduler()->OnReceivedLongPollIntervalUpdate(TimeDelta::FromDays(1)); | 803 scheduler()->OnReceivedLongPollIntervalUpdate(TimeDelta::FromDays(1)); |
| 903 SyncShareRecords records2; | 804 SyncShareRecords records2; |
| 904 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 805 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 905 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 806 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 906 WithArg<2>(RecordSyncShare(&records2)))); | 807 RecordSyncShare(&records2))); |
| 907 | 808 |
| 908 // TODO(tim): Figure out how to remove this dangerous need to reset | 809 // TODO(tim): Figure out how to remove this dangerous need to reset |
| 909 // routing info between mode switches. | 810 // routing info between mode switches. |
| 910 context()->set_routing_info(routing_info()); | 811 context()->set_routing_info(routing_info()); |
| 911 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 812 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 912 | 813 |
| 913 ASSERT_EQ(1U, records2.snapshots.size()); | |
| 914 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, | |
| 915 records2.snapshots[0].source().updates_source); | |
| 916 EXPECT_TRUE(ModelTypeSetMatchesInvalidationMap( | |
| 917 nudge_types, | |
| 918 records2.snapshots[0].source().types)); | |
| 919 PumpLoop(); | 814 PumpLoop(); |
| 920 } | 815 } |
| 921 | 816 |
| 922 class BackoffTriggersSyncSchedulerTest : public SyncSchedulerTest { | 817 class BackoffTriggersSyncSchedulerTest : public SyncSchedulerTest { |
| 923 virtual void SetUp() { | 818 virtual void SetUp() { |
| 924 SyncSchedulerTest::SetUp(); | 819 SyncSchedulerTest::SetUp(); |
| 925 UseMockDelayProvider(); | 820 UseMockDelayProvider(); |
| 926 EXPECT_CALL(*delay(), GetDelay(_)) | 821 EXPECT_CALL(*delay(), GetDelay(_)) |
| 927 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(1))); | 822 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(1))); |
| 928 } | 823 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 975 Return(true))) | 870 Return(true))) |
| 976 .WillRepeatedly(DoAll( | 871 .WillRepeatedly(DoAll( |
| 977 Invoke(sessions::test_util::SimulateDownloadUpdatesFailed), | 872 Invoke(sessions::test_util::SimulateDownloadUpdatesFailed), |
| 978 QuitLoopNowAction())); | 873 QuitLoopNowAction())); |
| 979 EXPECT_TRUE(RunAndGetBackoff()); | 874 EXPECT_TRUE(RunAndGetBackoff()); |
| 980 } | 875 } |
| 981 | 876 |
| 982 // Have the syncer fail to get the encryption key yet succeed in downloading | 877 // Have the syncer fail to get the encryption key yet succeed in downloading |
| 983 // updates. Expect this will leave the scheduler in backoff. | 878 // updates. Expect this will leave the scheduler in backoff. |
| 984 TEST_F(BackoffTriggersSyncSchedulerTest, FailGetEncryptionKey) { | 879 TEST_F(BackoffTriggersSyncSchedulerTest, FailGetEncryptionKey) { |
| 985 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_)) | 880 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) |
| 986 .WillOnce(DoAll( | 881 .WillOnce(DoAll( |
| 987 Invoke(sessions::test_util::SimulateGetEncryptionKeyFailed), | 882 Invoke(sessions::test_util::SimulateGetEncryptionKeyFailed), |
| 988 Return(true))) | 883 Return(true))) |
| 989 .WillRepeatedly(DoAll( | 884 .WillRepeatedly(DoAll( |
| 990 Invoke(sessions::test_util::SimulateGetEncryptionKeyFailed), | 885 Invoke(sessions::test_util::SimulateGetEncryptionKeyFailed), |
| 991 QuitLoopNowAction())); | 886 QuitLoopNowAction())); |
| 992 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); | 887 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 993 | 888 |
| 994 ModelTypeSet types(BOOKMARKS); | 889 ModelTypeSet types(BOOKMARKS); |
| 995 CallbackCounter counter; | 890 CallbackCounter counter; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1006 | 901 |
| 1007 // Test that no polls or extraneous nudges occur when in backoff. | 902 // Test that no polls or extraneous nudges occur when in backoff. |
| 1008 TEST_F(SyncSchedulerTest, BackoffDropsJobs) { | 903 TEST_F(SyncSchedulerTest, BackoffDropsJobs) { |
| 1009 SyncShareRecords r; | 904 SyncShareRecords r; |
| 1010 TimeDelta poll(TimeDelta::FromMilliseconds(5)); | 905 TimeDelta poll(TimeDelta::FromMilliseconds(5)); |
| 1011 const ModelTypeSet types(BOOKMARKS); | 906 const ModelTypeSet types(BOOKMARKS); |
| 1012 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | 907 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 1013 UseMockDelayProvider(); | 908 UseMockDelayProvider(); |
| 1014 | 909 |
| 1015 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 910 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 1016 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), | 911 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), |
| 1017 WithArg<2>(RecordSyncShareMultiple(&r, 1U)))); | 912 RecordSyncShareMultiple(&r, 1U))); |
| 1018 EXPECT_CALL(*delay(), GetDelay(_)). | 913 EXPECT_CALL(*delay(), GetDelay(_)). |
| 1019 WillRepeatedly(Return(TimeDelta::FromDays(1))); | 914 WillRepeatedly(Return(TimeDelta::FromDays(1))); |
| 1020 | 915 |
| 1021 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 916 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1022 | 917 |
| 1023 // This nudge should fail and put us into backoff. Thanks to our mock | 918 // This nudge should fail and put us into backoff. Thanks to our mock |
| 1024 // GetDelay() setup above, this will be a long backoff. | 919 // GetDelay() setup above, this will be a long backoff. |
| 1025 scheduler()->ScheduleLocalNudge(zero(), types, FROM_HERE); | 920 scheduler()->ScheduleLocalNudge(zero(), types, FROM_HERE); |
| 1026 RunLoop(); | 921 RunLoop(); |
| 1027 | 922 |
| 923 // From this point forward, no SyncShare functions should be invoked. | |
| 1028 Mock::VerifyAndClearExpectations(syncer()); | 924 Mock::VerifyAndClearExpectations(syncer()); |
| 1029 ASSERT_EQ(1U, r.snapshots.size()); | |
| 1030 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, | |
| 1031 r.snapshots[0].source().updates_source); | |
| 1032 | 925 |
| 1033 // Wait a while (10x poll interval) so a few poll jobs will be attempted. | 926 // Wait a while (10x poll interval) so a few poll jobs will be attempted. |
| 1034 PumpLoopFor(poll * 10); | 927 PumpLoopFor(poll * 10); |
| 1035 | 928 |
| 1036 // Try (and fail) to schedule a nudge. | 929 // Try (and fail) to schedule a nudge. |
| 1037 scheduler()->ScheduleLocalNudge( | 930 scheduler()->ScheduleLocalNudge( |
| 1038 base::TimeDelta::FromMilliseconds(1), | 931 base::TimeDelta::FromMilliseconds(1), |
| 1039 types, | 932 types, |
| 1040 FROM_HERE); | 933 FROM_HERE); |
| 1041 | 934 |
| 1042 Mock::VerifyAndClearExpectations(syncer()); | 935 Mock::VerifyAndClearExpectations(syncer()); |
| 1043 Mock::VerifyAndClearExpectations(delay()); | 936 Mock::VerifyAndClearExpectations(delay()); |
| 1044 | 937 |
| 1045 ASSERT_EQ(1U, r.snapshots.size()); | |
| 1046 | |
| 1047 EXPECT_CALL(*delay(), GetDelay(_)).Times(0); | 938 EXPECT_CALL(*delay(), GetDelay(_)).Times(0); |
| 1048 | 939 |
| 1049 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); | 940 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 1050 | 941 |
| 1051 CallbackCounter counter; | 942 CallbackCounter counter; |
| 1052 ConfigurationParams params( | 943 ConfigurationParams params( |
| 1053 GetUpdatesCallerInfo::RECONFIGURATION, | 944 GetUpdatesCallerInfo::RECONFIGURATION, |
| 1054 types, | 945 types, |
| 1055 TypesToRoutingInfo(types), | 946 TypesToRoutingInfo(types), |
| 1056 base::Bind(&CallbackCounter::Callback, base::Unretained(&counter))); | 947 base::Bind(&CallbackCounter::Callback, base::Unretained(&counter))); |
| 1057 ASSERT_FALSE(scheduler()->ScheduleConfiguration(params)); | 948 ASSERT_FALSE(scheduler()->ScheduleConfiguration(params)); |
| 1058 ASSERT_EQ(0, counter.times_called()); | 949 ASSERT_EQ(0, counter.times_called()); |
| 1059 } | 950 } |
| 1060 | 951 |
| 1061 // Test that backoff is shaping traffic properly with consecutive errors. | 952 // Test that backoff is shaping traffic properly with consecutive errors. |
| 1062 TEST_F(SyncSchedulerTest, BackoffElevation) { | 953 TEST_F(SyncSchedulerTest, BackoffElevation) { |
| 1063 SyncShareRecords r; | 954 SyncShareRecords r; |
| 1064 UseMockDelayProvider(); | 955 UseMockDelayProvider(); |
| 1065 | 956 |
| 1066 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)).Times(kMinNumSamples) | 957 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)).Times(kMinNumSamples) |
| 1067 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), | 958 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), |
| 1068 WithArg<2>(RecordSyncShareMultiple(&r, kMinNumSamples)))); | 959 RecordSyncShareMultiple(&r, kMinNumSamples))); |
| 1069 | 960 |
| 1070 const TimeDelta first = TimeDelta::FromSeconds(kInitialBackoffRetrySeconds); | 961 const TimeDelta first = TimeDelta::FromSeconds(kInitialBackoffRetrySeconds); |
| 1071 const TimeDelta second = TimeDelta::FromMilliseconds(2); | 962 const TimeDelta second = TimeDelta::FromMilliseconds(2); |
| 1072 const TimeDelta third = TimeDelta::FromMilliseconds(3); | 963 const TimeDelta third = TimeDelta::FromMilliseconds(3); |
| 1073 const TimeDelta fourth = TimeDelta::FromMilliseconds(4); | 964 const TimeDelta fourth = TimeDelta::FromMilliseconds(4); |
| 1074 const TimeDelta fifth = TimeDelta::FromMilliseconds(5); | 965 const TimeDelta fifth = TimeDelta::FromMilliseconds(5); |
| 1075 const TimeDelta sixth = TimeDelta::FromDays(1); | 966 const TimeDelta sixth = TimeDelta::FromDays(1); |
| 1076 | 967 |
| 1077 EXPECT_CALL(*delay(), GetDelay(first)).WillOnce(Return(second)) | 968 EXPECT_CALL(*delay(), GetDelay(first)).WillOnce(Return(second)) |
| 1078 .RetiresOnSaturation(); | 969 .RetiresOnSaturation(); |
| 1079 EXPECT_CALL(*delay(), GetDelay(second)).WillOnce(Return(third)) | 970 EXPECT_CALL(*delay(), GetDelay(second)).WillOnce(Return(third)) |
| 1080 .RetiresOnSaturation(); | 971 .RetiresOnSaturation(); |
| 1081 EXPECT_CALL(*delay(), GetDelay(third)).WillOnce(Return(fourth)) | 972 EXPECT_CALL(*delay(), GetDelay(third)).WillOnce(Return(fourth)) |
| 1082 .RetiresOnSaturation(); | 973 .RetiresOnSaturation(); |
| 1083 EXPECT_CALL(*delay(), GetDelay(fourth)).WillOnce(Return(fifth)) | 974 EXPECT_CALL(*delay(), GetDelay(fourth)).WillOnce(Return(fifth)) |
| 1084 .RetiresOnSaturation(); | 975 .RetiresOnSaturation(); |
| 1085 EXPECT_CALL(*delay(), GetDelay(fifth)).WillOnce(Return(sixth)); | 976 EXPECT_CALL(*delay(), GetDelay(fifth)).WillOnce(Return(sixth)); |
| 1086 | 977 |
| 1087 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 978 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1088 | 979 |
| 1089 // Run again with a nudge. | 980 // Run again with a nudge. |
| 1090 scheduler()->ScheduleLocalNudge(zero(), ModelTypeSet(BOOKMARKS), FROM_HERE); | 981 scheduler()->ScheduleLocalNudge(zero(), ModelTypeSet(BOOKMARKS), FROM_HERE); |
| 1091 RunLoop(); | 982 RunLoop(); |
| 1092 | 983 |
| 1093 ASSERT_EQ(kMinNumSamples, r.snapshots.size()); | 984 ASSERT_EQ(kMinNumSamples, r.times.size()); |
| 1094 EXPECT_GE(r.times[1] - r.times[0], second); | 985 EXPECT_GE(r.times[1] - r.times[0], second); |
| 1095 EXPECT_GE(r.times[2] - r.times[1], third); | 986 EXPECT_GE(r.times[2] - r.times[1], third); |
| 1096 EXPECT_GE(r.times[3] - r.times[2], fourth); | 987 EXPECT_GE(r.times[3] - r.times[2], fourth); |
| 1097 EXPECT_GE(r.times[4] - r.times[3], fifth); | 988 EXPECT_GE(r.times[4] - r.times[3], fifth); |
| 1098 } | 989 } |
| 1099 | 990 |
| 1100 // Test that things go back to normal once a retry makes forward progress. | 991 // Test that things go back to normal once a retry makes forward progress. |
| 1101 TEST_F(SyncSchedulerTest, BackoffRelief) { | 992 TEST_F(SyncSchedulerTest, BackoffRelief) { |
| 1102 SyncShareRecords r; | 993 SyncShareRecords r; |
| 1103 const TimeDelta poll(TimeDelta::FromMilliseconds(10)); | 994 const TimeDelta poll(TimeDelta::FromMilliseconds(10)); |
| 1104 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | 995 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 1105 UseMockDelayProvider(); | 996 UseMockDelayProvider(); |
| 1106 | 997 |
| 1107 const TimeDelta backoff = TimeDelta::FromMilliseconds(5); | 998 const TimeDelta backoff = TimeDelta::FromMilliseconds(5); |
| 1108 | |
| 1109 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | |
| 1110 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), | |
| 1111 WithArg<2>(RecordSyncShareMultiple(&r, kMinNumSamples)))) | |
| 1112 .WillRepeatedly(DoAll( | |
| 1113 Invoke(sessions::test_util::SimulateNormalSuccess), | |
| 1114 WithArg<2>(RecordSyncShareMultiple(&r, kMinNumSamples)))); | |
| 1115 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) | |
| 1116 .WillRepeatedly(DoAll( | |
| 1117 Invoke(sessions::test_util::SimulatePollSuccess), | |
| 1118 WithArg<1>(RecordSyncShareMultiple(&r, kMinNumSamples)))); | |
| 1119 EXPECT_CALL(*delay(), GetDelay(_)).WillOnce(Return(backoff)); | 999 EXPECT_CALL(*delay(), GetDelay(_)).WillOnce(Return(backoff)); |
| 1120 | 1000 |
| 1121 // Optimal start for the post-backoff poll party. | 1001 // Optimal start for the post-backoff poll party. |
| 1122 TimeTicks optimal_start = TimeTicks::Now(); | 1002 TimeTicks optimal_start = TimeTicks::Now(); |
| 1123 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 1003 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1124 | 1004 |
| 1125 // Run again to wait for polling. | 1005 // Kick off the test with a failed nudge. |
| 1006 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | |
| 1007 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), | |
| 1008 RecordSyncShare(&r))); | |
| 1126 scheduler()->ScheduleLocalNudge(zero(), ModelTypeSet(BOOKMARKS), FROM_HERE); | 1009 scheduler()->ScheduleLocalNudge(zero(), ModelTypeSet(BOOKMARKS), FROM_HERE); |
| 1127 RunLoop(); | 1010 RunLoop(); |
| 1011 Mock::VerifyAndClearExpectations(syncer()); | |
| 1012 TimeTicks optimal_job_time = optimal_start; | |
| 1013 ASSERT_EQ(1U, r.times.size()); | |
| 1014 EXPECT_GE(r.times[0], optimal_job_time); | |
| 1128 | 1015 |
| 1129 StopSyncScheduler(); | 1016 // The retry succeeds. |
| 1017 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | |
| 1018 .WillOnce(DoAll( | |
| 1019 Invoke(sessions::test_util::SimulateNormalSuccess), | |
| 1020 RecordSyncShare(&r))); | |
| 1021 RunLoop(); | |
| 1022 Mock::VerifyAndClearExpectations(syncer()); | |
| 1023 optimal_job_time = optimal_job_time + backoff; | |
| 1024 ASSERT_EQ(2U, r.times.size()); | |
| 1025 EXPECT_GE(r.times[1], optimal_job_time); | |
| 1130 | 1026 |
| 1131 EXPECT_EQ(kMinNumSamples, r.times.size()); | 1027 // Now let the Poll timer do its thing. |
| 1132 | 1028 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) |
| 1133 // The first nudge ran as soon as possible. It failed. | 1029 .WillRepeatedly(DoAll( |
| 1134 TimeTicks optimal_job_time = optimal_start; | 1030 Invoke(sessions::test_util::SimulatePollSuccess), |
| 1135 EXPECT_GE(r.times[0], optimal_job_time); | 1031 RecordSyncShareMultiple(&r, kMinNumSamples))); |
| 1136 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, | 1032 RunLoop(); |
| 1137 r.snapshots[0].source().updates_source); | 1033 Mock::VerifyAndClearExpectations(syncer()); |
| 1138 | 1034 ASSERT_EQ(kMinNumSamples, r.times.size()); |
| 1139 // It was followed by a successful retry nudge shortly afterward. | 1035 for (size_t i = 2; i < r.times.size(); i++) { |
| 1140 optimal_job_time = optimal_job_time + backoff; | |
| 1141 EXPECT_GE(r.times[1], optimal_job_time); | |
| 1142 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, | |
| 1143 r.snapshots[1].source().updates_source); | |
| 1144 // After that, we went back to polling. | |
| 1145 for (size_t i = 2; i < r.snapshots.size(); i++) { | |
| 1146 optimal_job_time = optimal_job_time + poll; | 1036 optimal_job_time = optimal_job_time + poll; |
| 1147 SCOPED_TRACE(testing::Message() << "SyncShare # (" << i << ")"); | 1037 SCOPED_TRACE(testing::Message() << "SyncShare # (" << i << ")"); |
| 1148 EXPECT_GE(r.times[i], optimal_job_time); | 1038 EXPECT_GE(r.times[i], optimal_job_time); |
| 1149 EXPECT_EQ(GetUpdatesCallerInfo::PERIODIC, | |
| 1150 r.snapshots[i].source().updates_source); | |
| 1151 } | 1039 } |
| 1040 | |
| 1041 StopSyncScheduler(); | |
| 1152 } | 1042 } |
| 1153 | 1043 |
| 1154 // Test that poll failures are ignored. They should have no effect on | 1044 // Test that poll failures are ignored. They should have no effect on |
| 1155 // subsequent poll attempts, nor should they trigger a backoff/retry. | 1045 // subsequent poll attempts, nor should they trigger a backoff/retry. |
| 1156 TEST_F(SyncSchedulerTest, TransientPollFailure) { | 1046 TEST_F(SyncSchedulerTest, TransientPollFailure) { |
| 1157 SyncShareRecords r; | 1047 SyncShareRecords r; |
| 1158 const TimeDelta poll_interval(TimeDelta::FromMilliseconds(1)); | 1048 const TimeDelta poll_interval(TimeDelta::FromMilliseconds(1)); |
| 1159 scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval); | 1049 scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval); |
| 1160 UseMockDelayProvider(); // Will cause test failure if backoff is initiated. | 1050 UseMockDelayProvider(); // Will cause test failure if backoff is initiated. |
| 1161 | 1051 |
| 1162 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) | 1052 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) |
| 1163 .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollFailed), | 1053 .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollFailed), |
| 1164 WithArg<1>(RecordSyncShare(&r)))) | 1054 RecordSyncShare(&r))) |
| 1165 .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), | 1055 .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), |
| 1166 WithArg<1>(RecordSyncShare(&r)))); | 1056 RecordSyncShare(&r))); |
| 1167 | 1057 |
| 1168 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 1058 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1169 | 1059 |
| 1170 // Run the unsucessful poll. The failed poll should not trigger backoff. | 1060 // Run the unsucessful poll. The failed poll should not trigger backoff. |
| 1171 RunLoop(); | 1061 RunLoop(); |
| 1172 EXPECT_FALSE(scheduler()->IsBackingOff()); | 1062 EXPECT_FALSE(scheduler()->IsBackingOff()); |
| 1173 | 1063 |
| 1174 // Run the successful poll. | 1064 // Run the successful poll. |
| 1175 RunLoop(); | 1065 RunLoop(); |
| 1176 EXPECT_FALSE(scheduler()->IsBackingOff()); | 1066 EXPECT_FALSE(scheduler()->IsBackingOff()); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1254 scheduler()->OnConnectionStatusChange(); | 1144 scheduler()->OnConnectionStatusChange(); |
| 1255 connection()->SetServerReachable(); | 1145 connection()->SetServerReachable(); |
| 1256 connection()->UpdateConnectionStatus(); | 1146 connection()->UpdateConnectionStatus(); |
| 1257 scheduler()->ScheduleLocalNudge(zero(), ModelTypeSet(BOOKMARKS), FROM_HERE); | 1147 scheduler()->ScheduleLocalNudge(zero(), ModelTypeSet(BOOKMARKS), FROM_HERE); |
| 1258 base::MessageLoop::current()->RunUntilIdle(); | 1148 base::MessageLoop::current()->RunUntilIdle(); |
| 1259 } | 1149 } |
| 1260 | 1150 |
| 1261 // Tests that we don't crash trying to run two canaries at once if we receive | 1151 // Tests that we don't crash trying to run two canaries at once if we receive |
| 1262 // extra connection status change notifications. See crbug.com/190085. | 1152 // extra connection status change notifications. See crbug.com/190085. |
| 1263 TEST_F(SyncSchedulerTest, DoubleCanaryInConfigure) { | 1153 TEST_F(SyncSchedulerTest, DoubleCanaryInConfigure) { |
| 1264 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_)) | 1154 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) |
| 1265 .WillRepeatedly(DoAll( | 1155 .WillRepeatedly(DoAll( |
| 1266 Invoke(sessions::test_util::SimulateConfigureConnectionFailure), | 1156 Invoke(sessions::test_util::SimulateConfigureConnectionFailure), |
| 1267 Return(true))); | 1157 Return(true))); |
| 1268 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); | 1158 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 1269 connection()->SetServerNotReachable(); | 1159 connection()->SetServerNotReachable(); |
| 1270 connection()->UpdateConnectionStatus(); | 1160 connection()->UpdateConnectionStatus(); |
| 1271 | 1161 |
| 1272 ModelTypeSet model_types(BOOKMARKS); | 1162 ModelTypeSet model_types(BOOKMARKS); |
| 1273 CallbackCounter counter; | 1163 CallbackCounter counter; |
| 1274 ConfigurationParams params( | 1164 ConfigurationParams params( |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1285 } | 1175 } |
| 1286 | 1176 |
| 1287 TEST_F(SyncSchedulerTest, PollFromCanaryAfterAuthError) { | 1177 TEST_F(SyncSchedulerTest, PollFromCanaryAfterAuthError) { |
| 1288 SyncShareRecords records; | 1178 SyncShareRecords records; |
| 1289 TimeDelta poll(TimeDelta::FromMilliseconds(15)); | 1179 TimeDelta poll(TimeDelta::FromMilliseconds(15)); |
| 1290 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | 1180 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 1291 | 1181 |
| 1292 ::testing::InSequence seq; | 1182 ::testing::InSequence seq; |
| 1293 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) | 1183 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) |
| 1294 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), | 1184 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), |
| 1295 WithArg<1>(RecordSyncShareMultiple(&records, kMinNumSamples)))); | 1185 RecordSyncShareMultiple(&records, kMinNumSamples))); |
| 1296 | 1186 |
| 1297 connection()->SetServerStatus(HttpResponse::SYNC_AUTH_ERROR); | 1187 connection()->SetServerStatus(HttpResponse::SYNC_AUTH_ERROR); |
| 1298 StartSyncScheduler(SyncScheduler::NORMAL_MODE); | 1188 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1299 | 1189 |
| 1300 // Run to wait for polling. | 1190 // Run to wait for polling. |
| 1301 RunLoop(); | 1191 RunLoop(); |
| 1302 | 1192 |
| 1303 // Normally OnCredentialsUpdated calls TryCanaryJob that doesn't run Poll, | 1193 // Normally OnCredentialsUpdated calls TryCanaryJob that doesn't run Poll, |
| 1304 // but after poll finished with auth error from poll timer it should retry | 1194 // but after poll finished with auth error from poll timer it should retry |
| 1305 // poll once more | 1195 // poll once more |
| 1306 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) | 1196 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) |
| 1307 .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), | 1197 .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), |
| 1308 WithArg<1>(RecordSyncShare(&records)))); | 1198 RecordSyncShare(&records))); |
| 1309 scheduler()->OnCredentialsUpdated(); | 1199 scheduler()->OnCredentialsUpdated(); |
| 1310 connection()->SetServerStatus(HttpResponse::SERVER_CONNECTION_OK); | 1200 connection()->SetServerStatus(HttpResponse::SERVER_CONNECTION_OK); |
| 1311 StopSyncScheduler(); | 1201 StopSyncScheduler(); |
| 1312 } | 1202 } |
| 1313 | 1203 |
| 1314 } // namespace syncer | 1204 } // namespace syncer |
| OLD | NEW |