| 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/run_loop.h" | 9 #include "base/run_loop.h" |
| 10 #include "base/test/test_timeouts.h" | 10 #include "base/test/test_timeouts.h" |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 SCOPED_TRACE(testing::Message() << "SyncShare # (" << i << ")"); | 187 SCOPED_TRACE(testing::Message() << "SyncShare # (" << i << ")"); |
| 188 TimeTicks optimal_next_sync = optimal_start + poll_interval * i; | 188 TimeTicks optimal_next_sync = optimal_start + poll_interval * i; |
| 189 EXPECT_GE(times[i], optimal_next_sync); | 189 EXPECT_GE(times[i], optimal_next_sync); |
| 190 } | 190 } |
| 191 } | 191 } |
| 192 | 192 |
| 193 void DoQuitLoopNow() { | 193 void DoQuitLoopNow() { |
| 194 QuitLoopNow(); | 194 QuitLoopNow(); |
| 195 } | 195 } |
| 196 | 196 |
| 197 void StartSyncConfiguration() { | 197 void StartSyncScheduler(SyncScheduler::Mode mode) { |
| 198 scheduler()->Start(SyncScheduler::CONFIGURATION_MODE, base::Time()); | 198 scheduler()->Start(mode); |
| 199 } | |
| 200 | |
| 201 void StartSyncScheduler(base::Time last_poll_time) { | |
| 202 scheduler()->Start(SyncScheduler::NORMAL_MODE, last_poll_time); | |
| 203 } | 199 } |
| 204 | 200 |
| 205 // This stops the scheduler synchronously. | 201 // This stops the scheduler synchronously. |
| 206 void StopSyncScheduler() { | 202 void StopSyncScheduler() { |
| 207 base::MessageLoop::current()->PostTask( | 203 base::MessageLoop::current()->PostTask( |
| 208 FROM_HERE, | 204 FROM_HERE, |
| 209 base::Bind(&SyncSchedulerTest::DoQuitLoopNow, | 205 base::Bind(&SyncSchedulerTest::DoQuitLoopNow, |
| 210 weak_ptr_factory_.GetWeakPtr())); | 206 weak_ptr_factory_.GetWeakPtr())); |
| 211 RunLoop(); | 207 RunLoop(); |
| 212 } | 208 } |
| 213 | 209 |
| 214 bool RunAndGetBackoff() { | 210 bool RunAndGetBackoff() { |
| 215 ModelTypeSet nudge_types(THEMES); | 211 ModelTypeSet nudge_types(THEMES); |
| 216 StartSyncScheduler(base::Time()); | 212 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 217 | 213 |
| 218 scheduler()->ScheduleLocalNudge(nudge_types, FROM_HERE); | 214 scheduler()->ScheduleLocalNudge(nudge_types, FROM_HERE); |
| 219 RunLoop(); | 215 RunLoop(); |
| 220 | 216 |
| 221 return scheduler()->IsBackingOff(); | 217 return scheduler()->IsBackingOff(); |
| 222 } | 218 } |
| 223 | 219 |
| 224 void UseMockDelayProvider() { | 220 void UseMockDelayProvider() { |
| 225 delay_ = new MockDelayProvider(); | 221 delay_ = new MockDelayProvider(); |
| 226 scheduler_->delay_provider_.reset(delay_); | 222 scheduler_->delay_provider_.reset(delay_); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 std::vector<scoped_refptr<ModelSafeWorker> > workers_; | 257 std::vector<scoped_refptr<ModelSafeWorker> > workers_; |
| 262 scoped_refptr<ExtensionsActivity> extensions_activity_; | 258 scoped_refptr<ExtensionsActivity> extensions_activity_; |
| 263 ModelSafeRoutingInfo routing_info_; | 259 ModelSafeRoutingInfo routing_info_; |
| 264 base::WeakPtrFactory<SyncSchedulerTest> weak_ptr_factory_; | 260 base::WeakPtrFactory<SyncSchedulerTest> weak_ptr_factory_; |
| 265 }; | 261 }; |
| 266 | 262 |
| 267 void RecordSyncShareImpl(SyncShareTimes* times) { | 263 void RecordSyncShareImpl(SyncShareTimes* times) { |
| 268 times->push_back(TimeTicks::Now()); | 264 times->push_back(TimeTicks::Now()); |
| 269 } | 265 } |
| 270 | 266 |
| 271 ACTION_P2(RecordSyncShare, times, success) { | 267 ACTION_P(RecordSyncShare, times) { |
| 272 RecordSyncShareImpl(times); | 268 RecordSyncShareImpl(times); |
| 273 if (base::MessageLoop::current()->is_running()) | 269 if (base::MessageLoop::current()->is_running()) |
| 274 QuitLoopNow(); | 270 QuitLoopNow(); |
| 275 return success; | 271 return true; |
| 276 } | 272 } |
| 277 | 273 |
| 278 ACTION_P3(RecordSyncShareMultiple, times, quit_after, success) { | 274 ACTION_P2(RecordSyncShareMultiple, times, quit_after) { |
| 279 RecordSyncShareImpl(times); | 275 RecordSyncShareImpl(times); |
| 280 EXPECT_LE(times->size(), quit_after); | 276 EXPECT_LE(times->size(), quit_after); |
| 281 if (times->size() >= quit_after && | 277 if (times->size() >= quit_after && |
| 282 base::MessageLoop::current()->is_running()) { | 278 base::MessageLoop::current()->is_running()) { |
| 283 QuitLoopNow(); | 279 QuitLoopNow(); |
| 284 } | 280 } |
| 285 return success; | 281 return true; |
| 286 } | 282 } |
| 287 | 283 |
| 288 ACTION_P(StopScheduler, scheduler) { | 284 ACTION_P(StopScheduler, scheduler) { |
| 289 scheduler->Stop(); | 285 scheduler->Stop(); |
| 290 } | 286 } |
| 291 | 287 |
| 292 ACTION(AddFailureAndQuitLoopNow) { | 288 ACTION(AddFailureAndQuitLoopNow) { |
| 293 ADD_FAILURE(); | 289 ADD_FAILURE(); |
| 294 QuitLoopNow(); | 290 QuitLoopNow(); |
| 295 return true; | 291 return true; |
| 296 } | 292 } |
| 297 | 293 |
| 298 ACTION_P(QuitLoopNowAction, success) { | 294 ACTION(QuitLoopNowAction) { |
| 299 QuitLoopNow(); | 295 QuitLoopNow(); |
| 300 return success; | 296 return true; |
| 301 } | 297 } |
| 302 | 298 |
| 303 // Test nudge scheduling. | 299 // Test nudge scheduling. |
| 304 TEST_F(SyncSchedulerTest, Nudge) { | 300 TEST_F(SyncSchedulerTest, Nudge) { |
| 305 SyncShareTimes times; | 301 SyncShareTimes times; |
| 306 ModelTypeSet model_types(THEMES); | 302 ModelTypeSet model_types(THEMES); |
| 307 | 303 |
| 308 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 304 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 309 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 305 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 310 RecordSyncShare(×, true))) | 306 RecordSyncShare(×))) |
| 311 .RetiresOnSaturation(); | 307 .RetiresOnSaturation(); |
| 312 | 308 |
| 313 StartSyncScheduler(base::Time()); | 309 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 314 | 310 |
| 315 scheduler()->ScheduleLocalNudge(model_types, FROM_HERE); | 311 scheduler()->ScheduleLocalNudge(model_types, FROM_HERE); |
| 316 RunLoop(); | 312 RunLoop(); |
| 317 | 313 |
| 318 Mock::VerifyAndClearExpectations(syncer()); | 314 Mock::VerifyAndClearExpectations(syncer()); |
| 319 | 315 |
| 320 // Make sure a second, later, nudge is unaffected by first (no coalescing). | 316 // Make sure a second, later, nudge is unaffected by first (no coalescing). |
| 321 SyncShareTimes times2; | 317 SyncShareTimes times2; |
| 322 model_types.Remove(THEMES); | 318 model_types.Remove(THEMES); |
| 323 model_types.Put(TYPED_URLS); | 319 model_types.Put(TYPED_URLS); |
| 324 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 320 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 325 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 321 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 326 RecordSyncShare(×2, true))); | 322 RecordSyncShare(×2))); |
| 327 scheduler()->ScheduleLocalNudge(model_types, FROM_HERE); | 323 scheduler()->ScheduleLocalNudge(model_types, FROM_HERE); |
| 328 RunLoop(); | 324 RunLoop(); |
| 329 } | 325 } |
| 330 | 326 |
| 331 // Make sure a regular config command is scheduled fine in the absence of any | 327 // Make sure a regular config command is scheduled fine in the absence of any |
| 332 // errors. | 328 // errors. |
| 333 TEST_F(SyncSchedulerTest, Config) { | 329 TEST_F(SyncSchedulerTest, Config) { |
| 334 SyncShareTimes times; | 330 SyncShareTimes times; |
| 335 const ModelTypeSet model_types(THEMES); | 331 const ModelTypeSet model_types(THEMES); |
| 336 | 332 |
| 337 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) | 333 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) |
| 338 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess), | 334 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess), |
| 339 RecordSyncShare(×, true))); | 335 RecordSyncShare(×))); |
| 340 | 336 |
| 341 StartSyncConfiguration(); | 337 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 342 | 338 |
| 343 CallbackCounter ready_counter; | 339 CallbackCounter ready_counter; |
| 344 CallbackCounter retry_counter; | 340 CallbackCounter retry_counter; |
| 345 ConfigurationParams params( | 341 ConfigurationParams params( |
| 346 GetUpdatesCallerInfo::RECONFIGURATION, | 342 GetUpdatesCallerInfo::RECONFIGURATION, |
| 347 model_types, | 343 model_types, |
| 348 TypesToRoutingInfo(model_types), | 344 TypesToRoutingInfo(model_types), |
| 349 base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), | 345 base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), |
| 350 base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); | 346 base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); |
| 351 scheduler()->ScheduleConfiguration(params); | 347 scheduler()->ScheduleConfiguration(params); |
| 352 PumpLoop(); | 348 PumpLoop(); |
| 353 ASSERT_EQ(1, ready_counter.times_called()); | 349 ASSERT_EQ(1, ready_counter.times_called()); |
| 354 ASSERT_EQ(0, retry_counter.times_called()); | 350 ASSERT_EQ(0, retry_counter.times_called()); |
| 355 } | 351 } |
| 356 | 352 |
| 357 // Simulate a failure and make sure the config request is retried. | 353 // Simulate a failure and make sure the config request is retried. |
| 358 TEST_F(SyncSchedulerTest, ConfigWithBackingOff) { | 354 TEST_F(SyncSchedulerTest, ConfigWithBackingOff) { |
| 359 UseMockDelayProvider(); | 355 UseMockDelayProvider(); |
| 360 EXPECT_CALL(*delay(), GetDelay(_)) | 356 EXPECT_CALL(*delay(), GetDelay(_)) |
| 361 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(20))); | 357 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(20))); |
| 362 SyncShareTimes times; | 358 SyncShareTimes times; |
| 363 const ModelTypeSet model_types(THEMES); | 359 const ModelTypeSet model_types(THEMES); |
| 364 | 360 |
| 365 StartSyncConfiguration(); | 361 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 366 | 362 |
| 367 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) | 363 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) |
| 368 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed), | 364 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed), |
| 369 RecordSyncShare(×, false))) | 365 RecordSyncShare(×))) |
| 370 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed), | 366 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed), |
| 371 RecordSyncShare(×, false))); | 367 RecordSyncShare(×))); |
| 372 | 368 |
| 373 CallbackCounter ready_counter; | 369 CallbackCounter ready_counter; |
| 374 CallbackCounter retry_counter; | 370 CallbackCounter retry_counter; |
| 375 ConfigurationParams params( | 371 ConfigurationParams params( |
| 376 GetUpdatesCallerInfo::RECONFIGURATION, | 372 GetUpdatesCallerInfo::RECONFIGURATION, |
| 377 model_types, | 373 model_types, |
| 378 TypesToRoutingInfo(model_types), | 374 TypesToRoutingInfo(model_types), |
| 379 base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), | 375 base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), |
| 380 base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); | 376 base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); |
| 381 scheduler()->ScheduleConfiguration(params); | 377 scheduler()->ScheduleConfiguration(params); |
| 382 RunLoop(); | 378 RunLoop(); |
| 383 ASSERT_EQ(0, ready_counter.times_called()); | 379 ASSERT_EQ(0, ready_counter.times_called()); |
| 384 ASSERT_EQ(1, retry_counter.times_called()); | 380 ASSERT_EQ(1, retry_counter.times_called()); |
| 385 | 381 |
| 386 // RunLoop() will trigger TryCanaryJob which will retry configuration. | 382 // RunLoop() will trigger TryCanaryJob which will retry configuration. |
| 387 // Since retry_task was already called it shouldn't be called again. | 383 // Since retry_task was already called it shouldn't be called again. |
| 388 RunLoop(); | 384 RunLoop(); |
| 389 ASSERT_EQ(0, ready_counter.times_called()); | 385 ASSERT_EQ(0, ready_counter.times_called()); |
| 390 ASSERT_EQ(1, retry_counter.times_called()); | 386 ASSERT_EQ(1, retry_counter.times_called()); |
| 391 | 387 |
| 392 Mock::VerifyAndClearExpectations(syncer()); | 388 Mock::VerifyAndClearExpectations(syncer()); |
| 393 | 389 |
| 394 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) | 390 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) |
| 395 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess), | 391 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess), |
| 396 RecordSyncShare(×, true))); | 392 RecordSyncShare(×))); |
| 397 RunLoop(); | 393 RunLoop(); |
| 398 | 394 |
| 399 ASSERT_EQ(1, ready_counter.times_called()); | 395 ASSERT_EQ(1, ready_counter.times_called()); |
| 400 } | 396 } |
| 401 | 397 |
| 402 // Simuilate SyncSchedulerImpl::Stop being called in the middle of Configure. | 398 // Simuilate SyncSchedulerImpl::Stop being called in the middle of Configure. |
| 403 // This can happen if server returns NOT_MY_BIRTHDAY. | 399 // This can happen if server returns NOT_MY_BIRTHDAY. |
| 404 TEST_F(SyncSchedulerTest, ConfigWithStop) { | 400 TEST_F(SyncSchedulerTest, ConfigWithStop) { |
| 405 UseMockDelayProvider(); | 401 UseMockDelayProvider(); |
| 406 EXPECT_CALL(*delay(), GetDelay(_)) | 402 EXPECT_CALL(*delay(), GetDelay(_)) |
| 407 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(20))); | 403 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(20))); |
| 408 SyncShareTimes times; | 404 SyncShareTimes times; |
| 409 const ModelTypeSet model_types(THEMES); | 405 const ModelTypeSet model_types(THEMES); |
| 410 | 406 |
| 411 StartSyncConfiguration(); | 407 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 412 | 408 |
| 413 // Make ConfigureSyncShare call scheduler->Stop(). It is not supposed to call | 409 // Make ConfigureSyncShare call scheduler->Stop(). It is not supposed to call |
| 414 // retry_task or dereference configuration params. | 410 // retry_task or dereference configuration params. |
| 415 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) | 411 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) |
| 416 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed), | 412 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed), |
| 417 StopScheduler(scheduler()), | 413 StopScheduler(scheduler()), |
| 418 RecordSyncShare(×, false))); | 414 RecordSyncShare(×))); |
| 419 | 415 |
| 420 CallbackCounter ready_counter; | 416 CallbackCounter ready_counter; |
| 421 CallbackCounter retry_counter; | 417 CallbackCounter retry_counter; |
| 422 ConfigurationParams params( | 418 ConfigurationParams params( |
| 423 GetUpdatesCallerInfo::RECONFIGURATION, | 419 GetUpdatesCallerInfo::RECONFIGURATION, |
| 424 model_types, | 420 model_types, |
| 425 TypesToRoutingInfo(model_types), | 421 TypesToRoutingInfo(model_types), |
| 426 base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), | 422 base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), |
| 427 base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); | 423 base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); |
| 428 scheduler()->ScheduleConfiguration(params); | 424 scheduler()->ScheduleConfiguration(params); |
| 429 PumpLoop(); | 425 PumpLoop(); |
| 430 ASSERT_EQ(0, ready_counter.times_called()); | 426 ASSERT_EQ(0, ready_counter.times_called()); |
| 431 ASSERT_EQ(0, retry_counter.times_called()); | 427 ASSERT_EQ(0, retry_counter.times_called()); |
| 432 } | 428 } |
| 433 | 429 |
| 434 // Issue a nudge when the config has failed. Make sure both the config and | 430 // Issue a nudge when the config has failed. Make sure both the config and |
| 435 // nudge are executed. | 431 // nudge are executed. |
| 436 TEST_F(SyncSchedulerTest, NudgeWithConfigWithBackingOff) { | 432 TEST_F(SyncSchedulerTest, NudgeWithConfigWithBackingOff) { |
| 437 const ModelTypeSet model_types(THEMES); | 433 const ModelTypeSet model_types(THEMES); |
| 438 UseMockDelayProvider(); | 434 UseMockDelayProvider(); |
| 439 EXPECT_CALL(*delay(), GetDelay(_)) | 435 EXPECT_CALL(*delay(), GetDelay(_)) |
| 440 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(50))); | 436 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(50))); |
| 441 SyncShareTimes times; | 437 SyncShareTimes times; |
| 442 | 438 |
| 443 StartSyncConfiguration(); | 439 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 444 | 440 |
| 445 // Request a configure and make sure it fails. | 441 // Request a configure and make sure it fails. |
| 446 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) | 442 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) |
| 447 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed), | 443 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed), |
| 448 RecordSyncShare(×, false))); | 444 RecordSyncShare(×))); |
| 449 CallbackCounter ready_counter; | 445 CallbackCounter ready_counter; |
| 450 CallbackCounter retry_counter; | 446 CallbackCounter retry_counter; |
| 451 ConfigurationParams params( | 447 ConfigurationParams params( |
| 452 GetUpdatesCallerInfo::RECONFIGURATION, | 448 GetUpdatesCallerInfo::RECONFIGURATION, |
| 453 model_types, | 449 model_types, |
| 454 TypesToRoutingInfo(model_types), | 450 TypesToRoutingInfo(model_types), |
| 455 base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), | 451 base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), |
| 456 base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); | 452 base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); |
| 457 scheduler()->ScheduleConfiguration(params); | 453 scheduler()->ScheduleConfiguration(params); |
| 458 RunLoop(); | 454 RunLoop(); |
| 459 ASSERT_EQ(0, ready_counter.times_called()); | 455 ASSERT_EQ(0, ready_counter.times_called()); |
| 460 ASSERT_EQ(1, retry_counter.times_called()); | 456 ASSERT_EQ(1, retry_counter.times_called()); |
| 461 Mock::VerifyAndClearExpectations(syncer()); | 457 Mock::VerifyAndClearExpectations(syncer()); |
| 462 | 458 |
| 463 // Ask for a nudge while dealing with repeated configure failure. | 459 // Ask for a nudge while dealing with repeated configure failure. |
| 464 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) | 460 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) |
| 465 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed), | 461 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureFailed), |
| 466 RecordSyncShare(×, false))); | 462 RecordSyncShare(×))); |
| 467 scheduler()->ScheduleLocalNudge(model_types, FROM_HERE); | 463 scheduler()->ScheduleLocalNudge(model_types, FROM_HERE); |
| 468 RunLoop(); | 464 RunLoop(); |
| 469 // Note that we're not RunLoop()ing for the NUDGE we just scheduled, but | 465 // Note that we're not RunLoop()ing for the NUDGE we just scheduled, but |
| 470 // for the first retry attempt from the config job (after | 466 // for the first retry attempt from the config job (after |
| 471 // waiting ~+/- 50ms). | 467 // waiting ~+/- 50ms). |
| 472 Mock::VerifyAndClearExpectations(syncer()); | 468 Mock::VerifyAndClearExpectations(syncer()); |
| 473 ASSERT_EQ(0, ready_counter.times_called()); | 469 ASSERT_EQ(0, ready_counter.times_called()); |
| 474 | 470 |
| 475 // Let the next configure retry succeed. | 471 // Let the next configure retry succeed. |
| 476 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) | 472 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) |
| 477 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess), | 473 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess), |
| 478 RecordSyncShare(×, true))); | 474 RecordSyncShare(×))); |
| 479 RunLoop(); | 475 RunLoop(); |
| 480 | 476 |
| 481 // Now change the mode so nudge can execute. | 477 // Now change the mode so nudge can execute. |
| 482 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 478 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 483 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 479 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 484 RecordSyncShare(×, true))); | 480 RecordSyncShare(×))); |
| 485 StartSyncScheduler(base::Time()); | 481 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 486 PumpLoop(); | 482 PumpLoop(); |
| 487 } | 483 } |
| 488 | 484 |
| 489 // Test that nudges are coalesced. | 485 // Test that nudges are coalesced. |
| 490 TEST_F(SyncSchedulerTest, NudgeCoalescing) { | 486 TEST_F(SyncSchedulerTest, NudgeCoalescing) { |
| 491 StartSyncScheduler(base::Time()); | 487 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 492 | 488 |
| 493 SyncShareTimes times; | 489 SyncShareTimes times; |
| 494 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 490 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 495 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 491 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 496 RecordSyncShare(×, true))); | 492 RecordSyncShare(×))); |
| 497 const ModelTypeSet types1(THEMES), types2(TYPED_URLS), types3(THEMES); | 493 const ModelTypeSet types1(THEMES), types2(TYPED_URLS), types3(THEMES); |
| 498 TimeTicks optimal_time = TimeTicks::Now() + default_delay(); | 494 TimeTicks optimal_time = TimeTicks::Now() + default_delay(); |
| 499 scheduler()->ScheduleLocalNudge(types1, FROM_HERE); | 495 scheduler()->ScheduleLocalNudge(types1, FROM_HERE); |
| 500 scheduler()->ScheduleLocalNudge(types2, FROM_HERE); | 496 scheduler()->ScheduleLocalNudge(types2, FROM_HERE); |
| 501 RunLoop(); | 497 RunLoop(); |
| 502 | 498 |
| 503 ASSERT_EQ(1U, times.size()); | 499 ASSERT_EQ(1U, times.size()); |
| 504 EXPECT_GE(times[0], optimal_time); | 500 EXPECT_GE(times[0], optimal_time); |
| 505 | 501 |
| 506 Mock::VerifyAndClearExpectations(syncer()); | 502 Mock::VerifyAndClearExpectations(syncer()); |
| 507 | 503 |
| 508 SyncShareTimes times2; | 504 SyncShareTimes times2; |
| 509 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 505 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 510 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 506 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 511 RecordSyncShare(×2, true))); | 507 RecordSyncShare(×2))); |
| 512 scheduler()->ScheduleLocalNudge(types3, FROM_HERE); | 508 scheduler()->ScheduleLocalNudge(types3, FROM_HERE); |
| 513 RunLoop(); | 509 RunLoop(); |
| 514 } | 510 } |
| 515 | 511 |
| 516 // Test that nudges are coalesced. | 512 // Test that nudges are coalesced. |
| 517 TEST_F(SyncSchedulerTest, NudgeCoalescingWithDifferentTimings) { | 513 TEST_F(SyncSchedulerTest, NudgeCoalescingWithDifferentTimings) { |
| 518 StartSyncScheduler(base::Time()); | 514 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 519 | 515 |
| 520 SyncShareTimes times; | 516 SyncShareTimes times; |
| 521 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 517 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 522 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 518 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 523 RecordSyncShare(×, true))); | 519 RecordSyncShare(×))); |
| 524 ModelTypeSet types1(THEMES), types2(TYPED_URLS), types3; | 520 ModelTypeSet types1(THEMES), types2(TYPED_URLS), types3; |
| 525 | 521 |
| 526 // Create a huge time delay. | 522 // Create a huge time delay. |
| 527 TimeDelta delay = TimeDelta::FromDays(1); | 523 TimeDelta delay = TimeDelta::FromDays(1); |
| 528 | 524 |
| 529 std::map<ModelType, TimeDelta> delay_map; | 525 std::map<ModelType, TimeDelta> delay_map; |
| 530 delay_map[types1.First().Get()] = delay; | 526 delay_map[types1.First().Get()] = delay; |
| 531 scheduler()->OnReceivedCustomNudgeDelays(delay_map); | 527 scheduler()->OnReceivedCustomNudgeDelays(delay_map); |
| 532 scheduler()->ScheduleLocalNudge(types1, FROM_HERE); | 528 scheduler()->ScheduleLocalNudge(types1, FROM_HERE); |
| 533 scheduler()->ScheduleLocalNudge(types2, FROM_HERE); | 529 scheduler()->ScheduleLocalNudge(types2, FROM_HERE); |
| 534 | 530 |
| 535 TimeTicks min_time = TimeTicks::Now(); | 531 TimeTicks min_time = TimeTicks::Now(); |
| 536 TimeTicks max_time = TimeTicks::Now() + delay; | 532 TimeTicks max_time = TimeTicks::Now() + delay; |
| 537 | 533 |
| 538 RunLoop(); | 534 RunLoop(); |
| 539 Mock::VerifyAndClearExpectations(syncer()); | 535 Mock::VerifyAndClearExpectations(syncer()); |
| 540 | 536 |
| 541 // Make sure the sync happened at the right time. | 537 // Make sure the sync happened at the right time. |
| 542 ASSERT_EQ(1U, times.size()); | 538 ASSERT_EQ(1U, times.size()); |
| 543 EXPECT_GE(times[0], min_time); | 539 EXPECT_GE(times[0], min_time); |
| 544 EXPECT_LE(times[0], max_time); | 540 EXPECT_LE(times[0], max_time); |
| 545 } | 541 } |
| 546 | 542 |
| 547 // Test nudge scheduling. | 543 // Test nudge scheduling. |
| 548 TEST_F(SyncSchedulerTest, NudgeWithStates) { | 544 TEST_F(SyncSchedulerTest, NudgeWithStates) { |
| 549 StartSyncScheduler(base::Time()); | 545 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 550 | 546 |
| 551 SyncShareTimes times1; | 547 SyncShareTimes times1; |
| 552 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 548 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 553 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 549 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 554 RecordSyncShare(×1, true))) | 550 RecordSyncShare(×1))) |
| 555 .RetiresOnSaturation(); | 551 .RetiresOnSaturation(); |
| 556 scheduler()->ScheduleInvalidationNudge( | 552 scheduler()->ScheduleInvalidationNudge( |
| 557 THEMES, BuildInvalidation(10, "test"), FROM_HERE); | 553 THEMES, BuildInvalidation(10, "test"), FROM_HERE); |
| 558 RunLoop(); | 554 RunLoop(); |
| 559 | 555 |
| 560 Mock::VerifyAndClearExpectations(syncer()); | 556 Mock::VerifyAndClearExpectations(syncer()); |
| 561 | 557 |
| 562 // Make sure a second, later, nudge is unaffected by first (no coalescing). | 558 // Make sure a second, later, nudge is unaffected by first (no coalescing). |
| 563 SyncShareTimes times2; | 559 SyncShareTimes times2; |
| 564 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 560 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 565 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 561 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 566 RecordSyncShare(×2, true))); | 562 RecordSyncShare(×2))); |
| 567 scheduler()->ScheduleInvalidationNudge( | 563 scheduler()->ScheduleInvalidationNudge( |
| 568 TYPED_URLS, BuildInvalidation(10, "test2"), FROM_HERE); | 564 TYPED_URLS, BuildInvalidation(10, "test2"), FROM_HERE); |
| 569 RunLoop(); | 565 RunLoop(); |
| 570 } | 566 } |
| 571 | 567 |
| 572 // Test that polling works as expected. | 568 // Test that polling works as expected. |
| 573 TEST_F(SyncSchedulerTest, Polling) { | 569 TEST_F(SyncSchedulerTest, Polling) { |
| 574 SyncShareTimes times; | 570 SyncShareTimes times; |
| 575 TimeDelta poll_interval(TimeDelta::FromMilliseconds(30)); | 571 TimeDelta poll_interval(TimeDelta::FromMilliseconds(30)); |
| 576 EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples)) | 572 EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples)) |
| 577 .WillRepeatedly( | 573 .WillRepeatedly( |
| 578 DoAll(Invoke(sessions::test_util::SimulatePollSuccess), | 574 DoAll(Invoke(sessions::test_util::SimulatePollSuccess), |
| 579 RecordSyncShareMultiple(×, kMinNumSamples, true))); | 575 RecordSyncShareMultiple(×, kMinNumSamples))); |
| 580 | 576 |
| 581 scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval); | 577 scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval); |
| 582 | 578 |
| 583 TimeTicks optimal_start = TimeTicks::Now() + poll_interval; | 579 TimeTicks optimal_start = TimeTicks::Now() + poll_interval; |
| 584 StartSyncScheduler(base::Time()); | 580 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 585 | 581 |
| 586 // Run again to wait for polling. | 582 // Run again to wait for polling. |
| 587 RunLoop(); | 583 RunLoop(); |
| 588 | 584 |
| 589 StopSyncScheduler(); | 585 StopSyncScheduler(); |
| 590 AnalyzePollRun(times, kMinNumSamples, optimal_start, poll_interval); | 586 AnalyzePollRun(times, kMinNumSamples, optimal_start, poll_interval); |
| 591 } | 587 } |
| 592 | 588 |
| 593 // Test that we reuse the previous poll time on startup, triggering the first | |
| 594 // poll based on when the last one happened. Subsequent polls should have the | |
| 595 // normal delay. | |
| 596 TEST_F(SyncSchedulerTest, PollingPersistence) { | |
| 597 SyncShareTimes times; | |
| 598 // Use a large poll interval that wouldn't normally get hit on its own for | |
| 599 // some time yet. | |
| 600 TimeDelta poll_interval(TimeDelta::FromMilliseconds(500)); | |
| 601 EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples)) | |
| 602 .WillRepeatedly( | |
| 603 DoAll(Invoke(sessions::test_util::SimulatePollSuccess), | |
| 604 RecordSyncShareMultiple(×, kMinNumSamples, true))); | |
| 605 | |
| 606 scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval); | |
| 607 | |
| 608 // Set the start time to now, as the poll was overdue. | |
| 609 TimeTicks optimal_start = TimeTicks::Now(); | |
| 610 StartSyncScheduler(base::Time::Now() - poll_interval); | |
| 611 | |
| 612 // Run again to wait for polling. | |
| 613 RunLoop(); | |
| 614 | |
| 615 StopSyncScheduler(); | |
| 616 AnalyzePollRun(times, kMinNumSamples, optimal_start, poll_interval); | |
| 617 } | |
| 618 | |
| 619 // Test that if the persisted poll is in the future, it's ignored (the case | |
| 620 // where the local time has been modified). | |
| 621 TEST_F(SyncSchedulerTest, PollingPersistenceBadClock) { | |
| 622 SyncShareTimes times; | |
| 623 TimeDelta poll_interval(TimeDelta::FromMilliseconds(30)); | |
| 624 EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples)) | |
| 625 .WillRepeatedly( | |
| 626 DoAll(Invoke(sessions::test_util::SimulatePollSuccess), | |
| 627 RecordSyncShareMultiple(×, kMinNumSamples, true))); | |
| 628 | |
| 629 scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval); | |
| 630 | |
| 631 // Set the start time to |poll_interval| in the future. | |
| 632 TimeTicks optimal_start = TimeTicks::Now() + poll_interval; | |
| 633 StartSyncScheduler(base::Time::Now() + base::TimeDelta::FromMinutes(10)); | |
| 634 | |
| 635 // Run again to wait for polling. | |
| 636 RunLoop(); | |
| 637 | |
| 638 StopSyncScheduler(); | |
| 639 AnalyzePollRun(times, kMinNumSamples, optimal_start, poll_interval); | |
| 640 } | |
| 641 | |
| 642 // Test that the short poll interval is used. | 589 // Test that the short poll interval is used. |
| 643 TEST_F(SyncSchedulerTest, PollNotificationsDisabled) { | 590 TEST_F(SyncSchedulerTest, PollNotificationsDisabled) { |
| 644 SyncShareTimes times; | 591 SyncShareTimes times; |
| 645 TimeDelta poll_interval(TimeDelta::FromMilliseconds(30)); | 592 TimeDelta poll_interval(TimeDelta::FromMilliseconds(30)); |
| 646 EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples)) | 593 EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples)) |
| 647 .WillRepeatedly( | 594 .WillRepeatedly( |
| 648 DoAll(Invoke(sessions::test_util::SimulatePollSuccess), | 595 DoAll(Invoke(sessions::test_util::SimulatePollSuccess), |
| 649 RecordSyncShareMultiple(×, kMinNumSamples, true))); | 596 RecordSyncShareMultiple(×, kMinNumSamples))); |
| 650 | 597 |
| 651 scheduler()->OnReceivedShortPollIntervalUpdate(poll_interval); | 598 scheduler()->OnReceivedShortPollIntervalUpdate(poll_interval); |
| 652 scheduler()->SetNotificationsEnabled(false); | 599 scheduler()->SetNotificationsEnabled(false); |
| 653 | 600 |
| 654 TimeTicks optimal_start = TimeTicks::Now() + poll_interval; | 601 TimeTicks optimal_start = TimeTicks::Now() + poll_interval; |
| 655 StartSyncScheduler(base::Time()); | 602 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 656 | 603 |
| 657 // Run again to wait for polling. | 604 // Run again to wait for polling. |
| 658 RunLoop(); | 605 RunLoop(); |
| 659 | 606 |
| 660 StopSyncScheduler(); | 607 StopSyncScheduler(); |
| 661 AnalyzePollRun(times, kMinNumSamples, optimal_start, poll_interval); | 608 AnalyzePollRun(times, kMinNumSamples, optimal_start, poll_interval); |
| 662 } | 609 } |
| 663 | 610 |
| 664 // Test that polling intervals are updated when needed. | 611 // Test that polling intervals are updated when needed. |
| 665 TEST_F(SyncSchedulerTest, PollIntervalUpdate) { | 612 TEST_F(SyncSchedulerTest, PollIntervalUpdate) { |
| 666 SyncShareTimes times; | 613 SyncShareTimes times; |
| 667 TimeDelta poll1(TimeDelta::FromMilliseconds(120)); | 614 TimeDelta poll1(TimeDelta::FromMilliseconds(120)); |
| 668 TimeDelta poll2(TimeDelta::FromMilliseconds(30)); | 615 TimeDelta poll2(TimeDelta::FromMilliseconds(30)); |
| 669 scheduler()->OnReceivedLongPollIntervalUpdate(poll1); | 616 scheduler()->OnReceivedLongPollIntervalUpdate(poll1); |
| 670 EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples)) | 617 EXPECT_CALL(*syncer(), PollSyncShare(_,_)).Times(AtLeast(kMinNumSamples)) |
| 671 .WillOnce(DoAll( | 618 .WillOnce(DoAll( |
| 672 WithArgs<0,1>( | 619 WithArgs<0,1>( |
| 673 sessions::test_util::SimulatePollIntervalUpdate(poll2)), | 620 sessions::test_util::SimulatePollIntervalUpdate(poll2)), |
| 674 Return(true))) | 621 Return(true))) |
| 675 .WillRepeatedly( | 622 .WillRepeatedly( |
| 676 DoAll(Invoke(sessions::test_util::SimulatePollSuccess), | 623 DoAll(Invoke(sessions::test_util::SimulatePollSuccess), |
| 677 WithArg<1>( | 624 WithArg<1>( |
| 678 RecordSyncShareMultiple(×, kMinNumSamples, true)))); | 625 RecordSyncShareMultiple(×, kMinNumSamples)))); |
| 679 | 626 |
| 680 TimeTicks optimal_start = TimeTicks::Now() + poll1 + poll2; | 627 TimeTicks optimal_start = TimeTicks::Now() + poll1 + poll2; |
| 681 StartSyncScheduler(base::Time()); | 628 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 682 | 629 |
| 683 // Run again to wait for polling. | 630 // Run again to wait for polling. |
| 684 RunLoop(); | 631 RunLoop(); |
| 685 | 632 |
| 686 StopSyncScheduler(); | 633 StopSyncScheduler(); |
| 687 AnalyzePollRun(times, kMinNumSamples, optimal_start, poll2); | 634 AnalyzePollRun(times, kMinNumSamples, optimal_start, poll2); |
| 688 } | 635 } |
| 689 | 636 |
| 690 // Test that no syncing occurs when throttled. | 637 // Test that no syncing occurs when throttled. |
| 691 TEST_F(SyncSchedulerTest, ThrottlingDoesThrottle) { | 638 TEST_F(SyncSchedulerTest, ThrottlingDoesThrottle) { |
| 692 const ModelTypeSet types(THEMES); | 639 const ModelTypeSet types(THEMES); |
| 693 TimeDelta poll(TimeDelta::FromMilliseconds(20)); | 640 TimeDelta poll(TimeDelta::FromMilliseconds(20)); |
| 694 TimeDelta throttle(TimeDelta::FromMinutes(10)); | 641 TimeDelta throttle(TimeDelta::FromMinutes(10)); |
| 695 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | 642 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 696 | 643 |
| 697 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) | 644 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) |
| 698 .WillOnce(DoAll( | 645 .WillOnce(DoAll( |
| 699 WithArg<2>(sessions::test_util::SimulateThrottled(throttle)), | 646 WithArg<2>(sessions::test_util::SimulateThrottled(throttle)), |
| 700 Return(false))) | 647 Return(true))) |
| 701 .WillRepeatedly(AddFailureAndQuitLoopNow()); | 648 .WillRepeatedly(AddFailureAndQuitLoopNow()); |
| 702 | 649 |
| 703 StartSyncScheduler(base::Time()); | 650 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 704 | 651 |
| 705 scheduler()->ScheduleLocalNudge(types, FROM_HERE); | 652 scheduler()->ScheduleLocalNudge(types, FROM_HERE); |
| 706 PumpLoop(); | 653 PumpLoop(); |
| 707 | 654 |
| 708 StartSyncConfiguration(); | 655 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 709 | 656 |
| 710 CallbackCounter ready_counter; | 657 CallbackCounter ready_counter; |
| 711 CallbackCounter retry_counter; | 658 CallbackCounter retry_counter; |
| 712 ConfigurationParams params( | 659 ConfigurationParams params( |
| 713 GetUpdatesCallerInfo::RECONFIGURATION, | 660 GetUpdatesCallerInfo::RECONFIGURATION, |
| 714 types, | 661 types, |
| 715 TypesToRoutingInfo(types), | 662 TypesToRoutingInfo(types), |
| 716 base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), | 663 base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), |
| 717 base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); | 664 base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); |
| 718 scheduler()->ScheduleConfiguration(params); | 665 scheduler()->ScheduleConfiguration(params); |
| 719 PumpLoop(); | 666 PumpLoop(); |
| 720 ASSERT_EQ(0, ready_counter.times_called()); | 667 ASSERT_EQ(0, ready_counter.times_called()); |
| 721 ASSERT_EQ(1, retry_counter.times_called()); | 668 ASSERT_EQ(1, retry_counter.times_called()); |
| 722 | 669 |
| 723 } | 670 } |
| 724 | 671 |
| 725 TEST_F(SyncSchedulerTest, ThrottlingExpiresFromPoll) { | 672 TEST_F(SyncSchedulerTest, ThrottlingExpiresFromPoll) { |
| 726 SyncShareTimes times; | 673 SyncShareTimes times; |
| 727 TimeDelta poll(TimeDelta::FromMilliseconds(15)); | 674 TimeDelta poll(TimeDelta::FromMilliseconds(15)); |
| 728 TimeDelta throttle1(TimeDelta::FromMilliseconds(150)); | 675 TimeDelta throttle1(TimeDelta::FromMilliseconds(150)); |
| 729 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | 676 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 730 | 677 |
| 731 ::testing::InSequence seq; | 678 ::testing::InSequence seq; |
| 732 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) | 679 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) |
| 733 .WillOnce(DoAll( | 680 .WillOnce(DoAll( |
| 734 WithArg<1>(sessions::test_util::SimulateThrottled(throttle1)), | 681 WithArg<1>(sessions::test_util::SimulateThrottled(throttle1)), |
| 735 Return(false))) | 682 Return(true))) |
| 736 .RetiresOnSaturation(); | 683 .RetiresOnSaturation(); |
| 737 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) | 684 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) |
| 738 .WillRepeatedly( | 685 .WillRepeatedly( |
| 739 DoAll(Invoke(sessions::test_util::SimulatePollSuccess), | 686 DoAll(Invoke(sessions::test_util::SimulatePollSuccess), |
| 740 RecordSyncShareMultiple(×, kMinNumSamples, true))); | 687 RecordSyncShareMultiple(×, kMinNumSamples))); |
| 741 | 688 |
| 742 TimeTicks optimal_start = TimeTicks::Now() + poll + throttle1; | 689 TimeTicks optimal_start = TimeTicks::Now() + poll + throttle1; |
| 743 StartSyncScheduler(base::Time()); | 690 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 744 | 691 |
| 745 // Run again to wait for polling. | 692 // Run again to wait for polling. |
| 746 RunLoop(); | 693 RunLoop(); |
| 747 | 694 |
| 748 StopSyncScheduler(); | 695 StopSyncScheduler(); |
| 749 AnalyzePollRun(times, kMinNumSamples, optimal_start, poll); | 696 AnalyzePollRun(times, kMinNumSamples, optimal_start, poll); |
| 750 } | 697 } |
| 751 | 698 |
| 752 TEST_F(SyncSchedulerTest, ThrottlingExpiresFromNudge) { | 699 TEST_F(SyncSchedulerTest, ThrottlingExpiresFromNudge) { |
| 753 SyncShareTimes times; | 700 SyncShareTimes times; |
| 754 TimeDelta poll(TimeDelta::FromDays(1)); | 701 TimeDelta poll(TimeDelta::FromDays(1)); |
| 755 TimeDelta throttle1(TimeDelta::FromMilliseconds(150)); | 702 TimeDelta throttle1(TimeDelta::FromMilliseconds(150)); |
| 756 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | 703 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 757 | 704 |
| 758 ::testing::InSequence seq; | 705 ::testing::InSequence seq; |
| 759 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 706 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 760 .WillOnce(DoAll( | 707 .WillOnce(DoAll( |
| 761 WithArg<2>(sessions::test_util::SimulateThrottled(throttle1)), | 708 WithArg<2>(sessions::test_util::SimulateThrottled(throttle1)), |
| 762 Return(false))) | 709 Return(true))) |
| 763 .RetiresOnSaturation(); | 710 .RetiresOnSaturation(); |
| 764 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 711 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 765 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 712 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 766 QuitLoopNowAction(true))); | 713 QuitLoopNowAction())); |
| 767 | 714 |
| 768 const ModelTypeSet types(THEMES); | 715 const ModelTypeSet types(THEMES); |
| 769 StartSyncScheduler(base::Time()); | 716 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 770 scheduler()->ScheduleLocalNudge(types, FROM_HERE); | 717 scheduler()->ScheduleLocalNudge(types, FROM_HERE); |
| 771 | 718 |
| 772 PumpLoop(); // To get PerformDelayedNudge called. | 719 PumpLoop(); // To get PerformDelayedNudge called. |
| 773 PumpLoop(); // To get TrySyncSessionJob called | 720 PumpLoop(); // To get TrySyncSessionJob called |
| 774 EXPECT_TRUE(scheduler()->IsCurrentlyThrottled()); | 721 EXPECT_TRUE(scheduler()->IsCurrentlyThrottled()); |
| 775 RunLoop(); | 722 RunLoop(); |
| 776 EXPECT_FALSE(scheduler()->IsCurrentlyThrottled()); | 723 EXPECT_FALSE(scheduler()->IsCurrentlyThrottled()); |
| 777 | 724 |
| 778 StopSyncScheduler(); | 725 StopSyncScheduler(); |
| 779 } | 726 } |
| 780 | 727 |
| 781 TEST_F(SyncSchedulerTest, ThrottlingExpiresFromConfigure) { | 728 TEST_F(SyncSchedulerTest, ThrottlingExpiresFromConfigure) { |
| 782 SyncShareTimes times; | 729 SyncShareTimes times; |
| 783 TimeDelta poll(TimeDelta::FromDays(1)); | 730 TimeDelta poll(TimeDelta::FromDays(1)); |
| 784 TimeDelta throttle1(TimeDelta::FromMilliseconds(150)); | 731 TimeDelta throttle1(TimeDelta::FromMilliseconds(150)); |
| 785 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | 732 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 786 | 733 |
| 787 ::testing::InSequence seq; | 734 ::testing::InSequence seq; |
| 788 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) | 735 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) |
| 789 .WillOnce(DoAll( | 736 .WillOnce(DoAll( |
| 790 WithArg<2>(sessions::test_util::SimulateThrottled(throttle1)), | 737 WithArg<2>(sessions::test_util::SimulateThrottled(throttle1)), |
| 791 Return(false))) | 738 Return(true))) |
| 792 .RetiresOnSaturation(); | 739 .RetiresOnSaturation(); |
| 793 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) | 740 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) |
| 794 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess), | 741 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess), |
| 795 QuitLoopNowAction(true))); | 742 QuitLoopNowAction())); |
| 796 | 743 |
| 797 const ModelTypeSet types(THEMES); | 744 const ModelTypeSet types(THEMES); |
| 798 StartSyncConfiguration(); | 745 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 799 | 746 |
| 800 CallbackCounter ready_counter; | 747 CallbackCounter ready_counter; |
| 801 CallbackCounter retry_counter; | 748 CallbackCounter retry_counter; |
| 802 ConfigurationParams params( | 749 ConfigurationParams params( |
| 803 GetUpdatesCallerInfo::RECONFIGURATION, | 750 GetUpdatesCallerInfo::RECONFIGURATION, |
| 804 types, | 751 types, |
| 805 TypesToRoutingInfo(types), | 752 TypesToRoutingInfo(types), |
| 806 base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), | 753 base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), |
| 807 base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); | 754 base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); |
| 808 scheduler()->ScheduleConfiguration(params); | 755 scheduler()->ScheduleConfiguration(params); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 826 TimeDelta throttle1(TimeDelta::FromSeconds(60)); | 773 TimeDelta throttle1(TimeDelta::FromSeconds(60)); |
| 827 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | 774 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 828 | 775 |
| 829 const ModelTypeSet types(THEMES); | 776 const ModelTypeSet types(THEMES); |
| 830 | 777 |
| 831 ::testing::InSequence seq; | 778 ::testing::InSequence seq; |
| 832 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 779 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 833 .WillOnce(DoAll( | 780 .WillOnce(DoAll( |
| 834 WithArg<2>( | 781 WithArg<2>( |
| 835 sessions::test_util::SimulateTypesThrottled(types, throttle1)), | 782 sessions::test_util::SimulateTypesThrottled(types, throttle1)), |
| 836 Return(false))) | 783 Return(true))) |
| 837 .RetiresOnSaturation(); | 784 .RetiresOnSaturation(); |
| 838 | 785 |
| 839 StartSyncScheduler(base::Time()); | 786 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 840 scheduler()->ScheduleLocalNudge(types, FROM_HERE); | 787 scheduler()->ScheduleLocalNudge(types, FROM_HERE); |
| 841 PumpLoop(); // To get PerformDelayedNudge called. | 788 PumpLoop(); // To get PerformDelayedNudge called. |
| 842 PumpLoop(); // To get TrySyncSessionJob called | 789 PumpLoop(); // To get TrySyncSessionJob called |
| 843 EXPECT_TRUE(GetThrottledTypes().HasAll(types)); | 790 EXPECT_TRUE(GetThrottledTypes().HasAll(types)); |
| 844 | 791 |
| 845 // This won't cause a sync cycle because the types are throttled. | 792 // This won't cause a sync cycle because the types are throttled. |
| 846 scheduler()->ScheduleLocalNudge(types, FROM_HERE); | 793 scheduler()->ScheduleLocalNudge(types, FROM_HERE); |
| 847 PumpLoop(); | 794 PumpLoop(); |
| 848 | 795 |
| 849 StopSyncScheduler(); | 796 StopSyncScheduler(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 861 | 808 |
| 862 const ModelTypeSet throttled_types(THEMES); | 809 const ModelTypeSet throttled_types(THEMES); |
| 863 const ModelTypeSet unthrottled_types(PREFERENCES); | 810 const ModelTypeSet unthrottled_types(PREFERENCES); |
| 864 | 811 |
| 865 ::testing::InSequence seq; | 812 ::testing::InSequence seq; |
| 866 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 813 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 867 .WillOnce(DoAll( | 814 .WillOnce(DoAll( |
| 868 WithArg<2>( | 815 WithArg<2>( |
| 869 sessions::test_util::SimulateTypesThrottled( | 816 sessions::test_util::SimulateTypesThrottled( |
| 870 throttled_types, throttle1)), | 817 throttled_types, throttle1)), |
| 871 Return(false))) | 818 Return(true))) |
| 872 .RetiresOnSaturation(); | 819 .RetiresOnSaturation(); |
| 873 | 820 |
| 874 StartSyncScheduler(base::Time()); | 821 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 875 scheduler()->ScheduleLocalNudge(throttled_types, FROM_HERE); | 822 scheduler()->ScheduleLocalNudge(throttled_types, FROM_HERE); |
| 876 PumpLoop(); // To get PerformDelayedNudge called. | 823 PumpLoop(); // To get PerformDelayedNudge called. |
| 877 PumpLoop(); // To get TrySyncSessionJob called | 824 PumpLoop(); // To get TrySyncSessionJob called |
| 878 EXPECT_TRUE(GetThrottledTypes().HasAll(throttled_types)); | 825 EXPECT_TRUE(GetThrottledTypes().HasAll(throttled_types)); |
| 879 | 826 |
| 880 // Ignore invalidations for throttled types. | 827 // Ignore invalidations for throttled types. |
| 881 scheduler()->ScheduleInvalidationNudge( | 828 scheduler()->ScheduleInvalidationNudge( |
| 882 THEMES, BuildInvalidation(10, "test"), FROM_HERE); | 829 THEMES, BuildInvalidation(10, "test"), FROM_HERE); |
| 883 PumpLoop(); | 830 PumpLoop(); |
| 884 | 831 |
| 885 // Ignore refresh requests for throttled types. | 832 // Ignore refresh requests for throttled types. |
| 886 scheduler()->ScheduleLocalRefreshRequest(throttled_types, FROM_HERE); | 833 scheduler()->ScheduleLocalRefreshRequest(throttled_types, FROM_HERE); |
| 887 PumpLoop(); | 834 PumpLoop(); |
| 888 | 835 |
| 889 Mock::VerifyAndClearExpectations(syncer()); | 836 Mock::VerifyAndClearExpectations(syncer()); |
| 890 | 837 |
| 891 // Local nudges for non-throttled types will trigger a sync. | 838 // Local nudges for non-throttled types will trigger a sync. |
| 892 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 839 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 893 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 840 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 894 RecordSyncShare(×, true))); | 841 RecordSyncShare(×))); |
| 895 scheduler()->ScheduleLocalNudge(unthrottled_types, FROM_HERE); | 842 scheduler()->ScheduleLocalNudge(unthrottled_types, FROM_HERE); |
| 896 RunLoop(); | 843 RunLoop(); |
| 897 Mock::VerifyAndClearExpectations(syncer()); | 844 Mock::VerifyAndClearExpectations(syncer()); |
| 898 | 845 |
| 899 StopSyncScheduler(); | 846 StopSyncScheduler(); |
| 900 } | 847 } |
| 901 | 848 |
| 902 // Test nudges / polls don't run in config mode and config tasks do. | 849 // Test nudges / polls don't run in config mode and config tasks do. |
| 903 TEST_F(SyncSchedulerTest, ConfigurationMode) { | 850 TEST_F(SyncSchedulerTest, ConfigurationMode) { |
| 904 TimeDelta poll(TimeDelta::FromMilliseconds(15)); | 851 TimeDelta poll(TimeDelta::FromMilliseconds(15)); |
| 905 SyncShareTimes times; | 852 SyncShareTimes times; |
| 906 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | 853 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 907 | 854 |
| 908 StartSyncConfiguration(); | 855 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 909 | 856 |
| 910 const ModelTypeSet nudge_types(TYPED_URLS); | 857 const ModelTypeSet nudge_types(TYPED_URLS); |
| 911 scheduler()->ScheduleLocalNudge(nudge_types, FROM_HERE); | 858 scheduler()->ScheduleLocalNudge(nudge_types, FROM_HERE); |
| 912 scheduler()->ScheduleLocalNudge(nudge_types, FROM_HERE); | 859 scheduler()->ScheduleLocalNudge(nudge_types, FROM_HERE); |
| 913 | 860 |
| 914 const ModelTypeSet config_types(THEMES); | 861 const ModelTypeSet config_types(THEMES); |
| 915 | 862 |
| 916 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) | 863 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) |
| 917 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess), | 864 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConfigureSuccess), |
| 918 RecordSyncShare(×, true))) | 865 RecordSyncShare(×))) |
| 919 .RetiresOnSaturation(); | 866 .RetiresOnSaturation(); |
| 920 CallbackCounter ready_counter; | 867 CallbackCounter ready_counter; |
| 921 CallbackCounter retry_counter; | 868 CallbackCounter retry_counter; |
| 922 ConfigurationParams params( | 869 ConfigurationParams params( |
| 923 GetUpdatesCallerInfo::RECONFIGURATION, | 870 GetUpdatesCallerInfo::RECONFIGURATION, |
| 924 config_types, | 871 config_types, |
| 925 TypesToRoutingInfo(config_types), | 872 TypesToRoutingInfo(config_types), |
| 926 base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), | 873 base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), |
| 927 base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); | 874 base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); |
| 928 scheduler()->ScheduleConfiguration(params); | 875 scheduler()->ScheduleConfiguration(params); |
| 929 RunLoop(); | 876 RunLoop(); |
| 930 ASSERT_EQ(1, ready_counter.times_called()); | 877 ASSERT_EQ(1, ready_counter.times_called()); |
| 931 ASSERT_EQ(0, retry_counter.times_called()); | 878 ASSERT_EQ(0, retry_counter.times_called()); |
| 932 | 879 |
| 933 Mock::VerifyAndClearExpectations(syncer()); | 880 Mock::VerifyAndClearExpectations(syncer()); |
| 934 | 881 |
| 935 // Switch to NORMAL_MODE to ensure NUDGES were properly saved and run. | 882 // Switch to NORMAL_MODE to ensure NUDGES were properly saved and run. |
| 936 scheduler()->OnReceivedLongPollIntervalUpdate(TimeDelta::FromDays(1)); | 883 scheduler()->OnReceivedLongPollIntervalUpdate(TimeDelta::FromDays(1)); |
| 937 SyncShareTimes times2; | 884 SyncShareTimes times2; |
| 938 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 885 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 939 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 886 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 940 RecordSyncShare(×2, true))); | 887 RecordSyncShare(×2))); |
| 941 | 888 |
| 942 // TODO(tim): Figure out how to remove this dangerous need to reset | 889 // TODO(tim): Figure out how to remove this dangerous need to reset |
| 943 // routing info between mode switches. | 890 // routing info between mode switches. |
| 944 context()->SetRoutingInfo(routing_info()); | 891 context()->SetRoutingInfo(routing_info()); |
| 945 StartSyncScheduler(base::Time()); | 892 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 946 | 893 |
| 947 RunLoop(); | 894 RunLoop(); |
| 948 Mock::VerifyAndClearExpectations(syncer()); | 895 Mock::VerifyAndClearExpectations(syncer()); |
| 949 } | 896 } |
| 950 | 897 |
| 951 class BackoffTriggersSyncSchedulerTest : public SyncSchedulerTest { | 898 class BackoffTriggersSyncSchedulerTest : public SyncSchedulerTest { |
| 952 void SetUp() override { | 899 void SetUp() override { |
| 953 SyncSchedulerTest::SetUp(); | 900 SyncSchedulerTest::SetUp(); |
| 954 UseMockDelayProvider(); | 901 UseMockDelayProvider(); |
| 955 EXPECT_CALL(*delay(), GetDelay(_)) | 902 EXPECT_CALL(*delay(), GetDelay(_)) |
| 956 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(10))); | 903 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(10))); |
| 957 } | 904 } |
| 958 | 905 |
| 959 void TearDown() override { | 906 void TearDown() override { |
| 960 StopSyncScheduler(); | 907 StopSyncScheduler(); |
| 961 SyncSchedulerTest::TearDown(); | 908 SyncSchedulerTest::TearDown(); |
| 962 } | 909 } |
| 963 }; | 910 }; |
| 964 | 911 |
| 965 // Have the syncer fail during commit. Expect that the scheduler enters | 912 // Have the sycner fail during commit. Expect that the scheduler enters |
| 966 // backoff. | 913 // backoff. |
| 967 TEST_F(BackoffTriggersSyncSchedulerTest, FailCommitOnce) { | 914 TEST_F(BackoffTriggersSyncSchedulerTest, FailCommitOnce) { |
| 968 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 915 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 969 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), | 916 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), |
| 970 QuitLoopNowAction(false))); | 917 QuitLoopNowAction())); |
| 971 EXPECT_TRUE(RunAndGetBackoff()); | 918 EXPECT_TRUE(RunAndGetBackoff()); |
| 972 } | 919 } |
| 973 | 920 |
| 974 // Have the syncer fail during download updates and succeed on the first | 921 // Have the syncer fail during download updates and succeed on the first |
| 975 // retry. Expect that this clears the backoff state. | 922 // retry. Expect that this clears the backoff state. |
| 976 TEST_F(BackoffTriggersSyncSchedulerTest, FailDownloadOnceThenSucceed) { | 923 TEST_F(BackoffTriggersSyncSchedulerTest, FailDownloadOnceThenSucceed) { |
| 977 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 924 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 978 .WillOnce(DoAll( | 925 .WillOnce(DoAll( |
| 979 Invoke(sessions::test_util::SimulateDownloadUpdatesFailed), | 926 Invoke(sessions::test_util::SimulateDownloadUpdatesFailed), |
| 980 Return(false))) | 927 Return(true))) |
| 981 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 928 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 982 QuitLoopNowAction(true))); | 929 QuitLoopNowAction())); |
| 983 EXPECT_FALSE(RunAndGetBackoff()); | 930 EXPECT_FALSE(RunAndGetBackoff()); |
| 984 } | 931 } |
| 985 | 932 |
| 986 // Have the syncer fail during commit and succeed on the first retry. Expect | 933 // Have the syncer fail during commit and succeed on the first retry. Expect |
| 987 // that this clears the backoff state. | 934 // that this clears the backoff state. |
| 988 TEST_F(BackoffTriggersSyncSchedulerTest, FailCommitOnceThenSucceed) { | 935 TEST_F(BackoffTriggersSyncSchedulerTest, FailCommitOnceThenSucceed) { |
| 989 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 936 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 990 .WillOnce(DoAll( | 937 .WillOnce(DoAll( |
| 991 Invoke(sessions::test_util::SimulateCommitFailed), | 938 Invoke(sessions::test_util::SimulateCommitFailed), |
| 992 Return(false))) | 939 Return(true))) |
| 993 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 940 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 994 QuitLoopNowAction(true))); | 941 QuitLoopNowAction())); |
| 995 EXPECT_FALSE(RunAndGetBackoff()); | 942 EXPECT_FALSE(RunAndGetBackoff()); |
| 996 } | 943 } |
| 997 | 944 |
| 998 // Have the syncer fail to download updates and fail again on the retry. | 945 // Have the syncer fail to download updates and fail again on the retry. |
| 999 // Expect this will leave the scheduler in backoff. | 946 // Expect this will leave the scheduler in backoff. |
| 1000 TEST_F(BackoffTriggersSyncSchedulerTest, FailDownloadTwice) { | 947 TEST_F(BackoffTriggersSyncSchedulerTest, FailDownloadTwice) { |
| 1001 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 948 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 1002 .WillOnce(DoAll( | 949 .WillOnce(DoAll( |
| 1003 Invoke(sessions::test_util::SimulateDownloadUpdatesFailed), | 950 Invoke(sessions::test_util::SimulateDownloadUpdatesFailed), |
| 1004 Return(false))) | 951 Return(true))) |
| 1005 .WillRepeatedly(DoAll( | 952 .WillRepeatedly(DoAll( |
| 1006 Invoke(sessions::test_util::SimulateDownloadUpdatesFailed), | 953 Invoke(sessions::test_util::SimulateDownloadUpdatesFailed), |
| 1007 QuitLoopNowAction(false))); | 954 QuitLoopNowAction())); |
| 1008 EXPECT_TRUE(RunAndGetBackoff()); | 955 EXPECT_TRUE(RunAndGetBackoff()); |
| 1009 } | 956 } |
| 1010 | 957 |
| 1011 // Have the syncer fail to get the encryption key yet succeed in downloading | 958 // Have the syncer fail to get the encryption key yet succeed in downloading |
| 1012 // updates. Expect this will leave the scheduler in backoff. | 959 // updates. Expect this will leave the scheduler in backoff. |
| 1013 TEST_F(BackoffTriggersSyncSchedulerTest, FailGetEncryptionKey) { | 960 TEST_F(BackoffTriggersSyncSchedulerTest, FailGetEncryptionKey) { |
| 1014 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) | 961 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) |
| 1015 .WillOnce(DoAll( | 962 .WillOnce(DoAll( |
| 1016 Invoke(sessions::test_util::SimulateGetEncryptionKeyFailed), | 963 Invoke(sessions::test_util::SimulateGetEncryptionKeyFailed), |
| 1017 Return(false))) | 964 Return(true))) |
| 1018 .WillRepeatedly(DoAll( | 965 .WillRepeatedly(DoAll( |
| 1019 Invoke(sessions::test_util::SimulateGetEncryptionKeyFailed), | 966 Invoke(sessions::test_util::SimulateGetEncryptionKeyFailed), |
| 1020 QuitLoopNowAction(false))); | 967 QuitLoopNowAction())); |
| 1021 StartSyncConfiguration(); | 968 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 1022 | 969 |
| 1023 ModelTypeSet types(THEMES); | 970 ModelTypeSet types(THEMES); |
| 1024 CallbackCounter ready_counter; | 971 CallbackCounter ready_counter; |
| 1025 CallbackCounter retry_counter; | 972 CallbackCounter retry_counter; |
| 1026 ConfigurationParams params( | 973 ConfigurationParams params( |
| 1027 GetUpdatesCallerInfo::RECONFIGURATION, | 974 GetUpdatesCallerInfo::RECONFIGURATION, |
| 1028 types, | 975 types, |
| 1029 TypesToRoutingInfo(types), | 976 TypesToRoutingInfo(types), |
| 1030 base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), | 977 base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), |
| 1031 base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); | 978 base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); |
| 1032 scheduler()->ScheduleConfiguration(params); | 979 scheduler()->ScheduleConfiguration(params); |
| 1033 RunLoop(); | 980 RunLoop(); |
| 1034 | 981 |
| 1035 EXPECT_TRUE(scheduler()->IsBackingOff()); | 982 EXPECT_TRUE(scheduler()->IsBackingOff()); |
| 1036 } | 983 } |
| 1037 | 984 |
| 1038 // Test that no polls or extraneous nudges occur when in backoff. | 985 // Test that no polls or extraneous nudges occur when in backoff. |
| 1039 TEST_F(SyncSchedulerTest, BackoffDropsJobs) { | 986 TEST_F(SyncSchedulerTest, BackoffDropsJobs) { |
| 1040 SyncShareTimes times; | 987 SyncShareTimes times; |
| 1041 TimeDelta poll(TimeDelta::FromMilliseconds(10)); | 988 TimeDelta poll(TimeDelta::FromMilliseconds(10)); |
| 1042 const ModelTypeSet types(THEMES); | 989 const ModelTypeSet types(THEMES); |
| 1043 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | 990 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 1044 UseMockDelayProvider(); | 991 UseMockDelayProvider(); |
| 1045 | 992 |
| 1046 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 993 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 1047 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), | 994 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), |
| 1048 RecordSyncShareMultiple(×, 1U, false))); | 995 RecordSyncShareMultiple(×, 1U))); |
| 1049 EXPECT_CALL(*delay(), GetDelay(_)). | 996 EXPECT_CALL(*delay(), GetDelay(_)). |
| 1050 WillRepeatedly(Return(TimeDelta::FromDays(1))); | 997 WillRepeatedly(Return(TimeDelta::FromDays(1))); |
| 1051 | 998 |
| 1052 StartSyncScheduler(base::Time()); | 999 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1053 | 1000 |
| 1054 // This nudge should fail and put us into backoff. Thanks to our mock | 1001 // This nudge should fail and put us into backoff. Thanks to our mock |
| 1055 // GetDelay() setup above, this will be a long backoff. | 1002 // GetDelay() setup above, this will be a long backoff. |
| 1056 scheduler()->ScheduleLocalNudge(types, FROM_HERE); | 1003 scheduler()->ScheduleLocalNudge(types, FROM_HERE); |
| 1057 RunLoop(); | 1004 RunLoop(); |
| 1058 | 1005 |
| 1059 // From this point forward, no SyncShare functions should be invoked. | 1006 // From this point forward, no SyncShare functions should be invoked. |
| 1060 Mock::VerifyAndClearExpectations(syncer()); | 1007 Mock::VerifyAndClearExpectations(syncer()); |
| 1061 | 1008 |
| 1062 // Wait a while (10x poll interval) so a few poll jobs will be attempted. | 1009 // Wait a while (10x poll interval) so a few poll jobs will be attempted. |
| 1063 PumpLoopFor(poll * 10); | 1010 PumpLoopFor(poll * 10); |
| 1064 | 1011 |
| 1065 // Try (and fail) to schedule a nudge. | 1012 // Try (and fail) to schedule a nudge. |
| 1066 scheduler()->ScheduleLocalNudge(types, FROM_HERE); | 1013 scheduler()->ScheduleLocalNudge(types, FROM_HERE); |
| 1067 | 1014 |
| 1068 Mock::VerifyAndClearExpectations(syncer()); | 1015 Mock::VerifyAndClearExpectations(syncer()); |
| 1069 Mock::VerifyAndClearExpectations(delay()); | 1016 Mock::VerifyAndClearExpectations(delay()); |
| 1070 | 1017 |
| 1071 EXPECT_CALL(*delay(), GetDelay(_)).Times(0); | 1018 EXPECT_CALL(*delay(), GetDelay(_)).Times(0); |
| 1072 | 1019 |
| 1073 StartSyncConfiguration(); | 1020 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 1074 | 1021 |
| 1075 CallbackCounter ready_counter; | 1022 CallbackCounter ready_counter; |
| 1076 CallbackCounter retry_counter; | 1023 CallbackCounter retry_counter; |
| 1077 ConfigurationParams params( | 1024 ConfigurationParams params( |
| 1078 GetUpdatesCallerInfo::RECONFIGURATION, | 1025 GetUpdatesCallerInfo::RECONFIGURATION, |
| 1079 types, | 1026 types, |
| 1080 TypesToRoutingInfo(types), | 1027 TypesToRoutingInfo(types), |
| 1081 base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), | 1028 base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), |
| 1082 base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); | 1029 base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); |
| 1083 scheduler()->ScheduleConfiguration(params); | 1030 scheduler()->ScheduleConfiguration(params); |
| 1084 PumpLoop(); | 1031 PumpLoop(); |
| 1085 ASSERT_EQ(0, ready_counter.times_called()); | 1032 ASSERT_EQ(0, ready_counter.times_called()); |
| 1086 ASSERT_EQ(1, retry_counter.times_called()); | 1033 ASSERT_EQ(1, retry_counter.times_called()); |
| 1087 | 1034 |
| 1088 } | 1035 } |
| 1089 | 1036 |
| 1090 // Test that backoff is shaping traffic properly with consecutive errors. | 1037 // Test that backoff is shaping traffic properly with consecutive errors. |
| 1091 TEST_F(SyncSchedulerTest, BackoffElevation) { | 1038 TEST_F(SyncSchedulerTest, BackoffElevation) { |
| 1092 SyncShareTimes times; | 1039 SyncShareTimes times; |
| 1093 UseMockDelayProvider(); | 1040 UseMockDelayProvider(); |
| 1094 | 1041 |
| 1095 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)).Times(kMinNumSamples) | 1042 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)).Times(kMinNumSamples) |
| 1096 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), | 1043 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), |
| 1097 RecordSyncShareMultiple(×, kMinNumSamples, false))); | 1044 RecordSyncShareMultiple(×, kMinNumSamples))); |
| 1098 | 1045 |
| 1099 const TimeDelta first = TimeDelta::FromSeconds(kInitialBackoffRetrySeconds); | 1046 const TimeDelta first = TimeDelta::FromSeconds(kInitialBackoffRetrySeconds); |
| 1100 const TimeDelta second = TimeDelta::FromMilliseconds(20); | 1047 const TimeDelta second = TimeDelta::FromMilliseconds(20); |
| 1101 const TimeDelta third = TimeDelta::FromMilliseconds(30); | 1048 const TimeDelta third = TimeDelta::FromMilliseconds(30); |
| 1102 const TimeDelta fourth = TimeDelta::FromMilliseconds(40); | 1049 const TimeDelta fourth = TimeDelta::FromMilliseconds(40); |
| 1103 const TimeDelta fifth = TimeDelta::FromMilliseconds(50); | 1050 const TimeDelta fifth = TimeDelta::FromMilliseconds(50); |
| 1104 const TimeDelta sixth = TimeDelta::FromDays(1); | 1051 const TimeDelta sixth = TimeDelta::FromDays(1); |
| 1105 | 1052 |
| 1106 EXPECT_CALL(*delay(), GetDelay(first)).WillOnce(Return(second)) | 1053 EXPECT_CALL(*delay(), GetDelay(first)).WillOnce(Return(second)) |
| 1107 .RetiresOnSaturation(); | 1054 .RetiresOnSaturation(); |
| 1108 EXPECT_CALL(*delay(), GetDelay(second)).WillOnce(Return(third)) | 1055 EXPECT_CALL(*delay(), GetDelay(second)).WillOnce(Return(third)) |
| 1109 .RetiresOnSaturation(); | 1056 .RetiresOnSaturation(); |
| 1110 EXPECT_CALL(*delay(), GetDelay(third)).WillOnce(Return(fourth)) | 1057 EXPECT_CALL(*delay(), GetDelay(third)).WillOnce(Return(fourth)) |
| 1111 .RetiresOnSaturation(); | 1058 .RetiresOnSaturation(); |
| 1112 EXPECT_CALL(*delay(), GetDelay(fourth)).WillOnce(Return(fifth)) | 1059 EXPECT_CALL(*delay(), GetDelay(fourth)).WillOnce(Return(fifth)) |
| 1113 .RetiresOnSaturation(); | 1060 .RetiresOnSaturation(); |
| 1114 EXPECT_CALL(*delay(), GetDelay(fifth)).WillOnce(Return(sixth)); | 1061 EXPECT_CALL(*delay(), GetDelay(fifth)).WillOnce(Return(sixth)); |
| 1115 | 1062 |
| 1116 StartSyncScheduler(base::Time()); | 1063 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1117 | 1064 |
| 1118 // Run again with a nudge. | 1065 // Run again with a nudge. |
| 1119 scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE); | 1066 scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE); |
| 1120 RunLoop(); | 1067 RunLoop(); |
| 1121 | 1068 |
| 1122 ASSERT_EQ(kMinNumSamples, times.size()); | 1069 ASSERT_EQ(kMinNumSamples, times.size()); |
| 1123 EXPECT_GE(times[1] - times[0], second); | 1070 EXPECT_GE(times[1] - times[0], second); |
| 1124 EXPECT_GE(times[2] - times[1], third); | 1071 EXPECT_GE(times[2] - times[1], third); |
| 1125 EXPECT_GE(times[3] - times[2], fourth); | 1072 EXPECT_GE(times[3] - times[2], fourth); |
| 1126 EXPECT_GE(times[4] - times[3], fifth); | 1073 EXPECT_GE(times[4] - times[3], fifth); |
| 1127 } | 1074 } |
| 1128 | 1075 |
| 1129 // Test that things go back to normal once a retry makes forward progress. | 1076 // Test that things go back to normal once a retry makes forward progress. |
| 1130 TEST_F(SyncSchedulerTest, BackoffRelief) { | 1077 TEST_F(SyncSchedulerTest, BackoffRelief) { |
| 1131 SyncShareTimes times; | 1078 SyncShareTimes times; |
| 1079 const TimeDelta poll(TimeDelta::FromMilliseconds(10)); |
| 1080 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 1132 UseMockDelayProvider(); | 1081 UseMockDelayProvider(); |
| 1133 | 1082 |
| 1134 const TimeDelta backoff = TimeDelta::FromMilliseconds(10); | 1083 const TimeDelta backoff = TimeDelta::FromMilliseconds(10); |
| 1135 EXPECT_CALL(*delay(), GetDelay(_)).WillOnce(Return(backoff)); | 1084 EXPECT_CALL(*delay(), GetDelay(_)).WillOnce(Return(backoff)); |
| 1136 | 1085 |
| 1137 // Optimal start for the post-backoff poll party. | 1086 // Optimal start for the post-backoff poll party. |
| 1138 TimeTicks optimal_start = TimeTicks::Now(); | 1087 TimeTicks optimal_start = TimeTicks::Now(); |
| 1139 StartSyncScheduler(base::Time()); | 1088 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1140 | 1089 |
| 1141 // Kick off the test with a failed nudge. | 1090 // Kick off the test with a failed nudge. |
| 1142 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 1091 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 1143 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), | 1092 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateCommitFailed), |
| 1144 RecordSyncShare(×, false))); | 1093 RecordSyncShare(×))); |
| 1145 scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE); | 1094 scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE); |
| 1146 RunLoop(); | 1095 RunLoop(); |
| 1147 Mock::VerifyAndClearExpectations(syncer()); | 1096 Mock::VerifyAndClearExpectations(syncer()); |
| 1148 TimeTicks optimal_job_time = optimal_start; | 1097 TimeTicks optimal_job_time = optimal_start; |
| 1149 ASSERT_EQ(1U, times.size()); | 1098 ASSERT_EQ(1U, times.size()); |
| 1150 EXPECT_GE(times[0], optimal_job_time); | 1099 EXPECT_GE(times[0], optimal_job_time); |
| 1151 | 1100 |
| 1152 // The retry succeeds. | 1101 // The retry succeeds. |
| 1153 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 1102 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 1154 .WillOnce(DoAll( | 1103 .WillOnce(DoAll( |
| 1155 Invoke(sessions::test_util::SimulateNormalSuccess), | 1104 Invoke(sessions::test_util::SimulateNormalSuccess), |
| 1156 RecordSyncShare(×, true))); | 1105 RecordSyncShare(×))); |
| 1157 RunLoop(); | 1106 RunLoop(); |
| 1158 Mock::VerifyAndClearExpectations(syncer()); | 1107 Mock::VerifyAndClearExpectations(syncer()); |
| 1159 optimal_job_time = optimal_job_time + backoff; | 1108 optimal_job_time = optimal_job_time + backoff; |
| 1160 ASSERT_EQ(2U, times.size()); | 1109 ASSERT_EQ(2U, times.size()); |
| 1161 EXPECT_GE(times[1], optimal_job_time); | 1110 EXPECT_GE(times[1], optimal_job_time); |
| 1162 | 1111 |
| 1163 // Now let the Poll timer do its thing. | 1112 // Now let the Poll timer do its thing. |
| 1164 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) | 1113 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) |
| 1165 .WillRepeatedly(DoAll( | 1114 .WillRepeatedly(DoAll( |
| 1166 Invoke(sessions::test_util::SimulatePollSuccess), | 1115 Invoke(sessions::test_util::SimulatePollSuccess), |
| 1167 RecordSyncShareMultiple(×, kMinNumSamples, true))); | 1116 RecordSyncShareMultiple(×, kMinNumSamples))); |
| 1168 const TimeDelta poll(TimeDelta::FromMilliseconds(10)); | |
| 1169 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | |
| 1170 | |
| 1171 // The new optimal time is now, since the desired poll should have happened | |
| 1172 // in the past. | |
| 1173 optimal_job_time = base::TimeTicks::Now(); | |
| 1174 RunLoop(); | 1117 RunLoop(); |
| 1175 Mock::VerifyAndClearExpectations(syncer()); | 1118 Mock::VerifyAndClearExpectations(syncer()); |
| 1176 ASSERT_EQ(kMinNumSamples, times.size()); | 1119 ASSERT_EQ(kMinNumSamples, times.size()); |
| 1177 for (size_t i = 2; i < times.size(); i++) { | 1120 for (size_t i = 2; i < times.size(); i++) { |
| 1121 optimal_job_time = optimal_job_time + poll; |
| 1178 SCOPED_TRACE(testing::Message() << "SyncShare # (" << i << ")"); | 1122 SCOPED_TRACE(testing::Message() << "SyncShare # (" << i << ")"); |
| 1179 EXPECT_GE(times[i], optimal_job_time); | 1123 EXPECT_GE(times[i], optimal_job_time); |
| 1180 optimal_job_time = optimal_job_time + poll; | |
| 1181 } | 1124 } |
| 1182 | 1125 |
| 1183 StopSyncScheduler(); | 1126 StopSyncScheduler(); |
| 1184 } | 1127 } |
| 1185 | 1128 |
| 1186 // Test that poll failures are treated like any other failure. They should | 1129 // Test that poll failures are ignored. They should have no effect on |
| 1187 // result in retry with backoff. | 1130 // subsequent poll attempts, nor should they trigger a backoff/retry. |
| 1188 TEST_F(SyncSchedulerTest, TransientPollFailure) { | 1131 TEST_F(SyncSchedulerTest, TransientPollFailure) { |
| 1189 SyncShareTimes times; | 1132 SyncShareTimes times; |
| 1190 const TimeDelta poll_interval(TimeDelta::FromMilliseconds(10)); | 1133 const TimeDelta poll_interval(TimeDelta::FromMilliseconds(10)); |
| 1191 scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval); | 1134 scheduler()->OnReceivedLongPollIntervalUpdate(poll_interval); |
| 1192 UseMockDelayProvider(); // Will cause test failure if backoff is initiated. | 1135 UseMockDelayProvider(); // Will cause test failure if backoff is initiated. |
| 1193 EXPECT_CALL(*delay(), GetDelay(_)) | |
| 1194 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(0))); | |
| 1195 | 1136 |
| 1196 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) | 1137 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) |
| 1197 .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollFailed), | 1138 .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollFailed), |
| 1198 RecordSyncShare(×, false))) | 1139 RecordSyncShare(×))) |
| 1199 .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), | 1140 .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), |
| 1200 RecordSyncShare(×, true))); | 1141 RecordSyncShare(×))); |
| 1201 | 1142 |
| 1202 StartSyncScheduler(base::Time()); | 1143 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1203 | 1144 |
| 1204 // Run the unsucessful poll. The failed poll should not trigger backoff. | 1145 // Run the unsucessful poll. The failed poll should not trigger backoff. |
| 1205 RunLoop(); | 1146 RunLoop(); |
| 1206 EXPECT_TRUE(scheduler()->IsBackingOff()); | 1147 EXPECT_FALSE(scheduler()->IsBackingOff()); |
| 1207 | 1148 |
| 1208 // Run the successful poll. | 1149 // Run the successful poll. |
| 1209 RunLoop(); | 1150 RunLoop(); |
| 1210 EXPECT_FALSE(scheduler()->IsBackingOff()); | 1151 EXPECT_FALSE(scheduler()->IsBackingOff()); |
| 1211 } | 1152 } |
| 1212 | 1153 |
| 1213 // Test that starting the syncer thread without a valid connection doesn't | 1154 // Test that starting the syncer thread without a valid connection doesn't |
| 1214 // break things when a connection is detected. | 1155 // break things when a connection is detected. |
| 1215 TEST_F(SyncSchedulerTest, StartWhenNotConnected) { | 1156 TEST_F(SyncSchedulerTest, StartWhenNotConnected) { |
| 1216 connection()->SetServerNotReachable(); | 1157 connection()->SetServerNotReachable(); |
| 1217 connection()->UpdateConnectionStatus(); | 1158 connection()->UpdateConnectionStatus(); |
| 1218 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 1159 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 1219 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConnectionFailure), | 1160 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConnectionFailure), |
| 1220 Return(false))) | 1161 Return(true))) |
| 1221 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 1162 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 1222 Return(true))); | 1163 Return(true))); |
| 1223 StartSyncScheduler(base::Time()); | 1164 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1224 | 1165 |
| 1225 scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE); | 1166 scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE); |
| 1226 // Should save the nudge for until after the server is reachable. | 1167 // Should save the nudge for until after the server is reachable. |
| 1227 base::RunLoop().RunUntilIdle(); | 1168 base::RunLoop().RunUntilIdle(); |
| 1228 | 1169 |
| 1229 scheduler()->OnConnectionStatusChange(); | 1170 scheduler()->OnConnectionStatusChange(); |
| 1230 connection()->SetServerReachable(); | 1171 connection()->SetServerReachable(); |
| 1231 connection()->UpdateConnectionStatus(); | 1172 connection()->UpdateConnectionStatus(); |
| 1232 base::RunLoop().RunUntilIdle(); | 1173 base::RunLoop().RunUntilIdle(); |
| 1233 } | 1174 } |
| 1234 | 1175 |
| 1235 TEST_F(SyncSchedulerTest, ServerConnectionChangeDuringBackoff) { | 1176 TEST_F(SyncSchedulerTest, ServerConnectionChangeDuringBackoff) { |
| 1236 UseMockDelayProvider(); | 1177 UseMockDelayProvider(); |
| 1237 EXPECT_CALL(*delay(), GetDelay(_)) | 1178 EXPECT_CALL(*delay(), GetDelay(_)) |
| 1238 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(0))); | 1179 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(0))); |
| 1239 | 1180 |
| 1240 StartSyncScheduler(base::Time()); | 1181 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1241 connection()->SetServerNotReachable(); | 1182 connection()->SetServerNotReachable(); |
| 1242 connection()->UpdateConnectionStatus(); | 1183 connection()->UpdateConnectionStatus(); |
| 1243 | 1184 |
| 1244 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 1185 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 1245 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConnectionFailure), | 1186 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConnectionFailure), |
| 1246 Return(false))) | 1187 Return(true))) |
| 1247 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 1188 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 1248 Return(true))); | 1189 Return(true))); |
| 1249 | 1190 |
| 1250 scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE); | 1191 scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE); |
| 1251 PumpLoop(); // To get PerformDelayedNudge called. | 1192 PumpLoop(); // To get PerformDelayedNudge called. |
| 1252 PumpLoop(); // Run the nudge, that will fail and schedule a quick retry. | 1193 PumpLoop(); // Run the nudge, that will fail and schedule a quick retry. |
| 1253 ASSERT_TRUE(scheduler()->IsBackingOff()); | 1194 ASSERT_TRUE(scheduler()->IsBackingOff()); |
| 1254 | 1195 |
| 1255 // Before we run the scheduled canary, trigger a server connection change. | 1196 // Before we run the scheduled canary, trigger a server connection change. |
| 1256 scheduler()->OnConnectionStatusChange(); | 1197 scheduler()->OnConnectionStatusChange(); |
| 1257 connection()->SetServerReachable(); | 1198 connection()->SetServerReachable(); |
| 1258 connection()->UpdateConnectionStatus(); | 1199 connection()->UpdateConnectionStatus(); |
| 1259 base::RunLoop().RunUntilIdle(); | 1200 base::RunLoop().RunUntilIdle(); |
| 1260 } | 1201 } |
| 1261 | 1202 |
| 1262 // This was supposed to test the scenario where we receive a nudge while a | 1203 // This was supposed to test the scenario where we receive a nudge while a |
| 1263 // connection change canary is scheduled, but has not run yet. Since we've made | 1204 // connection change canary is scheduled, but has not run yet. Since we've made |
| 1264 // the connection change canary synchronous, this is no longer possible. | 1205 // the connection change canary synchronous, this is no longer possible. |
| 1265 TEST_F(SyncSchedulerTest, ConnectionChangeCanaryPreemptedByNudge) { | 1206 TEST_F(SyncSchedulerTest, ConnectionChangeCanaryPreemptedByNudge) { |
| 1266 UseMockDelayProvider(); | 1207 UseMockDelayProvider(); |
| 1267 EXPECT_CALL(*delay(), GetDelay(_)) | 1208 EXPECT_CALL(*delay(), GetDelay(_)) |
| 1268 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(0))); | 1209 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(0))); |
| 1269 | 1210 |
| 1270 StartSyncScheduler(base::Time()); | 1211 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1271 connection()->SetServerNotReachable(); | 1212 connection()->SetServerNotReachable(); |
| 1272 connection()->UpdateConnectionStatus(); | 1213 connection()->UpdateConnectionStatus(); |
| 1273 | 1214 |
| 1274 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 1215 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 1275 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConnectionFailure), | 1216 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateConnectionFailure), |
| 1276 Return(false))) | 1217 Return(true))) |
| 1277 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 1218 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 1278 Return(true))) | 1219 Return(true))) |
| 1279 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 1220 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 1280 QuitLoopNowAction(true))); | 1221 QuitLoopNowAction())); |
| 1281 | 1222 |
| 1282 scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE); | 1223 scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE); |
| 1283 | 1224 |
| 1284 PumpLoop(); // To get PerformDelayedNudge called. | 1225 PumpLoop(); // To get PerformDelayedNudge called. |
| 1285 PumpLoop(); // Run the nudge, that will fail and schedule a quick retry. | 1226 PumpLoop(); // Run the nudge, that will fail and schedule a quick retry. |
| 1286 ASSERT_TRUE(scheduler()->IsBackingOff()); | 1227 ASSERT_TRUE(scheduler()->IsBackingOff()); |
| 1287 | 1228 |
| 1288 // Before we run the scheduled canary, trigger a server connection change. | 1229 // Before we run the scheduled canary, trigger a server connection change. |
| 1289 scheduler()->OnConnectionStatusChange(); | 1230 scheduler()->OnConnectionStatusChange(); |
| 1290 PumpLoop(); | 1231 PumpLoop(); |
| 1291 connection()->SetServerReachable(); | 1232 connection()->SetServerReachable(); |
| 1292 connection()->UpdateConnectionStatus(); | 1233 connection()->UpdateConnectionStatus(); |
| 1293 scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE); | 1234 scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE); |
| 1294 base::RunLoop().RunUntilIdle(); | 1235 base::RunLoop().RunUntilIdle(); |
| 1295 } | 1236 } |
| 1296 | 1237 |
| 1297 // Tests that we don't crash trying to run two canaries at once if we receive | 1238 // Tests that we don't crash trying to run two canaries at once if we receive |
| 1298 // extra connection status change notifications. See crbug.com/190085. | 1239 // extra connection status change notifications. See crbug.com/190085. |
| 1299 TEST_F(SyncSchedulerTest, DoubleCanaryInConfigure) { | 1240 TEST_F(SyncSchedulerTest, DoubleCanaryInConfigure) { |
| 1300 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) | 1241 EXPECT_CALL(*syncer(), ConfigureSyncShare(_,_,_)) |
| 1301 .WillRepeatedly(DoAll( | 1242 .WillRepeatedly(DoAll( |
| 1302 Invoke(sessions::test_util::SimulateConfigureConnectionFailure), | 1243 Invoke(sessions::test_util::SimulateConfigureConnectionFailure), |
| 1303 Return(true))); | 1244 Return(true))); |
| 1304 StartSyncConfiguration(); | 1245 StartSyncScheduler(SyncScheduler::CONFIGURATION_MODE); |
| 1305 connection()->SetServerNotReachable(); | 1246 connection()->SetServerNotReachable(); |
| 1306 connection()->UpdateConnectionStatus(); | 1247 connection()->UpdateConnectionStatus(); |
| 1307 | 1248 |
| 1308 ModelTypeSet model_types(THEMES); | 1249 ModelTypeSet model_types(THEMES); |
| 1309 CallbackCounter ready_counter; | 1250 CallbackCounter ready_counter; |
| 1310 CallbackCounter retry_counter; | 1251 CallbackCounter retry_counter; |
| 1311 ConfigurationParams params( | 1252 ConfigurationParams params( |
| 1312 GetUpdatesCallerInfo::RECONFIGURATION, | 1253 GetUpdatesCallerInfo::RECONFIGURATION, |
| 1313 model_types, | 1254 model_types, |
| 1314 TypesToRoutingInfo(model_types), | 1255 TypesToRoutingInfo(model_types), |
| 1315 base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), | 1256 base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), |
| 1316 base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); | 1257 base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); |
| 1317 scheduler()->ScheduleConfiguration(params); | 1258 scheduler()->ScheduleConfiguration(params); |
| 1318 | 1259 |
| 1319 scheduler()->OnConnectionStatusChange(); | 1260 scheduler()->OnConnectionStatusChange(); |
| 1320 scheduler()->OnConnectionStatusChange(); | 1261 scheduler()->OnConnectionStatusChange(); |
| 1321 | 1262 |
| 1322 PumpLoop(); // Run the nudge, that will fail and schedule a quick retry. | 1263 PumpLoop(); // Run the nudge, that will fail and schedule a quick retry. |
| 1323 } | 1264 } |
| 1324 | 1265 |
| 1325 TEST_F(SyncSchedulerTest, PollFromCanaryAfterAuthError) { | 1266 TEST_F(SyncSchedulerTest, PollFromCanaryAfterAuthError) { |
| 1326 SyncShareTimes times; | 1267 SyncShareTimes times; |
| 1327 TimeDelta poll(TimeDelta::FromMilliseconds(15)); | 1268 TimeDelta poll(TimeDelta::FromMilliseconds(15)); |
| 1328 scheduler()->OnReceivedLongPollIntervalUpdate(poll); | 1269 scheduler()->OnReceivedLongPollIntervalUpdate(poll); |
| 1329 | 1270 |
| 1330 ::testing::InSequence seq; | 1271 ::testing::InSequence seq; |
| 1331 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) | 1272 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) |
| 1332 .WillRepeatedly( | 1273 .WillRepeatedly( |
| 1333 DoAll(Invoke(sessions::test_util::SimulatePollSuccess), | 1274 DoAll(Invoke(sessions::test_util::SimulatePollSuccess), |
| 1334 RecordSyncShareMultiple(×, kMinNumSamples, true))); | 1275 RecordSyncShareMultiple(×, kMinNumSamples))); |
| 1335 | 1276 |
| 1336 connection()->SetServerStatus(HttpResponse::SYNC_AUTH_ERROR); | 1277 connection()->SetServerStatus(HttpResponse::SYNC_AUTH_ERROR); |
| 1337 StartSyncScheduler(base::Time()); | 1278 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1338 | 1279 |
| 1339 // Run to wait for polling. | 1280 // Run to wait for polling. |
| 1340 RunLoop(); | 1281 RunLoop(); |
| 1341 | 1282 |
| 1342 // Normally OnCredentialsUpdated calls TryCanaryJob that doesn't run Poll, | 1283 // Normally OnCredentialsUpdated calls TryCanaryJob that doesn't run Poll, |
| 1343 // but after poll finished with auth error from poll timer it should retry | 1284 // but after poll finished with auth error from poll timer it should retry |
| 1344 // poll once more | 1285 // poll once more |
| 1345 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) | 1286 EXPECT_CALL(*syncer(), PollSyncShare(_,_)) |
| 1346 .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), | 1287 .WillOnce(DoAll(Invoke(sessions::test_util::SimulatePollSuccess), |
| 1347 RecordSyncShare(×, true))); | 1288 RecordSyncShare(×))); |
| 1348 scheduler()->OnCredentialsUpdated(); | 1289 scheduler()->OnCredentialsUpdated(); |
| 1349 connection()->SetServerStatus(HttpResponse::SERVER_CONNECTION_OK); | 1290 connection()->SetServerStatus(HttpResponse::SERVER_CONNECTION_OK); |
| 1350 RunLoop(); | 1291 RunLoop(); |
| 1351 StopSyncScheduler(); | 1292 StopSyncScheduler(); |
| 1352 } | 1293 } |
| 1353 | 1294 |
| 1354 TEST_F(SyncSchedulerTest, SuccessfulRetry) { | 1295 TEST_F(SyncSchedulerTest, SuccessfulRetry) { |
| 1355 StartSyncScheduler(base::Time()); | 1296 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1356 | 1297 |
| 1357 SyncShareTimes times; | 1298 SyncShareTimes times; |
| 1358 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10); | 1299 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10); |
| 1359 scheduler()->OnReceivedGuRetryDelay(delay); | 1300 scheduler()->OnReceivedGuRetryDelay(delay); |
| 1360 EXPECT_EQ(delay, GetRetryTimerDelay()); | 1301 EXPECT_EQ(delay, GetRetryTimerDelay()); |
| 1361 | 1302 |
| 1362 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 1303 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 1363 .WillOnce( | 1304 .WillOnce( |
| 1364 DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 1305 DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 1365 RecordSyncShare(×, true))); | 1306 RecordSyncShare(×))); |
| 1366 | 1307 |
| 1367 // Run to wait for retrying. | 1308 // Run to wait for retrying. |
| 1368 RunLoop(); | 1309 RunLoop(); |
| 1369 | 1310 |
| 1370 StopSyncScheduler(); | 1311 StopSyncScheduler(); |
| 1371 } | 1312 } |
| 1372 | 1313 |
| 1373 TEST_F(SyncSchedulerTest, FailedRetry) { | 1314 TEST_F(SyncSchedulerTest, FailedRetry) { |
| 1374 SyncShareTimes times; | |
| 1375 | |
| 1376 UseMockDelayProvider(); | 1315 UseMockDelayProvider(); |
| 1377 EXPECT_CALL(*delay(), GetDelay(_)) | 1316 EXPECT_CALL(*delay(), GetDelay(_)) |
| 1378 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(10))); | 1317 .WillRepeatedly(Return(TimeDelta::FromMilliseconds(10))); |
| 1379 | 1318 |
| 1380 StartSyncScheduler(base::Time()); | 1319 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1381 | 1320 |
| 1382 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10); | 1321 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10); |
| 1383 scheduler()->OnReceivedGuRetryDelay(delay); | 1322 scheduler()->OnReceivedGuRetryDelay(delay); |
| 1384 | 1323 |
| 1385 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 1324 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 1386 .WillOnce( | 1325 .WillOnce( |
| 1387 DoAll(Invoke(sessions::test_util::SimulateDownloadUpdatesFailed), | 1326 DoAll(Invoke(sessions::test_util::SimulateDownloadUpdatesFailed), |
| 1388 RecordSyncShare(×, false))); | 1327 QuitLoopNowAction())); |
| 1389 | 1328 |
| 1390 // Run to wait for retrying. | 1329 // Run to wait for retrying. |
| 1391 RunLoop(); | 1330 RunLoop(); |
| 1392 | 1331 |
| 1393 EXPECT_TRUE(scheduler()->IsBackingOff()); | 1332 EXPECT_TRUE(scheduler()->IsBackingOff()); |
| 1394 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 1333 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 1395 .WillOnce( | 1334 .WillOnce( |
| 1396 DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 1335 DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 1397 RecordSyncShare(×, true))); | 1336 QuitLoopNowAction())); |
| 1398 | 1337 |
| 1399 // Run to wait for second retrying. | 1338 // Run to wait for second retrying. |
| 1400 RunLoop(); | 1339 RunLoop(); |
| 1401 | 1340 |
| 1402 StopSyncScheduler(); | 1341 StopSyncScheduler(); |
| 1403 } | 1342 } |
| 1404 | 1343 |
| 1405 ACTION_P2(VerifyRetryTimerDelay, scheduler_test, expected_delay) { | 1344 ACTION_P2(VerifyRetryTimerDelay, scheduler_test, expected_delay) { |
| 1406 EXPECT_EQ(expected_delay, scheduler_test->GetRetryTimerDelay()); | 1345 EXPECT_EQ(expected_delay, scheduler_test->GetRetryTimerDelay()); |
| 1407 } | 1346 } |
| 1408 | 1347 |
| 1409 TEST_F(SyncSchedulerTest, ReceiveNewRetryDelay) { | 1348 TEST_F(SyncSchedulerTest, ReceiveNewRetryDelay) { |
| 1410 StartSyncScheduler(base::Time()); | 1349 StartSyncScheduler(SyncScheduler::NORMAL_MODE); |
| 1411 | 1350 |
| 1412 SyncShareTimes times; | 1351 SyncShareTimes times; |
| 1413 base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(100); | 1352 base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(100); |
| 1414 base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(200); | 1353 base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(200); |
| 1415 | 1354 |
| 1416 scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE); | 1355 scheduler()->ScheduleLocalNudge(ModelTypeSet(THEMES), FROM_HERE); |
| 1417 scheduler()->OnReceivedGuRetryDelay(delay1); | 1356 scheduler()->OnReceivedGuRetryDelay(delay1); |
| 1418 EXPECT_EQ(delay1, GetRetryTimerDelay()); | 1357 EXPECT_EQ(delay1, GetRetryTimerDelay()); |
| 1419 | 1358 |
| 1420 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 1359 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 1421 .WillOnce(DoAll( | 1360 .WillOnce(DoAll( |
| 1422 WithoutArgs(VerifyRetryTimerDelay(this, delay1)), | 1361 WithoutArgs(VerifyRetryTimerDelay(this, delay1)), |
| 1423 WithArg<2>(sessions::test_util::SimulateGuRetryDelayCommand(delay2)), | 1362 WithArg<2>(sessions::test_util::SimulateGuRetryDelayCommand(delay2)), |
| 1424 RecordSyncShare(×, true))); | 1363 RecordSyncShare(×))); |
| 1425 | 1364 |
| 1426 // Run nudge GU. | 1365 // Run nudge GU. |
| 1427 RunLoop(); | 1366 RunLoop(); |
| 1428 EXPECT_EQ(delay2, GetRetryTimerDelay()); | 1367 EXPECT_EQ(delay2, GetRetryTimerDelay()); |
| 1429 | 1368 |
| 1430 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) | 1369 EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_)) |
| 1431 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), | 1370 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess), |
| 1432 RecordSyncShare(×, true))); | 1371 RecordSyncShare(×))); |
| 1433 | 1372 |
| 1434 // Run to wait for retrying. | 1373 // Run to wait for retrying. |
| 1435 RunLoop(); | 1374 RunLoop(); |
| 1436 | 1375 |
| 1437 StopSyncScheduler(); | 1376 StopSyncScheduler(); |
| 1438 } | 1377 } |
| 1439 | 1378 |
| 1440 } // namespace syncer | 1379 } // namespace syncer |
| OLD | NEW |